linear-agent-bridge 0.1.2

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.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +613 -0
  3. package/dist/index.d.ts +8 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +19 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/src/agent/context-builder.d.ts +9 -0
  8. package/dist/src/agent/context-builder.d.ts.map +1 -0
  9. package/dist/src/agent/context-builder.js +121 -0
  10. package/dist/src/agent/context-builder.js.map +1 -0
  11. package/dist/src/agent/plan-manager.d.ts +5 -0
  12. package/dist/src/agent/plan-manager.d.ts.map +1 -0
  13. package/dist/src/agent/plan-manager.js +11 -0
  14. package/dist/src/agent/plan-manager.js.map +1 -0
  15. package/dist/src/agent/response-tracker.d.ts +4 -0
  16. package/dist/src/agent/response-tracker.d.ts.map +1 -0
  17. package/dist/src/agent/response-tracker.js +11 -0
  18. package/dist/src/agent/response-tracker.js.map +1 -0
  19. package/dist/src/agent/session-token.d.ts +5 -0
  20. package/dist/src/agent/session-token.d.ts.map +1 -0
  21. package/dist/src/agent/session-token.js +15 -0
  22. package/dist/src/agent/session-token.js.map +1 -0
  23. package/dist/src/api/activity-ops.d.ts +2 -0
  24. package/dist/src/api/activity-ops.d.ts.map +1 -0
  25. package/dist/src/api/activity-ops.js +71 -0
  26. package/dist/src/api/activity-ops.js.map +1 -0
  27. package/dist/src/api/base-url.d.ts +3 -0
  28. package/dist/src/api/base-url.d.ts.map +1 -0
  29. package/dist/src/api/base-url.js +11 -0
  30. package/dist/src/api/base-url.js.map +1 -0
  31. package/dist/src/api/delegation-ops.d.ts +2 -0
  32. package/dist/src/api/delegation-ops.d.ts.map +1 -0
  33. package/dist/src/api/delegation-ops.js +51 -0
  34. package/dist/src/api/delegation-ops.js.map +1 -0
  35. package/dist/src/api/issue-ops.d.ts +2 -0
  36. package/dist/src/api/issue-ops.d.ts.map +1 -0
  37. package/dist/src/api/issue-ops.js +170 -0
  38. package/dist/src/api/issue-ops.js.map +1 -0
  39. package/dist/src/api/query-ops.d.ts +2 -0
  40. package/dist/src/api/query-ops.d.ts.map +1 -0
  41. package/dist/src/api/query-ops.js +77 -0
  42. package/dist/src/api/query-ops.js.map +1 -0
  43. package/dist/src/api/router.d.ts +12 -0
  44. package/dist/src/api/router.d.ts.map +1 -0
  45. package/dist/src/api/router.js +62 -0
  46. package/dist/src/api/router.js.map +1 -0
  47. package/dist/src/api/session-ops.d.ts +2 -0
  48. package/dist/src/api/session-ops.d.ts.map +1 -0
  49. package/dist/src/api/session-ops.js +96 -0
  50. package/dist/src/api/session-ops.js.map +1 -0
  51. package/dist/src/config.d.ts +3 -0
  52. package/dist/src/config.d.ts.map +1 -0
  53. package/dist/src/config.js +47 -0
  54. package/dist/src/config.js.map +1 -0
  55. package/dist/src/graphql/mutations.d.ts +9 -0
  56. package/dist/src/graphql/mutations.d.ts.map +1 -0
  57. package/dist/src/graphql/mutations.js +74 -0
  58. package/dist/src/graphql/mutations.js.map +1 -0
  59. package/dist/src/graphql/queries.d.ts +10 -0
  60. package/dist/src/graphql/queries.d.ts.map +1 -0
  61. package/dist/src/graphql/queries.js +121 -0
  62. package/dist/src/graphql/queries.js.map +1 -0
  63. package/dist/src/linear-client.d.ts +7 -0
  64. package/dist/src/linear-client.d.ts.map +1 -0
  65. package/dist/src/linear-client.js +72 -0
  66. package/dist/src/linear-client.js.map +1 -0
  67. package/dist/src/types.d.ts +85 -0
  68. package/dist/src/types.d.ts.map +1 -0
  69. package/dist/src/types.js +2 -0
  70. package/dist/src/types.js.map +1 -0
  71. package/dist/src/util.d.ts +13 -0
  72. package/dist/src/util.d.ts.map +1 -0
  73. package/dist/src/util.js +80 -0
  74. package/dist/src/util.js.map +1 -0
  75. package/dist/src/webhook/close-intent.d.ts +4 -0
  76. package/dist/src/webhook/close-intent.d.ts.map +1 -0
  77. package/dist/src/webhook/close-intent.js +37 -0
  78. package/dist/src/webhook/close-intent.js.map +1 -0
  79. package/dist/src/webhook/handler.d.ts +5 -0
  80. package/dist/src/webhook/handler.d.ts.map +1 -0
  81. package/dist/src/webhook/handler.js +441 -0
  82. package/dist/src/webhook/handler.js.map +1 -0
  83. package/dist/src/webhook/issue-policy.d.ts +7 -0
  84. package/dist/src/webhook/issue-policy.d.ts.map +1 -0
  85. package/dist/src/webhook/issue-policy.js +139 -0
  86. package/dist/src/webhook/issue-policy.js.map +1 -0
  87. package/dist/src/webhook/message-builder.d.ts +34 -0
  88. package/dist/src/webhook/message-builder.d.ts.map +1 -0
  89. package/dist/src/webhook/message-builder.js +144 -0
  90. package/dist/src/webhook/message-builder.js.map +1 -0
  91. package/dist/src/webhook/response-parser.d.ts +2 -0
  92. package/dist/src/webhook/response-parser.d.ts.map +1 -0
  93. package/dist/src/webhook/response-parser.js +51 -0
  94. package/dist/src/webhook/response-parser.js.map +1 -0
  95. package/dist/src/webhook/session-resolver.d.ts +6 -0
  96. package/dist/src/webhook/session-resolver.d.ts.map +1 -0
  97. package/dist/src/webhook/session-resolver.js +203 -0
  98. package/dist/src/webhook/session-resolver.js.map +1 -0
  99. package/dist/src/webhook/skip-filter.d.ts +4 -0
  100. package/dist/src/webhook/skip-filter.d.ts.map +1 -0
  101. package/dist/src/webhook/skip-filter.js +42 -0
  102. package/dist/src/webhook/skip-filter.js.map +1 -0
  103. package/dist/src/webhook/validation.d.ts +2 -0
  104. package/dist/src/webhook/validation.d.ts.map +1 -0
  105. package/dist/src/webhook/validation.js +11 -0
  106. package/dist/src/webhook/validation.js.map +1 -0
  107. package/openclaw.plugin.json +92 -0
  108. package/package.json +51 -0
@@ -0,0 +1,77 @@
1
+ import { registerApiHandler } from "./router.js";
2
+ import { callLinear, resolveViewer } from "../linear-client.js";
3
+ import { ISSUE_DETAIL_QUERY, TEAM_DETAIL_QUERY, REPO_SUGGESTIONS_QUERY, } from "../graphql/queries.js";
4
+ import { readString, readArray, sendJson } from "../util.js";
5
+ // POST /query/issue
6
+ registerApiHandler("/query/issue", async ({ api, cfg, context, body, res }) => {
7
+ const issueId = readString(body.issueId) || context.issueId;
8
+ if (!issueId) {
9
+ sendJson(res, 400, { ok: false, error: "issueId is required" });
10
+ return;
11
+ }
12
+ const result = await callLinear(api, cfg, "issue(detail)", {
13
+ query: ISSUE_DETAIL_QUERY,
14
+ variables: { id: issueId },
15
+ });
16
+ if (!result.ok) {
17
+ sendJson(res, 502, { ok: false, error: "Linear API error" });
18
+ return;
19
+ }
20
+ sendJson(res, 200, { ok: true, data: result.data.issue });
21
+ });
22
+ // POST /query/team
23
+ registerApiHandler("/query/team", async ({ api, cfg, context, body, res }) => {
24
+ const teamId = readString(body.teamId) || context.teamId;
25
+ if (!teamId) {
26
+ sendJson(res, 400, { ok: false, error: "teamId is required" });
27
+ return;
28
+ }
29
+ const result = await callLinear(api, cfg, "team(detail)", {
30
+ query: TEAM_DETAIL_QUERY,
31
+ variables: { id: teamId },
32
+ });
33
+ if (!result.ok) {
34
+ sendJson(res, 502, { ok: false, error: "Linear API error" });
35
+ return;
36
+ }
37
+ sendJson(res, 200, { ok: true, data: result.data.team });
38
+ });
39
+ // POST /query/repo-suggestions
40
+ registerApiHandler("/query/repo-suggestions", async ({ api, cfg, context, body, res }) => {
41
+ const issueId = readString(body.issueId) || context.issueId;
42
+ const candidates = readArray(body.candidateRepositories);
43
+ if (!issueId) {
44
+ sendJson(res, 400, { ok: false, error: "issueId is required" });
45
+ return;
46
+ }
47
+ if (candidates.length === 0) {
48
+ sendJson(res, 400, { ok: false, error: "candidateRepositories is required" });
49
+ return;
50
+ }
51
+ const result = await callLinear(api, cfg, "issueRepositorySuggestions", {
52
+ query: REPO_SUGGESTIONS_QUERY,
53
+ variables: {
54
+ issueId,
55
+ agentSessionId: context.sessionId,
56
+ candidateRepositories: candidates,
57
+ },
58
+ });
59
+ if (!result.ok) {
60
+ sendJson(res, 502, { ok: false, error: "Linear API error" });
61
+ return;
62
+ }
63
+ sendJson(res, 200, {
64
+ ok: true,
65
+ data: result.data.issueRepositorySuggestions,
66
+ });
67
+ });
68
+ // POST /query/viewer
69
+ registerApiHandler("/query/viewer", async ({ api, cfg, res }) => {
70
+ const id = await resolveViewer(api, cfg);
71
+ if (!id) {
72
+ sendJson(res, 502, { ok: false, error: "Could not resolve viewer" });
73
+ return;
74
+ }
75
+ sendJson(res, 200, { ok: true, data: { id } });
76
+ });
77
+ //# sourceMappingURL=query-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-ops.js","sourceRoot":"","sources":["../../../src/api/query-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { OpenClawPluginApi, PluginConfig, SessionContext } from "../types.js";
3
+ export type ApiHandler = (params: {
4
+ api: OpenClawPluginApi;
5
+ cfg: PluginConfig;
6
+ context: SessionContext;
7
+ body: Record<string, unknown>;
8
+ res: ServerResponse;
9
+ }) => Promise<void>;
10
+ export declare function registerApiHandler(path: string, handler: ApiHandler): void;
11
+ export declare function createApiRouter(api: OpenClawPluginApi): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
12
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/api/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKnF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE;IAChC,GAAG,EAAE,iBAAiB,CAAC;IACvB,GAAG,EAAE,YAAY,CAAC;IAClB,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,GAAG,EAAE,cAAc,CAAC;CACrB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAIpB,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,GAClB,IAAI,CAEN;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,iBAAiB,GACrB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAyD9D"}
@@ -0,0 +1,62 @@
1
+ import { normalizeCfg } from "../config.js";
2
+ import { validateSessionToken } from "../agent/session-token.js";
3
+ import { readBody, readHeader, sendJson } from "../util.js";
4
+ const routes = new Map();
5
+ export function registerApiHandler(path, handler) {
6
+ routes.set(path, handler);
7
+ }
8
+ export function createApiRouter(api) {
9
+ return async (req, res) => {
10
+ if (req.method !== "POST") {
11
+ res.statusCode = 405;
12
+ res.setHeader("Allow", "POST");
13
+ res.end("Method Not Allowed");
14
+ return;
15
+ }
16
+ const authHeader = readHeader(req, "authorization") ?? "";
17
+ const token = authHeader.startsWith("Bearer ")
18
+ ? authHeader.slice(7).trim()
19
+ : "";
20
+ const context = validateSessionToken(token);
21
+ if (!context) {
22
+ sendJson(res, 401, {
23
+ ok: false,
24
+ error: "Invalid or expired session token",
25
+ });
26
+ return;
27
+ }
28
+ const read = await readBody(req, 512 * 1024);
29
+ if (!read.ok) {
30
+ sendJson(res, read.status, { ok: false, error: read.error });
31
+ return;
32
+ }
33
+ let body;
34
+ try {
35
+ body = JSON.parse(read.body.toString("utf8"));
36
+ }
37
+ catch {
38
+ sendJson(res, 400, { ok: false, error: "Invalid JSON" });
39
+ return;
40
+ }
41
+ const cfg = normalizeCfg(api.pluginConfig);
42
+ const rawAction = typeof body.action === "string" ? body.action : "";
43
+ const action = rawAction.startsWith("/") ? rawAction : `/${rawAction}`;
44
+ const handler = routes.get(action);
45
+ if (!handler) {
46
+ sendJson(res, 404, {
47
+ ok: false,
48
+ error: `Unknown action: ${action || "(empty)"}`,
49
+ });
50
+ return;
51
+ }
52
+ try {
53
+ await handler({ api, cfg, context, body, res });
54
+ }
55
+ catch (err) {
56
+ const msg = err instanceof Error ? err.message : String(err);
57
+ api.logger.error?.(`linear api error (${action}): ${msg}`);
58
+ sendJson(res, 500, { ok: false, error: msg });
59
+ }
60
+ };
61
+ }
62
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/api/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-ops.d.ts","sourceRoot":"","sources":["../../../src/api/session-ops.ts"],"names":[],"mappings":""}
@@ -0,0 +1,96 @@
1
+ import { registerApiHandler } from "./router.js";
2
+ import { callLinear } from "../linear-client.js";
3
+ import { SESSION_UPDATE_MUTATION, AGENT_SESSION_CREATE_ON_ISSUE_MUTATION, AGENT_SESSION_CREATE_ON_COMMENT_MUTATION, } from "../graphql/mutations.js";
4
+ import { setPlan } from "../agent/plan-manager.js";
5
+ import { readObject, readString, readArray, sendJson } from "../util.js";
6
+ // POST /session/plan
7
+ registerApiHandler("/session/plan", async ({ api, cfg, context, body, res }) => {
8
+ const rawPlan = readArray(body.plan);
9
+ if (rawPlan.length === 0) {
10
+ sendJson(res, 400, { ok: false, error: "plan array is required" });
11
+ return;
12
+ }
13
+ const plan = rawPlan.map((item) => {
14
+ const obj = readObject(item);
15
+ return {
16
+ content: readString(obj?.content) ?? "",
17
+ status: (readString(obj?.status) ?? "pending"),
18
+ };
19
+ });
20
+ setPlan(context.sessionId, plan);
21
+ const result = await callLinear(api, cfg, "agentSessionUpdate(plan)", {
22
+ query: SESSION_UPDATE_MUTATION,
23
+ variables: { id: context.sessionId, input: { plan } },
24
+ });
25
+ if (!result.ok) {
26
+ sendJson(res, 502, { ok: false, error: "Linear API error" });
27
+ return;
28
+ }
29
+ sendJson(res, 200, { ok: true });
30
+ });
31
+ // POST /session/create-on-issue
32
+ registerApiHandler("/session/create-on-issue", async ({ api, cfg, body, res }) => {
33
+ const issueId = readString(body.issueId);
34
+ if (!issueId) {
35
+ sendJson(res, 400, { ok: false, error: "issueId is required" });
36
+ return;
37
+ }
38
+ const result = await callLinear(api, cfg, "agentSessionCreateOnIssue", {
39
+ query: AGENT_SESSION_CREATE_ON_ISSUE_MUTATION,
40
+ variables: { issueId },
41
+ });
42
+ if (!result.ok) {
43
+ sendJson(res, 502, { ok: false, error: "Linear API error" });
44
+ return;
45
+ }
46
+ const root = readObject(result.data.agentSessionCreateOnIssue);
47
+ const session = readObject(root?.agentSession);
48
+ sendJson(res, 200, {
49
+ ok: root?.success === true,
50
+ sessionId: readString(session?.id),
51
+ });
52
+ });
53
+ // POST /session/create-on-comment
54
+ registerApiHandler("/session/create-on-comment", async ({ api, cfg, body, res }) => {
55
+ const commentId = readString(body.commentId);
56
+ if (!commentId) {
57
+ sendJson(res, 400, { ok: false, error: "commentId is required" });
58
+ return;
59
+ }
60
+ const result = await callLinear(api, cfg, "agentSessionCreateOnComment", {
61
+ query: AGENT_SESSION_CREATE_ON_COMMENT_MUTATION,
62
+ variables: { commentId },
63
+ });
64
+ if (!result.ok) {
65
+ sendJson(res, 502, { ok: false, error: "Linear API error" });
66
+ return;
67
+ }
68
+ const root = readObject(result.data.agentSessionCreateOnComment);
69
+ const session = readObject(root?.agentSession);
70
+ sendJson(res, 200, {
71
+ ok: root?.success === true,
72
+ sessionId: readString(session?.id),
73
+ });
74
+ });
75
+ // POST /session/external-url
76
+ registerApiHandler("/session/external-url", async ({ api, cfg, context, body, res }) => {
77
+ const url = readString(body.url);
78
+ const label = readString(body.label) ?? "Link";
79
+ if (!url) {
80
+ sendJson(res, 400, { ok: false, error: "url is required" });
81
+ return;
82
+ }
83
+ const result = await callLinear(api, cfg, "agentSessionUpdate(externalUrl)", {
84
+ query: SESSION_UPDATE_MUTATION,
85
+ variables: {
86
+ id: context.sessionId,
87
+ input: { addedExternalUrls: [{ label, url }] },
88
+ },
89
+ });
90
+ if (!result.ok) {
91
+ sendJson(res, 502, { ok: false, error: "Linear API error" });
92
+ return;
93
+ }
94
+ sendJson(res, 200, { ok: true });
95
+ });
96
+ //# sourceMappingURL=session-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-ops.js","sourceRoot":"","sources":["../../../src/api/session-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { PluginConfig } from "./types.js";
2
+ export declare function normalizeCfg(input: Record<string, unknown> | undefined): PluginConfig;
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACzC,YAAY,CAmBd"}
@@ -0,0 +1,47 @@
1
+ export function normalizeCfg(input) {
2
+ const cfg = input ?? {};
3
+ return {
4
+ devAgentId: readCfgString(cfg, "devAgentId"),
5
+ linearWebhookSecret: readCfgString(cfg, "linearWebhookSecret"),
6
+ linearApiKey: readCfgString(cfg, "linearApiKey"),
7
+ notifyChannel: readCfgString(cfg, "notifyChannel"),
8
+ notifyTo: readCfgString(cfg, "notifyTo"),
9
+ notifyAccountId: readCfgString(cfg, "notifyAccountId"),
10
+ repoByTeam: readCfgMap(cfg, "repoByTeam"),
11
+ repoByProject: readCfgMap(cfg, "repoByProject"),
12
+ defaultDir: readCfgString(cfg, "defaultDir"),
13
+ delegateOnCreate: readCfgBool(cfg, "delegateOnCreate"),
14
+ startOnCreate: readCfgBool(cfg, "startOnCreate"),
15
+ externalUrlBase: readCfgString(cfg, "externalUrlBase"),
16
+ externalUrlLabel: readCfgString(cfg, "externalUrlLabel"),
17
+ enableAgentApi: readCfgBool(cfg, "enableAgentApi"),
18
+ apiBaseUrl: readCfgString(cfg, "apiBaseUrl"),
19
+ };
20
+ }
21
+ function readCfgString(cfg, key) {
22
+ const raw = cfg[key];
23
+ if (typeof raw !== "string")
24
+ return undefined;
25
+ const value = raw.trim();
26
+ return value || undefined;
27
+ }
28
+ function readCfgBool(cfg, key) {
29
+ const raw = cfg[key];
30
+ if (typeof raw !== "boolean")
31
+ return undefined;
32
+ return raw;
33
+ }
34
+ function readCfgMap(cfg, key) {
35
+ const raw = cfg[key];
36
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
37
+ return undefined;
38
+ const map = raw;
39
+ const out = {};
40
+ for (const [k, v] of Object.entries(map)) {
41
+ if (typeof v === "string" && v.trim()) {
42
+ out[k] = v.trim();
43
+ }
44
+ }
45
+ return Object.keys(out).length > 0 ? out : undefined;
46
+ }
47
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAC1B,KAA0C;IAE1C,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE,CAAC;IACxB,OAAO;QACL,UAAU,EAAE,aAAa,CAAC,GAAG,EAAE,YAAY,CAAC;QAC5C,mBAAmB,EAAE,aAAa,CAAC,GAAG,EAAE,qBAAqB,CAAC;QAC9D,YAAY,EAAE,aAAa,CAAC,GAAG,EAAE,cAAc,CAAC;QAChD,aAAa,EAAE,aAAa,CAAC,GAAG,EAAE,eAAe,CAAC;QAClD,QAAQ,EAAE,aAAa,CAAC,GAAG,EAAE,UAAU,CAAC;QACxC,eAAe,EAAE,aAAa,CAAC,GAAG,EAAE,iBAAiB,CAAC;QACtD,UAAU,EAAE,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC;QACzC,aAAa,EAAE,UAAU,CAAC,GAAG,EAAE,eAAe,CAAC;QAC/C,UAAU,EAAE,aAAa,CAAC,GAAG,EAAE,YAAY,CAAC;QAC5C,gBAAgB,EAAE,WAAW,CAAC,GAAG,EAAE,kBAAkB,CAAC;QACtD,aAAa,EAAE,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC;QAChD,eAAe,EAAE,aAAa,CAAC,GAAG,EAAE,iBAAiB,CAAC;QACtD,gBAAgB,EAAE,aAAa,CAAC,GAAG,EAAE,kBAAkB,CAAC;QACxD,cAAc,EAAE,WAAW,CAAC,GAAG,EAAE,gBAAgB,CAAC;QAClD,UAAU,EAAE,aAAa,CAAC,GAAG,EAAE,YAAY,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,GAA4B,EAC5B,GAAW;IAEX,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,OAAO,KAAK,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED,SAAS,WAAW,CAClB,GAA4B,EAC5B,GAAW;IAEX,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,IAAI,OAAO,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC/C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CACjB,GAA4B,EAC5B,GAAW;IAEX,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5E,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const ACTIVITY_MUTATION = "\n mutation AgentActivityCreate($input: AgentActivityCreateInput!) {\n agentActivityCreate(input: $input) {\n success\n agentActivity { id }\n }\n }\n";
2
+ export declare const SESSION_UPDATE_MUTATION = "\n mutation AgentSessionUpdate($id: String!, $input: AgentSessionUpdateInput!) {\n agentSessionUpdate(id: $id, input: $input) { success }\n }\n";
3
+ export declare const ISSUE_UPDATE_MUTATION = "\n mutation IssueUpdate($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue { id identifier }\n }\n }\n";
4
+ export declare const ISSUE_CREATE_MUTATION = "\n mutation IssueCreate($input: IssueCreateInput!) {\n issueCreate(input: $input) {\n success\n issue {\n id\n identifier\n title\n url\n state { id name type }\n team { id key }\n }\n }\n }\n";
5
+ export declare const ISSUE_RELATION_CREATE_MUTATION = "\n mutation IssueRelationCreate($input: IssueRelationCreateInput!) {\n issueRelationCreate(input: $input) {\n success\n issueRelation {\n id\n type\n issue { id identifier }\n relatedIssue { id identifier }\n }\n }\n }\n";
6
+ export declare const COMMENT_CREATE_MUTATION = "\n mutation CommentCreate($input: CommentCreateInput!) {\n commentCreate(input: $input) {\n success\n comment { id body }\n }\n }\n";
7
+ export declare const AGENT_SESSION_CREATE_ON_ISSUE_MUTATION = "\n mutation AgentSessionCreateOnIssue($issueId: String!) {\n agentSessionCreateOnIssue(issueId: $issueId) {\n success\n agentSession { id }\n }\n }\n";
8
+ export declare const AGENT_SESSION_CREATE_ON_COMMENT_MUTATION = "\n mutation AgentSessionCreateOnComment($commentId: String!) {\n agentSessionCreateOnComment(commentId: $commentId) {\n success\n agentSession { id }\n }\n }\n";
9
+ //# sourceMappingURL=mutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../../../src/graphql/mutations.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,6KAO7B,CAAC;AAEF,eAAO,MAAM,uBAAuB,yJAInC,CAAC;AAEF,eAAO,MAAM,qBAAqB,+KAOjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,sQAcjC,CAAC;AAEF,eAAO,MAAM,8BAA8B,oRAY1C,CAAC;AAEF,eAAO,MAAM,uBAAuB,0JAOnC,CAAC;AAEF,eAAO,MAAM,sCAAsC,4KAOlD,CAAC;AAEF,eAAO,MAAM,wCAAwC,sLAOpD,CAAC"}
@@ -0,0 +1,74 @@
1
+ export const ACTIVITY_MUTATION = `
2
+ mutation AgentActivityCreate($input: AgentActivityCreateInput!) {
3
+ agentActivityCreate(input: $input) {
4
+ success
5
+ agentActivity { id }
6
+ }
7
+ }
8
+ `;
9
+ export const SESSION_UPDATE_MUTATION = `
10
+ mutation AgentSessionUpdate($id: String!, $input: AgentSessionUpdateInput!) {
11
+ agentSessionUpdate(id: $id, input: $input) { success }
12
+ }
13
+ `;
14
+ export const ISSUE_UPDATE_MUTATION = `
15
+ mutation IssueUpdate($id: String!, $input: IssueUpdateInput!) {
16
+ issueUpdate(id: $id, input: $input) {
17
+ success
18
+ issue { id identifier }
19
+ }
20
+ }
21
+ `;
22
+ export const ISSUE_CREATE_MUTATION = `
23
+ mutation IssueCreate($input: IssueCreateInput!) {
24
+ issueCreate(input: $input) {
25
+ success
26
+ issue {
27
+ id
28
+ identifier
29
+ title
30
+ url
31
+ state { id name type }
32
+ team { id key }
33
+ }
34
+ }
35
+ }
36
+ `;
37
+ export const ISSUE_RELATION_CREATE_MUTATION = `
38
+ mutation IssueRelationCreate($input: IssueRelationCreateInput!) {
39
+ issueRelationCreate(input: $input) {
40
+ success
41
+ issueRelation {
42
+ id
43
+ type
44
+ issue { id identifier }
45
+ relatedIssue { id identifier }
46
+ }
47
+ }
48
+ }
49
+ `;
50
+ export const COMMENT_CREATE_MUTATION = `
51
+ mutation CommentCreate($input: CommentCreateInput!) {
52
+ commentCreate(input: $input) {
53
+ success
54
+ comment { id body }
55
+ }
56
+ }
57
+ `;
58
+ export const AGENT_SESSION_CREATE_ON_ISSUE_MUTATION = `
59
+ mutation AgentSessionCreateOnIssue($issueId: String!) {
60
+ agentSessionCreateOnIssue(issueId: $issueId) {
61
+ success
62
+ agentSession { id }
63
+ }
64
+ }
65
+ `;
66
+ export const AGENT_SESSION_CREATE_ON_COMMENT_MUTATION = `
67
+ mutation AgentSessionCreateOnComment($commentId: String!) {
68
+ agentSessionCreateOnComment(commentId: $commentId) {
69
+ success
70
+ agentSession { id }
71
+ }
72
+ }
73
+ `;
74
+ //# sourceMappingURL=mutations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.js","sourceRoot":"","sources":["../../../src/graphql/mutations.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;CAOhC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;CAItC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;CAOpC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;CAcpC,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAG;;;;;;;;;;;;CAY7C,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;CAOtC,CAAC;AAEF,MAAM,CAAC,MAAM,sCAAsC,GAAG;;;;;;;CAOrD,CAAC;AAEF,MAAM,CAAC,MAAM,wCAAwC,GAAG;;;;;;;CAOvD,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare const VIEWER_QUERY = "query Viewer { viewer { id } }";
2
+ export declare const ISSUE_INFO_QUERY = "\n query IssueInfo($id: String!) {\n issue(id: $id) {\n id\n state { type }\n team { id }\n delegate { id }\n }\n }\n";
3
+ export declare const ISSUE_DETAIL_QUERY = "\n query IssueDetail($id: String!) {\n issue(id: $id) {\n id\n identifier\n title\n description\n url\n priority\n priorityLabel\n state { id name type }\n team { id key name }\n assignee { id name displayName }\n delegate { id name displayName }\n labels { nodes { id name color } }\n parent { id identifier title }\n children { nodes { id identifier title state { type } } }\n relations { nodes { id type relatedIssue { id identifier title } } }\n comments(first: 20) {\n nodes { id body createdAt user { id name displayName } }\n }\n }\n }\n";
4
+ export declare const TEAM_STARTED_QUERY = "\n query TeamStartedStates($id: String!) {\n team(id: $id) {\n states(filter: { type: { eq: \"started\" } }) {\n nodes { id position }\n }\n }\n }\n";
5
+ export declare const TEAM_COMPLETED_QUERY = "\n query TeamCompletedStates($id: String!) {\n team(id: $id) {\n states(filter: { type: { eq: \"completed\" } }) {\n nodes { id position }\n }\n }\n }\n";
6
+ export declare const TEAM_DETAIL_QUERY = "\n query TeamDetail($id: String!) {\n team(id: $id) {\n id\n key\n name\n states { nodes { id name type position } }\n labels { nodes { id name color } }\n members { nodes { id name displayName } }\n }\n }\n";
7
+ export declare const COMMENT_SESSION_QUERY = "\n query CommentSession($id: String!) {\n comment(id: $id) {\n id\n parentId\n agentSession { id }\n agentSessions(first: 3) {\n nodes { id }\n }\n parent {\n id\n parentId\n agentSession { id }\n agentSessions(first: 3) {\n nodes { id }\n }\n }\n }\n }\n";
8
+ export declare const ISSUE_SESSION_QUERY = "\n query IssueSession($id: String!) {\n issue(id: $id) {\n comments(first: 25) {\n nodes {\n id\n parentId\n agentSession { id }\n agentSessions(first: 3) {\n nodes { id }\n }\n }\n }\n }\n }\n";
9
+ export declare const REPO_SUGGESTIONS_QUERY = "\n query RepoSuggestions(\n $issueId: String!,\n $agentSessionId: String!,\n $candidateRepositories: [CandidateRepositoryInput!]!\n ) {\n issueRepositorySuggestions(\n issueId: $issueId\n agentSessionId: $agentSessionId\n candidateRepositories: $candidateRepositories\n ) {\n suggestions {\n repositoryFullName\n hostname\n confidence\n }\n }\n }\n";
10
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/graphql/queries.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,mCAAmC,CAAC;AAE7D,eAAO,MAAM,gBAAgB,sJAS5B,CAAC;AAEF,eAAO,MAAM,kBAAkB,yoBAuB9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,kLAQ9B,CAAC;AAEF,eAAO,MAAM,oBAAoB,sLAQhC,CAAC;AAEF,eAAO,MAAM,iBAAiB,0PAW7B,CAAC;AAEF,eAAO,MAAM,qBAAqB,kWAmBjC,CAAC;AAEF,eAAO,MAAM,mBAAmB,8RAe/B,CAAC;AAEF,eAAO,MAAM,sBAAsB,oaAkBlC,CAAC"}
@@ -0,0 +1,121 @@
1
+ export const VIEWER_QUERY = `query Viewer { viewer { id } }`;
2
+ export const ISSUE_INFO_QUERY = `
3
+ query IssueInfo($id: String!) {
4
+ issue(id: $id) {
5
+ id
6
+ state { type }
7
+ team { id }
8
+ delegate { id }
9
+ }
10
+ }
11
+ `;
12
+ export const ISSUE_DETAIL_QUERY = `
13
+ query IssueDetail($id: String!) {
14
+ issue(id: $id) {
15
+ id
16
+ identifier
17
+ title
18
+ description
19
+ url
20
+ priority
21
+ priorityLabel
22
+ state { id name type }
23
+ team { id key name }
24
+ assignee { id name displayName }
25
+ delegate { id name displayName }
26
+ labels { nodes { id name color } }
27
+ parent { id identifier title }
28
+ children { nodes { id identifier title state { type } } }
29
+ relations { nodes { id type relatedIssue { id identifier title } } }
30
+ comments(first: 20) {
31
+ nodes { id body createdAt user { id name displayName } }
32
+ }
33
+ }
34
+ }
35
+ `;
36
+ export const TEAM_STARTED_QUERY = `
37
+ query TeamStartedStates($id: String!) {
38
+ team(id: $id) {
39
+ states(filter: { type: { eq: "started" } }) {
40
+ nodes { id position }
41
+ }
42
+ }
43
+ }
44
+ `;
45
+ export const TEAM_COMPLETED_QUERY = `
46
+ query TeamCompletedStates($id: String!) {
47
+ team(id: $id) {
48
+ states(filter: { type: { eq: "completed" } }) {
49
+ nodes { id position }
50
+ }
51
+ }
52
+ }
53
+ `;
54
+ export const TEAM_DETAIL_QUERY = `
55
+ query TeamDetail($id: String!) {
56
+ team(id: $id) {
57
+ id
58
+ key
59
+ name
60
+ states { nodes { id name type position } }
61
+ labels { nodes { id name color } }
62
+ members { nodes { id name displayName } }
63
+ }
64
+ }
65
+ `;
66
+ export const COMMENT_SESSION_QUERY = `
67
+ query CommentSession($id: String!) {
68
+ comment(id: $id) {
69
+ id
70
+ parentId
71
+ agentSession { id }
72
+ agentSessions(first: 3) {
73
+ nodes { id }
74
+ }
75
+ parent {
76
+ id
77
+ parentId
78
+ agentSession { id }
79
+ agentSessions(first: 3) {
80
+ nodes { id }
81
+ }
82
+ }
83
+ }
84
+ }
85
+ `;
86
+ export const ISSUE_SESSION_QUERY = `
87
+ query IssueSession($id: String!) {
88
+ issue(id: $id) {
89
+ comments(first: 25) {
90
+ nodes {
91
+ id
92
+ parentId
93
+ agentSession { id }
94
+ agentSessions(first: 3) {
95
+ nodes { id }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ `;
102
+ export const REPO_SUGGESTIONS_QUERY = `
103
+ query RepoSuggestions(
104
+ $issueId: String!,
105
+ $agentSessionId: String!,
106
+ $candidateRepositories: [CandidateRepositoryInput!]!
107
+ ) {
108
+ issueRepositorySuggestions(
109
+ issueId: $issueId
110
+ agentSessionId: $agentSessionId
111
+ candidateRepositories: $candidateRepositories
112
+ ) {
113
+ suggestions {
114
+ repositoryFullName
115
+ hostname
116
+ confidence
117
+ }
118
+ }
119
+ }
120
+ `;
121
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/graphql/queries.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,gCAAgC,CAAC;AAE7D,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;CAS/B,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBjC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;CAQjC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;CAQnC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;CAWhC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;CAmBpC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;CAelC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;CAkBrC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { OpenClawPluginApi, PluginConfig, LinearCallResult } from "./types.js";
2
+ export declare function callLinear(api: OpenClawPluginApi, cfg: PluginConfig, label: string, body: {
3
+ query: string;
4
+ variables: Record<string, unknown>;
5
+ }): Promise<LinearCallResult>;
6
+ export declare function resolveViewer(api: OpenClawPluginApi, cfg: PluginConfig): Promise<string>;
7
+ //# sourceMappingURL=linear-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear-client.d.ts","sourceRoot":"","sources":["../../src/linear-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAQpB,wBAAsB,UAAU,CAC9B,GAAG,EAAE,iBAAiB,EACtB,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC1D,OAAO,CAAC,gBAAgB,CAAC,CA6C3B;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,iBAAiB,EACtB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,MAAM,CAAC,CAYjB"}