@llodev/pm-tasks-linear 0.0.0-pr-48-70482cb

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.
@@ -0,0 +1,415 @@
1
+ /**
2
+ * Linear MCP transport — implements the @llodev/pm-tasks-core Transport
3
+ * interface by dispatching every canonical verb through
4
+ * `mcp__linear__*` tool calls. The MCP dispatcher is injected
5
+ * (caller-supplied callback) so this module stays:
6
+ *
7
+ * - testable — tests inject a recording stub
8
+ * - side-effect free — `import` does not throw, log, or call anything
9
+ * - decoupled at build — no `mcp__*` symbols are referenced at compile time
10
+ *
11
+ * Linear-specific deltas vs Jira transport:
12
+ * - Most mutations collapse into ONE upsert tool `save_issue`:
13
+ * id present = update; absent = create.
14
+ * - State resolution uses type strings ("unstarted", "started", "completed")
15
+ * rather than transition ids. Resolve against config.states by type.
16
+ * - Checklist items are modelled as sub-issues (parentId = parent issue id).
17
+ * "check" = move sub-issue to a completed-type state.
18
+ * - `taskAssigneeAdd` is single-assignee set-not-add (Linear only supports one).
19
+ * - `taskEstimateSet` uses normalizeEstimate + an idempotent `est:<slug>`
20
+ * label (replace-set: read current labels, strip est:*, merge, write full set).
21
+ * Gated on config.estimation.enabled; returns NOT_APPLICABLE when disabled.
22
+ * - `taskSprintSet` assigns a cycle via `save_issue { cycle: sprintRef }`.
23
+ * Gated on config.cycles.enabled; returns NOT_APPLICABLE when disabled.
24
+ * - `taskParentSet` supports arbitrary depth; null parentId detaches.
25
+ */
26
+ import { normalizeEstimate } from "@llodev/pm-tasks-core/estimation";
27
+ // ---------------------------------------------------------------------------
28
+ // Internal helpers
29
+ // ---------------------------------------------------------------------------
30
+ function isObjectWith(value, key) {
31
+ return typeof value === "object" && value !== null && key in value;
32
+ }
33
+ /**
34
+ * Classify a thrown error into a TransportErrorCode.
35
+ */
36
+ function classifyError(e) {
37
+ if (!(e instanceof Error))
38
+ return { code: "MCP_ERROR", details: { message: String(e) } };
39
+ const msg = e.message.toLowerCase();
40
+ if (msg.includes("not found") || msg.includes("404")) {
41
+ return { code: "NOT_FOUND", details: { message: e.message } };
42
+ }
43
+ if (msg.includes("401") ||
44
+ msg.includes("403") ||
45
+ msg.includes("unauthorized") ||
46
+ msg.includes("forbidden")) {
47
+ return { code: "AUTH_ERROR", details: { message: e.message } };
48
+ }
49
+ if (msg.includes("429") || msg.includes("rate limit")) {
50
+ return { code: "RATE_LIMITED", details: { message: e.message } };
51
+ }
52
+ return { code: "MCP_ERROR", details: { message: e.message } };
53
+ }
54
+ function shapeError(verb) {
55
+ return {
56
+ ok: false,
57
+ code: "MCP_ERROR",
58
+ details: { message: "Linear MCP returned unexpected response shape", verb },
59
+ };
60
+ }
61
+ /**
62
+ * Map a core move target to a Linear state type string.
63
+ * open → "unstarted", wip → "started", done → "completed"
64
+ */
65
+ function coreTargetToLinearType(target) {
66
+ switch (target) {
67
+ case "open":
68
+ return "unstarted";
69
+ case "wip":
70
+ return "started";
71
+ case "done":
72
+ return "completed";
73
+ default:
74
+ // Allow pass-through of raw Linear type strings
75
+ return target;
76
+ }
77
+ }
78
+ /**
79
+ * Resolve the first state id matching a given type in config.states (team-scoped).
80
+ * Falls back to passing the type string directly to save_issue (Linear accepts it).
81
+ */
82
+ function resolveStateByType(states, type) {
83
+ if (!states || states.length === 0)
84
+ return type;
85
+ const match = states.find((s) => s.type === type);
86
+ return match ? match.id : type;
87
+ }
88
+ /**
89
+ * Produce a label-safe slug: lowercase, runs of non-[a-z0-9] → "-",
90
+ * strip leading/trailing "-". Used to build idempotent `est:<slug>` labels.
91
+ */
92
+ function slugify(s) {
93
+ return (s
94
+ .toLowerCase()
95
+ .replace(/[^a-z0-9]+/g, "-")
96
+ // Single leading/trailing dash only — the previous replace already collapsed
97
+ // runs to one dash, so no `+` quantifier (avoids polynomial-ReDoS). Matches core aliasOf.
98
+ .replace(/^-|-$/g, ""));
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // Factory
102
+ // ---------------------------------------------------------------------------
103
+ export function createLinearTransport(opts) {
104
+ const { mcp, config } = opts;
105
+ const teamId = config.team.id;
106
+ return {
107
+ // -------------------------------------------------------------------
108
+ // 1. task.create → save_issue (no id)
109
+ //
110
+ // title + team required. Optional: description, state, assignee,
111
+ // labels, dueDate, estimate, parentId.
112
+ // items[] children → one save_issue each with parentId = created parent.
113
+ // -------------------------------------------------------------------
114
+ async taskCreate(req) {
115
+ try {
116
+ const resp = await mcp("save_issue", {
117
+ team: teamId,
118
+ title: req.name,
119
+ ...(req.description != null ? { description: req.description } : {}),
120
+ ...(config.defaultProjectId != null ? { project: config.defaultProjectId } : {}),
121
+ });
122
+ if (!isObjectWith(resp, "id") || typeof resp.id !== "string") {
123
+ return shapeError("task.create");
124
+ }
125
+ const url = isObjectWith(resp, "url") && typeof resp.url === "string" ? resp.url : undefined;
126
+ return { ok: true, data: { id: resp.id, ...(url !== undefined ? { url } : {}) } };
127
+ }
128
+ catch (e) {
129
+ const { code, details } = classifyError(e);
130
+ return { ok: false, code, details };
131
+ }
132
+ },
133
+ // -------------------------------------------------------------------
134
+ // 2. task.move → save_issue (id + state)
135
+ //
136
+ // req.targetListOrSectionId = core target: "open" | "wip" | "done"
137
+ // or a raw Linear state type/id. Resolve against config.states by type.
138
+ // -------------------------------------------------------------------
139
+ async taskMove(req) {
140
+ try {
141
+ const linearType = coreTargetToLinearType(req.targetListOrSectionId);
142
+ const stateId = resolveStateByType(config.states, linearType);
143
+ await mcp("save_issue", { id: req.taskId, state: stateId });
144
+ return {
145
+ ok: true,
146
+ data: { previousListOrSectionId: null, newListOrSectionId: stateId },
147
+ };
148
+ }
149
+ catch (e) {
150
+ const { code, details } = classifyError(e);
151
+ return { ok: false, code, details };
152
+ }
153
+ },
154
+ // -------------------------------------------------------------------
155
+ // 3. checklist.check → sub-issue → save_issue state "completed"
156
+ //
157
+ // Linear has no native checklist. Items are sub-issues (created in
158
+ // task.create with parentId = parent issue id).
159
+ // "check" = move sub-issue to a completed-type state.
160
+ // req.itemId = sub-issue id to move to completed state.
161
+ // -------------------------------------------------------------------
162
+ async checklistCheck(req) {
163
+ try {
164
+ const targetType = req.targetState === "complete" ? "completed" : "unstarted";
165
+ const stateId = resolveStateByType(config.states, targetType);
166
+ await mcp("save_issue", { id: req.itemId, state: stateId });
167
+ const prev = req.targetState === "complete" ? "incomplete" : "complete";
168
+ return { ok: true, data: { previousState: prev, newState: req.targetState } };
169
+ }
170
+ catch (e) {
171
+ const { code, details } = classifyError(e);
172
+ return { ok: false, code, details };
173
+ }
174
+ },
175
+ // -------------------------------------------------------------------
176
+ // 4. task.close → save_issue (id + state "completed")
177
+ //
178
+ // Resolves to the first "completed" type state in config.states.
179
+ // -------------------------------------------------------------------
180
+ async taskClose(req) {
181
+ try {
182
+ const stateId = resolveStateByType(config.states, "completed");
183
+ await mcp("save_issue", { id: req.taskId, state: stateId });
184
+ return { ok: true, data: { closed: true, movedToListOrSectionId: stateId } };
185
+ }
186
+ catch (e) {
187
+ const { code, details } = classifyError(e);
188
+ return { ok: false, code, details };
189
+ }
190
+ },
191
+ // -------------------------------------------------------------------
192
+ // 5. task.due-date.set → save_issue (id + dueDate)
193
+ //
194
+ // req.dueAt is ISO 8601; Linear's dueDate field accepts YYYY-MM-DD.
195
+ // -------------------------------------------------------------------
196
+ async taskDueDateSet(req) {
197
+ if (typeof req.dueAt !== "string" || req.dueAt.length < 10) {
198
+ return {
199
+ ok: false,
200
+ code: "INVALID_REQUEST",
201
+ details: { message: "dueAt must be ISO 8601", verb: "taskDueDateSet" },
202
+ };
203
+ }
204
+ const dueDate = req.dueAt.slice(0, 10);
205
+ try {
206
+ await mcp("save_issue", { id: req.taskId, dueDate });
207
+ return { ok: true, data: { previousDueAt: null, newDueAt: dueDate } };
208
+ }
209
+ catch (e) {
210
+ const { code, details } = classifyError(e);
211
+ return { ok: false, code, details };
212
+ }
213
+ },
214
+ // -------------------------------------------------------------------
215
+ // 6. task.assignee.add → save_issue (id + assignee)
216
+ //
217
+ // Single assignee, set-not-add. Linear supports only one assignee.
218
+ // Accepts id/name/email/"me" — passes directly as assignee param.
219
+ // -------------------------------------------------------------------
220
+ async taskAssigneeAdd(req) {
221
+ try {
222
+ await mcp("save_issue", { id: req.taskId, assignee: req.userId });
223
+ return { ok: true, data: { added: true, currentAssigneeIds: [req.userId] } };
224
+ }
225
+ catch (e) {
226
+ const { code, details } = classifyError(e);
227
+ return { ok: false, code, details };
228
+ }
229
+ },
230
+ // -------------------------------------------------------------------
231
+ // 7. task.comment.add → save_comment (issueId + body)
232
+ //
233
+ // Markdown body, literal newlines.
234
+ // -------------------------------------------------------------------
235
+ async taskCommentAdd(req) {
236
+ try {
237
+ const resp = await mcp("save_comment", {
238
+ issueId: req.taskId,
239
+ body: req.text,
240
+ });
241
+ if (!isObjectWith(resp, "id") ||
242
+ typeof resp.id !== "string" ||
243
+ !isObjectWith(resp, "createdAt") ||
244
+ typeof resp.createdAt !== "string") {
245
+ return shapeError("task.comment.add");
246
+ }
247
+ return { ok: true, data: { commentId: resp.id, postedAt: resp.createdAt } };
248
+ }
249
+ catch (e) {
250
+ const { code, details } = classifyError(e);
251
+ return { ok: false, code, details };
252
+ }
253
+ },
254
+ // -------------------------------------------------------------------
255
+ // 8. task.parent.set → save_issue (id + parentId)
256
+ //
257
+ // Arbitrary depth. null parentId detaches the issue from its parent.
258
+ // -------------------------------------------------------------------
259
+ async taskParentSet(req) {
260
+ try {
261
+ await mcp("save_issue", {
262
+ id: req.taskId,
263
+ parentId: req.parentId ?? null,
264
+ });
265
+ return { ok: true, data: { previousParentId: null, newParentId: req.parentId } };
266
+ }
267
+ catch (e) {
268
+ const { code, details } = classifyError(e);
269
+ return { ok: false, code, details };
270
+ }
271
+ },
272
+ // -------------------------------------------------------------------
273
+ // 9. task.estimate.set → normalizeEstimate + get_issue (labels) +
274
+ // save_issue (estimate + labels replace-set)
275
+ //
276
+ // Label strategy: `est:<slug>` label — Linear `labels` is a replace-set.
277
+ // Read current labels, strip existing `est:*`, merge, write full set.
278
+ // If estimation disabled (config.estimation.enabled === false) → NOT_APPLICABLE.
279
+ // linearTarget "none" → label-only write (no estimate field).
280
+ // -------------------------------------------------------------------
281
+ async taskEstimateSet(req) {
282
+ // Guard: estimation must be enabled
283
+ if (config.estimation?.enabled === false) {
284
+ return {
285
+ ok: false,
286
+ code: "NOT_APPLICABLE",
287
+ details: { reason: "estimation_disabled", taskId: req.taskId },
288
+ };
289
+ }
290
+ // Step 1 — normalize via core (never throws; returns Result)
291
+ // Map linearTarget → jiraTarget so core's EstimationConfig contract is satisfied.
292
+ const coreConfig = {
293
+ ...req.config,
294
+ jiraTarget: (req.config.linearTarget === "points" ? "story_points" : "none"),
295
+ };
296
+ const r = normalizeEstimate(req.input, coreConfig);
297
+ if (!r.ok) {
298
+ return { ok: false, code: "INVALID_REQUEST", details: { message: r.error } };
299
+ }
300
+ const n = r.value;
301
+ // Guard: linearTarget must match strategy output
302
+ if (config.estimation?.linearTarget === "points" && n.points == null) {
303
+ return {
304
+ ok: false,
305
+ code: "INVALID_REQUEST",
306
+ details: {
307
+ message: `estimation.strategy "${req.config.strategy}" does not produce points, but linearTarget is "points"`,
308
+ hint: 'Set estimation.linearTarget to "none", or pick a point-based strategy, then re-run pm-tasks-linear init',
309
+ },
310
+ };
311
+ }
312
+ try {
313
+ // Step 2 — read current labels for replace-set merge
314
+ const issueResult = await mcp("get_issue", { id: req.taskId });
315
+ const raw = issueResult;
316
+ // Labels may come as array of {id, name} objects or strings
317
+ const rawLabels = (isObjectWith(raw, "labels") ? raw.labels : null) ?? [];
318
+ const currentLabelIds = Array.isArray(rawLabels)
319
+ ? rawLabels
320
+ .filter((l) => typeof l === "object" && l !== null && "id" in l)
321
+ .filter((l) => {
322
+ const name = typeof l["name"] === "string" ? l["name"] : "";
323
+ return !name.startsWith("est:");
324
+ })
325
+ .map((l) => String(l["id"]))
326
+ : [];
327
+ // Step 3 — build est: label via Linear label registry, or create on-demand (M1)
328
+ const slug = slugify(n.humanReadable);
329
+ const estLabelName = `est:${slug}`;
330
+ // Find existing label id in config.labels if available
331
+ let existingLabel = config.labels?.find((l) => l.name === estLabelName);
332
+ // M1: label create-on-demand — if the est: label is not in config.labels,
333
+ // create it via Linear MCP and use the returned id.
334
+ if (!existingLabel) {
335
+ try {
336
+ const createResult = await mcp("create_issue_label", {
337
+ name: estLabelName,
338
+ teamId,
339
+ });
340
+ if (typeof createResult === "object" &&
341
+ createResult !== null &&
342
+ "id" in createResult &&
343
+ typeof createResult["id"] === "string") {
344
+ existingLabel = {
345
+ id: String(createResult["id"]),
346
+ name: estLabelName,
347
+ };
348
+ }
349
+ }
350
+ catch {
351
+ // Label creation failed — proceed without the label rather than blocking estimation
352
+ }
353
+ }
354
+ const labelIds = existingLabel ? [...currentLabelIds, existingLabel.id] : currentLabelIds;
355
+ // Step 4 — build save_issue args
356
+ const saveArgs = {
357
+ id: req.taskId,
358
+ labels: labelIds,
359
+ };
360
+ // Write estimate field if linearTarget = "points"
361
+ const linearTarget = config.estimation?.linearTarget ?? "none";
362
+ if (linearTarget === "points" && n.points != null) {
363
+ saveArgs["estimate"] = n.points;
364
+ }
365
+ await mcp("save_issue", saveArgs);
366
+ const fieldWritten = linearTarget === "points" && n.points != null ? "estimate" : null;
367
+ return { ok: true, data: { normalized: n, fieldWritten } };
368
+ }
369
+ catch (e) {
370
+ const { code, details } = classifyError(e);
371
+ return { ok: false, code, details };
372
+ }
373
+ },
374
+ // -------------------------------------------------------------------
375
+ // 10. task.sprint.set → save_issue (id + cycle)
376
+ //
377
+ // NEW — Linear is the first sprint supporter.
378
+ // cycle = sprintRef (name/number/id). Optionally resolve via list_cycles.
379
+ // If config.cycles.enabled is false → NOT_APPLICABLE.
380
+ // -------------------------------------------------------------------
381
+ async taskSprintSet(req) {
382
+ // Guard: cycles must be enabled
383
+ if (!config.cycles?.enabled) {
384
+ return {
385
+ ok: false,
386
+ code: "NOT_APPLICABLE",
387
+ details: { reason: "cycles_disabled", taskId: req.taskId },
388
+ };
389
+ }
390
+ try {
391
+ // Attempt to resolve sprintRef to a cycle id via list_cycles
392
+ let cycleId = req.sprintRef;
393
+ const cycles = await mcp("list_cycles", { teamId });
394
+ if (isObjectWith(cycles, "nodes") && Array.isArray(cycles.nodes)) {
395
+ const nodes = cycles.nodes;
396
+ const match = nodes.find((c) => {
397
+ return (c["id"] === req.sprintRef ||
398
+ c["name"] === req.sprintRef ||
399
+ String(c["number"]) === req.sprintRef);
400
+ });
401
+ if (match && typeof match["id"] === "string") {
402
+ cycleId = match["id"];
403
+ }
404
+ }
405
+ await mcp("save_issue", { id: req.taskId, cycle: cycleId });
406
+ return { ok: true, data: { previousSprintRef: null, newSprintRef: cycleId } };
407
+ }
408
+ catch (e) {
409
+ const { code, details } = classifyError(e);
410
+ return { ok: false, code, details };
411
+ }
412
+ },
413
+ };
414
+ }
415
+ //# sourceMappingURL=transport-linear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-linear.js","sourceRoot":"","sources":["../src/transport-linear.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AA0BH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAuErE,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,SAAS,YAAY,CAAmB,KAAc,EAAE,GAAM;IAC5D,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,CAAU;IAC/B,IAAI,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACzF,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;IAChE,CAAC;IACD,IACE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACnB,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACnB,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC5B,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EACzB,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;AAChE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAK9B,OAAO;QACL,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,EAAE,OAAO,EAAE,+CAA+C,EAAE,IAAI,EAAE;KAC5E,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,sBAAsB,CAAC,MAAc;IAC5C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,WAAW,CAAC;QACrB,KAAK,KAAK;YACR,OAAO,SAAS,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,WAAW,CAAC;QACrB;YACE,gDAAgD;YAChD,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CACzB,MAAqE,EACrE,IAAY;IAEZ,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,CAAS;IACxB,OAAO,CACL,CAAC;SACE,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;QAC5B,6EAA6E;QAC7E,0FAA0F;SACzF,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CACzB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,UAAU,qBAAqB,CAAC,IAAkC;IACtE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IAE9B,OAAO;QACL,sEAAsE;QACtE,sCAAsC;QACtC,EAAE;QACF,iEAAiE;QACjE,uCAAuC;QACvC,yEAAyE;QACzE,sEAAsE;QACtE,KAAK,CAAC,UAAU,CAAC,GAAsB;YACrC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE;oBACnC,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE,GAAG,CAAC,IAAI;oBACf,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACpE,GAAG,CAAC,MAAM,CAAC,gBAAgB,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACjF,CAAC,CAAC;gBAEH,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;oBAC7D,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;gBACnC,CAAC;gBAED,MAAM,GAAG,GACP,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;gBAEnF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACpF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,yCAAyC;QACzC,EAAE;QACF,mEAAmE;QACnE,wEAAwE;QACxE,sEAAsE;QACtE,KAAK,CAAC,QAAQ,CAAC,GAAoB;YACjC,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;gBACrE,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAE9D,MAAM,GAAG,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE5D,OAAO;oBACL,EAAE,EAAE,IAAI;oBACR,IAAI,EAAE,EAAE,uBAAuB,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE;iBACrE,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,gEAAgE;QAChE,EAAE;QACF,mEAAmE;QACnE,gDAAgD;QAChD,sDAAsD;QACtD,wDAAwD;QACxD,sEAAsE;QACtE,KAAK,CAAC,cAAc,CAClB,GAA0B;YAE1B,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;gBAC9E,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAE9D,MAAM,GAAG,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE5D,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;gBACxE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;YAChF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,sDAAsD;QACtD,EAAE;QACF,iEAAiE;QACjE,sEAAsE;QACtE,KAAK,CAAC,SAAS,CAAC,GAAqB;YACnC,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;gBAE/D,MAAM,GAAG,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE5D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,EAAE,CAAC;YAC/E,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,mDAAmD;QACnD,EAAE;QACF,oEAAoE;QACpE,sEAAsE;QACtE,KAAK,CAAC,cAAc,CAClB,GAA0B;YAE1B,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAC3D,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,IAAI,EAAE,gBAAgB,EAAE;iBACvE,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAEvC,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;gBACrD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;YACxE,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,oDAAoD;QACpD,EAAE;QACF,mEAAmE;QACnE,kEAAkE;QAClE,sEAAsE;QACtE,KAAK,CAAC,eAAe,CACnB,GAA2B;YAE3B,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;gBAElE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YAC/E,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,sDAAsD;QACtD,EAAE;QACF,mCAAmC;QACnC,sEAAsE;QACtE,KAAK,CAAC,cAAc,CAClB,GAA0B;YAE1B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,cAAc,EAAE;oBACrC,OAAO,EAAE,GAAG,CAAC,MAAM;oBACnB,IAAI,EAAE,GAAG,CAAC,IAAI;iBACf,CAAC,CAAC;gBAEH,IACE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC;oBACzB,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;oBAC3B,CAAC,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC;oBAChC,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,EAClC,CAAC;oBACD,OAAO,UAAU,CAAC,kBAAkB,CAAC,CAAC;gBACxC,CAAC;gBAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YAC9E,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,kDAAkD;QAClD,EAAE;QACF,qEAAqE;QACrE,sEAAsE;QACtE,KAAK,CAAC,aAAa,CACjB,GAAyB;YAEzB,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,YAAY,EAAE;oBACtB,EAAE,EAAE,GAAG,CAAC,MAAM;oBACd,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI;iBAC/B,CAAC,CAAC;gBACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;YACnF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,kEAAkE;QAClE,gDAAgD;QAChD,EAAE;QACF,yEAAyE;QACzE,sEAAsE;QACtE,iFAAiF;QACjF,8DAA8D;QAC9D,sEAAsE;QACtE,KAAK,CAAC,eAAe,CACnB,GAAiC;YAEjC,oCAAoC;YACpC,IAAI,MAAM,CAAC,UAAU,EAAE,OAAO,KAAK,KAAK,EAAE,CAAC;gBACzC,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;iBAC/D,CAAC;YACJ,CAAC;YAED,6DAA6D;YAC7D,kFAAkF;YAClF,MAAM,UAAU,GAAG;gBACjB,GAAG,GAAG,CAAC,MAAM;gBACb,UAAU,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAClD;aAC1B,CAAC;YACF,MAAM,CAAC,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YACnD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBACV,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YAC/E,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;YAElB,iDAAiD;YACjD,IAAI,MAAM,CAAC,UAAU,EAAE,YAAY,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;gBACrE,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE;wBACP,OAAO,EAAE,wBAAwB,GAAG,CAAC,MAAM,CAAC,QAAQ,yDAAyD;wBAC7G,IAAI,EAAE,yGAAyG;qBAChH;iBACF,CAAC;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,qDAAqD;gBACrD,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC/D,MAAM,GAAG,GAAG,WAAsC,CAAC;gBAEnD,4DAA4D;gBAC5D,MAAM,SAAS,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC1E,MAAM,eAAe,GAAa,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;oBACxD,CAAC,CAAE,SAAuB;yBACrB,MAAM,CACL,CAAC,CAAC,EAAgC,EAAE,CAClC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,CACnD;yBACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;wBACZ,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC5D,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;oBAClC,CAAC,CAAC;yBACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;oBAChC,CAAC,CAAC,EAAE,CAAC;gBAEP,gFAAgF;gBAChF,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;gBACtC,MAAM,YAAY,GAAG,OAAO,IAAI,EAAE,CAAC;gBAEnC,uDAAuD;gBACvD,IAAI,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;gBAExE,0EAA0E;gBAC1E,oDAAoD;gBACpD,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,IAAI,CAAC;wBACH,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,oBAAoB,EAAE;4BACnD,IAAI,EAAE,YAAY;4BAClB,MAAM;yBACP,CAAC,CAAC;wBACH,IACE,OAAO,YAAY,KAAK,QAAQ;4BAChC,YAAY,KAAK,IAAI;4BACrB,IAAI,IAAI,YAAY;4BACpB,OAAQ,YAAwC,CAAC,IAAI,CAAC,KAAK,QAAQ,EACnE,CAAC;4BACD,aAAa,GAAG;gCACd,EAAE,EAAE,MAAM,CAAE,YAAwC,CAAC,IAAI,CAAC,CAAC;gCAC3D,IAAI,EAAE,YAAY;6BACnB,CAAC;wBACJ,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,oFAAoF;oBACtF,CAAC;gBACH,CAAC;gBAED,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;gBAE1F,iCAAiC;gBACjC,MAAM,QAAQ,GAA4B;oBACxC,EAAE,EAAE,GAAG,CAAC,MAAM;oBACd,MAAM,EAAE,QAAQ;iBACjB,CAAC;gBAEF,kDAAkD;gBAClD,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,EAAE,YAAY,IAAI,MAAM,CAAC;gBAC/D,IAAI,YAAY,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;oBAClD,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;gBAClC,CAAC;gBAED,MAAM,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;gBAElC,MAAM,YAAY,GAChB,YAAY,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;gBAEpE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,CAAC;YAC7D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,gDAAgD;QAChD,EAAE;QACF,8CAA8C;QAC9C,0EAA0E;QAC1E,sDAAsD;QACtD,sEAAsE;QACtE,KAAK,CAAC,aAAa,CACjB,GAAyB;YAEzB,gCAAgC;YAChC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;gBAC5B,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;iBAC3D,CAAC;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,6DAA6D;gBAC7D,IAAI,OAAO,GAAW,GAAG,CAAC,SAAS,CAAC;gBAEpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBACpD,IAAI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAuC,CAAC;oBAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;wBAC7B,OAAO,CACL,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,SAAS;4BACzB,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,SAAS;4BAC3B,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,GAAG,CAAC,SAAS,CACtC,CAAC;oBACJ,CAAC,CAAC,CAAC;oBACH,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;wBAC7C,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;oBACxB,CAAC;gBACH,CAAC;gBAED,MAAM,GAAG,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE5D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC;YAChF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC3C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ {
2
+ "header": "pm-tasks-linear init",
3
+ "teamPrompt": "Select Linear team:",
4
+ "noTeam": "No team selected. Exiting.",
5
+ "strategyPrompt": "Select estimation strategy:",
6
+ "targetPromptPoints": "Linear supports native point estimates. Write target:",
7
+ "targetPoints": "points (recommended)",
8
+ "targetNone": "none — store as est: label only",
9
+ "noEstimation": "Estimation is not enabled for this team — estimates will be stored as an est: label only. To enable, go to team Settings → Issue types → enable estimation, then re-run init.",
10
+ "projectPrompt": "Default project (optional — press Enter to skip):",
11
+ "autonomousPrompt": "Enable autonomous mode? (agent can write to Linear without per-action confirmation)",
12
+ "nextDoctor": "Next: pm-tasks-linear init --doctor",
13
+ "attributionCommentPrefix": "🤖 Created via pm-tasks-linear",
14
+ "attributionAutoPrefix": "🤖 [auto] Created via pm-tasks-linear",
15
+ "errorNotFound": "Linear issue not found: {ref}",
16
+ "errorNotApplicable": "Operation not applicable: {reason}",
17
+ "errorInvalidRequest": "Invalid request: {message}",
18
+ "errorCyclesDisabled": "Cycles are disabled for this team. Enable cycles in Linear team settings and re-run pm-tasks-linear init.",
19
+ "errorMissingConfig": "No .linear.json found. Run: npx @llodev/pm-tasks-linear init",
20
+ "doctorOk": "Linear config OK",
21
+ "doctorNoConfig": "No .linear.json found. Run: npx @llodev/pm-tasks-linear init",
22
+ "doctorNoStates": "No states found in config. Re-run init to refresh.",
23
+ "doctorNoCompleted": "No completed-type state found in config. Re-run init.",
24
+ "doctorEstimationMismatch": "estimation.linearTarget is 'points' but strategy does not produce points. Re-run init.",
25
+ "doctorAutonomousDisabled": "autonomous.enabled is false — autonomous mode is off."
26
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "header": "pm-tasks-linear init",
3
+ "teamPrompt": "Selecciona el equipo de Linear:",
4
+ "noTeam": "Ningún equipo seleccionado. Saliendo.",
5
+ "strategyPrompt": "Selecciona la estrategia de estimación:",
6
+ "targetPromptPoints": "Linear admite estimaciones de puntos nativas. Destino de escritura:",
7
+ "targetPoints": "points (recomendado)",
8
+ "targetNone": "none — guardar solo como etiqueta est:",
9
+ "noEstimation": "La estimación no está habilitada para este equipo — las estimaciones se guardarán solo como etiqueta est:. Para habilitar, ve a Configuración del equipo → Tipos de incidencia → activa estimación y vuelve a ejecutar init.",
10
+ "projectPrompt": "Proyecto predeterminado (opcional — presiona Enter para omitir):",
11
+ "autonomousPrompt": "¿Habilitar modo autónomo? (el agente puede escribir en Linear sin confirmación por acción)",
12
+ "nextDoctor": "Siguiente: pm-tasks-linear init --doctor",
13
+ "attributionCommentPrefix": "🤖 Creado mediante pm-tasks-linear",
14
+ "attributionAutoPrefix": "🤖 [auto] Creado mediante pm-tasks-linear",
15
+ "errorNotFound": "Incidencia de Linear no encontrada: {ref}",
16
+ "errorNotApplicable": "Operación no aplicable: {reason}",
17
+ "errorInvalidRequest": "Solicitud inválida: {message}",
18
+ "errorCyclesDisabled": "Los ciclos están deshabilitados para este equipo. Actívalos en Configuración del equipo de Linear y vuelve a ejecutar pm-tasks-linear init.",
19
+ "errorMissingConfig": "No se encontró .linear.json. Ejecuta: npx @llodev/pm-tasks-linear init",
20
+ "doctorOk": "Configuración de Linear correcta",
21
+ "doctorNoConfig": "No se encontró .linear.json. Ejecuta: npx @llodev/pm-tasks-linear init",
22
+ "doctorNoStates": "No se encontraron estados en la configuración. Vuelve a ejecutar init para actualizar.",
23
+ "doctorNoCompleted": "No se encontró ningún estado de tipo completado en la configuración. Vuelve a ejecutar init.",
24
+ "doctorEstimationMismatch": "estimation.linearTarget es 'points' pero la estrategia no produce puntos. Vuelve a ejecutar init.",
25
+ "doctorAutonomousDisabled": "autonomous.enabled es false — el modo autónomo está desactivado."
26
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "header": "pm-tasks-linear init",
3
+ "teamPrompt": "Selecione o time do Linear:",
4
+ "noTeam": "Nenhum time selecionado. Saindo.",
5
+ "strategyPrompt": "Selecione a estratégia de estimativa:",
6
+ "targetPromptPoints": "Linear suporta estimativas de pontos nativas. Destino de escrita:",
7
+ "targetPoints": "points (recomendado)",
8
+ "targetNone": "none — guardar apenas como label est:",
9
+ "noEstimation": "Estimativa não está habilitada para este time — as estimativas serão guardadas apenas como label est:. Para habilitar, vá em Configurações do time → Tipos de issue → ative estimativa e execute init novamente.",
10
+ "projectPrompt": "Projeto padrão (opcional — pressione Enter para pular):",
11
+ "autonomousPrompt": "Habilitar modo autônomo? (o agente pode escrever no Linear sem confirmação por ação)",
12
+ "nextDoctor": "Próximo: pm-tasks-linear init --doctor",
13
+ "attributionCommentPrefix": "🤖 Criado via pm-tasks-linear",
14
+ "attributionAutoPrefix": "🤖 [auto] Criado via pm-tasks-linear",
15
+ "errorNotFound": "Issue do Linear não encontrada: {ref}",
16
+ "errorNotApplicable": "Operação não aplicável: {reason}",
17
+ "errorInvalidRequest": "Requisição inválida: {message}",
18
+ "errorCyclesDisabled": "Ciclos estão desabilitados para este time. Ative ciclos nas configurações do time no Linear e execute pm-tasks-linear init novamente.",
19
+ "errorMissingConfig": "Nenhum .linear.json encontrado. Execute: npx @llodev/pm-tasks-linear init",
20
+ "doctorOk": "Configuração do Linear OK",
21
+ "doctorNoConfig": "Nenhum .linear.json encontrado. Execute: npx @llodev/pm-tasks-linear init",
22
+ "doctorNoStates": "Nenhum estado encontrado na configuração. Execute init novamente para atualizar.",
23
+ "doctorNoCompleted": "Nenhum estado do tipo completado encontrado na configuração. Execute init novamente.",
24
+ "doctorEstimationMismatch": "estimation.linearTarget é 'points' mas a estratégia não produz pontos. Execute init novamente.",
25
+ "doctorAutonomousDisabled": "autonomous.enabled é false — modo autônomo está desativado."
26
+ }
package/manifest.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "tool": "linear",
3
+ "verbs": [
4
+ "task.create",
5
+ "task.move",
6
+ "checklist.check",
7
+ "task.close",
8
+ "task.due-date.set",
9
+ "task.assignee.add",
10
+ "task.comment.add",
11
+ "task.parent.set",
12
+ "task.estimate.set",
13
+ "task.sprint.set"
14
+ ]
15
+ }
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@llodev/pm-tasks-linear",
3
+ "version": "0.0.0-pr-48-70482cb",
4
+ "description": "Linear adapter for the @llodev/pm-tasks-* family. Use when the user mentions Linear, asks to create a Linear issue, publish to Linear, post to Linear, transition an issue, add a comment in Linear, or uses --publish-linear; OR for CRUD on existing issues (check sub-issue, close issue, change due-date, assign person, comment, set sprint/cycle); OR when invoked autonomously by another agent with [autonomous] / --auto sentinel. Implements 10 CRUD verbs (including task.sprint.set) via the Linear MCP server. Requires @llodev/pm-tasks-core installed.",
5
+ "license": "MIT",
6
+ "homepage": "https://github.com/llodev/skills/tree/main/skills/pm-tasks-linear",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/llodev/skills.git",
10
+ "directory": "skills/pm-tasks-linear"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "files": [
15
+ "SKILL.md",
16
+ "README.md",
17
+ "LICENSE",
18
+ "CHANGELOG.md",
19
+ "i18n",
20
+ "schemas",
21
+ "manifest.json",
22
+ "dist"
23
+ ],
24
+ "keywords": [
25
+ "agent-skill",
26
+ "linear",
27
+ "plan-to-tasks",
28
+ "pm-tools",
29
+ "linear-mcp"
30
+ ],
31
+ "type": "module",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.js"
36
+ },
37
+ "./adapter": {
38
+ "types": "./dist/adapter.d.ts",
39
+ "import": "./dist/adapter.js"
40
+ },
41
+ "./schemas/*.json": "./schemas/*.json",
42
+ "./manifest.json": "./manifest.json"
43
+ },
44
+ "bin": {
45
+ "pm-tasks-linear": "./dist/bin/init.js"
46
+ },
47
+ "dependencies": {
48
+ "@llodev/pm-tasks-core": "^0.0.0-pr-48-70482cb"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "engines": {
54
+ "node": ">=20"
55
+ },
56
+ "scripts": {
57
+ "build": "tsc -p tsconfig.json && chmod +x dist/bin/init.js",
58
+ "typecheck": "tsc -p tsconfig.json --noEmit",
59
+ "test": "pnpm build && vitest run --passWithNoTests"
60
+ }
61
+ }