@enrichlayer/el-linear 1.9.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +139 -10
  2. package/claude-skills/linear-operations/SKILL.md +41 -1
  3. package/dist/auth/linear-credential.d.ts +27 -0
  4. package/dist/auth/linear-credential.js +1 -0
  5. package/dist/auth/oauth-app-config.d.ts +4 -3
  6. package/dist/auth/oauth-app-config.js +13 -2
  7. package/dist/auth/oauth-callback.d.ts +2 -3
  8. package/dist/auth/oauth-callback.js +2 -2
  9. package/dist/auth/oauth-client.d.ts +8 -2
  10. package/dist/auth/oauth-client.js +26 -0
  11. package/dist/auth/oauth-fs.d.ts +2 -1
  12. package/dist/auth/oauth-headless.d.ts +2 -1
  13. package/dist/auth/oauth-storage.d.ts +5 -1
  14. package/dist/auth/oauth-storage.js +1 -1
  15. package/dist/auth/oauth-token.d.ts +4 -3
  16. package/dist/auth/oauth-token.js +16 -4
  17. package/dist/auth/token-resolver.d.ts +14 -5
  18. package/dist/auth/token-resolver.js +6 -1
  19. package/dist/commands/attachments.js +2 -1
  20. package/dist/commands/batch.js +18 -21
  21. package/dist/commands/comments.js +22 -33
  22. package/dist/commands/config.js +178 -5
  23. package/dist/commands/cycles.js +2 -1
  24. package/dist/commands/documents.js +2 -1
  25. package/dist/commands/graphql.js +4 -6
  26. package/dist/commands/init/aliases.js +1 -1
  27. package/dist/commands/init/defaults.d.ts +2 -1
  28. package/dist/commands/init/index.js +45 -35
  29. package/dist/commands/init/oauth.d.ts +4 -1
  30. package/dist/commands/init/oauth.js +22 -4
  31. package/dist/commands/init/shared.d.ts +24 -2
  32. package/dist/commands/init/shared.js +35 -4
  33. package/dist/commands/init/token.d.ts +3 -3
  34. package/dist/commands/init/token.js +5 -24
  35. package/dist/commands/init/workspace.d.ts +2 -1
  36. package/dist/commands/init/workspace.js +1 -1
  37. package/dist/commands/introspect.d.ts +27 -0
  38. package/dist/commands/introspect.js +178 -0
  39. package/dist/commands/issue-id.js +1 -3
  40. package/dist/commands/issues/branch.js +9 -1
  41. package/dist/commands/issues/description.js +2 -6
  42. package/dist/commands/issues/link-references.d.ts +21 -0
  43. package/dist/commands/issues/link-references.js +171 -0
  44. package/dist/commands/issues/relations.d.ts +44 -0
  45. package/dist/commands/issues/relations.js +132 -0
  46. package/dist/commands/issues.js +269 -309
  47. package/dist/commands/labels.js +15 -24
  48. package/dist/commands/profile.js +1 -0
  49. package/dist/commands/project-milestones.js +13 -20
  50. package/dist/commands/projects.d.ts +2 -0
  51. package/dist/commands/projects.js +157 -44
  52. package/dist/commands/read-shortcut.d.ts +1 -1
  53. package/dist/commands/read-shortcut.js +28 -8
  54. package/dist/commands/refs.js +75 -8
  55. package/dist/commands/releases.js +26 -30
  56. package/dist/commands/search.js +49 -33
  57. package/dist/commands/teams.js +2 -1
  58. package/dist/commands/templates.js +9 -14
  59. package/dist/commands/users.js +5 -2
  60. package/dist/config/config.d.ts +99 -1
  61. package/dist/config/config.js +264 -52
  62. package/dist/config/error-enrichment.d.ts +62 -0
  63. package/dist/config/error-enrichment.js +417 -0
  64. package/dist/config/issue-validation.d.ts +37 -0
  65. package/dist/config/issue-validation.js +63 -1
  66. package/dist/config/paths.d.ts +2 -8
  67. package/dist/config/paths.js +4 -2
  68. package/dist/config/resolver.d.ts +8 -1
  69. package/dist/config/resolver.js +11 -5
  70. package/dist/main.js +13 -1
  71. package/dist/queries/attachments-types.d.ts +30 -0
  72. package/dist/queries/attachments-types.js +5 -0
  73. package/dist/queries/comments-types.d.ts +55 -0
  74. package/dist/queries/comments-types.js +5 -0
  75. package/dist/queries/common.d.ts +2 -2
  76. package/dist/queries/common.js +8 -0
  77. package/dist/queries/documents-types.d.ts +62 -0
  78. package/dist/queries/documents-types.js +9 -0
  79. package/dist/queries/introspect-types.d.ts +58 -0
  80. package/dist/queries/introspect-types.js +10 -0
  81. package/dist/queries/issues-types.d.ts +481 -0
  82. package/dist/queries/issues-types.js +23 -0
  83. package/dist/queries/issues.d.ts +51 -10
  84. package/dist/queries/issues.js +147 -5
  85. package/dist/queries/labels-types.d.ts +65 -0
  86. package/dist/queries/labels-types.js +5 -0
  87. package/dist/queries/project-milestones-types.d.ts +92 -0
  88. package/dist/queries/project-milestones-types.js +10 -0
  89. package/dist/queries/project-milestones.d.ts +1 -1
  90. package/dist/queries/projects-types.d.ts +76 -0
  91. package/dist/queries/projects-types.js +5 -0
  92. package/dist/queries/projects.d.ts +2 -0
  93. package/dist/queries/projects.js +22 -0
  94. package/dist/queries/releases-types.d.ts +85 -0
  95. package/dist/queries/releases-types.js +5 -0
  96. package/dist/queries/search-types.d.ts +102 -0
  97. package/dist/queries/search-types.js +6 -0
  98. package/dist/queries/templates-types.d.ts +62 -0
  99. package/dist/queries/templates-types.js +9 -0
  100. package/dist/types/linear.d.ts +21 -3
  101. package/dist/utils/auto-link-references.d.ts +3 -3
  102. package/dist/utils/auto-link-references.js +30 -34
  103. package/dist/utils/extract-field.d.ts +19 -0
  104. package/dist/utils/extract-field.js +99 -0
  105. package/dist/utils/file-service.d.ts +6 -13
  106. package/dist/utils/file-service.js +0 -2
  107. package/dist/utils/formatters/summary.js +6 -1
  108. package/dist/utils/graphql-attachments-service.js +6 -9
  109. package/dist/utils/graphql-documents-service.js +19 -25
  110. package/dist/utils/graphql-issues-service.d.ts +112 -46
  111. package/dist/utils/graphql-issues-service.js +398 -206
  112. package/dist/utils/graphql-service.d.ts +10 -12
  113. package/dist/utils/graphql-service.js +0 -3
  114. package/dist/utils/issue-reference-extractor.d.ts +7 -0
  115. package/dist/utils/issue-reference-extractor.js +5 -3
  116. package/dist/utils/issues-service-bootstrap.d.ts +28 -0
  117. package/dist/utils/issues-service-bootstrap.js +27 -0
  118. package/dist/utils/linear-service.d.ts +21 -14
  119. package/dist/utils/linear-service.js +73 -11
  120. package/dist/utils/markdown-prosemirror.js +12 -12
  121. package/dist/utils/mention-resolver.js +1 -1
  122. package/dist/utils/output.d.ts +82 -2
  123. package/dist/utils/output.js +76 -11
  124. package/dist/utils/project-slug.d.ts +21 -0
  125. package/dist/utils/project-slug.js +45 -0
  126. package/dist/utils/protected-ranges.d.ts +14 -0
  127. package/dist/utils/protected-ranges.js +88 -2
  128. package/dist/utils/sanitize-for-log.d.ts +24 -0
  129. package/dist/utils/sanitize-for-log.js +38 -0
  130. package/dist/utils/table-formatter.js +24 -0
  131. package/dist/utils/validators.d.ts +7 -2
  132. package/dist/utils/validators.js +6 -0
  133. package/dist/utils/workspace-url.d.ts +5 -1
  134. package/dist/utils/workspace-url.js +53 -7
  135. package/package.json +2 -2
package/dist/main.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
2
5
  import { program } from "commander";
3
6
  import { setupAttachmentsCommands } from "./commands/attachments.js";
4
7
  import { setupBatchCommands } from "./commands/batch.js";
@@ -10,6 +13,7 @@ import { setupEmbedsCommands } from "./commands/embeds.js";
10
13
  import { setupGdocCommands } from "./commands/gdoc.js";
11
14
  import { setupGraphQLCommands } from "./commands/graphql.js";
12
15
  import { setupInitCommands } from "./commands/init/index.js";
16
+ import { setupIntrospectCommand } from "./commands/introspect.js";
13
17
  import { setupIssueIdCommand } from "./commands/issue-id.js";
14
18
  import { setupIssuesCommands } from "./commands/issues.js";
15
19
  import { setupLabelsCommands } from "./commands/labels.js";
@@ -27,10 +31,17 @@ import { setActiveProfileForSession } from "./config/paths.js";
27
31
  import { setFieldsFilter, setJqFilter, setOutputFormat, setRawMode, } from "./utils/output.js";
28
32
  import { outputUsageInfo } from "./utils/usage.js";
29
33
  import { splitList } from "./utils/validators.js";
34
+ // Read the version from package.json at startup so `--version` can never
35
+ // drift from the published release (pre-fix: a stale 1.8.1 literal lived
36
+ // here while package.json was at 1.10.0). `dist/main.js` lives one
37
+ // directory below the package root, so `../package.json` resolves
38
+ // correctly in both `pnpm dev` (tsx) and `node dist/main.js` invocations.
39
+ const __dirname_main = dirname(fileURLToPath(import.meta.url));
40
+ const packageJson = JSON.parse(readFileSync(join(__dirname_main, "..", "package.json"), "utf-8"));
30
41
  program
31
42
  .name("el-linear")
32
43
  .description("A pragmatic CLI for Linear.app — deterministic resolution, structured validation, GraphQL escape hatch.")
33
- .version("1.8.1")
44
+ .version(packageJson.version)
34
45
  .option("--api-token <token>", "Linear API token")
35
46
  .option("--profile <name>", "named profile (under ~/.config/el-linear/profiles/<name>/) for this invocation. Overrides EL_LINEAR_PROFILE env + the on-disk active-profile marker.")
36
47
  .option("--json", "output as JSON (default, accepted for compatibility)")
@@ -117,6 +128,7 @@ setupConfigCommands(program);
117
128
  setupInitCommands(program);
118
129
  setupProfileCommands(program);
119
130
  setupRefsCommands(program);
131
+ setupIntrospectCommand(program);
120
132
  setupReadShortcut(program);
121
133
  program
122
134
  .command("usage")
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Typed response shapes for the queries in `./attachments.ts`.
3
+ * See `./issues-types.ts` for the rationale (ALL-937).
4
+ */
5
+ /** Mirrors `ATTACHMENT_FRAGMENT` from `src/queries/attachments.ts`. */
6
+ export interface AttachmentNode {
7
+ id: string;
8
+ title: string | null;
9
+ url: string;
10
+ createdAt: string | null;
11
+ updatedAt: string | null;
12
+ }
13
+ export interface CreateAttachmentResponse {
14
+ attachmentCreate: {
15
+ success: boolean;
16
+ attachment: AttachmentNode | null;
17
+ };
18
+ }
19
+ export interface DeleteAttachmentResponse {
20
+ attachmentDelete: {
21
+ success: boolean;
22
+ };
23
+ }
24
+ export interface ListAttachmentsResponse {
25
+ issue: {
26
+ attachments: {
27
+ nodes: AttachmentNode[];
28
+ };
29
+ } | null;
30
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Typed response shapes for the queries in `./attachments.ts`.
3
+ * See `./issues-types.ts` for the rationale (ALL-937).
4
+ */
5
+ export {};
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Typed response shapes for the queries in `./comments.ts`.
3
+ * See `./issues-types.ts` for the rationale (ALL-937).
4
+ */
5
+ interface CommentUserRef {
6
+ id: string;
7
+ name: string;
8
+ displayName: string | null;
9
+ url: string | null;
10
+ }
11
+ /**
12
+ * Comment shape returned by the standalone comment queries:
13
+ * `LIST_COMMENTS_QUERY`, `CREATE_COMMENT_MUTATION`, and (with `issue`
14
+ * overlay) `UPDATE_COMMENT_MUTATION`. Distinct from
15
+ * `issues-types.ts:IssueCommentNode`, which is the embedded-in-issue
16
+ * shape — that one allows `user: null`, this one does not (a standalone
17
+ * comment without an author isn't a valid Linear state). The two were
18
+ * a single `CommentNode` interface pre-DEV-4068 T2, but with incompatible
19
+ * `user` shapes — renamed to disambiguate the per-context contract.
20
+ */
21
+ export interface CommentResourceNode {
22
+ id: string;
23
+ body: string;
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ user: CommentUserRef;
27
+ }
28
+ interface UpdatedCommentResourceNode extends CommentResourceNode {
29
+ issue: {
30
+ id: string;
31
+ identifier: string;
32
+ } | null;
33
+ }
34
+ export interface ListCommentsResponse {
35
+ issue: {
36
+ id: string;
37
+ identifier: string;
38
+ comments: {
39
+ nodes: CommentResourceNode[];
40
+ };
41
+ } | null;
42
+ }
43
+ export interface CreateCommentResponse {
44
+ commentCreate: {
45
+ success: boolean;
46
+ comment: CommentResourceNode | null;
47
+ };
48
+ }
49
+ export interface UpdateCommentResponse {
50
+ commentUpdate: {
51
+ success: boolean;
52
+ comment: UpdatedCommentResourceNode | null;
53
+ };
54
+ }
55
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Typed response shapes for the queries in `./comments.ts`.
3
+ * See `./issues-types.ts` for the rationale (ALL-937).
4
+ */
5
+ export {};
@@ -1,2 +1,2 @@
1
- export declare const COMPLETE_ISSUE_FRAGMENT = "\n \n id\n identifier\n title\n description\n summary { content generationStatus }\n branchName\n priority\n estimate\n dueDate\n url\n createdAt\n updatedAt\n\n \n state {\n id\n name\n }\n\n \n assignee {\n id\n name\n url\n }\n\n \n team {\n id\n key\n name\n }\n\n \n project {\n id\n name\n }\n\n \n labels {\n nodes {\n id\n name\n }\n }\n\n \n cycle {\n id\n name\n number\n }\n\n \n projectMilestone {\n id\n name\n targetDate\n }\n\n \n parent {\n id\n identifier\n title\n }\n\n \n children {\n nodes {\n id\n identifier\n title\n }\n }\n\n";
2
- export declare const COMPLETE_ISSUE_WITH_COMMENTS_FRAGMENT = "\n \n \n id\n identifier\n title\n description\n summary { content generationStatus }\n branchName\n priority\n estimate\n dueDate\n url\n createdAt\n updatedAt\n\n \n state {\n id\n name\n }\n\n \n assignee {\n id\n name\n url\n }\n\n \n team {\n id\n key\n name\n }\n\n \n project {\n id\n name\n }\n\n \n labels {\n nodes {\n id\n name\n }\n }\n\n \n cycle {\n id\n name\n number\n }\n\n \n projectMilestone {\n id\n name\n targetDate\n }\n\n \n parent {\n id\n identifier\n title\n }\n\n \n children {\n nodes {\n id\n identifier\n title\n }\n }\n\n\n \n comments {\n nodes {\n id\n body\n createdAt\n updatedAt\n user {\n id\n name\n url\n }\n }\n }\n\n";
1
+ export declare const COMPLETE_ISSUE_FRAGMENT = "\n \n id\n identifier\n title\n description\n summary { content generationStatus }\n branchName\n priority\n estimate\n dueDate\n url\n createdAt\n updatedAt\n\n \n state {\n id\n name\n }\n\n \n assignee {\n id\n name\n url\n }\n\n \n delegate {\n id\n name\n url\n }\n\n \n team {\n id\n key\n name\n }\n\n \n project {\n id\n name\n }\n\n \n labels {\n nodes {\n id\n name\n }\n }\n\n \n cycle {\n id\n name\n number\n }\n\n \n projectMilestone {\n id\n name\n targetDate\n }\n\n \n parent {\n id\n identifier\n title\n }\n\n \n children {\n nodes {\n id\n identifier\n title\n }\n }\n\n";
2
+ export declare const COMPLETE_ISSUE_WITH_COMMENTS_FRAGMENT = "\n \n \n id\n identifier\n title\n description\n summary { content generationStatus }\n branchName\n priority\n estimate\n dueDate\n url\n createdAt\n updatedAt\n\n \n state {\n id\n name\n }\n\n \n assignee {\n id\n name\n url\n }\n\n \n delegate {\n id\n name\n url\n }\n\n \n team {\n id\n key\n name\n }\n\n \n project {\n id\n name\n }\n\n \n labels {\n nodes {\n id\n name\n }\n }\n\n \n cycle {\n id\n name\n number\n }\n\n \n projectMilestone {\n id\n name\n targetDate\n }\n\n \n parent {\n id\n identifier\n title\n }\n\n \n children {\n nodes {\n id\n identifier\n title\n }\n }\n\n\n \n comments {\n nodes {\n id\n body\n createdAt\n updatedAt\n user {\n id\n name\n url\n }\n }\n }\n\n";
@@ -25,6 +25,13 @@ const ISSUE_ASSIGNEE_FRAGMENT = `
25
25
  url
26
26
  }
27
27
  `;
28
+ const ISSUE_DELEGATE_FRAGMENT = `
29
+ delegate {
30
+ id
31
+ name
32
+ url
33
+ }
34
+ `;
28
35
  const ISSUE_TEAM_FRAGMENT = `
29
36
  team {
30
37
  id
@@ -95,6 +102,7 @@ export const COMPLETE_ISSUE_FRAGMENT = `
95
102
  ${ISSUE_CORE_FIELDS}
96
103
  ${ISSUE_STATE_FRAGMENT}
97
104
  ${ISSUE_ASSIGNEE_FRAGMENT}
105
+ ${ISSUE_DELEGATE_FRAGMENT}
98
106
  ${ISSUE_TEAM_FRAGMENT}
99
107
  ${ISSUE_PROJECT_FRAGMENT}
100
108
  ${ISSUE_LABELS_FRAGMENT}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Typed response shapes for the queries in `./documents.ts`.
3
+ *
4
+ * Mirrors `DOCUMENT_FRAGMENT` so the consumer in
5
+ * `graphql-documents-service.ts` can read fields without recursive
6
+ * `Record<string, unknown>` casts. See `./issues-types.ts` for the
7
+ * full rationale and pattern (ALL-937).
8
+ */
9
+ interface DocumentCreatorRef {
10
+ id: string;
11
+ name: string;
12
+ }
13
+ interface DocumentProjectRef {
14
+ id: string;
15
+ name: string;
16
+ }
17
+ interface DocumentIssueRef {
18
+ id: string;
19
+ identifier: string;
20
+ title: string;
21
+ }
22
+ /** Mirrors `DOCUMENT_FRAGMENT` from `src/queries/documents.ts`. */
23
+ export interface DocumentNode {
24
+ id: string;
25
+ title: string;
26
+ content: string | null;
27
+ slugId: string | null;
28
+ url: string | null;
29
+ icon: string | null;
30
+ color: string | null;
31
+ createdAt: string | null;
32
+ updatedAt: string | null;
33
+ creator: DocumentCreatorRef | null;
34
+ project: DocumentProjectRef | null;
35
+ issue: DocumentIssueRef | null;
36
+ }
37
+ export interface CreateDocumentResponse {
38
+ documentCreate: {
39
+ success: boolean;
40
+ document: DocumentNode | null;
41
+ };
42
+ }
43
+ export interface UpdateDocumentResponse {
44
+ documentUpdate: {
45
+ success: boolean;
46
+ document: DocumentNode | null;
47
+ };
48
+ }
49
+ export interface GetDocumentResponse {
50
+ document: DocumentNode | null;
51
+ }
52
+ export interface ListDocumentsResponse {
53
+ documents: {
54
+ nodes: DocumentNode[];
55
+ };
56
+ }
57
+ export interface DeleteDocumentResponse {
58
+ documentDelete: {
59
+ success: boolean;
60
+ };
61
+ }
62
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Typed response shapes for the queries in `./documents.ts`.
3
+ *
4
+ * Mirrors `DOCUMENT_FRAGMENT` so the consumer in
5
+ * `graphql-documents-service.ts` can read fields without recursive
6
+ * `Record<string, unknown>` casts. See `./issues-types.ts` for the
7
+ * full rationale and pattern (ALL-937).
8
+ */
9
+ export {};
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Typed response shapes for `INTROSPECT_TYPE_QUERY` /
3
+ * `INTROSPECT_ROOT_QUERY`. See `./issues-types.ts` for the
4
+ * rationale (ALL-937).
5
+ *
6
+ * GraphQL introspection types are recursive (a type contains
7
+ * fields whose types contain fields…). We model the recursion
8
+ * shallowly — only as deep as the queries actually select.
9
+ */
10
+ interface IntrospectTypeRefShallow {
11
+ name: string | null;
12
+ kind: string;
13
+ ofType: {
14
+ name: string | null;
15
+ } | null;
16
+ }
17
+ interface IntrospectTypeRef {
18
+ name: string | null;
19
+ kind: string;
20
+ ofType: IntrospectTypeRefShallow | null;
21
+ }
22
+ interface IntrospectArg {
23
+ name: string;
24
+ type: IntrospectTypeRef;
25
+ }
26
+ interface IntrospectField {
27
+ name: string;
28
+ description: string | null;
29
+ type: IntrospectTypeRef;
30
+ args: IntrospectArg[];
31
+ }
32
+ interface IntrospectEnumValue {
33
+ name: string;
34
+ description: string | null;
35
+ }
36
+ interface IntrospectInputField {
37
+ name: string;
38
+ type: IntrospectTypeRef;
39
+ }
40
+ /** Mirrors the inner `__type` shape selected by `INTROSPECT_TYPE_QUERY`. */
41
+ interface IntrospectTypeNode {
42
+ name: string;
43
+ kind: string;
44
+ description: string | null;
45
+ fields: IntrospectField[] | null;
46
+ enumValues: IntrospectEnumValue[] | null;
47
+ inputFields: IntrospectInputField[] | null;
48
+ }
49
+ export interface IntrospectTypeResponse {
50
+ __type: IntrospectTypeNode | null;
51
+ }
52
+ /** `INTROSPECT_ROOT_QUERY` selects only fields (with args). */
53
+ export interface IntrospectRootResponse {
54
+ __type: {
55
+ fields: IntrospectField[];
56
+ } | null;
57
+ }
58
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Typed response shapes for `INTROSPECT_TYPE_QUERY` /
3
+ * `INTROSPECT_ROOT_QUERY`. See `./issues-types.ts` for the
4
+ * rationale (ALL-937).
5
+ *
6
+ * GraphQL introspection types are recursive (a type contains
7
+ * fields whose types contain fields…). We model the recursion
8
+ * shallowly — only as deep as the queries actually select.
9
+ */
10
+ export {};