@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.
- package/README.md +24 -12
- package/dist/batch-source.d.ts +63 -0
- package/dist/batch-source.d.ts.map +1 -0
- package/dist/batch-source.js +149 -0
- package/dist/batch-source.js.map +1 -0
- package/dist/comments.d.ts +36 -0
- package/dist/comments.d.ts.map +1 -0
- package/dist/comments.js +104 -0
- package/dist/comments.js.map +1 -0
- package/dist/documents.d.ts +1 -15
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js +37 -27
- package/dist/documents.js.map +1 -1
- package/dist/format-action.d.ts +25 -0
- package/dist/format-action.d.ts.map +1 -0
- package/dist/format-action.js +250 -0
- package/dist/format-action.js.map +1 -0
- package/dist/index.d.ts +119 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +231 -59
- package/dist/index.js.map +1 -1
- package/dist/issue-graph.d.ts +37 -0
- package/dist/issue-graph.d.ts.map +1 -0
- package/dist/issue-graph.js +125 -0
- package/dist/issue-graph.js.map +1 -0
- package/dist/issues.d.ts +27 -2
- package/dist/issues.d.ts.map +1 -1
- package/dist/issues.js +33 -10
- package/dist/issues.js.map +1 -1
- package/dist/labels.d.ts +48 -1
- package/dist/labels.d.ts.map +1 -1
- package/dist/labels.js +72 -24
- package/dist/labels.js.map +1 -1
- package/dist/linear-client.d.ts +51 -0
- package/dist/linear-client.d.ts.map +1 -1
- package/dist/linear-client.js +233 -34
- package/dist/linear-client.js.map +1 -1
- package/dist/oauth.d.ts +52 -12
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +91 -34
- package/dist/oauth.js.map +1 -1
- package/dist/recording-client.d.ts +20 -2
- package/dist/recording-client.d.ts.map +1 -1
- package/dist/recording-client.js +39 -1
- package/dist/recording-client.js.map +1 -1
- package/dist/responding-client.d.ts +49 -0
- package/dist/responding-client.d.ts.map +1 -0
- package/dist/responding-client.js +47 -0
- package/dist/responding-client.js.map +1 -0
- package/dist/teams.d.ts +20 -0
- package/dist/teams.d.ts.map +1 -0
- package/dist/teams.js +32 -0
- package/dist/teams.js.map +1 -0
- package/package.json +8 -10
- package/src/batch-source.ts +208 -0
- package/src/comments.ts +126 -0
- package/src/documents.ts +162 -0
- package/src/format-action.ts +279 -0
- package/src/index.ts +617 -0
- package/src/issue-graph.ts +169 -0
- package/src/issues.ts +142 -0
- package/src/labels.ts +254 -0
- package/src/linear-client.ts +448 -0
- package/src/oauth.ts +255 -0
- package/src/recording-client.ts +141 -0
- package/src/responding-client.ts +106 -0
- 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
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
|
|
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
|
|
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
|
|
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:
|
|
123
|
+
workspaceId: payload.organizationId,
|
|
55
124
|
linearPayload: payload,
|
|
56
125
|
ts,
|
|
57
126
|
};
|
|
58
|
-
if (
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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 (
|
|
216
|
+
if (payload.type === "OAuthApp" && payload.action === "revoked") {
|
|
102
217
|
return { ...base, type: "oauth-revoked", subject: {} };
|
|
103
218
|
}
|
|
104
|
-
|
|
105
|
-
|
|
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=${
|
|
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 {
|
|
128
|
-
export {
|
|
129
|
-
export {
|
|
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
|
|
46
|
-
*
|
|
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
|
package/dist/issues.d.ts.map
CHANGED
|
@@ -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
|
|
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"}
|