@enrichlayer/el-linear 1.32.1 → 1.32.3
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 -1
- package/claude-skills/linear-operations/SKILL.md +26 -1
- package/claude-skills/linear-operations/evals/evals.json +83 -0
- package/dist/commands/comments.js +67 -4
- package/dist/queries/comments-types.d.ts +10 -0
- package/dist/queries/comments.d.ts +1 -0
- package/dist/queries/comments.js +21 -0
- package/dist/utils/formatters/summary.js +4 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -442,7 +442,7 @@ el-linear <command> --help # detailed help for one command
|
|
|
442
442
|
| Group | Common commands |
|
|
443
443
|
|-------|-----------------|
|
|
444
444
|
| Issues | `issues {list, search, create, read, update, start, delete, history, related, link-references}` |
|
|
445
|
-
| Comments | `comments {list, create, update}` |
|
|
445
|
+
| Comments | `comments {list, read, create, update, delete}` |
|
|
446
446
|
| Labels | `labels {list, create, retire, restore}` |
|
|
447
447
|
| Projects | `projects {list, add-team, remove-team}` |
|
|
448
448
|
| Cycles | `cycles {list, read}` |
|
|
@@ -660,6 +660,29 @@ el-linear issues read DEV-123 --body
|
|
|
660
660
|
|
|
661
661
|
Mutually exclusive with `--field` / `--sections` / `--with`.
|
|
662
662
|
|
|
663
|
+
### Read full comment bodies without JSON parsing
|
|
664
|
+
|
|
665
|
+
`comments read <comment-id>` reads one comment by full UUID, `comment-<hash>`
|
|
666
|
+
token, or a Linear URL containing `#comment-<hash>`. Use `--body` for the raw
|
|
667
|
+
markdown body with real newlines and no JSON envelope. `comments list --body`
|
|
668
|
+
prints every complete body on an issue as plain text blocks, and
|
|
669
|
+
`comments list --format summary --no-truncate` keeps the summary shape while
|
|
670
|
+
showing full bodies.
|
|
671
|
+
|
|
672
|
+
```bash
|
|
673
|
+
el-linear comments list DEV-123 --format summary
|
|
674
|
+
# comment c5d15b28-... Alice 2026-07-01T00:00:00.000Z
|
|
675
|
+
# Short preview...
|
|
676
|
+
|
|
677
|
+
el-linear comments read comment-c5d15b28 --body
|
|
678
|
+
# Full comment body...
|
|
679
|
+
|
|
680
|
+
el-linear comments list DEV-123 --body
|
|
681
|
+
# comment c5d15b28-...
|
|
682
|
+
#
|
|
683
|
+
# Full comment body...
|
|
684
|
+
```
|
|
685
|
+
|
|
663
686
|
### One-line write confirmations: `-q, --quiet`
|
|
664
687
|
|
|
665
688
|
`issues create|update`, `issues relate`, and `comments create|update` accept
|
|
@@ -63,6 +63,9 @@ el-linear issues read DEV-123 --format summary 2>&1
|
|
|
63
63
|
|
|
64
64
|
# ✅ Whole description as raw text → --body. Terse write confirmation → --quiet
|
|
65
65
|
el-linear issues read DEV-123 --body 2>&1
|
|
66
|
+
el-linear comments read comment-c5d15b28 --body 2>&1
|
|
67
|
+
el-linear comments list DEV-123 --body 2>&1
|
|
68
|
+
el-linear comments list DEV-123 --format summary --no-truncate 2>&1
|
|
66
69
|
el-linear issues update DEV-123 --status Done --quiet 2>&1
|
|
67
70
|
```
|
|
68
71
|
|
|
@@ -96,6 +99,28 @@ el-linear issues read DEV-123 --format json 2>&1 | python3 -c "import json,sys;
|
|
|
96
99
|
|
|
97
100
|
`--body` is mutually exclusive with `--field` / `--sections` / `--with` (those extract named parts or extend the JSON envelope; `--body` is the whole thing as text).
|
|
98
101
|
|
|
102
|
+
### Comment reads and full comment bodies
|
|
103
|
+
|
|
104
|
+
When you need a specific comment, or the full text of a long comment, use the
|
|
105
|
+
comments read/list surfaces instead of dumping JSON:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# ✅ Resolve a Linear permalink anchor or full comment UUID
|
|
109
|
+
el-linear comments read comment-c5d15b28 --format summary 2>&1
|
|
110
|
+
el-linear comments read comment-c5d15b28 --body 2>&1
|
|
111
|
+
|
|
112
|
+
# ✅ Full bodies for every comment on an issue
|
|
113
|
+
el-linear comments list DEV-123 --body 2>&1
|
|
114
|
+
el-linear comments list DEV-123 --format summary --no-truncate 2>&1
|
|
115
|
+
|
|
116
|
+
# ❌ Don't do this
|
|
117
|
+
el-linear comments list DEV-123 --format json 2>&1 | python3 -c "import json,sys; print(json.load(sys.stdin)['data'][0]['body'])"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`comments read` accepts a full UUID, `comment-<hash>`, or a URL containing
|
|
121
|
+
`#comment-<hash>`. `comments list --format summary` includes each comment id
|
|
122
|
+
so you can copy it straight into `comments read`.
|
|
123
|
+
|
|
99
124
|
### Terse write confirmations: `-q, --quiet`
|
|
100
125
|
|
|
101
126
|
`issues create|update` and `comments create|update` accept `-q, --quiet`, which prints a single machine-stable confirmation line instead of the full JSON envelope — no need to `grep` the result for the identifier / state / url:
|
|
@@ -118,7 +143,7 @@ For tools that aren't `el-linear` (e.g. `gh`, `glab`, `kubectl`), prefer `jq` fo
|
|
|
118
143
|
|
|
119
144
|
`--format summary` is implemented for:
|
|
120
145
|
|
|
121
|
-
- **Single resources:** `issues read`, `projects read`, `cycles read`, `project-milestones read`, `documents read`, `templates read`, releases (`graphql` query results), `users read`
|
|
146
|
+
- **Single resources:** `issues read`, `comments read`, `projects read`, `cycles read`, `project-milestones read`, `documents read`, `templates read`, releases (`graphql` query results), `users read`
|
|
122
147
|
- **Lists:** `issues list`, `issues search`, `projects list`, `comments list`, `cycles list`, `project-milestones list`, `labels list`, `teams list`, `users list`, `documents list`, `templates list`, `attachments list`, `releases list`, and the cross-resource `search` command
|
|
123
148
|
|
|
124
149
|
Commands without a dedicated formatter (e.g. `config show`, custom `graphql` queries) fall back to a generic key/value rendering of their JSON payload.
|
|
@@ -10,6 +10,28 @@
|
|
|
10
10
|
"Selects labels from the known label taxonomy (e.g., bug)",
|
|
11
11
|
"Description includes a 'Why we need this' section",
|
|
12
12
|
"Uses el-linear CLI to create the issue, not raw curl"
|
|
13
|
+
],
|
|
14
|
+
"assertions": [
|
|
15
|
+
{
|
|
16
|
+
"type": "skill_used",
|
|
17
|
+
"name": "linear-operations",
|
|
18
|
+
"description": "Issue creation must route through the Linear operations skill."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "command_matches",
|
|
22
|
+
"pattern": "el-linear\\s+issues?\\s+search",
|
|
23
|
+
"description": "Duplicate checking runs before creating the issue."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "command_matches",
|
|
27
|
+
"pattern": "el-linear\\s+issues?\\s+create",
|
|
28
|
+
"description": "The issue is created through el-linear."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "output_contains",
|
|
32
|
+
"value": "Why we need this",
|
|
33
|
+
"description": "The issue body includes the required intent section."
|
|
34
|
+
}
|
|
13
35
|
]
|
|
14
36
|
},
|
|
15
37
|
{
|
|
@@ -20,6 +42,23 @@
|
|
|
20
42
|
"Uses el-linear search command with appropriate query",
|
|
21
43
|
"Does not attempt to use curl against api.linear.app",
|
|
22
44
|
"Returns formatted results with issue IDs and titles"
|
|
45
|
+
],
|
|
46
|
+
"assertions": [
|
|
47
|
+
{
|
|
48
|
+
"type": "skill_used",
|
|
49
|
+
"name": "linear-operations",
|
|
50
|
+
"description": "Linear search should use the Linear operations skill."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"type": "command_matches",
|
|
54
|
+
"pattern": "el-linear\\s+issues?\\s+search\\s+.*auth",
|
|
55
|
+
"description": "Searches Linear with the requested auth query."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type": "output_not_contains",
|
|
59
|
+
"value": "api.linear.app",
|
|
60
|
+
"description": "Does not bypass el-linear with raw Linear API calls."
|
|
61
|
+
}
|
|
23
62
|
]
|
|
24
63
|
},
|
|
25
64
|
{
|
|
@@ -30,6 +69,23 @@
|
|
|
30
69
|
"Uses el-linear update command with the issue identifier DEV-123",
|
|
31
70
|
"Sets the status to In Progress",
|
|
32
71
|
"Does not create a new issue"
|
|
72
|
+
],
|
|
73
|
+
"assertions": [
|
|
74
|
+
{
|
|
75
|
+
"type": "skill_used",
|
|
76
|
+
"name": "linear-operations",
|
|
77
|
+
"description": "Issue mutation should use the Linear operations skill."
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"type": "command_matches",
|
|
81
|
+
"pattern": "el-linear\\s+issues?\\s+update\\s+DEV-123\\b.*--status\\s+['\\\"]?In Progress",
|
|
82
|
+
"description": "Updates DEV-123 to In Progress through el-linear."
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"type": "command_matches",
|
|
86
|
+
"pattern": "el-linear\\s+issues?\\s+read\\s+DEV-123",
|
|
87
|
+
"description": "Reads the existing issue before mutation."
|
|
88
|
+
}
|
|
33
89
|
]
|
|
34
90
|
},
|
|
35
91
|
{
|
|
@@ -40,6 +96,33 @@
|
|
|
40
96
|
"Does NOT trigger linear-operations skill",
|
|
41
97
|
"Routes to git-branch-from-linear instead",
|
|
42
98
|
"No el-linear create or update commands are issued"
|
|
99
|
+
],
|
|
100
|
+
"assertions": [
|
|
101
|
+
{
|
|
102
|
+
"type": "skill_not_used",
|
|
103
|
+
"name": "linear-operations",
|
|
104
|
+
"description": "Branch creation is outside linear-operations scope."
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"type": "skill_used",
|
|
108
|
+
"name": "git-branch-from-linear",
|
|
109
|
+
"description": "Branch creation should route to the branch skill."
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"type": "command_matches",
|
|
113
|
+
"pattern": "el-linear\\s+issues?\\s+read\\s+DEV-456",
|
|
114
|
+
"description": "Reading issue metadata is allowed for branch creation."
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "output_not_contains",
|
|
118
|
+
"value": "el-linear issues create",
|
|
119
|
+
"description": "Does not create a new issue for branch creation."
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"type": "output_not_contains",
|
|
123
|
+
"value": "el-linear issues update",
|
|
124
|
+
"description": "Does not update issue fields for branch creation."
|
|
125
|
+
}
|
|
43
126
|
]
|
|
44
127
|
}
|
|
45
128
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { resolveUserDisplayName } from "../config/resolver.js";
|
|
3
|
-
import { CREATE_COMMENT_MUTATION, DELETE_COMMENT_MUTATION, LIST_COMMENTS_QUERY, UPDATE_COMMENT_MUTATION, } from "../queries/comments.js";
|
|
3
|
+
import { CREATE_COMMENT_MUTATION, DELETE_COMMENT_MUTATION, GET_COMMENT_QUERY, LIST_COMMENTS_QUERY, UPDATE_COMMENT_MUTATION, } from "../queries/comments.js";
|
|
4
4
|
import { autoLinkReferences, } from "../utils/auto-link-references.js";
|
|
5
5
|
import { applyFooter } from "../utils/footer.js";
|
|
6
6
|
import { createGraphQLService, } from "../utils/graphql-service.js";
|
|
@@ -9,7 +9,7 @@ import { wrapIssueReferencesAsLinks } from "../utils/issue-reference-wrapper.js"
|
|
|
9
9
|
import { createLinearService, } from "../utils/linear-service.js";
|
|
10
10
|
import { logger } from "../utils/logger.js";
|
|
11
11
|
import { resolveMentions, } from "../utils/mention-resolver.js";
|
|
12
|
-
import { getQuietMode, handleAsyncCommand, outputSuccess, } from "../utils/output.js";
|
|
12
|
+
import { getOutputFormat, getQuietMode, handleAsyncCommand, outputSuccess, } from "../utils/output.js";
|
|
13
13
|
import { getRootOpts } from "../utils/root-opts.js";
|
|
14
14
|
import { validateReferences } from "../utils/validate-references.js";
|
|
15
15
|
import { parsePositiveInt } from "../utils/validators.js";
|
|
@@ -18,6 +18,8 @@ import { getWorkspaceUrlKey } from "../utils/workspace-url.js";
|
|
|
18
18
|
// tweak on their side doesn't silently regress the fallback path.
|
|
19
19
|
const BODY_DATA_ERROR_RE = /prosemirror|bodydata|invalid.*body/i;
|
|
20
20
|
const ISSUE_IDENTIFIER_REGEX = /^[A-Z][A-Z0-9]*-\d+$/;
|
|
21
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
22
|
+
const COMMENT_ANCHOR_REGEX = /(?:^|[#/])comment-([A-Za-z0-9-]+)/;
|
|
21
23
|
/**
|
|
22
24
|
* Turn a {@link MentionReport} into the `mentions` output field, or `undefined`
|
|
23
25
|
* when there is nothing to report. `delivered=false` records a bodyData→plain
|
|
@@ -90,10 +92,11 @@ async function fetchSelfUserId(graphQLService) {
|
|
|
90
92
|
return;
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
|
-
function transformComment(comment) {
|
|
95
|
+
function transformComment(comment, options = {}) {
|
|
94
96
|
return {
|
|
95
97
|
id: comment.id,
|
|
96
98
|
body: comment.body,
|
|
99
|
+
url: comment.url ?? undefined,
|
|
97
100
|
user: {
|
|
98
101
|
id: comment.user.id,
|
|
99
102
|
name: resolveUserDisplayName(comment.user.id, comment.user.name),
|
|
@@ -101,8 +104,35 @@ function transformComment(comment) {
|
|
|
101
104
|
},
|
|
102
105
|
createdAt: comment.createdAt,
|
|
103
106
|
updatedAt: comment.updatedAt,
|
|
107
|
+
...(options.fullBodySummary ? { _summaryFullBody: true } : {}),
|
|
104
108
|
};
|
|
105
109
|
}
|
|
110
|
+
function normalizeCommentRef(input) {
|
|
111
|
+
const trimmed = input.trim();
|
|
112
|
+
const anchorMatch = COMMENT_ANCHOR_REGEX.exec(trimmed);
|
|
113
|
+
const candidate = anchorMatch?.[1] ?? trimmed.replace(/^#?comment-/, "");
|
|
114
|
+
if (UUID_REGEX.test(candidate)) {
|
|
115
|
+
return { id: candidate.toLowerCase() };
|
|
116
|
+
}
|
|
117
|
+
return { hash: candidate };
|
|
118
|
+
}
|
|
119
|
+
function printRawCommentBody(comment, label) {
|
|
120
|
+
const body = typeof comment.body === "string" ? comment.body : "";
|
|
121
|
+
if (body.trim() === "") {
|
|
122
|
+
process.stderr.write(`el-linear: comment ${label} has no body\n`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
process.stdout.write(`${body}\n`);
|
|
126
|
+
}
|
|
127
|
+
function formatCommentBodyBlocks(comments) {
|
|
128
|
+
return comments
|
|
129
|
+
.map((comment) => {
|
|
130
|
+
const id = typeof comment.id === "string" ? comment.id : "-";
|
|
131
|
+
const body = typeof comment.body === "string" ? comment.body : "";
|
|
132
|
+
return `comment ${id}\n\n${body}`;
|
|
133
|
+
})
|
|
134
|
+
.join("\n\n---\n\n");
|
|
135
|
+
}
|
|
106
136
|
/**
|
|
107
137
|
* Wrap valid issue references in a comment body as markdown links — same logic as for
|
|
108
138
|
* issue descriptions. Returns the rewritten body plus the validated identifier→UUID map
|
|
@@ -324,7 +354,12 @@ async function handleListComments(issueId, options, command) {
|
|
|
324
354
|
if (!result.issue) {
|
|
325
355
|
throw new Error(`Issue "${issueId}" not found`);
|
|
326
356
|
}
|
|
327
|
-
const
|
|
357
|
+
const fullBodySummary = options.truncate === false && getOutputFormat() === "summary";
|
|
358
|
+
const nodes = result.issue.comments.nodes.map((comment) => transformComment(comment, { fullBodySummary }));
|
|
359
|
+
if (options.body === true) {
|
|
360
|
+
process.stdout.write(`${formatCommentBodyBlocks(nodes)}\n`);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
328
363
|
outputSuccess({
|
|
329
364
|
data: nodes,
|
|
330
365
|
meta: {
|
|
@@ -333,6 +368,23 @@ async function handleListComments(issueId, options, command) {
|
|
|
333
368
|
},
|
|
334
369
|
});
|
|
335
370
|
}
|
|
371
|
+
async function handleReadComment(commentRef, options, command) {
|
|
372
|
+
const rootOpts = getRootOpts(command);
|
|
373
|
+
const graphQLService = await createGraphQLService(rootOpts);
|
|
374
|
+
const ref = normalizeCommentRef(commentRef);
|
|
375
|
+
const result = await graphQLService.rawRequest(GET_COMMENT_QUERY, ref);
|
|
376
|
+
if (!result.comment) {
|
|
377
|
+
throw new Error(`Comment "${commentRef}" not found`);
|
|
378
|
+
}
|
|
379
|
+
const comment = transformComment(result.comment, {
|
|
380
|
+
fullBodySummary: getOutputFormat() === "summary",
|
|
381
|
+
});
|
|
382
|
+
if (options.body === true) {
|
|
383
|
+
printRawCommentBody(comment, commentRef);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
outputSuccess(comment);
|
|
387
|
+
}
|
|
336
388
|
async function handleDeleteComment(commentId, _options, command) {
|
|
337
389
|
const rootOpts = getRootOpts(command);
|
|
338
390
|
const graphQLService = await createGraphQLService(rootOpts);
|
|
@@ -374,7 +426,18 @@ export function setupCommentsCommands(program) {
|
|
|
374
426
|
.description("List comments on an issue.")
|
|
375
427
|
.addHelpText("after", "\nBoth UUID and identifiers like ABC-123 are supported.")
|
|
376
428
|
.option("-l, --limit <number>", "limit results", "25")
|
|
429
|
+
.option("--body", "print complete comment bodies as plain text blocks instead of JSON")
|
|
430
|
+
.option("--no-truncate", "do not truncate comment bodies in --format summary output")
|
|
377
431
|
.action(handleAsyncCommand(handleListComments));
|
|
432
|
+
comments
|
|
433
|
+
.command("read <commentId>")
|
|
434
|
+
.alias("get")
|
|
435
|
+
.alias("show")
|
|
436
|
+
.description("Read a comment by id or Linear #comment-<hash> anchor.")
|
|
437
|
+
.addHelpText("after", "\nAccepts a full comment UUID, a comment-<hash> token, or a URL containing #comment-<hash>.")
|
|
438
|
+
.option("--body", "print the raw comment body with no JSON envelope")
|
|
439
|
+
.option("-q, --quiet", "print one confirmation line (comment <id>) instead of the full JSON")
|
|
440
|
+
.action(handleAsyncCommand(handleReadComment));
|
|
378
441
|
comments
|
|
379
442
|
.command("delete <commentId>")
|
|
380
443
|
.alias("remove")
|
|
@@ -21,6 +21,7 @@ interface CommentUserRef {
|
|
|
21
21
|
export interface CommentResourceNode {
|
|
22
22
|
id: string;
|
|
23
23
|
body: string;
|
|
24
|
+
url?: string | null;
|
|
24
25
|
createdAt: string;
|
|
25
26
|
updatedAt: string;
|
|
26
27
|
user: CommentUserRef;
|
|
@@ -31,6 +32,12 @@ interface UpdatedCommentResourceNode extends CommentResourceNode {
|
|
|
31
32
|
identifier: string;
|
|
32
33
|
} | null;
|
|
33
34
|
}
|
|
35
|
+
interface ReadCommentResourceNode extends CommentResourceNode {
|
|
36
|
+
issue: {
|
|
37
|
+
id: string;
|
|
38
|
+
identifier: string;
|
|
39
|
+
} | null;
|
|
40
|
+
}
|
|
34
41
|
export interface ListCommentsResponse {
|
|
35
42
|
issue: {
|
|
36
43
|
id: string;
|
|
@@ -40,6 +47,9 @@ export interface ListCommentsResponse {
|
|
|
40
47
|
};
|
|
41
48
|
} | null;
|
|
42
49
|
}
|
|
50
|
+
export interface GetCommentResponse {
|
|
51
|
+
comment: ReadCommentResourceNode | null;
|
|
52
|
+
}
|
|
43
53
|
export interface CreateCommentResponse {
|
|
44
54
|
commentCreate: {
|
|
45
55
|
success: boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const LIST_COMMENTS_QUERY = "\n query ListComments($issueId: String!, $first: Int) {\n issue(id: $issueId) {\n id\n identifier\n comments(first: $first, orderBy: createdAt) {\n nodes {\n id\n body\n createdAt\n updatedAt\n user {\n id\n name\n displayName\n url\n }\n }\n }\n }\n }\n";
|
|
2
|
+
export declare const GET_COMMENT_QUERY = "\n query GetComment($id: String, $hash: String) {\n comment(id: $id, hash: $hash) {\n id\n body\n url\n createdAt\n updatedAt\n user {\n id\n name\n displayName\n url\n }\n issue {\n id\n identifier\n }\n }\n }\n";
|
|
2
3
|
export declare const CREATE_COMMENT_MUTATION = "\n mutation CreateComment($input: CommentCreateInput!) {\n commentCreate(input: $input) {\n success\n comment {\n id\n body\n createdAt\n updatedAt\n user {\n id\n name\n displayName\n url\n }\n }\n }\n }\n";
|
|
3
4
|
export declare const UPDATE_COMMENT_MUTATION = "\n mutation UpdateComment($id: String!, $input: CommentUpdateInput!) {\n commentUpdate(id: $id, input: $input) {\n success\n comment {\n id\n body\n createdAt\n updatedAt\n user {\n id\n name\n displayName\n url\n }\n issue {\n id\n identifier\n }\n }\n }\n }\n";
|
|
4
5
|
export declare const DELETE_COMMENT_MUTATION = "\n mutation DeleteComment($id: String!) {\n commentDelete(id: $id) {\n success\n }\n }\n";
|
package/dist/queries/comments.js
CHANGED
|
@@ -20,6 +20,27 @@ export const LIST_COMMENTS_QUERY = `
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
`;
|
|
23
|
+
export const GET_COMMENT_QUERY = `
|
|
24
|
+
query GetComment($id: String, $hash: String) {
|
|
25
|
+
comment(id: $id, hash: $hash) {
|
|
26
|
+
id
|
|
27
|
+
body
|
|
28
|
+
url
|
|
29
|
+
createdAt
|
|
30
|
+
updatedAt
|
|
31
|
+
user {
|
|
32
|
+
id
|
|
33
|
+
name
|
|
34
|
+
displayName
|
|
35
|
+
url
|
|
36
|
+
}
|
|
37
|
+
issue {
|
|
38
|
+
id
|
|
39
|
+
identifier
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
23
44
|
export const CREATE_COMMENT_MUTATION = `
|
|
24
45
|
mutation CreateComment($input: CommentCreateInput!) {
|
|
25
46
|
commentCreate(input: $input) {
|
|
@@ -567,8 +567,10 @@ export function formatProjectList(projects, fields) {
|
|
|
567
567
|
export function formatCommentSummary(comment) {
|
|
568
568
|
const author = getName(comment.user);
|
|
569
569
|
const createdAt = s(comment.createdAt);
|
|
570
|
-
const body =
|
|
571
|
-
|
|
570
|
+
const body = comment._summaryFullBody === true
|
|
571
|
+
? s(comment.body)
|
|
572
|
+
: clipDescription(comment.body);
|
|
573
|
+
const headerLine = `comment ${s(comment.id)} ${author} ${createdAt}`;
|
|
572
574
|
const parts = [headerLine];
|
|
573
575
|
if (body)
|
|
574
576
|
parts.push("", body);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enrichlayer/el-linear",
|
|
3
|
-
"version": "1.32.
|
|
3
|
+
"version": "1.32.3",
|
|
4
4
|
"description": "A pragmatic CLI for Linear.app — deterministic team/label/member resolution, structured issue validation, configurable term enforcement, and a GraphQL escape hatch.",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"types": "dist/main.d.ts",
|