@enrichlayer/el-linear 1.33.0 → 1.34.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/dist/commands/issues.js
CHANGED
|
@@ -1042,8 +1042,30 @@ export function setupIssuesCommands(program) {
|
|
|
1042
1042
|
const issues = program
|
|
1043
1043
|
.command("issues")
|
|
1044
1044
|
.alias("issue")
|
|
1045
|
-
.description("Issue operations")
|
|
1046
|
-
|
|
1045
|
+
.description("Issue operations")
|
|
1046
|
+
.argument("[issueId...]", "issue ID(s) to read when no subcommand is given — shorthand for `issues read`")
|
|
1047
|
+
.option("--body", "Print the issue's full description as raw markdown text — no JSON " +
|
|
1048
|
+
"envelope, single-issue only. Exits non-zero if the issue has no " +
|
|
1049
|
+
"description. The whole-body sibling of --field; mutually exclusive " +
|
|
1050
|
+
"with --field / --sections / --with.")
|
|
1051
|
+
.option("--field <name>", 'Extract a single named section from the issue description (e.g. "Done when"). ' +
|
|
1052
|
+
"Matches H2/H3 headers and bold pseudo-headers case-insensitively. " +
|
|
1053
|
+
"Outputs the section text only — no JSON envelope. Single-issue only.")
|
|
1054
|
+
.option("--sections <names>", 'Extract multiple named description sections in one call (comma-separated, e.g. "Done when,Out of scope"). ' +
|
|
1055
|
+
"Single-issue only. Returns a JSON envelope { identifier, sections: { name -> text|null } }; missing sections appear as null + a _warnings entry. " +
|
|
1056
|
+
"Sibling of --field (singular). Named --sections rather than --fields because the program already has a global --fields for output-key filtering.")
|
|
1057
|
+
.option("--with <names>", "Comma-separated opt-in includes. Each value fetches an extra " +
|
|
1058
|
+
'block of data and adds it to the JSON envelope. Currently supported: "relations" ' +
|
|
1059
|
+
"(adds an array of cross-issue relations under a top-level `relations` key).")
|
|
1060
|
+
.addHelpText("after", "\nNo-subcommand shorthand: `el-linear issue DEV-123` behaves like `issues read DEV-123`, " +
|
|
1061
|
+
"including its options (--body, --field, --sections, --with).");
|
|
1062
|
+
issues.action(handleAsyncCommand((issueIds = [], options, command) => {
|
|
1063
|
+
if (issueIds.length === 0) {
|
|
1064
|
+
issues.help();
|
|
1065
|
+
return Promise.resolve();
|
|
1066
|
+
}
|
|
1067
|
+
return readIssues(issueIds, options, command);
|
|
1068
|
+
}));
|
|
1047
1069
|
// DEV-4480: `issues tree <ID>` lives in its own file because the
|
|
1048
1070
|
// recursive query builder + ASCII formatter belong together and are
|
|
1049
1071
|
// substantial enough to warrant the split.
|
|
@@ -42,6 +42,15 @@ export declare function formatLabelList(labels: unknown[]): string;
|
|
|
42
42
|
* the row falls back to the stored direction.
|
|
43
43
|
*/
|
|
44
44
|
export declare function formatRelationList(relations: unknown[], sourceRef?: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Table render for `issues related <id>` — the `{ data: RelatedIssueEntry[] }`
|
|
47
|
+
* envelope where each entry is `{ type, direction, issue }`. Distinct from
|
|
48
|
+
* `formatRelationList` (the `issues relate` mutation echo, `{ type, issue,
|
|
49
|
+
* relatedIssue }` shape): this is the read-path listing of ALL of an issue's
|
|
50
|
+
* relations, so direction, state, and assignee are surfaced per row instead
|
|
51
|
+
* of collapsing to a single source-oriented type/target/title line.
|
|
52
|
+
*/
|
|
53
|
+
export declare function formatIssueRelationList(relations: unknown[]): string;
|
|
45
54
|
export declare function formatUserSummary(user: Record<string, unknown>): string;
|
|
46
55
|
export declare function formatUserList(users: unknown[]): string;
|
|
47
56
|
export declare function formatDocumentSummary(doc: Record<string, unknown>): string;
|
|
@@ -59,7 +68,7 @@ export declare function formatSearchResultList(results: unknown[]): string;
|
|
|
59
68
|
* the full payload. Lists fall back to a simple bulleted list.
|
|
60
69
|
*/
|
|
61
70
|
export declare function formatGenericSummary(value: unknown): string;
|
|
62
|
-
export type ResourceKind = "issue" | "issue-list" | "project" | "project-list" | "comment" | "comment-list" | "cycle" | "cycle-list" | "milestone" | "milestone-list" | "team-list" | "label-list" | "user" | "user-list" | "document" | "document-list" | "template" | "template-list" | "attachment-list" | "release" | "release-list" | "search-result-list" | "relation-list" | "empty-list" | "generic";
|
|
71
|
+
export type ResourceKind = "issue" | "issue-list" | "project" | "project-list" | "comment" | "comment-list" | "cycle" | "cycle-list" | "milestone" | "milestone-list" | "team-list" | "label-list" | "user" | "user-list" | "document" | "document-list" | "template" | "template-list" | "attachment-list" | "release" | "release-list" | "search-result-list" | "relation-list" | "issue-relation-list" | "empty-list" | "generic";
|
|
63
72
|
/**
|
|
64
73
|
* Heuristic — used by the central `outputSuccess` path which doesn't know
|
|
65
74
|
* which command produced the payload. Looks at the shape of the data to
|
|
@@ -749,6 +749,42 @@ export function formatRelationList(relations, sourceRef = "—") {
|
|
|
749
749
|
},
|
|
750
750
|
], { emptyText: "(no relations)", itemNoun: "relation" });
|
|
751
751
|
}
|
|
752
|
+
/**
|
|
753
|
+
* Table render for `issues related <id>` — the `{ data: RelatedIssueEntry[] }`
|
|
754
|
+
* envelope where each entry is `{ type, direction, issue }`. Distinct from
|
|
755
|
+
* `formatRelationList` (the `issues relate` mutation echo, `{ type, issue,
|
|
756
|
+
* relatedIssue }` shape): this is the read-path listing of ALL of an issue's
|
|
757
|
+
* relations, so direction, state, and assignee are surfaced per row instead
|
|
758
|
+
* of collapsing to a single source-oriented type/target/title line.
|
|
759
|
+
*/
|
|
760
|
+
export function formatIssueRelationList(relations) {
|
|
761
|
+
const rows = relations.map((raw) => asObj(raw) ?? {});
|
|
762
|
+
return renderTable(rows, [
|
|
763
|
+
{ header: "RELATION", minWidth: 8, extract: (r) => s(r.type) },
|
|
764
|
+
{ header: "DIRECTION", minWidth: 9, extract: (r) => s(r.direction) },
|
|
765
|
+
{
|
|
766
|
+
header: "ID",
|
|
767
|
+
minWidth: 2,
|
|
768
|
+
extract: (r) => s(asObj(r.issue)?.identifier),
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
header: "STATE",
|
|
772
|
+
minWidth: 5,
|
|
773
|
+
extract: (r) => getName(asObj(r.issue)?.state),
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
header: "ASSIGNEE",
|
|
777
|
+
minWidth: 8,
|
|
778
|
+
extract: (r) => getName(asObj(r.issue)?.assignee),
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
header: "TITLE",
|
|
782
|
+
minWidth: 5,
|
|
783
|
+
maxWidth: TITLE_TRUNC,
|
|
784
|
+
extract: (r) => s(asObj(r.issue)?.title),
|
|
785
|
+
},
|
|
786
|
+
], { emptyText: "(no issue relations)", itemNoun: "relation" });
|
|
787
|
+
}
|
|
752
788
|
// ── users ──────────────────────────────────────────────────────
|
|
753
789
|
export function formatUserSummary(user) {
|
|
754
790
|
const name = s(user.name);
|
|
@@ -1032,6 +1068,10 @@ function inferListKind(items) {
|
|
|
1032
1068
|
// identifier/title, so this must precede the issue-list check below.
|
|
1033
1069
|
if ("relatedIssue" in sample && "issue" in sample && "type" in sample)
|
|
1034
1070
|
return "relation-list";
|
|
1071
|
+
// `issues related <id>` rows ({ type, direction, issue }) — the read-path
|
|
1072
|
+
// listing, distinct from the `relatedIssue`-shaped mutation echo above.
|
|
1073
|
+
if ("direction" in sample && "issue" in sample && "type" in sample)
|
|
1074
|
+
return "issue-relation-list";
|
|
1035
1075
|
if ("identifier" in sample && "title" in sample) {
|
|
1036
1076
|
// could be issue or search result
|
|
1037
1077
|
if ("type" in sample && !("templateData" in sample)) {
|
|
@@ -1154,6 +1194,8 @@ export function dispatch(kind, payload, fields) {
|
|
|
1154
1194
|
return formatSearchResultList(list ?? []);
|
|
1155
1195
|
case "relation-list":
|
|
1156
1196
|
return formatRelationList(list ?? [], s(asObj(obj?.meta)?.source));
|
|
1197
|
+
case "issue-relation-list":
|
|
1198
|
+
return formatIssueRelationList(list ?? []);
|
|
1157
1199
|
case "empty-list":
|
|
1158
1200
|
return "(no results)";
|
|
1159
1201
|
case "generic":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enrichlayer/el-linear",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.34.0",
|
|
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",
|