@manhq/localmcp 1.0.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 +239 -0
- package/README.vi.md +239 -0
- package/bin/localmcp.js +31 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +333 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -0
- package/dist/services/atlassian/client.d.ts +4 -0
- package/dist/services/atlassian/client.d.ts.map +1 -0
- package/dist/services/atlassian/client.js +26 -0
- package/dist/services/atlassian/client.js.map +1 -0
- package/dist/services/atlassian/index.d.ts +3 -0
- package/dist/services/atlassian/index.d.ts.map +1 -0
- package/dist/services/atlassian/index.js +7 -0
- package/dist/services/atlassian/index.js.map +1 -0
- package/dist/services/atlassian/tools/confluence.d.ts +3 -0
- package/dist/services/atlassian/tools/confluence.d.ts.map +1 -0
- package/dist/services/atlassian/tools/confluence.js +222 -0
- package/dist/services/atlassian/tools/confluence.js.map +1 -0
- package/dist/services/atlassian/tools/jira.d.ts +3 -0
- package/dist/services/atlassian/tools/jira.d.ts.map +1 -0
- package/dist/services/atlassian/tools/jira.js +266 -0
- package/dist/services/atlassian/tools/jira.js.map +1 -0
- package/dist/services/atlassian/types.d.ts +74 -0
- package/dist/services/atlassian/types.d.ts.map +1 -0
- package/dist/services/atlassian/types.js +2 -0
- package/dist/services/atlassian/types.js.map +1 -0
- package/dist/services/figma/client.d.ts +3 -0
- package/dist/services/figma/client.d.ts.map +1 -0
- package/dist/services/figma/client.js +27 -0
- package/dist/services/figma/client.js.map +1 -0
- package/dist/services/figma/index.d.ts +3 -0
- package/dist/services/figma/index.d.ts.map +1 -0
- package/dist/services/figma/index.js +13 -0
- package/dist/services/figma/index.js.map +1 -0
- package/dist/services/figma/tools/comments.d.ts +3 -0
- package/dist/services/figma/tools/comments.d.ts.map +1 -0
- package/dist/services/figma/tools/comments.js +41 -0
- package/dist/services/figma/tools/comments.js.map +1 -0
- package/dist/services/figma/tools/components.d.ts +3 -0
- package/dist/services/figma/tools/components.d.ts.map +1 -0
- package/dist/services/figma/tools/components.js +101 -0
- package/dist/services/figma/tools/components.js.map +1 -0
- package/dist/services/figma/tools/files.d.ts +3 -0
- package/dist/services/figma/tools/files.d.ts.map +1 -0
- package/dist/services/figma/tools/files.js +86 -0
- package/dist/services/figma/tools/files.js.map +1 -0
- package/dist/services/figma/tools/images.d.ts +3 -0
- package/dist/services/figma/tools/images.d.ts.map +1 -0
- package/dist/services/figma/tools/images.js +67 -0
- package/dist/services/figma/tools/images.js.map +1 -0
- package/dist/services/figma/tools/variables.d.ts +3 -0
- package/dist/services/figma/tools/variables.d.ts.map +1 -0
- package/dist/services/figma/tools/variables.js +44 -0
- package/dist/services/figma/tools/variables.js.map +1 -0
- package/dist/services/figma/types.d.ts +65 -0
- package/dist/services/figma/types.d.ts.map +1 -0
- package/dist/services/figma/types.js +2 -0
- package/dist/services/figma/types.js.map +1 -0
- package/dist/services/google-chat/auth.d.ts +2 -0
- package/dist/services/google-chat/auth.d.ts.map +1 -0
- package/dist/services/google-chat/auth.js +18 -0
- package/dist/services/google-chat/auth.js.map +1 -0
- package/dist/services/google-chat/client.d.ts +3 -0
- package/dist/services/google-chat/client.d.ts.map +1 -0
- package/dist/services/google-chat/client.js +14 -0
- package/dist/services/google-chat/client.js.map +1 -0
- package/dist/services/google-chat/index.d.ts +3 -0
- package/dist/services/google-chat/index.d.ts.map +1 -0
- package/dist/services/google-chat/index.js +5 -0
- package/dist/services/google-chat/index.js.map +1 -0
- package/dist/services/google-chat/tools/messages.d.ts +3 -0
- package/dist/services/google-chat/tools/messages.d.ts.map +1 -0
- package/dist/services/google-chat/tools/messages.js +144 -0
- package/dist/services/google-chat/tools/messages.js.map +1 -0
- package/dist/services/google-chat/types.d.ts +31 -0
- package/dist/services/google-chat/types.d.ts.map +1 -0
- package/dist/services/google-chat/types.js +2 -0
- package/dist/services/google-chat/types.js.map +1 -0
- package/dist/shared/env.d.ts +18 -0
- package/dist/shared/env.d.ts.map +1 -0
- package/dist/shared/env.js +27 -0
- package/dist/shared/env.js.map +1 -0
- package/dist/shared/errors.d.ts +8 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +38 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/response.d.ts +7 -0
- package/dist/shared/response.d.ts.map +1 -0
- package/dist/shared/response.js +7 -0
- package/dist/shared/response.js.map +1 -0
- package/dist/shared/settings.d.ts +36 -0
- package/dist/shared/settings.d.ts.map +1 -0
- package/dist/shared/settings.js +104 -0
- package/dist/shared/settings.js.map +1 -0
- package/docs/atlassian.md +170 -0
- package/docs/figma.md +154 -0
- package/docs/google-chat.md +130 -0
- package/docs/vi/atlassian.md +170 -0
- package/docs/vi/figma.md +154 -0
- package/docs/vi/google-chat.md +130 -0
- package/package.json +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/services/figma/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,IAAI,WAAW,GAAyB,IAAI,CAAC;AAE7C,MAAM,UAAU,cAAc;IAC5B,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC;QACzB,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI;QACvB,OAAO,EAAE;YACP,eAAe,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK;SACjC;KACF,CAAC,CAAC;IAEH,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CACnC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EACtB,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC7D,KAAK,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;YAC7B,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;YAC9E,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;YACvE,OAAO,WAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC,CACF,CAAC;IAEF,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/figma/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAM1D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { registerFileTools } from "./tools/files.js";
|
|
2
|
+
import { registerCommentTools } from "./tools/comments.js";
|
|
3
|
+
import { registerVariableTools } from "./tools/variables.js";
|
|
4
|
+
import { registerImageTools } from "./tools/images.js";
|
|
5
|
+
import { registerComponentTools } from "./tools/components.js";
|
|
6
|
+
export function registerFigmaTools(server) {
|
|
7
|
+
registerFileTools(server);
|
|
8
|
+
registerCommentTools(server);
|
|
9
|
+
registerVariableTools(server);
|
|
10
|
+
registerImageTools(server);
|
|
11
|
+
registerComponentTools(server);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/figma/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,sBAAsB,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../../../src/services/figma/tools/comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4C5D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getFigmaClient } from "../client.js";
|
|
3
|
+
import { handleToolError } from "../../../shared/errors.js";
|
|
4
|
+
import { toTextResponse } from "../../../shared/response.js";
|
|
5
|
+
export function registerCommentTools(server) {
|
|
6
|
+
server.registerTool("figma_get_comments", {
|
|
7
|
+
description: "Get all comments on a Figma file. Returns comment text, author, creation date, and resolved status.",
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
fileKey: z.string().describe("The Figma file key"),
|
|
10
|
+
}),
|
|
11
|
+
}, async ({ fileKey }) => {
|
|
12
|
+
try {
|
|
13
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/comments`);
|
|
14
|
+
return toTextResponse(data.comments);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return handleToolError(error);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
server.registerTool("figma_post_comment", {
|
|
21
|
+
description: "Post a comment on a Figma file. Optionally attach it to a specific node by providing nodeId.",
|
|
22
|
+
inputSchema: z.object({
|
|
23
|
+
fileKey: z.string().describe("The Figma file key"),
|
|
24
|
+
message: z.string().describe("The comment text"),
|
|
25
|
+
nodeId: z.string().optional().describe("Optional node ID to attach the comment to a specific element"),
|
|
26
|
+
}),
|
|
27
|
+
}, async ({ fileKey, message, nodeId }) => {
|
|
28
|
+
try {
|
|
29
|
+
const body = { message };
|
|
30
|
+
if (nodeId) {
|
|
31
|
+
body["client_meta"] = { node_id: nodeId };
|
|
32
|
+
}
|
|
33
|
+
const { data } = await getFigmaClient().post(`/files/${fileKey}/comments`, body);
|
|
34
|
+
return toTextResponse(data);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
return handleToolError(error);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=comments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../../../src/services/figma/tools/comments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EAAE,qGAAqG;QAClH,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;SACnD,CAAC;KACH,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC,GAAG,CAAwB,UAAU,OAAO,WAAW,CAAC,CAAC;YACjG,OAAO,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EACT,8FAA8F;QAChG,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAClD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAChD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;SACvG,CAAC;KACH,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,GAA4B,EAAE,OAAO,EAAE,CAAC;YAClD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YAC5C,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC,IAAI,CAAC,UAAU,OAAO,WAAW,EAAE,IAAI,CAAC,CAAC;YACjF,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../src/services/figma/tools/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuH9D"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getFigmaClient } from "../client.js";
|
|
3
|
+
import { handleToolError } from "../../../shared/errors.js";
|
|
4
|
+
import { toTextResponse } from "../../../shared/response.js";
|
|
5
|
+
export function registerComponentTools(server) {
|
|
6
|
+
/**
|
|
7
|
+
* Mirrors: get_libraries (file-level components)
|
|
8
|
+
* Lists all published components in a file.
|
|
9
|
+
*/
|
|
10
|
+
server.registerTool("figma_get_components", {
|
|
11
|
+
description: "Get all published components in a Figma file. Returns component names, descriptions, and node IDs. " +
|
|
12
|
+
"Use this to discover available components in a design library.",
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
fileKey: z.string().describe("Figma file key"),
|
|
15
|
+
}),
|
|
16
|
+
}, async ({ fileKey }) => {
|
|
17
|
+
try {
|
|
18
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/components`);
|
|
19
|
+
return toTextResponse(data);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
return handleToolError(error);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Get component sets (variants) in a file.
|
|
27
|
+
*/
|
|
28
|
+
server.registerTool("figma_get_component_sets", {
|
|
29
|
+
description: "Get all component sets (variant groups) in a Figma file. " +
|
|
30
|
+
"Use this to see which components have variants and their groupings.",
|
|
31
|
+
inputSchema: z.object({
|
|
32
|
+
fileKey: z.string().describe("Figma file key"),
|
|
33
|
+
}),
|
|
34
|
+
}, async ({ fileKey }) => {
|
|
35
|
+
try {
|
|
36
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/component_sets`);
|
|
37
|
+
return toTextResponse(data);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return handleToolError(error);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* Get styles (colors, text, effects, grids) defined in a file.
|
|
45
|
+
*/
|
|
46
|
+
server.registerTool("figma_get_styles", {
|
|
47
|
+
description: "Get all published styles in a Figma file: color styles, text styles, effect styles, and grid styles. " +
|
|
48
|
+
"Use this to extract the design system's style definitions.",
|
|
49
|
+
inputSchema: z.object({
|
|
50
|
+
fileKey: z.string().describe("Figma file key"),
|
|
51
|
+
}),
|
|
52
|
+
}, async ({ fileKey }) => {
|
|
53
|
+
try {
|
|
54
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/styles`);
|
|
55
|
+
return toTextResponse(data);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
return handleToolError(error);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Mirrors: search_design_system (team-level)
|
|
63
|
+
* Lists all components published across a team's libraries.
|
|
64
|
+
*/
|
|
65
|
+
server.registerTool("figma_get_team_components", {
|
|
66
|
+
description: "Get all published components across a Figma team's shared libraries. " +
|
|
67
|
+
"Use this to search for reusable components available to the whole team. Requires a teamId.",
|
|
68
|
+
inputSchema: z.object({
|
|
69
|
+
teamId: z.string().describe("Figma team ID (found in the team URL)"),
|
|
70
|
+
pageSize: z.number().int().min(1).max(100).default(50).describe("Number of results per page (default 50)"),
|
|
71
|
+
cursor: z.string().optional().describe("Pagination cursor from a previous response"),
|
|
72
|
+
}),
|
|
73
|
+
}, async ({ teamId, pageSize, cursor }) => {
|
|
74
|
+
try {
|
|
75
|
+
const { data } = await getFigmaClient().get(`/teams/${teamId}/components`, {
|
|
76
|
+
params: { page_size: pageSize, ...(cursor && { cursor }) },
|
|
77
|
+
});
|
|
78
|
+
return toTextResponse(data);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return handleToolError(error);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* Mirrors: whoami
|
|
86
|
+
*/
|
|
87
|
+
server.registerTool("figma_whoami", {
|
|
88
|
+
description: "Get the identity of the authenticated Figma user: name, email, and account ID. " +
|
|
89
|
+
"Use this to verify credentials or identify who the token belongs to.",
|
|
90
|
+
inputSchema: z.object({}),
|
|
91
|
+
}, async () => {
|
|
92
|
+
try {
|
|
93
|
+
const { data } = await getFigmaClient().get("/me");
|
|
94
|
+
return toTextResponse(data);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return handleToolError(error);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../../../../src/services/figma/tools/components.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../../src/services/figma/tools/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwFzD"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getFigmaClient } from "../client.js";
|
|
3
|
+
import { handleToolError } from "../../../shared/errors.js";
|
|
4
|
+
import { toTextResponse } from "../../../shared/response.js";
|
|
5
|
+
export function registerFileTools(server) {
|
|
6
|
+
/**
|
|
7
|
+
* Mirrors: get_metadata
|
|
8
|
+
* Returns a sparse outline of the file or a specific node — IDs, names, types,
|
|
9
|
+
* bounding boxes. Intentionally lightweight; use figma_get_design_context for
|
|
10
|
+
* full property details.
|
|
11
|
+
*/
|
|
12
|
+
server.registerTool("figma_get_metadata", {
|
|
13
|
+
description: "Get a sparse structural outline of a Figma file or a specific node: layer names, IDs, types, and bounding boxes. " +
|
|
14
|
+
"Use this first to understand the file layout before fetching full design details. " +
|
|
15
|
+
"If nodeId is omitted, returns the top-level page list.",
|
|
16
|
+
inputSchema: z.object({
|
|
17
|
+
fileKey: z.string().describe("Figma file key (from the file URL)"),
|
|
18
|
+
nodeId: z.string().optional().describe("Optional node ID to scope the outline to a specific layer"),
|
|
19
|
+
depth: z.number().int().min(1).max(5).default(2).describe("How many levels deep to traverse (default 2)"),
|
|
20
|
+
}),
|
|
21
|
+
}, async ({ fileKey, nodeId, depth }) => {
|
|
22
|
+
try {
|
|
23
|
+
if (nodeId) {
|
|
24
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/nodes`, {
|
|
25
|
+
params: { ids: nodeId, depth },
|
|
26
|
+
});
|
|
27
|
+
return toTextResponse(summarizeNodes(data.nodes));
|
|
28
|
+
}
|
|
29
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}`, {
|
|
30
|
+
params: { depth },
|
|
31
|
+
});
|
|
32
|
+
const outline = {
|
|
33
|
+
name: data.name,
|
|
34
|
+
pages: data.document.children.map((page) => ({
|
|
35
|
+
id: page.id,
|
|
36
|
+
name: page.name,
|
|
37
|
+
type: page.type,
|
|
38
|
+
childCount: page.children?.length ?? 0,
|
|
39
|
+
children: page.children?.slice(0, 20).map((n) => ({
|
|
40
|
+
id: n.id,
|
|
41
|
+
name: n.name,
|
|
42
|
+
type: n.type,
|
|
43
|
+
})),
|
|
44
|
+
})),
|
|
45
|
+
};
|
|
46
|
+
return toTextResponse(outline);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return handleToolError(error);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* Mirrors: get_design_context
|
|
54
|
+
* Returns full design properties for a specific node: fills, strokes, typography,
|
|
55
|
+
* layout, effects, constraints — enough for a developer to implement the design.
|
|
56
|
+
*/
|
|
57
|
+
server.registerTool("figma_get_design_context", {
|
|
58
|
+
description: "Get full design context for a specific Figma node: fills, strokes, typography, auto-layout, effects, and constraints. " +
|
|
59
|
+
"Use this when you need implementation details for a component or frame. Requires a nodeId — use figma_get_metadata first to find IDs.",
|
|
60
|
+
inputSchema: z.object({
|
|
61
|
+
fileKey: z.string().describe("Figma file key"),
|
|
62
|
+
nodeId: z.string().describe("Node ID to inspect (e.g. '123:456')"),
|
|
63
|
+
}),
|
|
64
|
+
}, async ({ fileKey, nodeId }) => {
|
|
65
|
+
try {
|
|
66
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/nodes`, {
|
|
67
|
+
params: { ids: nodeId },
|
|
68
|
+
});
|
|
69
|
+
const node = data.nodes[nodeId];
|
|
70
|
+
if (!node) {
|
|
71
|
+
return toTextResponse(`Node ${nodeId} not found in file ${fileKey}`);
|
|
72
|
+
}
|
|
73
|
+
return toTextResponse(node);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return handleToolError(error);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function summarizeNodes(nodes) {
|
|
81
|
+
return Object.entries(nodes).map(([id, node]) => ({
|
|
82
|
+
id,
|
|
83
|
+
...node,
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../../../src/services/figma/tools/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../../../src/services/figma/tools/images.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuE1D"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getFigmaClient } from "../client.js";
|
|
3
|
+
import { handleToolError } from "../../../shared/errors.js";
|
|
4
|
+
import { toTextResponse } from "../../../shared/response.js";
|
|
5
|
+
export function registerImageTools(server) {
|
|
6
|
+
/**
|
|
7
|
+
* Mirrors: get_screenshot
|
|
8
|
+
* Renders one or more nodes to image URLs (PNG/JPG/SVG/PDF).
|
|
9
|
+
*/
|
|
10
|
+
server.registerTool("figma_export_image", {
|
|
11
|
+
description: "Export a Figma node as an image and get a temporary download URL. " +
|
|
12
|
+
"Supports PNG, JPG, SVG, and PDF formats. Use this to get a visual snapshot of a frame or component.",
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
fileKey: z.string().describe("Figma file key"),
|
|
15
|
+
nodeIds: z
|
|
16
|
+
.array(z.string())
|
|
17
|
+
.min(1)
|
|
18
|
+
.describe("One or more node IDs to export (e.g. ['123:456', '789:0'])"),
|
|
19
|
+
format: z
|
|
20
|
+
.enum(["png", "jpg", "svg", "pdf"])
|
|
21
|
+
.default("png")
|
|
22
|
+
.describe("Export format (default: png)"),
|
|
23
|
+
scale: z
|
|
24
|
+
.number()
|
|
25
|
+
.min(0.01)
|
|
26
|
+
.max(4)
|
|
27
|
+
.default(1)
|
|
28
|
+
.describe("Image scale multiplier, 1 = 1x (default: 1)"),
|
|
29
|
+
}),
|
|
30
|
+
}, async ({ fileKey, nodeIds, format, scale }) => {
|
|
31
|
+
try {
|
|
32
|
+
const { data } = await getFigmaClient().get(`/images/${fileKey}`, {
|
|
33
|
+
params: {
|
|
34
|
+
ids: nodeIds.join(","),
|
|
35
|
+
format,
|
|
36
|
+
scale,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
return toTextResponse({
|
|
40
|
+
images: data.images,
|
|
41
|
+
err: data.err ?? null,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return handleToolError(error);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* Get image fills embedded in a file (images used as fill sources).
|
|
50
|
+
*/
|
|
51
|
+
server.registerTool("figma_get_image_fills", {
|
|
52
|
+
description: "Get download URLs for all image fills used inside a Figma file. " +
|
|
53
|
+
"Use this to download assets (logos, photos) that are embedded as fills in the design.",
|
|
54
|
+
inputSchema: z.object({
|
|
55
|
+
fileKey: z.string().describe("Figma file key"),
|
|
56
|
+
}),
|
|
57
|
+
}, async ({ fileKey }) => {
|
|
58
|
+
try {
|
|
59
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/images`);
|
|
60
|
+
return toTextResponse(data);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
return handleToolError(error);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=images.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.js","sourceRoot":"","sources":["../../../../src/services/figma/tools/images.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD;;;OAGG;IACH,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,WAAW,EACT,oEAAoE;YACpE,qGAAqG;QACvG,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YAC9C,OAAO,EAAE,CAAC;iBACP,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,4DAA4D,CAAC;YACzE,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;iBAClC,OAAO,CAAC,KAAK,CAAC;iBACd,QAAQ,CAAC,8BAA8B,CAAC;YAC3C,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,GAAG,CAAC,IAAI,CAAC;iBACT,GAAG,CAAC,CAAC,CAAC;iBACN,OAAO,CAAC,CAAC,CAAC;iBACV,QAAQ,CAAC,6CAA6C,CAAC;SAC3D,CAAC;KACH,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5C,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC,GAAG,CAAC,WAAW,OAAO,EAAE,EAAE;gBAChE,MAAM,EAAE;oBACN,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;oBACtB,MAAM;oBACN,KAAK;iBACN;aACF,CAAC,CAAC;YAEH,OAAO,cAAc,CAAC;gBACpB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI;aACtB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;IAEF;;OAEG;IACH,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EACT,kEAAkE;YAClE,uFAAuF;QACzF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;SAC/C,CAAC;KACH,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC,GAAG,CAAC,UAAU,OAAO,SAAS,CAAC,CAAC;YACxE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../../../src/services/figma/tools/variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+C7D"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getFigmaClient } from "../client.js";
|
|
3
|
+
import { handleToolError } from "../../../shared/errors.js";
|
|
4
|
+
import { toTextResponse } from "../../../shared/response.js";
|
|
5
|
+
export function registerVariableTools(server) {
|
|
6
|
+
/**
|
|
7
|
+
* Mirrors: get_variable_defs
|
|
8
|
+
* Extracts design tokens (colors, spacing, typography, etc.) from a Figma file.
|
|
9
|
+
*/
|
|
10
|
+
server.registerTool("figma_get_variables", {
|
|
11
|
+
description: "Get all local design variables (tokens) from a Figma file: colors, spacing, typography, radii, etc. " +
|
|
12
|
+
"Use this to extract a file's design system tokens for implementation or documentation.",
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
fileKey: z.string().describe("Figma file key"),
|
|
15
|
+
}),
|
|
16
|
+
}, async ({ fileKey }) => {
|
|
17
|
+
try {
|
|
18
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/variables/local`);
|
|
19
|
+
return toTextResponse(data);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
return handleToolError(error);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Get published variables from a library file.
|
|
27
|
+
*/
|
|
28
|
+
server.registerTool("figma_get_published_variables", {
|
|
29
|
+
description: "Get published design variables from a Figma library file. " +
|
|
30
|
+
"Use this to see which tokens are exported for use in other files.",
|
|
31
|
+
inputSchema: z.object({
|
|
32
|
+
fileKey: z.string().describe("Figma library file key"),
|
|
33
|
+
}),
|
|
34
|
+
}, async ({ fileKey }) => {
|
|
35
|
+
try {
|
|
36
|
+
const { data } = await getFigmaClient().get(`/files/${fileKey}/variables/published`);
|
|
37
|
+
return toTextResponse(data);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return handleToolError(error);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.js","sourceRoot":"","sources":["../../../../src/services/figma/tools/variables.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD;;;OAGG;IACH,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,WAAW,EACT,sGAAsG;YACtG,wFAAwF;QAC1F,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;SAC/C,CAAC;KACH,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC,GAAG,CAAC,UAAU,OAAO,kBAAkB,CAAC,CAAC;YACjF,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;IAEF;;OAEG;IACH,MAAM,CAAC,YAAY,CACjB,+BAA+B,EAC/B;QACE,WAAW,EACT,4DAA4D;YAC5D,mEAAmE;QACrE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SACvD,CAAC;KACH,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC,GAAG,CAAC,UAAU,OAAO,sBAAsB,CAAC,CAAC;YACrF,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export interface FigmaPage {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
type: string;
|
|
5
|
+
children?: FigmaNode[];
|
|
6
|
+
}
|
|
7
|
+
export interface FigmaNode {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
type: string;
|
|
11
|
+
children?: FigmaNode[];
|
|
12
|
+
}
|
|
13
|
+
export interface FigmaFile {
|
|
14
|
+
name: string;
|
|
15
|
+
document: {
|
|
16
|
+
children: FigmaPage[];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface FigmaComment {
|
|
20
|
+
id: string;
|
|
21
|
+
message: string;
|
|
22
|
+
created_at: string;
|
|
23
|
+
user: {
|
|
24
|
+
handle: string;
|
|
25
|
+
img_url: string;
|
|
26
|
+
};
|
|
27
|
+
resolved_at: string | null;
|
|
28
|
+
client_meta?: {
|
|
29
|
+
node_id?: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export interface FigmaCommentsResponse {
|
|
33
|
+
comments: FigmaComment[];
|
|
34
|
+
}
|
|
35
|
+
export interface FigmaComponent {
|
|
36
|
+
key: string;
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
node_id: string;
|
|
40
|
+
thumbnail_url?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface FigmaStyle {
|
|
43
|
+
key: string;
|
|
44
|
+
name: string;
|
|
45
|
+
description: string;
|
|
46
|
+
style_type: "FILL" | "TEXT" | "EFFECT" | "GRID";
|
|
47
|
+
node_id: string;
|
|
48
|
+
}
|
|
49
|
+
export interface FigmaVariable {
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
resolvedType: "COLOR" | "FLOAT" | "STRING" | "BOOLEAN";
|
|
53
|
+
valuesByMode: Record<string, unknown>;
|
|
54
|
+
description: string;
|
|
55
|
+
}
|
|
56
|
+
export interface FigmaVariableCollection {
|
|
57
|
+
id: string;
|
|
58
|
+
name: string;
|
|
59
|
+
modes: {
|
|
60
|
+
modeId: string;
|
|
61
|
+
name: string;
|
|
62
|
+
}[];
|
|
63
|
+
variableIds: string[];
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/figma/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE;QACR,QAAQ,EAAE,SAAS,EAAE,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACvD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/figma/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/services/google-chat/auth.ts"],"names":[],"mappings":"AAMA,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAgBtD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { env } from "../../shared/env.js";
|
|
3
|
+
let _token = null;
|
|
4
|
+
let _expiry = 0;
|
|
5
|
+
export async function getAccessToken() {
|
|
6
|
+
if (_token && Date.now() < _expiry - 60_000)
|
|
7
|
+
return _token;
|
|
8
|
+
const { data } = await axios.post("https://oauth2.googleapis.com/token", {
|
|
9
|
+
grant_type: "refresh_token",
|
|
10
|
+
client_id: env.gchat.CLIENT_ID,
|
|
11
|
+
client_secret: env.gchat.CLIENT_SECRET,
|
|
12
|
+
refresh_token: env.gchat.REFRESH_TOKEN,
|
|
13
|
+
});
|
|
14
|
+
_token = data.access_token;
|
|
15
|
+
_expiry = Date.now() + data.expires_in * 1000;
|
|
16
|
+
return _token;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/services/google-chat/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,IAAI,MAAM,GAAkB,IAAI,CAAC;AACjC,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,MAAM;QAAE,OAAO,MAAM,CAAC;IAE3D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,IAAI,CAC/B,qCAAqC,EACrC;QACE,UAAU,EAAE,eAAe;QAC3B,SAAS,EAAE,GAAG,CAAC,KAAM,CAAC,SAAS;QAC/B,aAAa,EAAE,GAAG,CAAC,KAAM,CAAC,aAAa;QACvC,aAAa,EAAE,GAAG,CAAC,KAAM,CAAC,aAAa;KACxC,CACF,CAAC;IAEF,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC;IAC3B,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IAC9C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/services/google-chat/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG7C,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,CAU5D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { getAccessToken } from "./auth.js";
|
|
3
|
+
export async function getChatClient() {
|
|
4
|
+
const token = await getAccessToken();
|
|
5
|
+
return axios.create({
|
|
6
|
+
baseURL: "https://chat.googleapis.com/v1",
|
|
7
|
+
headers: {
|
|
8
|
+
Authorization: `Bearer ${token}`,
|
|
9
|
+
Accept: "application/json",
|
|
10
|
+
"Content-Type": "application/json",
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/services/google-chat/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,KAAK,GAAG,MAAM,cAAc,EAAE,CAAC;IACrC,OAAO,KAAK,CAAC,MAAM,CAAC;QAClB,OAAO,EAAE,gCAAgC;QACzC,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,MAAM,EAAE,kBAAkB;YAC1B,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/google-chat/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAE1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/google-chat/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../src/services/google-chat/tools/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqJ5D"}
|