@dahrk/linear 0.1.0 → 0.2.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.
Files changed (67) hide show
  1. package/README.md +24 -12
  2. package/dist/batch-source.d.ts +63 -0
  3. package/dist/batch-source.d.ts.map +1 -0
  4. package/dist/batch-source.js +149 -0
  5. package/dist/batch-source.js.map +1 -0
  6. package/dist/comments.d.ts +36 -0
  7. package/dist/comments.d.ts.map +1 -0
  8. package/dist/comments.js +104 -0
  9. package/dist/comments.js.map +1 -0
  10. package/dist/documents.d.ts +1 -15
  11. package/dist/documents.d.ts.map +1 -1
  12. package/dist/documents.js +37 -27
  13. package/dist/documents.js.map +1 -1
  14. package/dist/format-action.d.ts +25 -0
  15. package/dist/format-action.d.ts.map +1 -0
  16. package/dist/format-action.js +250 -0
  17. package/dist/format-action.js.map +1 -0
  18. package/dist/index.d.ts +119 -15
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +231 -59
  21. package/dist/index.js.map +1 -1
  22. package/dist/issue-graph.d.ts +37 -0
  23. package/dist/issue-graph.d.ts.map +1 -0
  24. package/dist/issue-graph.js +125 -0
  25. package/dist/issue-graph.js.map +1 -0
  26. package/dist/issues.d.ts +27 -2
  27. package/dist/issues.d.ts.map +1 -1
  28. package/dist/issues.js +33 -10
  29. package/dist/issues.js.map +1 -1
  30. package/dist/labels.d.ts +48 -1
  31. package/dist/labels.d.ts.map +1 -1
  32. package/dist/labels.js +72 -24
  33. package/dist/labels.js.map +1 -1
  34. package/dist/linear-client.d.ts +51 -0
  35. package/dist/linear-client.d.ts.map +1 -1
  36. package/dist/linear-client.js +233 -34
  37. package/dist/linear-client.js.map +1 -1
  38. package/dist/oauth.d.ts +52 -12
  39. package/dist/oauth.d.ts.map +1 -1
  40. package/dist/oauth.js +91 -34
  41. package/dist/oauth.js.map +1 -1
  42. package/dist/recording-client.d.ts +20 -2
  43. package/dist/recording-client.d.ts.map +1 -1
  44. package/dist/recording-client.js +39 -1
  45. package/dist/recording-client.js.map +1 -1
  46. package/dist/responding-client.d.ts +49 -0
  47. package/dist/responding-client.d.ts.map +1 -0
  48. package/dist/responding-client.js +47 -0
  49. package/dist/responding-client.js.map +1 -0
  50. package/dist/teams.d.ts +20 -0
  51. package/dist/teams.d.ts.map +1 -0
  52. package/dist/teams.js +32 -0
  53. package/dist/teams.js.map +1 -0
  54. package/package.json +8 -10
  55. package/src/batch-source.ts +208 -0
  56. package/src/comments.ts +126 -0
  57. package/src/documents.ts +162 -0
  58. package/src/format-action.ts +279 -0
  59. package/src/index.ts +617 -0
  60. package/src/issue-graph.ts +169 -0
  61. package/src/issues.ts +142 -0
  62. package/src/labels.ts +254 -0
  63. package/src/linear-client.ts +448 -0
  64. package/src/oauth.ts +255 -0
  65. package/src/recording-client.ts +141 -0
  66. package/src/responding-client.ts +106 -0
  67. package/src/teams.ts +44 -0
package/dist/index.js CHANGED
@@ -1,32 +1,102 @@
1
+ import { LinearWebhookClient } from "@linear/sdk/webhooks";
1
2
  /**
2
- * @dahrk/linear - the Linear-native control surface (build spec section 14).
3
- *
4
- * Two responsibilities:
5
- * 1. Intake-side (used by the hub): verify the webhook signature, and normalise a
6
- * raw Linear webhook into the internal LinearEvent. tenantId/workspaceId are
7
- * resolved from the authenticated connection, never from the payload.
8
- * 2. Session-side (used by hub + edge): drive the Agent Session API natively -
9
- * post activities (thought/action/response), render the stage graph as the
10
- * agent-plan checklist, raise elicitation gates, take prompted-drive turns,
11
- * handle the stop signal, set externalUrls.
12
- *
13
- * Re-implemented directly against the Agent Session API; cyrus's posting code is a
14
- * reference, not a dependency. Intended runtime dep: the Linear TypeScript SDK
15
- * (added at M2/M5).
3
+ * Verify a Linear webhook signature and timestamp freshness, then return the parsed
4
+ * payload, or throw. Delegates to LinearWebhookClient.parseData which uses
5
+ * HMAC-SHA256 + timingSafeEqual. The webhookTimestamp field is extracted from the
6
+ * raw body so the SDK's built-in ±60 s replay window applies; a missing or
7
+ * non-numeric timestamp skips the freshness check. Throws "Invalid webhook
8
+ * signature" on bad HMAC and "Invalid webhook timestamp" on a stale delivery.
16
9
  */
17
- import { createHmac, timingSafeEqual } from "node:crypto";
10
+ export function verifyWebhook(rawBody, signature, secret) {
11
+ // Extract webhookTimestamp so parseData can enforce the ±60 s replay window.
12
+ // If the body is not valid JSON or the field is absent, we omit the argument and
13
+ // parseData skips the check (same as a missing timestamp in the old hand-rolled path).
14
+ let ts;
15
+ try {
16
+ const raw = JSON.parse(rawBody.toString("utf8")).webhookTimestamp;
17
+ if (typeof raw === "number")
18
+ ts = raw;
19
+ else if (typeof raw === "string") {
20
+ const n = Number(raw);
21
+ if (Number.isFinite(n))
22
+ ts = n;
23
+ }
24
+ }
25
+ catch {
26
+ /* non-JSON body – parseData will re-parse and also throw */
27
+ }
28
+ return new LinearWebhookClient(secret).parseData(rawBody, signature, ts);
29
+ }
18
30
  /**
19
- * Verify a Linear webhook signature and return the parsed payload, or throw.
20
- * Linear signs the raw request body with HMAC-SHA256 (hex) under the connection's
21
- * webhook secret; we recompute and compare in constant time over the raw bytes.
31
+ * Strip a leading @mention token from a triggering comment body (DHK-322), returning the bare
32
+ * instruction (trimmed). Two spellings are handled: a plain-text `@name` prefix (the structured
33
+ * `agentSession.comment.body` form) and a leading Linear `<user id="...">name</user>` element (the
34
+ * `promptContext` primary-directive-thread form). A body that is only the mention yields "". Pure, so
35
+ * the instruction parsing is unit-testable and free of an LLM.
22
36
  */
23
- export function verifyWebhook(rawBody, signature, secret) {
24
- const expected = createHmac("sha256", secret).update(rawBody).digest();
25
- const given = Buffer.from(signature ?? "", "hex");
26
- if (expected.length !== given.length || !timingSafeEqual(expected, given)) {
27
- throw new Error("linear webhook signature mismatch");
37
+ function stripLeadingMention(body) {
38
+ let text = body.replace(/^\s+/, "");
39
+ const userMatch = /^<user\b[^>]*>[\s\S]*?<\/user>/.exec(text);
40
+ if (userMatch)
41
+ text = text.slice(userMatch[0].length);
42
+ else
43
+ text = text.replace(/^@\S+/, "");
44
+ return text.trim();
45
+ }
46
+ /**
47
+ * Parse the triggering comment out of a `promptContext` primary-directive-thread (DHK-322): the
48
+ * `comment-id` attribute plus the last `<comment>` body (the triggering message), with its leading
49
+ * mention stripped. The fallback path when the webhook carries no structured `agentSession.comment`.
50
+ * Pure.
51
+ */
52
+ function directiveFromPromptContext(promptContext) {
53
+ const block = /<primary-directive-thread\b([^>]*)>([\s\S]*?)<\/primary-directive-thread>/.exec(promptContext);
54
+ if (!block)
55
+ return {};
56
+ const commentId = /\bcomment-id="([^"]*)"/.exec(block[1] ?? "")?.[1]?.trim();
57
+ const comments = [...(block[2] ?? "").matchAll(/<comment\b[^>]*>([\s\S]*?)<\/comment>/g)];
58
+ const lastBody = comments.at(-1)?.[1];
59
+ const instruction = lastBody !== undefined ? stripLeadingMention(lastBody) : undefined;
60
+ return {
61
+ ...(commentId ? { commentId } : {}),
62
+ ...(instruction ? { instruction } : {}),
63
+ };
64
+ }
65
+ /**
66
+ * Compute the NAMES of the labels newly added by an `Issue`/`update` webhook (DHK-93). Positive
67
+ * evidence only: `updatedFrom` must carry a `labelIds` array (the pre-change set) - a title/description
68
+ * edit that never touched labels carries none, so it yields []. The new set is read from `data.labelIds`
69
+ * (falling back to the ids on `data.labels`), the added ids are the new-set minus the old-set, and each
70
+ * added id is resolved to a name via `data.labels` (`[{id,name}]`). An added id with no resolvable name
71
+ * is dropped, so a payload we cannot name from produces no false trigger. Pure; no LLM.
72
+ */
73
+ function addedLabelNames(data, updatedFrom) {
74
+ if (!data || !updatedFrom)
75
+ return [];
76
+ const oldIds = updatedFrom.labelIds;
77
+ if (!Array.isArray(oldIds))
78
+ return []; // labels were not part of this change
79
+ const oldSet = new Set(oldIds.filter((v) => typeof v === "string"));
80
+ const labels = Array.isArray(data.labels)
81
+ ? data.labels.filter((l) => !!l && typeof l === "object")
82
+ : [];
83
+ const nameById = new Map();
84
+ for (const l of labels) {
85
+ if (typeof l.id === "string" && typeof l.name === "string")
86
+ nameById.set(l.id, l.name);
87
+ }
88
+ const newIds = Array.isArray(data.labelIds)
89
+ ? data.labelIds.filter((v) => typeof v === "string")
90
+ : labels.map((l) => l.id).filter((v) => typeof v === "string");
91
+ const names = [];
92
+ for (const id of newIds) {
93
+ if (oldSet.has(id))
94
+ continue; // pre-existing, not part of the delta
95
+ const name = nameById.get(id);
96
+ if (name !== undefined)
97
+ names.push(name);
28
98
  }
29
- return JSON.parse(rawBody.toString("utf8"));
99
+ return names;
30
100
  }
31
101
  /** Fixed 👍/👎 -> sentiment lookup. A reaction's sentiment comes from this table, never an LLM, so the
32
102
  * determinism boundary holds. Returns undefined for any emoji we do not treat as feedback. */
@@ -46,24 +116,48 @@ function reactionSentiment(emoji) {
46
116
  * Connection (the single source of truth for a workspace's tenant), never inferred here.
47
117
  */
48
118
  export function normalise(payload, connectionId, tenantId) {
49
- const p = (payload ?? {});
50
- const ts = typeof p.webhookTimestamp === "string" ? p.webhookTimestamp : "1970-01-01T00:00:00Z";
119
+ const ts = new Date(payload.webhookTimestamp).toISOString();
51
120
  const base = {
52
121
  tenantId,
53
122
  connectionId,
54
- workspaceId: p.organizationId ?? "",
123
+ workspaceId: payload.organizationId,
55
124
  linearPayload: payload,
56
125
  ts,
57
126
  };
58
- if (p.type === "AgentSessionEvent" || p.type === "AgentSession") {
59
- const agentSessionId = p.agentSession?.id ?? "";
127
+ if (payload.type === "AgentSessionEvent" || payload.type === "AgentSession") {
128
+ // Narrow to the AgentSessionEvent shape; "AgentSession" is a legacy alias Linear still emits.
129
+ const p = payload;
130
+ // Linear's webhook body nests the issue under `agentSession.issue.id`; the SDK type models it
131
+ // flattened as `agentSession.issueId`. Tolerate both so the issue id survives for routing.
132
+ const agentSession = p.agentSession;
133
+ const agentSessionId = agentSession.id;
134
+ const issueId = agentSession.issueId ?? agentSession.issue?.id ?? undefined;
60
135
  if (p.action === "created") {
136
+ // DHK-322: classify the trigger modality deterministically from the payload alone. An @mention
137
+ // leaves the issue delegated to someone other than the app; a delegate/assign delegates it to the
138
+ // app itself (mirrors `shouldSetDelegate`). When the app user id cannot be resolved, default to
139
+ // `delegate` - the safe default is today's labelled pipeline, never mis-routing a real assignment
140
+ // to converse. No LLM: this is a pure id comparison.
141
+ const appUserId = agentSession.appUser?.id ?? undefined;
142
+ const issueDelegateId = agentSession.issue?.delegateId ?? agentSession.issue?.delegate?.id ?? undefined;
143
+ const trigger = appUserId !== undefined && issueDelegateId !== appUserId ? "mention" : "delegate";
144
+ // The instruction rides the triggering comment: prefer the structured `agentSession.comment`,
145
+ // else parse it out of the promptContext primary-directive-thread. The leading @mention is
146
+ // stripped so a bare mention yields no instruction.
147
+ const structured = agentSession.comment;
148
+ const promptContext = payload.promptContext;
149
+ const directive = typeof promptContext === "string" ? directiveFromPromptContext(promptContext) : {};
150
+ const structuredInstruction = structured?.body !== undefined ? stripLeadingMention(structured.body) : undefined;
151
+ const instruction = (structuredInstruction && structuredInstruction.length > 0 ? structuredInstruction : undefined) ??
152
+ directive.instruction;
153
+ const commentId = structured?.id ?? directive.commentId;
61
154
  // Carry the issue id so the hub can map issue -> run (for later Inbox-notification routing).
62
- const issueId = p.agentSession?.issue?.id;
63
155
  return {
64
156
  ...base,
65
157
  type: "agent-session-created",
66
- subject: { agentSessionId, ...(issueId ? { issueId } : {}) },
158
+ trigger,
159
+ subject: { agentSessionId, ...(issueId ? { issueId } : {}), ...(commentId ? { commentId } : {}) },
160
+ ...(instruction ? { instruction } : {}),
67
161
  };
68
162
  }
69
163
  if (p.action === "prompted") {
@@ -72,40 +166,112 @@ export function normalise(payload, connectionId, tenantId) {
72
166
  if (p.action === "stopped" || p.action === "stop") {
73
167
  return { ...base, type: "signal-stop", subject: { agentSessionId } };
74
168
  }
75
- }
76
- // Inbox notification: the agent was unassigned from an issue -> disengage (stop its run).
77
- if (p.type === "AppUserNotification" && p.action === "issueUnassignedFromYou") {
78
- const issueId = p.notification?.issueId ?? p.notification?.issue?.id ?? "";
79
- return { ...base, type: "issue-unassigned", subject: { issueId } };
80
- }
81
- // Inbox notification: the issue's status changed. Only a move to a *canceled* workflow-state type is
82
- // a disengagement signal (stop its run); any other status change falls through to ignored.
83
- if (p.type === "AppUserNotification" && p.action === "issueStatusChanged") {
84
- const stateType = p.notification?.issue?.state?.type ?? p.notification?.issueStatusType;
85
- if (stateType === "canceled") {
86
- const issueId = p.notification?.issueId ?? p.notification?.issue?.id ?? "";
87
- return { ...base, type: "issue-canceled", subject: { issueId } };
169
+ // The session was archived or deleted (the human tore the agent off the issue). Linear does not
170
+ // guarantee an Inbox notification for this, but when it sends the raw AgentSession action we can
171
+ // stop the run it drives directly. Carry the issue id when present so the run can also be found by
172
+ // issue if the session map is stale.
173
+ if (p.action === "archived" || p.action === "deleted") {
174
+ return {
175
+ ...base,
176
+ type: "session-archived",
177
+ subject: { agentSessionId, ...(issueId ? { issueId } : {}) },
178
+ };
88
179
  }
89
180
  }
90
- // Inbox notification: a 👍/👎 reaction on a Skakel response -> a feedback signal. A non-thumb emoji
91
- // falls through to ignored (never mis-dispatched).
92
- if (p.type === "AppUserNotification" &&
93
- (p.action === "issueEmojiReaction" || p.action === "issueCommentReaction")) {
94
- const reaction = reactionSentiment(p.notification?.reaction?.emoji ?? p.notification?.reactionEmoji ?? p.notification?.emoji);
95
- if (reaction) {
96
- const issueId = p.notification?.issueId ?? p.notification?.issue?.id ?? "";
97
- return { ...base, type: "issue-reaction", subject: { issueId }, reaction };
181
+ if (payload.type === "AppUserNotification") {
182
+ const p = payload;
183
+ // The notification-kind discriminator is carried at the top-level `action` on the real webhook
184
+ // body (the SDK only models it as `notification.type`, which the live payload omits). Read from
185
+ // `action`, and tolerate the alternate field spellings the live body uses for issue id, reaction
186
+ // emoji, and status type.
187
+ const action = p.action;
188
+ const n = p.notification;
189
+ const issueId = n.issueId ?? n.issue?.id ?? "";
190
+ // Inbox notification: the agent was unassigned from an issue -> disengage (stop its run).
191
+ if (action === "issueUnassignedFromYou") {
192
+ return { ...base, type: "issue-unassigned", subject: { issueId } };
193
+ }
194
+ // Inbox notification: the issue's status changed. A move to a *canceled* or *completed* workflow-state
195
+ // type is a disengagement signal (stop its run); any other status change falls through to ignored.
196
+ // (A completed move only settles a run parked at a gate; that gate-open rule lives on the hub side.)
197
+ if (action === "issueStatusChanged") {
198
+ const stateType = n.issue?.state?.type ?? n.issueStatusType;
199
+ if (stateType === "canceled") {
200
+ return { ...base, type: "issue-canceled", subject: { issueId } };
201
+ }
202
+ if (stateType === "completed") {
203
+ return { ...base, type: "issue-completed", subject: { issueId } };
204
+ }
205
+ }
206
+ // Inbox notification: a 👍/👎 reaction on a Dahrk response -> a feedback signal. A non-thumb emoji
207
+ // falls through to ignored (never mis-dispatched).
208
+ if (action === "issueEmojiReaction" || action === "issueCommentReaction") {
209
+ const reaction = reactionSentiment(n.reactionEmoji ?? n.reaction?.emoji ?? n.emoji);
210
+ if (reaction) {
211
+ return { ...base, type: "issue-reaction", subject: { issueId }, reaction };
212
+ }
98
213
  }
99
214
  }
100
215
  // The OAuth app install was revoked: the connection is dead, deactivate it. No subject needed.
101
- if (p.type === "OAuthApp" && p.action === "revoked") {
216
+ if (payload.type === "OAuthApp" && payload.action === "revoked") {
102
217
  return { ...base, type: "oauth-revoked", subject: {} };
103
218
  }
104
- if (p.type === "Issue") {
105
- const issueId = p.issue?.id ?? p.agentSession?.issue?.id ?? "";
219
+ // Permission Changes webhook: the Connection's set of accessible teams changed. Like `oauth-revoked`
220
+ // it is about the Connection, not an issue/session, so the subject is empty; the added/removed team
221
+ // deltas ride on `teamAccess` for the hub to merge into the Connection's tracked set. The SDK's
222
+ // webhook union does not model `PermissionChange`, so cast the payload (same pattern as the
223
+ // AppUserNotification branch above). Defensive: default missing deltas to [] and the flag to false.
224
+ if (payload.type === "PermissionChange" && payload.action === "teamAccessChanged") {
225
+ const p = payload;
226
+ return {
227
+ ...base,
228
+ type: "team-access-changed",
229
+ subject: {},
230
+ teamAccess: {
231
+ addedTeamIds: p.addedTeamIds ?? [],
232
+ removedTeamIds: p.removedTeamIds ?? [],
233
+ canAccessAllPublicTeams: p.canAccessAllPublicTeams ?? false,
234
+ },
235
+ };
236
+ }
237
+ // Issue SLA webhook (DHK-63): a proactive trigger. Only `breached` is actionable (a pre-brief
238
+ // enrichment worth running); `set`/`highRisk` are lifecycle noise and fall through to the throw so
239
+ // they never spawn a session. The SDK's webhook union does not model `IssueSLA`, so cast to read the
240
+ // serialised issue (`issueData`), tolerating the field spellings the live body may use for the id.
241
+ if (payload.type === "IssueSLA" || payload.type === "Issue SLA") {
242
+ const p = payload;
243
+ if (p.action === "breached") {
244
+ const issueId = p.issueData?.id ?? p.issueId ?? p.issue?.id ?? p.data?.id ?? "";
245
+ return { ...base, type: "sla-breach", subject: { issueId } };
246
+ }
247
+ }
248
+ if (payload.type === "Issue") {
249
+ const p = payload;
250
+ // Live "Issue" entity webhooks carry the issue under `data`; tolerate a top-level `issue` too.
251
+ const issueId = p.data?.id ?? p.issue?.id ?? "";
252
+ // An archive is a soft-delete (`archivedAt` set, or an explicit `archived`/`remove` action): treat
253
+ // it as disengagement so any run parked on the issue is stopped. Any other Issue action is a
254
+ // create/update we currently only route as `issue-created`.
255
+ if (p.action === "archived" || p.action === "remove" || p.data?.archivedAt) {
256
+ return { ...base, type: "issue-archived", subject: { issueId } };
257
+ }
258
+ // Triage entry (DHK-63): the issue just MOVED into a triage-typed state - a proactive trigger for
259
+ // pre-brief enrichment. Conservative on purpose: emit only on positive evidence of an entry (the
260
+ // current state is `triage` AND `updatedFrom` shows the state changed, i.e. carries `stateId`), so
261
+ // an ordinary edit on a ticket already in triage still normalises to `issue-created`.
262
+ if (p.data?.state?.type === "triage" && p.updatedFrom && "stateId" in p.updatedFrom) {
263
+ return { ...base, type: "triage-entry", subject: { issueId } };
264
+ }
265
+ // Label add (DHK-93): a workflow-trigger label was applied. Emit a distinct `label-added` only on
266
+ // positive evidence - `updatedFrom` carries `labelIds` and at least one added label name resolves -
267
+ // so a pure removal, or any edit that never touched labels, still falls through to `issue-created`.
268
+ const addedLabels = addedLabelNames(p.data ?? undefined, p.updatedFrom);
269
+ if (addedLabels.length > 0) {
270
+ return { ...base, type: "label-added", subject: { issueId }, addedLabels };
271
+ }
106
272
  return { ...base, type: "issue-created", subject: { issueId } };
107
273
  }
108
- throw new Error(`unsupported Linear webhook: type=${p.type} action=${p.action}`);
274
+ throw new Error(`unsupported Linear webhook: type=${payload.type} action=${payload.action}`);
109
275
  }
110
276
  /** Keep only the externalUrls Linear accepts: http(s) URLs (internal `skakel://` refs are dropped),
111
277
  * with empty/blank URLs removed and duplicates collapsed by `url` (first wins, since Linear requires
@@ -123,9 +289,15 @@ export function filterExternalUrls(urls) {
123
289
  return kept;
124
290
  }
125
291
  export { createRecordingClient } from "./recording-client.js";
292
+ export { createRespondingLinearClient } from "./responding-client.js";
126
293
  export { createLinearClient } from "./linear-client.js";
127
- export { authorizeUrl, exchangeCode, refreshTokens, mintAppToken, fetchOrganizationId, probeToken, DEFAULT_AGENT_SCOPES } from "./oauth.js";
128
- export { provisionLabels, provisionWorkflowLabels, provisionRepoLabels, linearLabelApi, projectLabelApi, fetchIssueProjectRepoLabels, REPO_LABEL_GROUP, } from "./labels.js";
129
- export { linearTriageApi, linearClientAuth } from "./issues.js";
294
+ export { formatToolAction, formatToolResult } from "./format-action.js";
295
+ export { authorizeUrl, exchangeCode, refreshTokens, revokeToken, mintAppToken, fetchOrganizationId, probeToken, DEFAULT_AGENT_SCOPES } from "./oauth.js";
296
+ export { provisionLabels, provisionWorkflowLabels, provisionRepoLabels, linearLabelApi, projectLabelApi, fetchIssueProjectRepoLabels, fetchIssueChildCount, fetchOpenBlockers, isBlockerSettled, REPO_LABEL_GROUP, } from "./labels.js";
297
+ export { linearTeamsApi, listWorkspaceTeams } from "./teams.js";
298
+ export { linearTriageApi, linearClientAuth, linearCaptureApi } from "./issues.js";
130
299
  export { fetchAttachedDocuments, collectAttachedDocuments, linearDocumentSource, documentSlugFromUrl, documentSlug, } from "./documents.js";
300
+ export { fetchIssueComments, collectIssueComments, linearCommentSource } from "./comments.js";
301
+ export { fetchRelatedIssues, collectRelatedIssues, linearIssueGraphSource, MAX_RELATED_ISSUES, } from "./issue-graph.js";
302
+ export { fetchParentBatchSource, collectParentBatchSource, linearParentBatchSource, MAX_BATCH_CHILDREN, } from "./batch-source.js";
131
303
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { IssueRelation, RelatedIssue } from "@dahrk/contracts";
2
+ /** An issue as returned by Linear before normalisation, with its state already resolved. */
3
+ export interface RawRelatedIssue {
4
+ identifier?: string;
5
+ title?: string;
6
+ url?: string;
7
+ stateName?: string;
8
+ stateType?: string;
9
+ }
10
+ /** One edge: the neighbouring issue plus how it sits relative to the subject issue. */
11
+ export interface RawEdge {
12
+ relation: IssueRelation;
13
+ issue: RawRelatedIssue | null;
14
+ }
15
+ /** The read seam the assembly depends on; the live impl wraps GraphQL, tests inject a fake. */
16
+ export interface IssueGraphSource {
17
+ /** Every one-hop edge from the issue, in any order. */
18
+ issueEdges(issueId: string): Promise<RawEdge[]>;
19
+ }
20
+ /** How many neighbours ride the manifest. Beyond this the prompt stops being a summary. */
21
+ export declare const MAX_RELATED_ISSUES = 50;
22
+ /**
23
+ * Collect the issue's one-hop neighbourhood from a source: drop edges whose issue did not resolve or
24
+ * carries no identifier, de-dupe by identifier (an issue can be reachable by more than one edge -
25
+ * keep the structurally strongest, which is the lowest `RELATION_ORDER`), sort, and cap. Pure of any
26
+ * network.
27
+ */
28
+ export declare function collectRelatedIssues(source: IssueGraphSource, issueId: string): Promise<RelatedIssue[]>;
29
+ /** The live `IssueGraphSource`, backed by a Linear bearer token. Uses the typed SDK. */
30
+ export declare function linearIssueGraphSource(token: string): IssueGraphSource;
31
+ /**
32
+ * Fetch the issue's one-hop neighbourhood as contract `RelatedIssue`s, ready to snapshot into a run.
33
+ * The single entry point the hub calls. A hard failure (auth, network) propagates so the caller can
34
+ * log and proceed with none.
35
+ */
36
+ export declare function fetchRelatedIssues(token: string, issueId: string): Promise<RelatedIssue[]>;
37
+ //# sourceMappingURL=issue-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-graph.d.ts","sourceRoot":"","sources":["../src/issue-graph.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEpE,4FAA4F;AAC5F,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uFAAuF;AACvF,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,+FAA+F;AAC/F,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CACjD;AAED,2FAA2F;AAC3F,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAarC;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,EAAE,CAAC,CAwBzB;AAED,wFAAwF;AACxF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAoEtE;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAEhG"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Fetch the metadata of the issues one hop from a run's issue - parent, children, blockers, blocked,
3
+ * related - so the hub can snapshot a manifest into the run and tell the agent WHAT EXISTS around the
4
+ * ticket it is working.
5
+ *
6
+ * This is deliberately metadata only: identifier, title, relation, state. No descriptions, no comments,
7
+ * no documents. That keeps the manifest cheap enough to send on every run, and it is the piece that
8
+ * makes on-demand context work at all - an agent that cannot see there is a spike or an epic attached
9
+ * will never think to open one.
10
+ *
11
+ * Distinct from `fetchOpenBlockers` in `labels.ts`, which reads the same edges for the deterministic
12
+ * blocked guard: that one answers "may this run proceed" and feeds control flow, this one answers
13
+ * "what surrounds this ticket" and is context only. They are kept apart on purpose so a change to the
14
+ * manifest can never alter a guard.
15
+ *
16
+ * The `IssueGraphSource` seam keeps the assembly pure and unit-testable.
17
+ */
18
+ import { LinearClient } from "@linear/sdk";
19
+ /** How many neighbours ride the manifest. Beyond this the prompt stops being a summary. */
20
+ export const MAX_RELATED_ISSUES = 50;
21
+ /** Stable ordering for the manifest: the structurally important edges first, so a truncated list keeps
22
+ * what matters. Parent and blockers change how the work should be done; `related` is a loose,
23
+ * human-curated edge and is the first thing worth losing. */
24
+ const RELATION_ORDER = {
25
+ parent: 0,
26
+ blocker: 1,
27
+ child: 2,
28
+ blocked: 3,
29
+ related: 4,
30
+ };
31
+ /**
32
+ * Collect the issue's one-hop neighbourhood from a source: drop edges whose issue did not resolve or
33
+ * carries no identifier, de-dupe by identifier (an issue can be reachable by more than one edge -
34
+ * keep the structurally strongest, which is the lowest `RELATION_ORDER`), sort, and cap. Pure of any
35
+ * network.
36
+ */
37
+ export async function collectRelatedIssues(source, issueId) {
38
+ const byKey = new Map();
39
+ for (const edge of await source.issueEdges(issueId)) {
40
+ const issue = edge.issue;
41
+ const key = issue?.identifier?.trim();
42
+ if (!issue || !key)
43
+ continue;
44
+ const candidate = {
45
+ key,
46
+ title: (issue.title ?? "").trim() || "Untitled issue",
47
+ relation: edge.relation,
48
+ stateName: (issue.stateName ?? "").trim() || "unknown",
49
+ stateType: (issue.stateType ?? "").trim() || "unknown",
50
+ url: issue.url ?? "",
51
+ };
52
+ const existing = byKey.get(key);
53
+ if (!existing || RELATION_ORDER[candidate.relation] < RELATION_ORDER[existing.relation]) {
54
+ byKey.set(key, candidate);
55
+ }
56
+ }
57
+ return [...byKey.values()]
58
+ .sort((a, b) => RELATION_ORDER[a.relation] - RELATION_ORDER[b.relation] || a.key.localeCompare(b.key))
59
+ .slice(0, MAX_RELATED_ISSUES);
60
+ }
61
+ /** The live `IssueGraphSource`, backed by a Linear bearer token. Uses the typed SDK. */
62
+ export function linearIssueGraphSource(token) {
63
+ const client = new LinearClient({ accessToken: token });
64
+ return {
65
+ async issueEdges(issueId) {
66
+ const issue = await client.issue(issueId);
67
+ // Resolve one neighbouring issue into the raw shape, including its state. Returns null when the
68
+ // issue or its state does not resolve, which the assembly then skips.
69
+ const shape = async (node) => {
70
+ if (!node)
71
+ return null;
72
+ const state = await node.state;
73
+ return {
74
+ ...(node.identifier ? { identifier: node.identifier } : {}),
75
+ ...(node.title ? { title: node.title } : {}),
76
+ ...(node.url ? { url: node.url } : {}),
77
+ ...(state?.name ? { stateName: state.name } : {}),
78
+ ...(state?.type ? { stateType: state.type } : {}),
79
+ };
80
+ };
81
+ // The four reads run concurrently; each is independently capped. `relations` is what this issue
82
+ // blocks/relates to, `inverseRelations` is what points AT this issue - the direction matters, and
83
+ // getting it backwards is the bug called out on `fetchOpenBlockers` (labels.ts).
84
+ const [parent, children, relations, inverseRelations] = await Promise.all([
85
+ issue.parent,
86
+ issue.children({ first: 25 }),
87
+ issue.relations({ first: 25 }),
88
+ issue.inverseRelations({ first: 25 }),
89
+ ]);
90
+ const edges = [];
91
+ const parentShape = await shape(parent);
92
+ if (parentShape)
93
+ edges.push({ relation: "parent", issue: parentShape });
94
+ for (const child of children.nodes) {
95
+ edges.push({ relation: "child", issue: await shape(child) });
96
+ }
97
+ // Outbound: `A blocks B` stored on A means B is blocked BY us; anything else is a plain relation.
98
+ for (const rel of relations.nodes) {
99
+ const related = await rel.relatedIssue;
100
+ edges.push({
101
+ relation: rel.type === "blocks" ? "blocked" : "related",
102
+ issue: await shape(related),
103
+ });
104
+ }
105
+ // Inbound: a `blocks` relation pointing at us means that issue is OUR blocker.
106
+ for (const rel of inverseRelations.nodes) {
107
+ const other = await rel.issue;
108
+ edges.push({
109
+ relation: rel.type === "blocks" ? "blocker" : "related",
110
+ issue: await shape(other),
111
+ });
112
+ }
113
+ return edges;
114
+ },
115
+ };
116
+ }
117
+ /**
118
+ * Fetch the issue's one-hop neighbourhood as contract `RelatedIssue`s, ready to snapshot into a run.
119
+ * The single entry point the hub calls. A hard failure (auth, network) propagates so the caller can
120
+ * log and proceed with none.
121
+ */
122
+ export async function fetchRelatedIssues(token, issueId) {
123
+ return collectRelatedIssues(linearIssueGraphSource(token), issueId);
124
+ }
125
+ //# sourceMappingURL=issue-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-graph.js","sourceRoot":"","sources":["../src/issue-graph.ts"],"names":[],"mappings":"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"}
package/dist/issues.d.ts CHANGED
@@ -42,7 +42,32 @@ export declare function linearClientAuth(token: string): {
42
42
  accessToken: string;
43
43
  };
44
44
  /** The live `TriageApi` backed by a Linear token (personal API key or OAuth access token). Resolves
45
- * team (and optional project) by name, paginating like the label provisioner rather than relying on
46
- * SDK filter shapes. */
45
+ * team by key and optional project by name via server-side `filter` (verified on @linear/sdk 86.0.0,
46
+ * DHK-579: `TeamFilter.key`/`ProjectFilter.name` return exactly the expected node - the earlier
47
+ * paginate-then-match workaround is no longer needed). */
47
48
  export declare function linearTriageApi(token: string): TriageApi;
49
+ /** The result of a Capture create/update: the issue's internal id plus its human identifier and url. */
50
+ export interface CaptureIssueResult {
51
+ issueId: string;
52
+ identifier: string;
53
+ url: string;
54
+ }
55
+ /** The Capture Linear seam (DHK-1187): create an issue in a team (or under a project), or update an
56
+ * existing one. Unlike {@link TriageApi}, it returns the issue's internal `issueId` too (a Capture
57
+ * receipt needs it) and can update. Backed by a CUSTOMER connection token, never the hub triage token. */
58
+ export interface CaptureLinearApi {
59
+ createIssue(input: {
60
+ teamKey: string;
61
+ projectName?: string;
62
+ title: string;
63
+ description: string;
64
+ }): Promise<CaptureIssueResult>;
65
+ updateIssue(input: {
66
+ issueId: string;
67
+ title: string;
68
+ description: string;
69
+ }): Promise<CaptureIssueResult>;
70
+ }
71
+ /** The live {@link CaptureLinearApi} backed by a tenant connection token (API key or OAuth token). */
72
+ export declare function linearCaptureApi(token: string): CaptureLinearApi;
48
73
  //# sourceMappingURL=issues.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../src/issues.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IACxB;;uFAEmF;IACnF,WAAW,CAAC,KAAK,EAAE;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD;;uEAEmE;IACnE,kBAAkB,CAAC,KAAK,EAAE;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5B;;;sFAGkF;IAClF,YAAY,CAAC,KAAK,EAAE;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;KAC7B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED;;;2FAG2F;AAC3F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAE5F;AAED;;yBAEyB;AACzB,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CA8CxD"}
1
+ {"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../src/issues.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IACxB;;uFAEmF;IACnF,WAAW,CAAC,KAAK,EAAE;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD;;uEAEmE;IACnE,kBAAkB,CAAC,KAAK,EAAE;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5B;;;sFAGkF;IAClF,YAAY,CAAC,KAAK,EAAE;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;KAC7B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED;;;2FAG2F;AAC3F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAE5F;AAED;;;2DAG2D;AAC3D,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CA0CxD;AAED,wGAAwG;AACxG,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;2GAE2G;AAC3G,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,KAAK,EAAE;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChC,WAAW,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC1G;AAED,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CA0BhE"}