@render-harness/cap-linear 0.4.0 → 0.4.1

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/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { LinearWebhookClient } from '@linear/sdk/webhooks';
7
7
 
8
8
  // package.json
9
9
  var package_default = {
10
- version: "0.4.0"};
10
+ version: "0.4.1"};
11
11
 
12
12
  // src/normalize.ts
13
13
  function normalizeLinearEvent(body, cfg = {}) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/normalize.ts","../src/tools.ts","../src/verify.ts","../src/index.ts"],"names":["stringValue","stringAt"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"name\": \"@render-harness/cap-linear\",\n \"version\": \"0.4.0\",\n \"description\": \"Linear monitoring capability pack for the Render agent harness.\",\n \"type\": \"module\",\n \"license\": \"MIT\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\"\n ],\n \"keywords\": [\n \"render-harness-cap\",\n \"render-harness\",\n \"linear\"\n ],\n \"renderHarness\": {\n \"gallery\": {\n \"label\": \"Linear\",\n \"envHint\": \"LINEAR_API_KEY\"\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run --passWithNoTests\"\n },\n \"dependencies\": {\n \"@linear/sdk\": \"^63.4.0\",\n \"@render-harness/registry\": \"workspace:*\"\n },\n \"devDependencies\": {\n \"@render-harness/core\": \"workspace:*\",\n \"@types/node\": \"^25.6.2\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^6.0.3\",\n \"vitest\": \"^4.1.5\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/render-lab/render-agent-harness.git\",\n \"directory\": \"packages/capabilities/cap-linear\"\n }\n}\n","export interface LinearFilterConfig {\n allowedTeams?: string[];\n allowedProjects?: string[];\n states?: string[];\n labels?: string[];\n ignoredActors?: string[];\n}\n\nexport interface NormalizedLinearEvent {\n type: string;\n action?: string;\n organizationId?: string;\n teamId?: string;\n teamKey?: string;\n projectId?: string;\n issueId?: string;\n issueIdentifier?: string;\n state?: string;\n actorId?: string;\n url?: string;\n summary: string;\n}\n\nexport function normalizeLinearEvent(\n body: unknown,\n cfg: LinearFilterConfig = {},\n): NormalizedLinearEvent | null {\n if (!body || typeof body !== \"object\") return null;\n const payload = body as Record<string, unknown>;\n const type = stringValue(payload.type);\n if (!type) return null;\n const action = stringValue(payload.action);\n const data = objectValue(payload.data);\n if (!data) return null;\n\n const actorId = stringAt(payload, \"actor.id\") ?? stringAt(payload, \"actorId\");\n if (actorId && cfg.ignoredActors?.includes(actorId)) return null;\n const teamId = stringAt(data, \"team.id\") ?? stringAt(data, \"teamId\");\n const teamKey = stringAt(data, \"team.key\");\n if (cfg.allowedTeams?.length && !matchesAny([teamId, teamKey], cfg.allowedTeams)) return null;\n const projectId = stringAt(data, \"project.id\") ?? stringAt(data, \"projectId\");\n const projectName = stringAt(data, \"project.name\");\n if (cfg.allowedProjects?.length && !matchesAny([projectId, projectName], cfg.allowedProjects)) {\n return null;\n }\n const state = stringAt(data, \"state.name\") ?? stringAt(data, \"state\");\n if (cfg.states?.length && state && !cfg.states.includes(state)) return null;\n if (cfg.labels?.length && !hasAllowedLabel(data, cfg.labels)) return null;\n\n const issueId = stringValue(data.id);\n const issueIdentifier = stringValue(data.identifier);\n const organizationId = stringValue(payload.organizationId);\n const url = stringValue(data.url);\n return {\n type,\n ...(action ? { action } : {}),\n ...(organizationId ? { organizationId } : {}),\n ...(teamId ? { teamId } : {}),\n ...(teamKey ? { teamKey } : {}),\n ...(projectId ? { projectId } : {}),\n ...(issueId ? { issueId } : {}),\n ...(issueIdentifier ? { issueIdentifier } : {}),\n ...(state ? { state } : {}),\n ...(actorId ? { actorId } : {}),\n ...(url ? { url } : {}),\n summary: `Linear ${type}${issueIdentifier ? ` ${issueIdentifier}` : \"\"} ${action ?? \"changed\"}`,\n };\n}\n\nfunction hasAllowedLabel(data: Record<string, unknown>, allowed: string[]): boolean {\n const labels = arrayValue(data.labels)\n .map((label) =>\n label && typeof label === \"object\" ? stringValue((label as { name?: unknown }).name) : null,\n )\n .filter((label): label is string => !!label);\n return labels.some((label) => allowed.includes(label));\n}\n\nfunction matchesAny(values: Array<string | undefined>, allowed: string[]): boolean {\n return values.some((value) => value !== undefined && allowed.includes(value));\n}\n\nfunction stringAt(value: unknown, path: string): string | undefined {\n let cursor = value;\n for (const part of path.split(\".\")) {\n if (!cursor || typeof cursor !== \"object\") return undefined;\n cursor = (cursor as Record<string, unknown>)[part];\n }\n return stringValue(cursor);\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction arrayValue(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n","import { LinearClient } from \"@linear/sdk\";\nimport type { LocalToolHandler } from \"@render-harness/core\";\n\nexport type LinearAccessMode = \"read\" | \"read_write\";\n\nexport function linearTools(args: {\n apiKey: string;\n accessMode: LinearAccessMode;\n}): LocalToolHandler[] {\n const client = new LinearClient({ apiKey: args.apiKey });\n const tools: LocalToolHandler[] = [\n jsonTool(\n \"linear.get_issue\",\n \"Read a Linear issue by id.\",\n idSchema(\"issueId\"),\n async (input) => {\n const { issueId } = input as { issueId: string };\n return client.client.request(\n `query Issue($id: String!) {\n issue(id: $id) {\n id\n identifier\n title\n description\n url\n state { id name }\n team { id key name }\n project { id name }\n assignee { id name email }\n labels { nodes { id name } }\n }\n }`,\n { id: issueId },\n );\n },\n ),\n jsonTool(\n \"linear.search_issues\",\n \"Search Linear issues with a text query.\",\n objectSchema({ query: { type: \"string\" } }),\n async (input) => {\n const { query } = input as { query: string };\n return client.client.request(\n `query SearchIssues($query: String!) {\n issueSearch(query: $query) {\n nodes {\n id\n identifier\n title\n url\n state { name }\n team { key name }\n }\n }\n }`,\n { query },\n );\n },\n ),\n jsonTool(\n \"linear.list_comments\",\n \"List comments for a Linear issue.\",\n idSchema(\"issueId\"),\n async (input) => {\n const { issueId } = input as { issueId: string };\n return client.client.request(\n `query IssueComments($id: String!) {\n issue(id: $id) {\n comments {\n nodes {\n id\n body\n createdAt\n user { id name email }\n }\n }\n }\n }`,\n { id: issueId },\n );\n },\n ),\n jsonTool(\"linear.list_teams\", \"List Linear teams.\", emptySchema(), async () =>\n client.client.request(\n `query Teams {\n teams {\n nodes {\n id\n key\n name\n }\n }\n }`,\n ),\n ),\n jsonTool(\"linear.list_projects\", \"List Linear projects.\", emptySchema(), async () =>\n client.client.request(\n `query Projects {\n projects {\n nodes {\n id\n name\n url\n state\n teams { nodes { id key name } }\n }\n }\n }`,\n ),\n ),\n jsonTool(\n \"linear.list_workflow_states\",\n \"List Linear workflow states, optionally scoped to a team.\",\n objectSchema({ teamId: { type: \"string\", optional: true } }),\n async (input) => {\n const { teamId } = input as { teamId?: string };\n return client.client.request(\n `query WorkflowStates($filter: WorkflowStateFilter) {\n workflowStates(filter: $filter) {\n nodes {\n id\n name\n type\n team { id key name }\n }\n }\n }`,\n { filter: teamId ? { team: { id: { eq: teamId } } } : undefined },\n );\n },\n ),\n jsonTool(\"linear.list_users\", \"List Linear users.\", emptySchema(), async () =>\n client.client.request(\n `query Users {\n users {\n nodes {\n id\n name\n email\n active\n }\n }\n }`,\n ),\n ),\n ];\n\n if (args.accessMode === \"read_write\") {\n tools.push(\n jsonTool(\n \"linear.create_issue\",\n \"Create a Linear issue.\",\n createIssueSchema(),\n async (input) => {\n const { teamId, title, description, assigneeId, projectId, cycleId, stateId, priority } =\n input as CreateIssueInput;\n return client.client.request(\n `mutation IssueCreate($input: IssueCreateInput!) {\n issueCreate(input: $input) {\n success\n issue { id identifier title url }\n }\n }`,\n {\n input: {\n teamId,\n title,\n ...(description ? { description } : {}),\n ...(assigneeId ? { assigneeId } : {}),\n ...(projectId ? { projectId } : {}),\n ...(cycleId ? { cycleId } : {}),\n ...(stateId ? { stateId } : {}),\n ...(priority !== undefined ? { priority } : {}),\n },\n },\n );\n },\n ),\n jsonTool(\n \"linear.create_comment\",\n \"Create a comment on a Linear issue.\",\n objectSchema({ issueId: { type: \"string\" }, body: { type: \"string\" } }),\n async (input) => {\n const { issueId, body } = input as { issueId: string; body: string };\n return client.client.request(\n `mutation CommentCreate($input: CommentCreateInput!) {\n commentCreate(input: $input) {\n success\n comment { id url body }\n }\n }`,\n { input: { issueId, body } },\n );\n },\n ),\n jsonTool(\n \"linear.update_issue\",\n \"Update Linear issue fields.\",\n updateIssueSchema(),\n async (input) => {\n const {\n issueId,\n title,\n description,\n stateId,\n assigneeId,\n projectId,\n cycleId,\n priority,\n labelIds,\n } = input as UpdateIssueInput;\n return client.client.request(\n `mutation IssueUpdate($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue {\n id\n identifier\n title\n state { id name }\n assignee { id name }\n project { id name }\n cycle { id name }\n }\n }\n }`,\n {\n id: issueId,\n input: {\n ...(title ? { title } : {}),\n ...(description ? { description } : {}),\n ...(stateId ? { stateId } : {}),\n ...(assigneeId ? { assigneeId } : {}),\n ...(projectId ? { projectId } : {}),\n ...(cycleId ? { cycleId } : {}),\n ...(priority !== undefined ? { priority } : {}),\n ...(labelIds ? { labelIds } : {}),\n },\n },\n );\n },\n ),\n jsonTool(\n \"linear.update_issue_status\",\n \"Update a Linear issue's status.\",\n objectSchema({ issueId: { type: \"string\" }, stateId: { type: \"string\" } }),\n async (input) => {\n const { issueId, stateId } = input as { issueId: string; stateId: string };\n return client.client.request(\n `mutation IssueUpdate($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue { id identifier state { id name } }\n }\n }`,\n { id: issueId, input: { stateId } },\n );\n },\n ),\n jsonTool(\n \"linear.assign_issue\",\n \"Assign a Linear issue to a user.\",\n objectSchema({ issueId: { type: \"string\" }, assigneeId: { type: \"string\" } }),\n async (input) => {\n const { issueId, assigneeId } = input as { issueId: string; assigneeId: string };\n return client.client.request(\n `mutation IssueAssign($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue { id identifier assignee { id name } }\n }\n }`,\n { id: issueId, input: { assigneeId } },\n );\n },\n ),\n jsonTool(\n \"linear.link_related_issue\",\n \"Create a Linear issue relation between two issues.\",\n objectSchema({\n issueId: { type: \"string\" },\n relatedIssueId: { type: \"string\" },\n type: { type: \"string\" },\n }),\n async (input) => {\n const { issueId, relatedIssueId, type } = input as {\n issueId: string;\n relatedIssueId: string;\n type: string;\n };\n return client.client.request(\n `mutation IssueRelationCreate($input: IssueRelationCreateInput!) {\n issueRelationCreate(input: $input) {\n success\n issueRelation { id type }\n }\n }`,\n { input: { issueId, relatedIssueId, type } },\n );\n },\n ),\n );\n }\n\n return tools;\n}\n\nfunction jsonTool(\n name: string,\n description: string,\n inputSchema: Record<string, unknown>,\n call: (input: unknown) => Promise<unknown>,\n): LocalToolHandler {\n return {\n definition: { name, description, inputSchema, source: \"pack:cap-linear\" },\n handler: async ({ input }) => {\n try {\n return { content: JSON.stringify(await call(input), null, 2) };\n } catch (err) {\n return { content: err instanceof Error ? err.message : String(err), isError: true };\n }\n },\n };\n}\n\ninterface CreateIssueInput {\n teamId: string;\n title: string;\n description?: string;\n assigneeId?: string;\n projectId?: string;\n cycleId?: string;\n stateId?: string;\n priority?: number;\n}\n\ninterface UpdateIssueInput {\n issueId: string;\n title?: string;\n description?: string;\n stateId?: string;\n assigneeId?: string;\n projectId?: string;\n cycleId?: string;\n priority?: number;\n labelIds?: string[];\n}\n\nfunction emptySchema() {\n return objectSchema({});\n}\n\nfunction idSchema(name: string) {\n return objectSchema({ [name]: { type: \"string\" } });\n}\n\nfunction createIssueSchema() {\n return objectSchema({\n teamId: { type: \"string\" },\n title: { type: \"string\" },\n description: { type: \"string\", optional: true },\n assigneeId: { type: \"string\", optional: true },\n projectId: { type: \"string\", optional: true },\n cycleId: { type: \"string\", optional: true },\n stateId: { type: \"string\", optional: true },\n priority: { type: \"number\", optional: true },\n });\n}\n\nfunction updateIssueSchema() {\n return objectSchema({\n issueId: { type: \"string\" },\n title: { type: \"string\", optional: true },\n description: { type: \"string\", optional: true },\n stateId: { type: \"string\", optional: true },\n assigneeId: { type: \"string\", optional: true },\n projectId: { type: \"string\", optional: true },\n cycleId: { type: \"string\", optional: true },\n priority: { type: \"number\", optional: true },\n labelIds: { type: \"array\", items: { type: \"string\" }, optional: true },\n });\n}\n\nfunction objectSchema(properties: Record<string, unknown>) {\n return {\n type: \"object\",\n additionalProperties: false,\n properties,\n required: Object.entries(properties)\n .filter(([, value]) => !(value as { optional?: boolean }).optional)\n .map(([key]) => key),\n };\n}\n","import { LinearWebhookClient } from \"@linear/sdk/webhooks\";\n\nexport function verifyLinearWebhook(args: {\n rawBody: string;\n signature: string | null;\n secret: string;\n timestamp?: number;\n}): boolean {\n if (!args.signature) return false;\n try {\n return new LinearWebhookClient(args.secret).verify(\n Buffer.from(args.rawBody),\n args.signature,\n args.timestamp,\n );\n } catch {\n return false;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport type { LocalToolHandler } from \"@render-harness/core\";\nimport { type ConnectorContribution, definePack, type PackContext } from \"@render-harness/registry\";\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport { type LinearFilterConfig, normalizeLinearEvent } from \"./normalize.js\";\nimport { type LinearAccessMode, linearTools } from \"./tools.js\";\nimport { verifyLinearWebhook } from \"./verify.js\";\n\ninterface LinearConfig extends LinearFilterConfig {\n agent?: string;\n userId?: string;\n webhookSecretEnv?: string;\n apiKeyEnv?: string;\n accessMode?: LinearAccessMode;\n}\n\nconst DEFAULT_WEBHOOK_SECRET_ENV = \"LINEAR_WEBHOOK_SECRET\";\nconst DEFAULT_API_KEY_ENV = \"LINEAR_API_KEY\";\n\nconst pack = definePack({\n name: \"cap-linear\",\n version: pkg.version,\n envSchema: [\n {\n name: DEFAULT_WEBHOOK_SECRET_ENV,\n required: true,\n secret: true,\n description: \"Linear webhook signing secret.\",\n },\n {\n name: DEFAULT_API_KEY_ENV,\n required: true,\n secret: true,\n description: \"Linear API key used for read tools and optional write tools.\",\n },\n ],\n localTools(ctx: PackContext): LocalToolHandler[] {\n const cfg = readConfig(ctx.config);\n const apiKey = ctx.env(cfg.apiKeyEnv);\n if (!apiKey) return [];\n return linearTools({ apiKey, accessMode: cfg.accessMode });\n },\n connectors(ctx: PackContext): ConnectorContribution[] {\n const cfg = readConfig(ctx.config);\n return [\n {\n key: \"linear\",\n webhook: async (req, webCtx) => {\n const rawBody = await req.text();\n const parsed = parseBody(rawBody);\n const secret = ctx.env(cfg.webhookSecretEnv);\n if (!secret) return json({ error: \"missing_secret\", env: cfg.webhookSecretEnv }, 500);\n const verifyArgs = {\n rawBody,\n secret,\n signature: req.headers.get(\"linear-signature\"),\n };\n const timestamp = timestampFrom(parsed);\n if (\n !verifyLinearWebhook({\n ...verifyArgs,\n ...(timestamp !== undefined ? { timestamp } : {}),\n })\n ) {\n return json({ error: \"invalid_signature\" }, 401);\n }\n\n const normalized = normalizeLinearEvent(parsed, cfg);\n if (!normalized) return json({ ok: true, skipped: true });\n const agent = webCtx.resolveAgent(cfg.agent);\n const runId = `linear-${hash(deliverySeed(parsed, rawBody))}`;\n const result = await webCtx.enqueueRun({\n agentName: agent.name,\n agentVersion: agent.version,\n userId: cfg.userId ?? \"cap-linear\",\n runId,\n initialContent: [{ type: \"text\", text: normalized.summary }],\n metadata: { connector: \"cap-linear\", ...normalized },\n });\n return json(result, result.status === \"enqueued\" ? 202 : 200);\n },\n },\n ];\n },\n});\n\nexport default pack;\n\ntype ResolvedLinearConfig = Required<\n Pick<LinearConfig, \"webhookSecretEnv\" | \"apiKeyEnv\" | \"accessMode\">\n> &\n Omit<LinearConfig, \"webhookSecretEnv\" | \"apiKeyEnv\" | \"accessMode\">;\n\nfunction readConfig(raw: Record<string, unknown>): ResolvedLinearConfig {\n const cfg: ResolvedLinearConfig = {\n webhookSecretEnv: stringValue(raw.webhookSecretEnv) ?? DEFAULT_WEBHOOK_SECRET_ENV,\n apiKeyEnv: stringValue(raw.apiKeyEnv) ?? DEFAULT_API_KEY_ENV,\n accessMode: raw.accessMode === \"read_write\" ? \"read_write\" : \"read\",\n };\n const agent = stringValue(raw.agent);\n if (agent) cfg.agent = agent;\n const userId = stringValue(raw.userId);\n if (userId) cfg.userId = userId;\n const allowedTeams = stringArray(raw.allowedTeams);\n if (allowedTeams) cfg.allowedTeams = allowedTeams;\n const allowedProjects = stringArray(raw.allowedProjects);\n if (allowedProjects) cfg.allowedProjects = allowedProjects;\n const states = stringArray(raw.states);\n if (states) cfg.states = states;\n const labels = stringArray(raw.labels);\n if (labels) cfg.labels = labels;\n const ignoredActors = stringArray(raw.ignoredActors);\n if (ignoredActors) cfg.ignoredActors = ignoredActors;\n return cfg;\n}\n\nfunction parseBody(rawBody: string): unknown {\n try {\n return JSON.parse(rawBody);\n } catch {\n return null;\n }\n}\n\nfunction timestampFrom(value: unknown): number | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const found = (value as Record<string, unknown>).webhookTimestamp;\n return typeof found === \"number\" ? found : undefined;\n}\n\nfunction deliverySeed(value: unknown, rawBody: string): string {\n if (!value || typeof value !== \"object\") return rawBody;\n const payload = value as Record<string, unknown>;\n return [\n stringValue(payload.organizationId),\n stringValue(payload.type),\n stringValue(payload.action),\n stringAt(payload, \"data.id\"),\n stringAt(payload, \"data.updatedAt\"),\n stringAt(payload, \"data.createdAt\"),\n ]\n .filter(Boolean)\n .join(\":\");\n}\n\nfunction stringAt(value: unknown, path: string): string | undefined {\n let cursor = value;\n for (const part of path.split(\".\")) {\n if (!cursor || typeof cursor !== \"object\") return undefined;\n cursor = (cursor as Record<string, unknown>)[part];\n }\n return stringValue(cursor);\n}\n\nfunction hash(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 32);\n}\n\nfunction json(body: unknown, status = 200): Response {\n return Response.json(body, { status });\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction stringArray(value: unknown): string[] | undefined {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : undefined;\n}\n"]}
1
+ {"version":3,"sources":["../package.json","../src/normalize.ts","../src/tools.ts","../src/verify.ts","../src/index.ts"],"names":["stringValue","stringAt"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"name\": \"@render-harness/cap-linear\",\n \"version\": \"0.4.1\",\n \"description\": \"Linear monitoring capability pack for the Render agent harness.\",\n \"type\": \"module\",\n \"license\": \"MIT\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\"\n ],\n \"keywords\": [\n \"render-harness-cap\",\n \"render-harness\",\n \"linear\"\n ],\n \"renderHarness\": {\n \"gallery\": {\n \"label\": \"Linear\",\n \"envHint\": \"LINEAR_API_KEY\"\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run --passWithNoTests\"\n },\n \"dependencies\": {\n \"@linear/sdk\": \"^63.4.0\",\n \"@render-harness/registry\": \"workspace:*\"\n },\n \"devDependencies\": {\n \"@render-harness/core\": \"workspace:*\",\n \"@types/node\": \"^25.6.2\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^6.0.3\",\n \"vitest\": \"^4.1.5\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/render-lab/render-agent-harness.git\",\n \"directory\": \"packages/capabilities/cap-linear\"\n }\n}\n","export interface LinearFilterConfig {\n allowedTeams?: string[];\n allowedProjects?: string[];\n states?: string[];\n labels?: string[];\n ignoredActors?: string[];\n}\n\nexport interface NormalizedLinearEvent {\n type: string;\n action?: string;\n organizationId?: string;\n teamId?: string;\n teamKey?: string;\n projectId?: string;\n issueId?: string;\n issueIdentifier?: string;\n state?: string;\n actorId?: string;\n url?: string;\n summary: string;\n}\n\nexport function normalizeLinearEvent(\n body: unknown,\n cfg: LinearFilterConfig = {},\n): NormalizedLinearEvent | null {\n if (!body || typeof body !== \"object\") return null;\n const payload = body as Record<string, unknown>;\n const type = stringValue(payload.type);\n if (!type) return null;\n const action = stringValue(payload.action);\n const data = objectValue(payload.data);\n if (!data) return null;\n\n const actorId = stringAt(payload, \"actor.id\") ?? stringAt(payload, \"actorId\");\n if (actorId && cfg.ignoredActors?.includes(actorId)) return null;\n const teamId = stringAt(data, \"team.id\") ?? stringAt(data, \"teamId\");\n const teamKey = stringAt(data, \"team.key\");\n if (cfg.allowedTeams?.length && !matchesAny([teamId, teamKey], cfg.allowedTeams)) return null;\n const projectId = stringAt(data, \"project.id\") ?? stringAt(data, \"projectId\");\n const projectName = stringAt(data, \"project.name\");\n if (cfg.allowedProjects?.length && !matchesAny([projectId, projectName], cfg.allowedProjects)) {\n return null;\n }\n const state = stringAt(data, \"state.name\") ?? stringAt(data, \"state\");\n if (cfg.states?.length && state && !cfg.states.includes(state)) return null;\n if (cfg.labels?.length && !hasAllowedLabel(data, cfg.labels)) return null;\n\n const issueId = stringValue(data.id);\n const issueIdentifier = stringValue(data.identifier);\n const organizationId = stringValue(payload.organizationId);\n const url = stringValue(data.url);\n return {\n type,\n ...(action ? { action } : {}),\n ...(organizationId ? { organizationId } : {}),\n ...(teamId ? { teamId } : {}),\n ...(teamKey ? { teamKey } : {}),\n ...(projectId ? { projectId } : {}),\n ...(issueId ? { issueId } : {}),\n ...(issueIdentifier ? { issueIdentifier } : {}),\n ...(state ? { state } : {}),\n ...(actorId ? { actorId } : {}),\n ...(url ? { url } : {}),\n summary: `Linear ${type}${issueIdentifier ? ` ${issueIdentifier}` : \"\"} ${action ?? \"changed\"}`,\n };\n}\n\nfunction hasAllowedLabel(data: Record<string, unknown>, allowed: string[]): boolean {\n const labels = arrayValue(data.labels)\n .map((label) =>\n label && typeof label === \"object\" ? stringValue((label as { name?: unknown }).name) : null,\n )\n .filter((label): label is string => !!label);\n return labels.some((label) => allowed.includes(label));\n}\n\nfunction matchesAny(values: Array<string | undefined>, allowed: string[]): boolean {\n return values.some((value) => value !== undefined && allowed.includes(value));\n}\n\nfunction stringAt(value: unknown, path: string): string | undefined {\n let cursor = value;\n for (const part of path.split(\".\")) {\n if (!cursor || typeof cursor !== \"object\") return undefined;\n cursor = (cursor as Record<string, unknown>)[part];\n }\n return stringValue(cursor);\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction arrayValue(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n","import { LinearClient } from \"@linear/sdk\";\nimport type { LocalToolHandler } from \"@render-harness/core\";\n\nexport type LinearAccessMode = \"read\" | \"read_write\";\n\nexport function linearTools(args: {\n apiKey: string;\n accessMode: LinearAccessMode;\n}): LocalToolHandler[] {\n const client = new LinearClient({ apiKey: args.apiKey });\n const tools: LocalToolHandler[] = [\n jsonTool(\n \"linear.get_issue\",\n \"Read a Linear issue by id.\",\n idSchema(\"issueId\"),\n async (input) => {\n const { issueId } = input as { issueId: string };\n return client.client.request(\n `query Issue($id: String!) {\n issue(id: $id) {\n id\n identifier\n title\n description\n url\n state { id name }\n team { id key name }\n project { id name }\n assignee { id name email }\n labels { nodes { id name } }\n }\n }`,\n { id: issueId },\n );\n },\n ),\n jsonTool(\n \"linear.search_issues\",\n \"Search Linear issues with a text query.\",\n objectSchema({ query: { type: \"string\" } }),\n async (input) => {\n const { query } = input as { query: string };\n return client.client.request(\n `query SearchIssues($query: String!) {\n issueSearch(query: $query) {\n nodes {\n id\n identifier\n title\n url\n state { name }\n team { key name }\n }\n }\n }`,\n { query },\n );\n },\n ),\n jsonTool(\n \"linear.list_comments\",\n \"List comments for a Linear issue.\",\n idSchema(\"issueId\"),\n async (input) => {\n const { issueId } = input as { issueId: string };\n return client.client.request(\n `query IssueComments($id: String!) {\n issue(id: $id) {\n comments {\n nodes {\n id\n body\n createdAt\n user { id name email }\n }\n }\n }\n }`,\n { id: issueId },\n );\n },\n ),\n jsonTool(\"linear.list_teams\", \"List Linear teams.\", emptySchema(), async () =>\n client.client.request(\n `query Teams {\n teams {\n nodes {\n id\n key\n name\n }\n }\n }`,\n ),\n ),\n jsonTool(\"linear.list_projects\", \"List Linear projects.\", emptySchema(), async () =>\n client.client.request(\n `query Projects {\n projects {\n nodes {\n id\n name\n url\n state\n teams { nodes { id key name } }\n }\n }\n }`,\n ),\n ),\n jsonTool(\n \"linear.list_workflow_states\",\n \"List Linear workflow states, optionally scoped to a team.\",\n objectSchema({ teamId: { type: \"string\", optional: true } }),\n async (input) => {\n const { teamId } = input as { teamId?: string };\n return client.client.request(\n `query WorkflowStates($filter: WorkflowStateFilter) {\n workflowStates(filter: $filter) {\n nodes {\n id\n name\n type\n team { id key name }\n }\n }\n }`,\n { filter: teamId ? { team: { id: { eq: teamId } } } : undefined },\n );\n },\n ),\n jsonTool(\"linear.list_users\", \"List Linear users.\", emptySchema(), async () =>\n client.client.request(\n `query Users {\n users {\n nodes {\n id\n name\n email\n active\n }\n }\n }`,\n ),\n ),\n ];\n\n if (args.accessMode === \"read_write\") {\n tools.push(\n jsonTool(\n \"linear.create_issue\",\n \"Create a Linear issue.\",\n createIssueSchema(),\n async (input) => {\n const { teamId, title, description, assigneeId, projectId, cycleId, stateId, priority } =\n input as CreateIssueInput;\n return client.client.request(\n `mutation IssueCreate($input: IssueCreateInput!) {\n issueCreate(input: $input) {\n success\n issue { id identifier title url }\n }\n }`,\n {\n input: {\n teamId,\n title,\n ...(description ? { description } : {}),\n ...(assigneeId ? { assigneeId } : {}),\n ...(projectId ? { projectId } : {}),\n ...(cycleId ? { cycleId } : {}),\n ...(stateId ? { stateId } : {}),\n ...(priority !== undefined ? { priority } : {}),\n },\n },\n );\n },\n ),\n jsonTool(\n \"linear.create_comment\",\n \"Create a comment on a Linear issue.\",\n objectSchema({ issueId: { type: \"string\" }, body: { type: \"string\" } }),\n async (input) => {\n const { issueId, body } = input as { issueId: string; body: string };\n return client.client.request(\n `mutation CommentCreate($input: CommentCreateInput!) {\n commentCreate(input: $input) {\n success\n comment { id url body }\n }\n }`,\n { input: { issueId, body } },\n );\n },\n ),\n jsonTool(\n \"linear.update_issue\",\n \"Update Linear issue fields.\",\n updateIssueSchema(),\n async (input) => {\n const {\n issueId,\n title,\n description,\n stateId,\n assigneeId,\n projectId,\n cycleId,\n priority,\n labelIds,\n } = input as UpdateIssueInput;\n return client.client.request(\n `mutation IssueUpdate($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue {\n id\n identifier\n title\n state { id name }\n assignee { id name }\n project { id name }\n cycle { id name }\n }\n }\n }`,\n {\n id: issueId,\n input: {\n ...(title ? { title } : {}),\n ...(description ? { description } : {}),\n ...(stateId ? { stateId } : {}),\n ...(assigneeId ? { assigneeId } : {}),\n ...(projectId ? { projectId } : {}),\n ...(cycleId ? { cycleId } : {}),\n ...(priority !== undefined ? { priority } : {}),\n ...(labelIds ? { labelIds } : {}),\n },\n },\n );\n },\n ),\n jsonTool(\n \"linear.update_issue_status\",\n \"Update a Linear issue's status.\",\n objectSchema({ issueId: { type: \"string\" }, stateId: { type: \"string\" } }),\n async (input) => {\n const { issueId, stateId } = input as { issueId: string; stateId: string };\n return client.client.request(\n `mutation IssueUpdate($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue { id identifier state { id name } }\n }\n }`,\n { id: issueId, input: { stateId } },\n );\n },\n ),\n jsonTool(\n \"linear.assign_issue\",\n \"Assign a Linear issue to a user.\",\n objectSchema({ issueId: { type: \"string\" }, assigneeId: { type: \"string\" } }),\n async (input) => {\n const { issueId, assigneeId } = input as { issueId: string; assigneeId: string };\n return client.client.request(\n `mutation IssueAssign($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue { id identifier assignee { id name } }\n }\n }`,\n { id: issueId, input: { assigneeId } },\n );\n },\n ),\n jsonTool(\n \"linear.link_related_issue\",\n \"Create a Linear issue relation between two issues.\",\n objectSchema({\n issueId: { type: \"string\" },\n relatedIssueId: { type: \"string\" },\n type: { type: \"string\" },\n }),\n async (input) => {\n const { issueId, relatedIssueId, type } = input as {\n issueId: string;\n relatedIssueId: string;\n type: string;\n };\n return client.client.request(\n `mutation IssueRelationCreate($input: IssueRelationCreateInput!) {\n issueRelationCreate(input: $input) {\n success\n issueRelation { id type }\n }\n }`,\n { input: { issueId, relatedIssueId, type } },\n );\n },\n ),\n );\n }\n\n return tools;\n}\n\nfunction jsonTool(\n name: string,\n description: string,\n inputSchema: Record<string, unknown>,\n call: (input: unknown) => Promise<unknown>,\n): LocalToolHandler {\n return {\n definition: { name, description, inputSchema, source: \"pack:cap-linear\" },\n handler: async ({ input }) => {\n try {\n return { content: JSON.stringify(await call(input), null, 2) };\n } catch (err) {\n return { content: err instanceof Error ? err.message : String(err), isError: true };\n }\n },\n };\n}\n\ninterface CreateIssueInput {\n teamId: string;\n title: string;\n description?: string;\n assigneeId?: string;\n projectId?: string;\n cycleId?: string;\n stateId?: string;\n priority?: number;\n}\n\ninterface UpdateIssueInput {\n issueId: string;\n title?: string;\n description?: string;\n stateId?: string;\n assigneeId?: string;\n projectId?: string;\n cycleId?: string;\n priority?: number;\n labelIds?: string[];\n}\n\nfunction emptySchema() {\n return objectSchema({});\n}\n\nfunction idSchema(name: string) {\n return objectSchema({ [name]: { type: \"string\" } });\n}\n\nfunction createIssueSchema() {\n return objectSchema({\n teamId: { type: \"string\" },\n title: { type: \"string\" },\n description: { type: \"string\", optional: true },\n assigneeId: { type: \"string\", optional: true },\n projectId: { type: \"string\", optional: true },\n cycleId: { type: \"string\", optional: true },\n stateId: { type: \"string\", optional: true },\n priority: { type: \"number\", optional: true },\n });\n}\n\nfunction updateIssueSchema() {\n return objectSchema({\n issueId: { type: \"string\" },\n title: { type: \"string\", optional: true },\n description: { type: \"string\", optional: true },\n stateId: { type: \"string\", optional: true },\n assigneeId: { type: \"string\", optional: true },\n projectId: { type: \"string\", optional: true },\n cycleId: { type: \"string\", optional: true },\n priority: { type: \"number\", optional: true },\n labelIds: { type: \"array\", items: { type: \"string\" }, optional: true },\n });\n}\n\nfunction objectSchema(properties: Record<string, unknown>) {\n return {\n type: \"object\",\n additionalProperties: false,\n properties,\n required: Object.entries(properties)\n .filter(([, value]) => !(value as { optional?: boolean }).optional)\n .map(([key]) => key),\n };\n}\n","import { LinearWebhookClient } from \"@linear/sdk/webhooks\";\n\nexport function verifyLinearWebhook(args: {\n rawBody: string;\n signature: string | null;\n secret: string;\n timestamp?: number;\n}): boolean {\n if (!args.signature) return false;\n try {\n return new LinearWebhookClient(args.secret).verify(\n Buffer.from(args.rawBody),\n args.signature,\n args.timestamp,\n );\n } catch {\n return false;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport type { LocalToolHandler } from \"@render-harness/core\";\nimport { type ConnectorContribution, definePack, type PackContext } from \"@render-harness/registry\";\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport { type LinearFilterConfig, normalizeLinearEvent } from \"./normalize.js\";\nimport { type LinearAccessMode, linearTools } from \"./tools.js\";\nimport { verifyLinearWebhook } from \"./verify.js\";\n\ninterface LinearConfig extends LinearFilterConfig {\n agent?: string;\n userId?: string;\n webhookSecretEnv?: string;\n apiKeyEnv?: string;\n accessMode?: LinearAccessMode;\n}\n\nconst DEFAULT_WEBHOOK_SECRET_ENV = \"LINEAR_WEBHOOK_SECRET\";\nconst DEFAULT_API_KEY_ENV = \"LINEAR_API_KEY\";\n\nconst pack = definePack({\n name: \"cap-linear\",\n version: pkg.version,\n envSchema: [\n {\n name: DEFAULT_WEBHOOK_SECRET_ENV,\n required: true,\n secret: true,\n description: \"Linear webhook signing secret.\",\n },\n {\n name: DEFAULT_API_KEY_ENV,\n required: true,\n secret: true,\n description: \"Linear API key used for read tools and optional write tools.\",\n },\n ],\n localTools(ctx: PackContext): LocalToolHandler[] {\n const cfg = readConfig(ctx.config);\n const apiKey = ctx.env(cfg.apiKeyEnv);\n if (!apiKey) return [];\n return linearTools({ apiKey, accessMode: cfg.accessMode });\n },\n connectors(ctx: PackContext): ConnectorContribution[] {\n const cfg = readConfig(ctx.config);\n return [\n {\n key: \"linear\",\n webhook: async (req, webCtx) => {\n const rawBody = await req.text();\n const parsed = parseBody(rawBody);\n const secret = ctx.env(cfg.webhookSecretEnv);\n if (!secret) return json({ error: \"missing_secret\", env: cfg.webhookSecretEnv }, 500);\n const verifyArgs = {\n rawBody,\n secret,\n signature: req.headers.get(\"linear-signature\"),\n };\n const timestamp = timestampFrom(parsed);\n if (\n !verifyLinearWebhook({\n ...verifyArgs,\n ...(timestamp !== undefined ? { timestamp } : {}),\n })\n ) {\n return json({ error: \"invalid_signature\" }, 401);\n }\n\n const normalized = normalizeLinearEvent(parsed, cfg);\n if (!normalized) return json({ ok: true, skipped: true });\n const agent = webCtx.resolveAgent(cfg.agent);\n const runId = `linear-${hash(deliverySeed(parsed, rawBody))}`;\n const result = await webCtx.enqueueRun({\n agentName: agent.name,\n agentVersion: agent.version,\n userId: cfg.userId ?? \"cap-linear\",\n runId,\n initialContent: [{ type: \"text\", text: normalized.summary }],\n metadata: { connector: \"cap-linear\", ...normalized },\n });\n return json(result, result.status === \"enqueued\" ? 202 : 200);\n },\n },\n ];\n },\n});\n\nexport default pack;\n\ntype ResolvedLinearConfig = Required<\n Pick<LinearConfig, \"webhookSecretEnv\" | \"apiKeyEnv\" | \"accessMode\">\n> &\n Omit<LinearConfig, \"webhookSecretEnv\" | \"apiKeyEnv\" | \"accessMode\">;\n\nfunction readConfig(raw: Record<string, unknown>): ResolvedLinearConfig {\n const cfg: ResolvedLinearConfig = {\n webhookSecretEnv: stringValue(raw.webhookSecretEnv) ?? DEFAULT_WEBHOOK_SECRET_ENV,\n apiKeyEnv: stringValue(raw.apiKeyEnv) ?? DEFAULT_API_KEY_ENV,\n accessMode: raw.accessMode === \"read_write\" ? \"read_write\" : \"read\",\n };\n const agent = stringValue(raw.agent);\n if (agent) cfg.agent = agent;\n const userId = stringValue(raw.userId);\n if (userId) cfg.userId = userId;\n const allowedTeams = stringArray(raw.allowedTeams);\n if (allowedTeams) cfg.allowedTeams = allowedTeams;\n const allowedProjects = stringArray(raw.allowedProjects);\n if (allowedProjects) cfg.allowedProjects = allowedProjects;\n const states = stringArray(raw.states);\n if (states) cfg.states = states;\n const labels = stringArray(raw.labels);\n if (labels) cfg.labels = labels;\n const ignoredActors = stringArray(raw.ignoredActors);\n if (ignoredActors) cfg.ignoredActors = ignoredActors;\n return cfg;\n}\n\nfunction parseBody(rawBody: string): unknown {\n try {\n return JSON.parse(rawBody);\n } catch {\n return null;\n }\n}\n\nfunction timestampFrom(value: unknown): number | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const found = (value as Record<string, unknown>).webhookTimestamp;\n return typeof found === \"number\" ? found : undefined;\n}\n\nfunction deliverySeed(value: unknown, rawBody: string): string {\n if (!value || typeof value !== \"object\") return rawBody;\n const payload = value as Record<string, unknown>;\n return [\n stringValue(payload.organizationId),\n stringValue(payload.type),\n stringValue(payload.action),\n stringAt(payload, \"data.id\"),\n stringAt(payload, \"data.updatedAt\"),\n stringAt(payload, \"data.createdAt\"),\n ]\n .filter(Boolean)\n .join(\":\");\n}\n\nfunction stringAt(value: unknown, path: string): string | undefined {\n let cursor = value;\n for (const part of path.split(\".\")) {\n if (!cursor || typeof cursor !== \"object\") return undefined;\n cursor = (cursor as Record<string, unknown>)[part];\n }\n return stringValue(cursor);\n}\n\nfunction hash(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 32);\n}\n\nfunction json(body: unknown, status = 200): Response {\n return Response.json(body, { status });\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction stringArray(value: unknown): string[] | undefined {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : undefined;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@render-harness/cap-linear",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Linear monitoring capability pack for the Render agent harness.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -29,14 +29,14 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@linear/sdk": "^63.4.0",
32
- "@render-harness/registry": "0.4.0"
32
+ "@render-harness/registry": "0.4.1"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/node": "^25.6.2",
36
36
  "tsup": "^8.5.1",
37
37
  "typescript": "^6.0.3",
38
38
  "vitest": "^4.1.5",
39
- "@render-harness/core": "0.4.0"
39
+ "@render-harness/core": "0.4.1"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public"