callman-mcp 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/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/dist/client/api.d.ts +109 -0
- package/dist/client/api.d.ts.map +1 -0
- package/dist/client/api.js +180 -0
- package/dist/client/api.js.map +1 -0
- package/dist/client/errors.d.ts +27 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +98 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/http.d.ts +34 -0
- package/dist/client/http.d.ts.map +1 -0
- package/dist/client/http.js +121 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/types.d.ts +327 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +5 -0
- package/dist/client/types.js.map +1 -0
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +69 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +35 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +91 -0
- package/dist/context.js.map +1 -0
- package/dist/domain/diagram/build.d.ts +260 -0
- package/dist/domain/diagram/build.d.ts.map +1 -0
- package/dist/domain/diagram/build.js +160 -0
- package/dist/domain/diagram/build.js.map +1 -0
- package/dist/domain/diagram/layout.d.ts +17 -0
- package/dist/domain/diagram/layout.d.ts.map +1 -0
- package/dist/domain/diagram/layout.js +61 -0
- package/dist/domain/diagram/layout.js.map +1 -0
- package/dist/domain/diagram/patch.d.ts +330 -0
- package/dist/domain/diagram/patch.d.ts.map +1 -0
- package/dist/domain/diagram/patch.js +176 -0
- package/dist/domain/diagram/patch.js.map +1 -0
- package/dist/domain/diagram/summarize.d.ts +41 -0
- package/dist/domain/diagram/summarize.d.ts.map +1 -0
- package/dist/domain/diagram/summarize.js +47 -0
- package/dist/domain/diagram/summarize.js.map +1 -0
- package/dist/domain/importDetect.d.ts +6 -0
- package/dist/domain/importDetect.d.ts.map +1 -0
- package/dist/domain/importDetect.js +32 -0
- package/dist/domain/importDetect.js.map +1 -0
- package/dist/domain/requestShape.d.ts +796 -0
- package/dist/domain/requestShape.d.ts.map +1 -0
- package/dist/domain/requestShape.js +250 -0
- package/dist/domain/requestShape.js.map +1 -0
- package/dist/domain/resolve.d.ts +30 -0
- package/dist/domain/resolve.d.ts.map +1 -0
- package/dist/domain/resolve.js +56 -0
- package/dist/domain/resolve.js.map +1 -0
- package/dist/domain/scenario/build.d.ts +270 -0
- package/dist/domain/scenario/build.d.ts.map +1 -0
- package/dist/domain/scenario/build.js +135 -0
- package/dist/domain/scenario/build.js.map +1 -0
- package/dist/domain/scenario/summarize.d.ts +206 -0
- package/dist/domain/scenario/summarize.d.ts.map +1 -0
- package/dist/domain/scenario/summarize.js +138 -0
- package/dist/domain/scenario/summarize.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +142 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cache.d.ts +12 -0
- package/dist/lib/cache.d.ts.map +1 -0
- package/dist/lib/cache.js +40 -0
- package/dist/lib/cache.js.map +1 -0
- package/dist/lib/ids.d.ts +5 -0
- package/dist/lib/ids.d.ts.map +1 -0
- package/dist/lib/ids.js +19 -0
- package/dist/lib/ids.js.map +1 -0
- package/dist/lib/log.d.ts +10 -0
- package/dist/lib/log.d.ts.map +1 -0
- package/dist/lib/log.js +25 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/lib/mask.d.ts +24 -0
- package/dist/lib/mask.d.ts.map +1 -0
- package/dist/lib/mask.js +63 -0
- package/dist/lib/mask.js.map +1 -0
- package/dist/lib/pagination.d.ts +21 -0
- package/dist/lib/pagination.d.ts.map +1 -0
- package/dist/lib/pagination.js +40 -0
- package/dist/lib/pagination.js.map +1 -0
- package/dist/lib/truncate.d.ts +25 -0
- package/dist/lib/truncate.d.ts.map +1 -0
- package/dist/lib/truncate.js +45 -0
- package/dist/lib/truncate.js.map +1 -0
- package/dist/main.d.ts +9 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +12 -0
- package/dist/main.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +72 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/docs/diagramSchema.d.ts +2 -0
- package/dist/resources/docs/diagramSchema.d.ts.map +1 -0
- package/dist/resources/docs/diagramSchema.js +65 -0
- package/dist/resources/docs/diagramSchema.js.map +1 -0
- package/dist/resources/docs/overview.d.ts +2 -0
- package/dist/resources/docs/overview.d.ts.map +1 -0
- package/dist/resources/docs/overview.js +46 -0
- package/dist/resources/docs/overview.js.map +1 -0
- package/dist/resources/docs/requestSchema.d.ts +2 -0
- package/dist/resources/docs/requestSchema.d.ts.map +1 -0
- package/dist/resources/docs/requestSchema.js +70 -0
- package/dist/resources/docs/requestSchema.js.map +1 -0
- package/dist/resources/generated/aiPacks.d.ts +3 -0
- package/dist/resources/generated/aiPacks.d.ts.map +1 -0
- package/dist/resources/generated/aiPacks.js +11 -0
- package/dist/resources/generated/aiPacks.js.map +1 -0
- package/dist/resources/index.d.ts +4 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +114 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/run/executeCollection.d.ts +19 -0
- package/dist/run/executeCollection.d.ts.map +1 -0
- package/dist/run/executeCollection.js +89 -0
- package/dist/run/executeCollection.js.map +1 -0
- package/dist/run/loadBundle.d.ts +9 -0
- package/dist/run/loadBundle.d.ts.map +1 -0
- package/dist/run/loadBundle.js +242 -0
- package/dist/run/loadBundle.js.map +1 -0
- package/dist/run/resolveTemplate.d.ts +2 -0
- package/dist/run/resolveTemplate.d.ts.map +1 -0
- package/dist/run/resolveTemplate.js +12 -0
- package/dist/run/resolveTemplate.js.map +1 -0
- package/dist/run/summarize.d.ts +73 -0
- package/dist/run/summarize.d.ts.map +1 -0
- package/dist/run/summarize.js +69 -0
- package/dist/run/summarize.js.map +1 -0
- package/dist/run/types.d.ts +46 -0
- package/dist/run/types.d.ts.map +1 -0
- package/dist/run/types.js +2 -0
- package/dist/run/types.js.map +1 -0
- package/dist/server.d.ts +23 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +25 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/catalog.d.ts +18 -0
- package/dist/tools/catalog.d.ts.map +1 -0
- package/dist/tools/catalog.js +66 -0
- package/dist/tools/catalog.js.map +1 -0
- package/dist/tools/collections.d.ts +4 -0
- package/dist/tools/collections.d.ts.map +1 -0
- package/dist/tools/collections.js +201 -0
- package/dist/tools/collections.js.map +1 -0
- package/dist/tools/diagrams.d.ts +4 -0
- package/dist/tools/diagrams.d.ts.map +1 -0
- package/dist/tools/diagrams.js +226 -0
- package/dist/tools/diagrams.js.map +1 -0
- package/dist/tools/environments.d.ts +4 -0
- package/dist/tools/environments.d.ts.map +1 -0
- package/dist/tools/environments.js +150 -0
- package/dist/tools/environments.js.map +1 -0
- package/dist/tools/import.d.ts +6 -0
- package/dist/tools/import.d.ts.map +1 -0
- package/dist/tools/import.js +144 -0
- package/dist/tools/import.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +26 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/lookups.d.ts +33 -0
- package/dist/tools/lookups.d.ts.map +1 -0
- package/dist/tools/lookups.js +132 -0
- package/dist/tools/lookups.js.map +1 -0
- package/dist/tools/meta.d.ts +4 -0
- package/dist/tools/meta.d.ts.map +1 -0
- package/dist/tools/meta.js +78 -0
- package/dist/tools/meta.js.map +1 -0
- package/dist/tools/requests.d.ts +4 -0
- package/dist/tools/requests.d.ts.map +1 -0
- package/dist/tools/requests.js +247 -0
- package/dist/tools/requests.js.map +1 -0
- package/dist/tools/run.d.ts +4 -0
- package/dist/tools/run.d.ts.map +1 -0
- package/dist/tools/run.js +167 -0
- package/dist/tools/run.js.map +1 -0
- package/dist/tools/scenarios.d.ts +4 -0
- package/dist/tools/scenarios.d.ts.map +1 -0
- package/dist/tools/scenarios.js +242 -0
- package/dist/tools/scenarios.js.map +1 -0
- package/dist/tools/shared.d.ts +20 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +74 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/workspaces.d.ts +4 -0
- package/dist/tools/workspaces.d.ts.map +1 -0
- package/dist/tools/workspaces.js +80 -0
- package/dist/tools/workspaces.js.map +1 -0
- package/dist-cjs/client/api.js +183 -0
- package/dist-cjs/client/errors.js +104 -0
- package/dist-cjs/client/http.js +124 -0
- package/dist-cjs/client/types.js +5 -0
- package/dist-cjs/config.js +73 -0
- package/dist-cjs/context.js +94 -0
- package/dist-cjs/domain/diagram/build.js +164 -0
- package/dist-cjs/domain/diagram/layout.js +98 -0
- package/dist-cjs/domain/diagram/patch.js +179 -0
- package/dist-cjs/domain/diagram/summarize.js +52 -0
- package/dist-cjs/domain/importDetect.js +40 -0
- package/dist-cjs/domain/requestShape.js +260 -0
- package/dist-cjs/domain/resolve.js +63 -0
- package/dist-cjs/domain/scenario/build.js +140 -0
- package/dist-cjs/domain/scenario/summarize.js +144 -0
- package/dist-cjs/lib/cache.js +43 -0
- package/dist-cjs/lib/ids.js +24 -0
- package/dist-cjs/lib/log.js +28 -0
- package/dist-cjs/lib/mask.js +72 -0
- package/dist-cjs/lib/pagination.js +48 -0
- package/dist-cjs/lib/truncate.js +52 -0
- package/dist-cjs/main.js +31 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/prompts/index.js +75 -0
- package/dist-cjs/resources/docs/diagramSchema.js +67 -0
- package/dist-cjs/resources/docs/overview.js +48 -0
- package/dist-cjs/resources/docs/requestSchema.js +72 -0
- package/dist-cjs/resources/generated/aiPacks.js +13 -0
- package/dist-cjs/resources/index.js +117 -0
- package/dist-cjs/run/executeCollection.js +93 -0
- package/dist-cjs/run/loadBundle.js +246 -0
- package/dist-cjs/run/resolveTemplate.js +15 -0
- package/dist-cjs/run/summarize.js +73 -0
- package/dist-cjs/run/types.js +2 -0
- package/dist-cjs/server.js +28 -0
- package/dist-cjs/tools/catalog.js +69 -0
- package/dist-cjs/tools/collections.js +204 -0
- package/dist-cjs/tools/diagrams.js +229 -0
- package/dist-cjs/tools/environments.js +153 -0
- package/dist-cjs/tools/import.js +147 -0
- package/dist-cjs/tools/index.js +31 -0
- package/dist-cjs/tools/lookups.js +149 -0
- package/dist-cjs/tools/meta.js +81 -0
- package/dist-cjs/tools/requests.js +250 -0
- package/dist-cjs/tools/run.js +203 -0
- package/dist-cjs/tools/scenarios.js +245 -0
- package/dist-cjs/tools/shared.js +81 -0
- package/dist-cjs/tools/workspaces.js +83 -0
- package/package.json +80 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Configuration for the callman-mcp server, resolved ONCE at startup from
|
|
2
|
+
// environment variables (the only host-specific input) and frozen. Every
|
|
3
|
+
// other module reads the resolved object — never process.env — so the same
|
|
4
|
+
// tool layer can be hosted by the backend later with a different source.
|
|
5
|
+
//
|
|
6
|
+
// CALLMAN_API_URL server ORIGIN (https://api.callman.io, or the
|
|
7
|
+
// on-prem address incl. any prefix); `/api` is
|
|
8
|
+
// appended here, exactly like callme-cli.
|
|
9
|
+
// CALLMAN_TOKEN personal token (cm_pat_…) from Settings → AI tools
|
|
10
|
+
// CALLMAN_TOKEN_FILE alternative: path of a file holding the token
|
|
11
|
+
// CALLMAN_WORKSPACE_ID default workspace (optional — tools resolve it)
|
|
12
|
+
// CALLMAN_ALLOW_RUN "0"/"false" disables local request execution
|
|
13
|
+
// CALLMAN_LOG_LEVEL silent | error | warn | info | debug (stderr)
|
|
14
|
+
// CALLMAN_TIMEOUT_MS per API call (default 30s)
|
|
15
|
+
// CALLMAN_RUN_TIMEOUT_MS whole local run (default 10 min)
|
|
16
|
+
// CALLMAN_MAX_BODY_BYTES response-body preview cap in run output (16 KB)
|
|
17
|
+
export const DEFAULT_CLOUD_API_URL = "https://api.callman.io";
|
|
18
|
+
const LOG_LEVELS = ["silent", "error", "warn", "info", "debug"];
|
|
19
|
+
export const MAX_BODY_BYTES_LIMIT = 256 * 1024;
|
|
20
|
+
const pick = (...candidates) => {
|
|
21
|
+
for (const candidate of candidates) {
|
|
22
|
+
if (typeof candidate === "string" && candidate.trim() !== "")
|
|
23
|
+
return candidate.trim();
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
};
|
|
27
|
+
const numberOr = (raw, fallback, min, max) => {
|
|
28
|
+
const parsed = raw === undefined ? NaN : Number(raw);
|
|
29
|
+
if (!Number.isFinite(parsed))
|
|
30
|
+
return fallback;
|
|
31
|
+
return Math.min(max, Math.max(min, Math.floor(parsed)));
|
|
32
|
+
};
|
|
33
|
+
const boolOr = (raw, fallback) => {
|
|
34
|
+
if (raw === undefined || raw.trim() === "")
|
|
35
|
+
return fallback;
|
|
36
|
+
return !["0", "false", "no", "off"].includes(raw.trim().toLowerCase());
|
|
37
|
+
};
|
|
38
|
+
export const normalizeApiUrl = (raw) => {
|
|
39
|
+
let url = raw.trim().replace(/\/+$/, "");
|
|
40
|
+
// Accept the desktop's VITE_API_URL form (…/api) too — the client appends /api.
|
|
41
|
+
url = url.replace(/\/api$/i, "");
|
|
42
|
+
if (!/^https?:\/\//i.test(url)) {
|
|
43
|
+
throw new Error(`CALLMAN_API_URL must start with http:// or https:// (got "${raw}")`);
|
|
44
|
+
}
|
|
45
|
+
return url;
|
|
46
|
+
};
|
|
47
|
+
export const resolveConfig = ({ env, readTokenFile }) => {
|
|
48
|
+
const apiUrl = normalizeApiUrl(pick(env.CALLMAN_API_URL) ?? DEFAULT_CLOUD_API_URL);
|
|
49
|
+
let token = pick(env.CALLMAN_TOKEN);
|
|
50
|
+
const tokenFile = pick(env.CALLMAN_TOKEN_FILE);
|
|
51
|
+
if (!token && tokenFile) {
|
|
52
|
+
if (!readTokenFile)
|
|
53
|
+
throw new Error("CALLMAN_TOKEN_FILE is set but no file reader is available");
|
|
54
|
+
token = readTokenFile(tokenFile).trim() || null;
|
|
55
|
+
}
|
|
56
|
+
const logLevelRaw = (pick(env.CALLMAN_LOG_LEVEL) ?? "warn").toLowerCase();
|
|
57
|
+
const logLevel = LOG_LEVELS.includes(logLevelRaw) ? logLevelRaw : "warn";
|
|
58
|
+
return Object.freeze({
|
|
59
|
+
apiUrl,
|
|
60
|
+
token,
|
|
61
|
+
defaultWorkspaceId: pick(env.CALLMAN_WORKSPACE_ID),
|
|
62
|
+
allowLocalRun: boolOr(env.CALLMAN_ALLOW_RUN, true),
|
|
63
|
+
logLevel,
|
|
64
|
+
timeoutMs: numberOr(env.CALLMAN_TIMEOUT_MS, 30_000, 1_000, 600_000),
|
|
65
|
+
runTimeoutMs: numberOr(env.CALLMAN_RUN_TIMEOUT_MS, 600_000, 1_000, 3_600_000),
|
|
66
|
+
maxBodyBytes: numberOr(env.CALLMAN_MAX_BODY_BYTES, 16 * 1024, 256, MAX_BODY_BYTES_LIMIT),
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CallmanApi } from "./client/api.js";
|
|
2
|
+
import type { Workspace } from "./client/types.js";
|
|
3
|
+
import type { CallmanMcpConfig } from "./config.js";
|
|
4
|
+
import { TtlCache } from "./lib/cache.js";
|
|
5
|
+
import { type Logger } from "./lib/log.js";
|
|
6
|
+
export interface ToolContext {
|
|
7
|
+
config: CallmanMcpConfig;
|
|
8
|
+
api: CallmanApi;
|
|
9
|
+
logger: Logger;
|
|
10
|
+
cache: TtlCache;
|
|
11
|
+
version: string;
|
|
12
|
+
resolveWorkspace(explicit?: string | null): Promise<Workspace>;
|
|
13
|
+
resolveWorkspaceOrNull(explicit?: string | null): Promise<Workspace | null>;
|
|
14
|
+
listWorkspaces(): Promise<Workspace[]>;
|
|
15
|
+
getTokenScopes(): Promise<string[]>;
|
|
16
|
+
withRunLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
17
|
+
invalidate(prefix?: string): void;
|
|
18
|
+
pollDelaysMs: {
|
|
19
|
+
fast: number;
|
|
20
|
+
slow: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface CreateContextOptions {
|
|
24
|
+
config: CallmanMcpConfig;
|
|
25
|
+
version: string;
|
|
26
|
+
fetch?: typeof fetch;
|
|
27
|
+
logger?: Logger;
|
|
28
|
+
cacheTtlMs?: number;
|
|
29
|
+
pollDelaysMs?: {
|
|
30
|
+
fast: number;
|
|
31
|
+
slow: number;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export declare const createToolContext: (options: CreateContextOptions) => ToolContext;
|
|
35
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,cAAc,CAAC;AAMzD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,UAAU,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAKhB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAG/D,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5E,cAAc,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAGvC,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAGpC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,eAAO,MAAM,iBAAiB,GAAI,SAAS,oBAAoB,KAAG,WAwFjE,CAAC"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { CallmanApi } from "./client/api.js";
|
|
2
|
+
import { ToolInputError } from "./client/errors.js";
|
|
3
|
+
import { CallmanHttpClient } from "./client/http.js";
|
|
4
|
+
import { TtlCache } from "./lib/cache.js";
|
|
5
|
+
import { isObjectId, normalizeName } from "./lib/ids.js";
|
|
6
|
+
import { silentLogger } from "./lib/log.js";
|
|
7
|
+
export const createToolContext = (options) => {
|
|
8
|
+
const logger = options.logger ?? silentLogger;
|
|
9
|
+
const http = new CallmanHttpClient({
|
|
10
|
+
apiUrl: options.config.apiUrl,
|
|
11
|
+
token: options.config.token,
|
|
12
|
+
fetch: options.fetch,
|
|
13
|
+
timeoutMs: options.config.timeoutMs,
|
|
14
|
+
userAgent: `callman-mcp/${options.version}`,
|
|
15
|
+
logger,
|
|
16
|
+
});
|
|
17
|
+
const api = new CallmanApi(http);
|
|
18
|
+
const cache = new TtlCache(options.cacheTtlMs ?? 15_000);
|
|
19
|
+
let runLock = Promise.resolve();
|
|
20
|
+
const listWorkspaces = () => cache.getOrSet("workspaces", () => api.listWorkspaces());
|
|
21
|
+
const pickWorkspace = async (explicit, required) => {
|
|
22
|
+
const workspaces = await listWorkspaces();
|
|
23
|
+
const wanted = (explicit ?? "").trim() || options.config.defaultWorkspaceId || "";
|
|
24
|
+
if (wanted) {
|
|
25
|
+
const byId = workspaces.find((workspace) => workspace.id === wanted);
|
|
26
|
+
if (byId)
|
|
27
|
+
return byId;
|
|
28
|
+
const needle = normalizeName(wanted);
|
|
29
|
+
const byName = workspaces.filter((workspace) => normalizeName(workspace.name) === needle);
|
|
30
|
+
if (byName.length === 1)
|
|
31
|
+
return byName[0];
|
|
32
|
+
const byPartial = workspaces.filter((workspace) => normalizeName(workspace.name).includes(needle));
|
|
33
|
+
if (byName.length === 0 && byPartial.length === 1)
|
|
34
|
+
return byPartial[0];
|
|
35
|
+
if (isObjectId(wanted) && explicit) {
|
|
36
|
+
// A well-formed id that is not in the list: let the server answer
|
|
37
|
+
// (it may be a workspace the user was just added to).
|
|
38
|
+
return { id: wanted, name: wanted, role: "viewer" };
|
|
39
|
+
}
|
|
40
|
+
if (!required)
|
|
41
|
+
return null;
|
|
42
|
+
throw new ToolInputError(byName.length > 1 || byPartial.length > 1 ? "WORKSPACE_AMBIGUOUS" : "WORKSPACE_NOT_FOUND", byName.length > 1 || byPartial.length > 1
|
|
43
|
+
? `Several workspaces match "${wanted}". Pass the id instead.`
|
|
44
|
+
: `No workspace matches "${wanted}".`, { candidates: summarize(byPartial.length > 0 ? byPartial : workspaces) });
|
|
45
|
+
}
|
|
46
|
+
if (workspaces.length === 1)
|
|
47
|
+
return workspaces[0];
|
|
48
|
+
if (!required)
|
|
49
|
+
return null;
|
|
50
|
+
throw new ToolInputError(workspaces.length === 0 ? "WORKSPACE_NONE" : "WORKSPACE_REQUIRED", workspaces.length === 0
|
|
51
|
+
? "You are not a member of any workspace."
|
|
52
|
+
: "Several workspaces are available — pass `workspace` (name or id) or set CALLMAN_WORKSPACE_ID.", { candidates: summarize(workspaces) });
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
config: options.config,
|
|
56
|
+
api,
|
|
57
|
+
logger,
|
|
58
|
+
cache,
|
|
59
|
+
version: options.version,
|
|
60
|
+
listWorkspaces,
|
|
61
|
+
getTokenScopes: () => cache.getOrSet("token-scopes", async () => {
|
|
62
|
+
try {
|
|
63
|
+
return (await api.me()).token.scopes ?? [];
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
logger.debug("could not read token scopes", error instanceof Error ? error.message : error);
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
}),
|
|
70
|
+
resolveWorkspace: async (explicit) => (await pickWorkspace(explicit, true)),
|
|
71
|
+
resolveWorkspaceOrNull: (explicit) => pickWorkspace(explicit, false),
|
|
72
|
+
withRunLock: async (fn) => {
|
|
73
|
+
const previous = runLock;
|
|
74
|
+
let release = () => { };
|
|
75
|
+
runLock = new Promise((resolve) => {
|
|
76
|
+
release = resolve;
|
|
77
|
+
});
|
|
78
|
+
try {
|
|
79
|
+
await previous.catch(() => undefined);
|
|
80
|
+
return await fn();
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
release();
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
invalidate: (prefix) => (prefix ? cache.delete(prefix) : cache.clear()),
|
|
87
|
+
pollDelaysMs: options.pollDelaysMs ?? { fast: 2000, slow: 5000 },
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
const summarize = (workspaces) => workspaces.slice(0, 20).map((workspace) => ({ id: workspace.id, name: workspace.name, role: workspace.role }));
|
|
91
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { type DiagramDocument } from "callman-core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const EDGE_SEMANTICS_INPUT: readonly ["sync", "async", "fallback", "bus"];
|
|
4
|
+
export declare const diagramNodeInputSchema: z.ZodObject<{
|
|
5
|
+
id: z.ZodOptional<z.ZodString>;
|
|
6
|
+
type: z.ZodString;
|
|
7
|
+
label: z.ZodOptional<z.ZodString>;
|
|
8
|
+
parent: z.ZodOptional<z.ZodString>;
|
|
9
|
+
position: z.ZodOptional<z.ZodObject<{
|
|
10
|
+
x: z.ZodNumber;
|
|
11
|
+
y: z.ZodNumber;
|
|
12
|
+
}, "strip", z.ZodTypeAny, {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
}, {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
}>>;
|
|
19
|
+
size: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
width: z.ZodNumber;
|
|
21
|
+
height: z.ZodNumber;
|
|
22
|
+
}, "strip", z.ZodTypeAny, {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
}, {
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
}>>;
|
|
29
|
+
style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
30
|
+
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
31
|
+
}, "strip", z.ZodTypeAny, {
|
|
32
|
+
type: string;
|
|
33
|
+
data?: Record<string, unknown> | undefined;
|
|
34
|
+
id?: string | undefined;
|
|
35
|
+
parent?: string | undefined;
|
|
36
|
+
size?: {
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
} | undefined;
|
|
40
|
+
label?: string | undefined;
|
|
41
|
+
position?: {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
} | undefined;
|
|
45
|
+
style?: Record<string, unknown> | undefined;
|
|
46
|
+
}, {
|
|
47
|
+
type: string;
|
|
48
|
+
data?: Record<string, unknown> | undefined;
|
|
49
|
+
id?: string | undefined;
|
|
50
|
+
parent?: string | undefined;
|
|
51
|
+
size?: {
|
|
52
|
+
width: number;
|
|
53
|
+
height: number;
|
|
54
|
+
} | undefined;
|
|
55
|
+
label?: string | undefined;
|
|
56
|
+
position?: {
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
} | undefined;
|
|
60
|
+
style?: Record<string, unknown> | undefined;
|
|
61
|
+
}>;
|
|
62
|
+
export declare const diagramEdgeInputSchema: z.ZodObject<{
|
|
63
|
+
id: z.ZodOptional<z.ZodString>;
|
|
64
|
+
source: z.ZodString;
|
|
65
|
+
target: z.ZodString;
|
|
66
|
+
label: z.ZodOptional<z.ZodString>;
|
|
67
|
+
semantic: z.ZodOptional<z.ZodEnum<["sync", "async", "fallback", "bus"]>>;
|
|
68
|
+
routing: z.ZodOptional<z.ZodEnum<["orthogonal", "straight", "curved"]>>;
|
|
69
|
+
markerEnd: z.ZodOptional<z.ZodEnum<["none", "classic", "classicThin", "open", "block", "diamond", "oval"]>>;
|
|
70
|
+
}, "strip", z.ZodTypeAny, {
|
|
71
|
+
source: string;
|
|
72
|
+
target: string;
|
|
73
|
+
id?: string | undefined;
|
|
74
|
+
label?: string | undefined;
|
|
75
|
+
semantic?: "sync" | "async" | "fallback" | "bus" | undefined;
|
|
76
|
+
routing?: "orthogonal" | "straight" | "curved" | undefined;
|
|
77
|
+
markerEnd?: "none" | "classic" | "classicThin" | "open" | "block" | "diamond" | "oval" | undefined;
|
|
78
|
+
}, {
|
|
79
|
+
source: string;
|
|
80
|
+
target: string;
|
|
81
|
+
id?: string | undefined;
|
|
82
|
+
label?: string | undefined;
|
|
83
|
+
semantic?: "sync" | "async" | "fallback" | "bus" | undefined;
|
|
84
|
+
routing?: "orthogonal" | "straight" | "curved" | undefined;
|
|
85
|
+
markerEnd?: "none" | "classic" | "classicThin" | "open" | "block" | "diamond" | "oval" | undefined;
|
|
86
|
+
}>;
|
|
87
|
+
export declare const diagramInputSchema: z.ZodObject<{
|
|
88
|
+
title: z.ZodString;
|
|
89
|
+
nodes: z.ZodArray<z.ZodObject<{
|
|
90
|
+
id: z.ZodOptional<z.ZodString>;
|
|
91
|
+
type: z.ZodString;
|
|
92
|
+
label: z.ZodOptional<z.ZodString>;
|
|
93
|
+
parent: z.ZodOptional<z.ZodString>;
|
|
94
|
+
position: z.ZodOptional<z.ZodObject<{
|
|
95
|
+
x: z.ZodNumber;
|
|
96
|
+
y: z.ZodNumber;
|
|
97
|
+
}, "strip", z.ZodTypeAny, {
|
|
98
|
+
x: number;
|
|
99
|
+
y: number;
|
|
100
|
+
}, {
|
|
101
|
+
x: number;
|
|
102
|
+
y: number;
|
|
103
|
+
}>>;
|
|
104
|
+
size: z.ZodOptional<z.ZodObject<{
|
|
105
|
+
width: z.ZodNumber;
|
|
106
|
+
height: z.ZodNumber;
|
|
107
|
+
}, "strip", z.ZodTypeAny, {
|
|
108
|
+
width: number;
|
|
109
|
+
height: number;
|
|
110
|
+
}, {
|
|
111
|
+
width: number;
|
|
112
|
+
height: number;
|
|
113
|
+
}>>;
|
|
114
|
+
style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
115
|
+
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
116
|
+
}, "strip", z.ZodTypeAny, {
|
|
117
|
+
type: string;
|
|
118
|
+
data?: Record<string, unknown> | undefined;
|
|
119
|
+
id?: string | undefined;
|
|
120
|
+
parent?: string | undefined;
|
|
121
|
+
size?: {
|
|
122
|
+
width: number;
|
|
123
|
+
height: number;
|
|
124
|
+
} | undefined;
|
|
125
|
+
label?: string | undefined;
|
|
126
|
+
position?: {
|
|
127
|
+
x: number;
|
|
128
|
+
y: number;
|
|
129
|
+
} | undefined;
|
|
130
|
+
style?: Record<string, unknown> | undefined;
|
|
131
|
+
}, {
|
|
132
|
+
type: string;
|
|
133
|
+
data?: Record<string, unknown> | undefined;
|
|
134
|
+
id?: string | undefined;
|
|
135
|
+
parent?: string | undefined;
|
|
136
|
+
size?: {
|
|
137
|
+
width: number;
|
|
138
|
+
height: number;
|
|
139
|
+
} | undefined;
|
|
140
|
+
label?: string | undefined;
|
|
141
|
+
position?: {
|
|
142
|
+
x: number;
|
|
143
|
+
y: number;
|
|
144
|
+
} | undefined;
|
|
145
|
+
style?: Record<string, unknown> | undefined;
|
|
146
|
+
}>, "many">;
|
|
147
|
+
edges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
148
|
+
id: z.ZodOptional<z.ZodString>;
|
|
149
|
+
source: z.ZodString;
|
|
150
|
+
target: z.ZodString;
|
|
151
|
+
label: z.ZodOptional<z.ZodString>;
|
|
152
|
+
semantic: z.ZodOptional<z.ZodEnum<["sync", "async", "fallback", "bus"]>>;
|
|
153
|
+
routing: z.ZodOptional<z.ZodEnum<["orthogonal", "straight", "curved"]>>;
|
|
154
|
+
markerEnd: z.ZodOptional<z.ZodEnum<["none", "classic", "classicThin", "open", "block", "diamond", "oval"]>>;
|
|
155
|
+
}, "strip", z.ZodTypeAny, {
|
|
156
|
+
source: string;
|
|
157
|
+
target: string;
|
|
158
|
+
id?: string | undefined;
|
|
159
|
+
label?: string | undefined;
|
|
160
|
+
semantic?: "sync" | "async" | "fallback" | "bus" | undefined;
|
|
161
|
+
routing?: "orthogonal" | "straight" | "curved" | undefined;
|
|
162
|
+
markerEnd?: "none" | "classic" | "classicThin" | "open" | "block" | "diamond" | "oval" | undefined;
|
|
163
|
+
}, {
|
|
164
|
+
source: string;
|
|
165
|
+
target: string;
|
|
166
|
+
id?: string | undefined;
|
|
167
|
+
label?: string | undefined;
|
|
168
|
+
semantic?: "sync" | "async" | "fallback" | "bus" | undefined;
|
|
169
|
+
routing?: "orthogonal" | "straight" | "curved" | undefined;
|
|
170
|
+
markerEnd?: "none" | "classic" | "classicThin" | "open" | "block" | "diamond" | "oval" | undefined;
|
|
171
|
+
}>, "many">>;
|
|
172
|
+
canvas: z.ZodOptional<z.ZodObject<{
|
|
173
|
+
background: z.ZodOptional<z.ZodEnum<["grid", "dots", "blank"]>>;
|
|
174
|
+
gridSize: z.ZodOptional<z.ZodNumber>;
|
|
175
|
+
}, "strip", z.ZodTypeAny, {
|
|
176
|
+
background?: "grid" | "dots" | "blank" | undefined;
|
|
177
|
+
gridSize?: number | undefined;
|
|
178
|
+
}, {
|
|
179
|
+
background?: "grid" | "dots" | "blank" | undefined;
|
|
180
|
+
gridSize?: number | undefined;
|
|
181
|
+
}>>;
|
|
182
|
+
}, "strip", z.ZodTypeAny, {
|
|
183
|
+
title: string;
|
|
184
|
+
nodes: {
|
|
185
|
+
type: string;
|
|
186
|
+
data?: Record<string, unknown> | undefined;
|
|
187
|
+
id?: string | undefined;
|
|
188
|
+
parent?: string | undefined;
|
|
189
|
+
size?: {
|
|
190
|
+
width: number;
|
|
191
|
+
height: number;
|
|
192
|
+
} | undefined;
|
|
193
|
+
label?: string | undefined;
|
|
194
|
+
position?: {
|
|
195
|
+
x: number;
|
|
196
|
+
y: number;
|
|
197
|
+
} | undefined;
|
|
198
|
+
style?: Record<string, unknown> | undefined;
|
|
199
|
+
}[];
|
|
200
|
+
edges: {
|
|
201
|
+
source: string;
|
|
202
|
+
target: string;
|
|
203
|
+
id?: string | undefined;
|
|
204
|
+
label?: string | undefined;
|
|
205
|
+
semantic?: "sync" | "async" | "fallback" | "bus" | undefined;
|
|
206
|
+
routing?: "orthogonal" | "straight" | "curved" | undefined;
|
|
207
|
+
markerEnd?: "none" | "classic" | "classicThin" | "open" | "block" | "diamond" | "oval" | undefined;
|
|
208
|
+
}[];
|
|
209
|
+
canvas?: {
|
|
210
|
+
background?: "grid" | "dots" | "blank" | undefined;
|
|
211
|
+
gridSize?: number | undefined;
|
|
212
|
+
} | undefined;
|
|
213
|
+
}, {
|
|
214
|
+
title: string;
|
|
215
|
+
nodes: {
|
|
216
|
+
type: string;
|
|
217
|
+
data?: Record<string, unknown> | undefined;
|
|
218
|
+
id?: string | undefined;
|
|
219
|
+
parent?: string | undefined;
|
|
220
|
+
size?: {
|
|
221
|
+
width: number;
|
|
222
|
+
height: number;
|
|
223
|
+
} | undefined;
|
|
224
|
+
label?: string | undefined;
|
|
225
|
+
position?: {
|
|
226
|
+
x: number;
|
|
227
|
+
y: number;
|
|
228
|
+
} | undefined;
|
|
229
|
+
style?: Record<string, unknown> | undefined;
|
|
230
|
+
}[];
|
|
231
|
+
edges?: {
|
|
232
|
+
source: string;
|
|
233
|
+
target: string;
|
|
234
|
+
id?: string | undefined;
|
|
235
|
+
label?: string | undefined;
|
|
236
|
+
semantic?: "sync" | "async" | "fallback" | "bus" | undefined;
|
|
237
|
+
routing?: "orthogonal" | "straight" | "curved" | undefined;
|
|
238
|
+
markerEnd?: "none" | "classic" | "classicThin" | "open" | "block" | "diamond" | "oval" | undefined;
|
|
239
|
+
}[] | undefined;
|
|
240
|
+
canvas?: {
|
|
241
|
+
background?: "grid" | "dots" | "blank" | undefined;
|
|
242
|
+
gridSize?: number | undefined;
|
|
243
|
+
} | undefined;
|
|
244
|
+
}>;
|
|
245
|
+
export type DiagramInput = z.infer<typeof diagramInputSchema>;
|
|
246
|
+
export type DiagramNodeInput = z.infer<typeof diagramNodeInputSchema>;
|
|
247
|
+
export type DiagramEdgeInput = z.infer<typeof diagramEdgeInputSchema>;
|
|
248
|
+
export interface BuildDiagramOptions {
|
|
249
|
+
strictTypes?: boolean;
|
|
250
|
+
existingId?: string;
|
|
251
|
+
createdAt?: string;
|
|
252
|
+
}
|
|
253
|
+
export interface BuildDiagramResult {
|
|
254
|
+
document: DiagramDocument;
|
|
255
|
+
warnings: string[];
|
|
256
|
+
unpositionedNodeIds: string[];
|
|
257
|
+
}
|
|
258
|
+
export declare const suggestComponentTypes: (type: string, limit?: number) => string[];
|
|
259
|
+
export declare const buildDiagramDocument: (input: DiagramInput, options?: BuildDiagramOptions) => BuildDiagramResult;
|
|
260
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/domain/diagram/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAWL,KAAK,eAAe,EAIrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,oBAAoB,+CAAgD,CAAC;AAElF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;EAQjC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,MAAM,WAAW,mBAAmB;IAGlC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,EAAE,cAAS,KAAG,MAAM,EA2BrE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,UAAS,mBAAwB,KAAG,kBAoG7F,CAAC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { DIAGRAM_COMPONENT_CATALOG, getDiagramComponent, isBusComponentType, isDefaultEdgeStyle, normalizeDiagramStyles, nowIso, safeParseDiagramDocument, SCHEMA_VERSION, searchDiagramComponents, semanticStyle, } from "callman-core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { ToolInputError } from "../../client/errors.js";
|
|
4
|
+
import { sequentialIds } from "../../lib/ids.js";
|
|
5
|
+
// From the COMPACT diagram a model writes (typed nodes with labels, edges
|
|
6
|
+
// with a meaning) to the DiagramDocument the Diagram Studio renders. Ids are
|
|
7
|
+
// short and stable (n1…, e1…), component types are checked against the
|
|
8
|
+
// shared catalog (unknown → suggestions, never a silent blank shape), edge
|
|
9
|
+
// meaning becomes the studio's notation (sync / async / fallback / bus), and
|
|
10
|
+
// the result is validated with the same parser the backend and desktop use.
|
|
11
|
+
export const EDGE_SEMANTICS_INPUT = ["sync", "async", "fallback", "bus"];
|
|
12
|
+
export const diagramNodeInputSchema = z.object({
|
|
13
|
+
id: z.string().min(1).max(64).optional().describe("Stable id (n1, api, db…); generated when omitted"),
|
|
14
|
+
type: z.string().min(1).max(80).describe("Component type from callman://diagram/components, e.g. net.service, db.postgres, aws.lambda, flow.process"),
|
|
15
|
+
label: z.string().max(200).optional(),
|
|
16
|
+
parent: z.string().max(64).optional().describe("Id of a container node (net.zone, flow.frame…) this node sits inside"),
|
|
17
|
+
position: z.object({ x: z.number(), y: z.number() }).optional(),
|
|
18
|
+
size: z.object({ width: z.number().positive(), height: z.number().positive() }).optional(),
|
|
19
|
+
style: z.record(z.unknown()).optional(),
|
|
20
|
+
data: z.record(z.unknown()).optional(),
|
|
21
|
+
});
|
|
22
|
+
export const diagramEdgeInputSchema = z.object({
|
|
23
|
+
id: z.string().min(1).max(64).optional(),
|
|
24
|
+
source: z.string().min(1).max(64),
|
|
25
|
+
target: z.string().min(1).max(64),
|
|
26
|
+
label: z.string().max(200).optional(),
|
|
27
|
+
semantic: z.enum(EDGE_SEMANTICS_INPUT).optional().describe("sync (default) = request/response, async = event, fallback = retry/optional, bus = message bus"),
|
|
28
|
+
routing: z.enum(["orthogonal", "straight", "curved"]).optional(),
|
|
29
|
+
markerEnd: z.enum(["none", "classic", "classicThin", "open", "block", "diamond", "oval"]).optional(),
|
|
30
|
+
});
|
|
31
|
+
export const diagramInputSchema = z.object({
|
|
32
|
+
title: z.string().min(1).max(200),
|
|
33
|
+
nodes: z.array(diagramNodeInputSchema).min(1).max(500),
|
|
34
|
+
edges: z.array(diagramEdgeInputSchema).max(2000).default([]),
|
|
35
|
+
canvas: z.object({ background: z.enum(["grid", "dots", "blank"]).optional(), gridSize: z.number().int().positive().optional() }).optional(),
|
|
36
|
+
});
|
|
37
|
+
export const suggestComponentTypes = (type, limit = 5) => {
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
const out = [];
|
|
40
|
+
const push = (candidate) => {
|
|
41
|
+
if (!seen.has(candidate) && out.length < limit) {
|
|
42
|
+
seen.add(candidate);
|
|
43
|
+
out.push(candidate);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
for (const entry of searchDiagramComponents(type))
|
|
47
|
+
push(entry.type);
|
|
48
|
+
// A typo usually sits at the END of the last segment ("db.postgresqlx"):
|
|
49
|
+
// shrink it until something in the catalog contains it.
|
|
50
|
+
const tail = (type.split(".").pop() ?? type).toLowerCase();
|
|
51
|
+
for (let length = tail.length; length >= 3 && out.length < limit; length -= 1) {
|
|
52
|
+
const needle = tail.slice(0, length);
|
|
53
|
+
for (const entry of DIAGRAM_COMPONENT_CATALOG) {
|
|
54
|
+
const haystack = [entry.type, entry.label, ...(entry.aliases ?? [])].join(" ").toLowerCase();
|
|
55
|
+
if (haystack.includes(needle))
|
|
56
|
+
push(entry.type);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Still nothing: offer the same namespace ("db.*", "aws.*").
|
|
60
|
+
const namespace = type.includes(".") ? `${type.split(".")[0].toLowerCase()}.` : null;
|
|
61
|
+
if (namespace) {
|
|
62
|
+
for (const entry of DIAGRAM_COMPONENT_CATALOG)
|
|
63
|
+
if (entry.type.toLowerCase().startsWith(namespace))
|
|
64
|
+
push(entry.type);
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
};
|
|
68
|
+
export const buildDiagramDocument = (input, options = {}) => {
|
|
69
|
+
const strict = options.strictTypes !== false;
|
|
70
|
+
const warnings = [];
|
|
71
|
+
const nextNodeId = sequentialIds("n", input.nodes.map((node) => node.id).filter((id) => Boolean(id)));
|
|
72
|
+
const nextEdgeId = sequentialIds("e", input.edges.map((edge) => edge.id).filter((id) => Boolean(id)));
|
|
73
|
+
// Ids first so parents/edges can reference nodes declared later.
|
|
74
|
+
const ids = input.nodes.map((node) => node.id ?? nextNodeId());
|
|
75
|
+
const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
|
|
76
|
+
if (duplicates.length > 0) {
|
|
77
|
+
throw new ToolInputError("DIAGRAM_DUPLICATE_NODE_ID", `Duplicate node ids: ${[...new Set(duplicates)].join(", ")}`);
|
|
78
|
+
}
|
|
79
|
+
const idSet = new Set(ids);
|
|
80
|
+
const unknown = [];
|
|
81
|
+
const typeOf = new Map();
|
|
82
|
+
const nodes = input.nodes.map((node, index) => {
|
|
83
|
+
const id = ids[index];
|
|
84
|
+
let type = node.type.trim();
|
|
85
|
+
const known = getDiagramComponent(type);
|
|
86
|
+
if (!known) {
|
|
87
|
+
const suggestions = suggestComponentTypes(type);
|
|
88
|
+
if (strict)
|
|
89
|
+
unknown.push({ type, suggestions });
|
|
90
|
+
else {
|
|
91
|
+
warnings.push(`Unknown component type "${type}" on ${id} → drawn as a rectangle (suggestions: ${suggestions.join(", ") || "none"})`);
|
|
92
|
+
type = "rect";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const def = getDiagramComponent(type);
|
|
96
|
+
typeOf.set(id, type);
|
|
97
|
+
if (node.parent && !idSet.has(node.parent)) {
|
|
98
|
+
throw new ToolInputError("DIAGRAM_PARENT_NOT_FOUND", `Node ${id} references parent "${node.parent}" which is not in nodes.`);
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
id,
|
|
102
|
+
type,
|
|
103
|
+
position: node.position ?? { x: 0, y: 0 },
|
|
104
|
+
size: node.size ?? def?.defaultSize ?? { width: 140, height: 60 },
|
|
105
|
+
...(node.label !== undefined || !known ? { label: node.label ?? node.type } : def?.defaultLabel ? { label: def.defaultLabel } : {}),
|
|
106
|
+
...(node.parent ? { parentId: node.parent } : {}),
|
|
107
|
+
...(node.style ? { style: node.style } : {}),
|
|
108
|
+
...(node.data ? { data: node.data } : {}),
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
if (unknown.length > 0) {
|
|
112
|
+
throw new ToolInputError("DIAGRAM_UNKNOWN_COMPONENT_TYPE", `Unknown component type(s): ${unknown.map((entry) => entry.type).join(", ")}. Read callman://diagram/components for the catalog, or pass strictTypes:false to draw them as rectangles.`, { unknownTypes: unknown });
|
|
113
|
+
}
|
|
114
|
+
const edgeIds = new Set();
|
|
115
|
+
const edges = input.edges.map((edge) => {
|
|
116
|
+
const id = edge.id ?? nextEdgeId();
|
|
117
|
+
if (edgeIds.has(id))
|
|
118
|
+
throw new ToolInputError("DIAGRAM_DUPLICATE_EDGE_ID", `Duplicate edge id: ${id}`);
|
|
119
|
+
edgeIds.add(id);
|
|
120
|
+
for (const endpoint of [edge.source, edge.target]) {
|
|
121
|
+
if (!idSet.has(endpoint)) {
|
|
122
|
+
throw new ToolInputError("DIAGRAM_EDGE_ENDPOINT_NOT_FOUND", `Edge ${id} references "${endpoint}" which is not a node id.`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
let semantic = edge.semantic;
|
|
126
|
+
// A fresh edge into a broker reads as a bus line — the studio's own rule.
|
|
127
|
+
if (!semantic && (isBusComponentType(typeOf.get(edge.source)) || isBusComponentType(typeOf.get(edge.target)))) {
|
|
128
|
+
semantic = "bus";
|
|
129
|
+
}
|
|
130
|
+
const style = semantic ? semanticStyle(semantic) : undefined;
|
|
131
|
+
return {
|
|
132
|
+
id,
|
|
133
|
+
source: edge.source,
|
|
134
|
+
target: edge.target,
|
|
135
|
+
...(edge.label ? { label: edge.label } : {}),
|
|
136
|
+
routing: edge.routing ?? "orthogonal",
|
|
137
|
+
markerEnd: edge.markerEnd ?? "classicThin",
|
|
138
|
+
...(style && !isDefaultEdgeStyle(style) ? { style } : semantic === "sync" ? { style } : {}),
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
const timestamp = options.createdAt ?? nowIso();
|
|
142
|
+
const document = normalizeDiagramStyles({
|
|
143
|
+
schemaVersion: SCHEMA_VERSION,
|
|
144
|
+
id: options.existingId ?? `doc_${Math.random().toString(36).slice(2, 10)}`,
|
|
145
|
+
meta: { title: input.title.trim(), createdAt: timestamp, updatedAt: nowIso() },
|
|
146
|
+
canvas: { background: input.canvas?.background ?? "dots", gridSize: input.canvas?.gridSize ?? 16 },
|
|
147
|
+
nodes,
|
|
148
|
+
edges,
|
|
149
|
+
});
|
|
150
|
+
const parsed = safeParseDiagramDocument(document);
|
|
151
|
+
if (!parsed.ok) {
|
|
152
|
+
throw new ToolInputError("DIAGRAM_DOCUMENT_INVALID", `The diagram document is invalid: ${parsed.errors.join("; ")}`, { errors: parsed.errors });
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
document: parsed.document,
|
|
156
|
+
warnings,
|
|
157
|
+
unpositionedNodeIds: input.nodes.filter((node) => !node.position).map((_node, index) => ids[index]),
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
//# sourceMappingURL=build.js.map
|