@enrichlayer/el-linear 1.10.0 → 1.16.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 (108) hide show
  1. package/README.md +126 -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/batch.js +18 -21
  20. package/dist/commands/comments.js +27 -6
  21. package/dist/commands/config.js +178 -5
  22. package/dist/commands/init/aliases.js +1 -1
  23. package/dist/commands/init/defaults.d.ts +2 -1
  24. package/dist/commands/init/index.js +45 -35
  25. package/dist/commands/init/oauth.d.ts +4 -1
  26. package/dist/commands/init/oauth.js +22 -4
  27. package/dist/commands/init/shared.d.ts +24 -2
  28. package/dist/commands/init/shared.js +35 -4
  29. package/dist/commands/init/token.d.ts +3 -3
  30. package/dist/commands/init/token.js +5 -24
  31. package/dist/commands/init/workspace.d.ts +2 -1
  32. package/dist/commands/init/workspace.js +1 -1
  33. package/dist/commands/introspect.d.ts +27 -0
  34. package/dist/commands/introspect.js +178 -0
  35. package/dist/commands/issues/branch.js +9 -1
  36. package/dist/commands/issues/relations.d.ts +3 -14
  37. package/dist/commands/issues/relations.js +3 -3
  38. package/dist/commands/issues.js +222 -43
  39. package/dist/commands/labels.js +2 -1
  40. package/dist/commands/profile.js +1 -0
  41. package/dist/commands/projects.d.ts +2 -0
  42. package/dist/commands/projects.js +91 -7
  43. package/dist/commands/read-shortcut.d.ts +1 -1
  44. package/dist/commands/read-shortcut.js +28 -8
  45. package/dist/commands/refs.js +67 -8
  46. package/dist/commands/search.js +30 -5
  47. package/dist/commands/users.js +4 -2
  48. package/dist/config/config.d.ts +99 -1
  49. package/dist/config/config.js +264 -52
  50. package/dist/config/error-enrichment.d.ts +62 -0
  51. package/dist/config/error-enrichment.js +417 -0
  52. package/dist/config/issue-validation.d.ts +37 -0
  53. package/dist/config/issue-validation.js +63 -1
  54. package/dist/config/paths.d.ts +2 -8
  55. package/dist/config/paths.js +4 -2
  56. package/dist/config/resolver.d.ts +8 -1
  57. package/dist/config/resolver.js +9 -2
  58. package/dist/main.js +13 -1
  59. package/dist/output.d.ts +82 -0
  60. package/dist/output.js +82 -0
  61. package/dist/queries/comments-types.d.ts +15 -9
  62. package/dist/queries/common.d.ts +2 -2
  63. package/dist/queries/common.js +8 -0
  64. package/dist/queries/documents-types.d.ts +4 -3
  65. package/dist/queries/introspect-types.d.ts +8 -7
  66. package/dist/queries/issues-types.d.ts +92 -27
  67. package/dist/queries/issues.d.ts +49 -10
  68. package/dist/queries/issues.js +125 -5
  69. package/dist/queries/labels-types.d.ts +7 -6
  70. package/dist/queries/project-milestones-types.d.ts +5 -4
  71. package/dist/queries/project-milestones.d.ts +1 -1
  72. package/dist/queries/projects-types.d.ts +8 -7
  73. package/dist/queries/releases-types.d.ts +5 -4
  74. package/dist/queries/search-types.d.ts +28 -12
  75. package/dist/queries/templates-types.d.ts +3 -2
  76. package/dist/types/linear.d.ts +13 -1
  77. package/dist/utils/auto-link-references.d.ts +3 -3
  78. package/dist/utils/auto-link-references.js +1 -10
  79. package/dist/utils/extract-field.d.ts +19 -0
  80. package/dist/utils/extract-field.js +99 -0
  81. package/dist/utils/file-service.d.ts +6 -13
  82. package/dist/utils/file-service.js +0 -2
  83. package/dist/utils/formatters/summary.js +6 -1
  84. package/dist/utils/graphql-issues-service.d.ts +101 -45
  85. package/dist/utils/graphql-issues-service.js +252 -39
  86. package/dist/utils/graphql-service.d.ts +10 -12
  87. package/dist/utils/graphql-service.js +0 -3
  88. package/dist/utils/issue-reference-extractor.d.ts +7 -0
  89. package/dist/utils/issue-reference-extractor.js +5 -3
  90. package/dist/utils/issues-service-bootstrap.d.ts +28 -0
  91. package/dist/utils/issues-service-bootstrap.js +27 -0
  92. package/dist/utils/linear-service.d.ts +21 -14
  93. package/dist/utils/linear-service.js +73 -11
  94. package/dist/utils/markdown-prosemirror.js +12 -12
  95. package/dist/utils/mention-resolver.js +1 -1
  96. package/dist/utils/output.d.ts +81 -3
  97. package/dist/utils/output.js +61 -6
  98. package/dist/utils/project-slug.d.ts +21 -0
  99. package/dist/utils/project-slug.js +45 -0
  100. package/dist/utils/protected-ranges.d.ts +14 -0
  101. package/dist/utils/protected-ranges.js +88 -2
  102. package/dist/utils/sanitize-for-log.d.ts +24 -0
  103. package/dist/utils/sanitize-for-log.js +38 -0
  104. package/dist/utils/table-formatter.js +24 -0
  105. package/dist/utils/validators.d.ts +7 -2
  106. package/dist/utils/validators.js +6 -0
  107. package/dist/utils/workspace-url.js +20 -4
  108. package/package.json +7 -2
@@ -1,15 +1,52 @@
1
- export declare const GET_ISSUES_QUERY = "\n query GetIssues($first: Int!, $orderBy: PaginationOrderBy) {\n issues(\n first: $first\n orderBy: $orderBy\n filter: {\n state: { type: { neq: \"completed\" } }\n }\n ) {\n nodes {\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 }\n }\n";
2
- export declare const SEARCH_ISSUES_QUERY = "\n query SearchIssues($term: String!, $first: Int!) {\n searchIssues(term: $term, first: $first, includeArchived: false) {\n nodes {\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 }\n }\n";
3
- export declare const FILTERED_SEARCH_ISSUES_QUERY = "\n query FilteredSearchIssues(\n $first: Int!\n $filter: IssueFilter\n $orderBy: PaginationOrderBy\n ) {\n issues(\n first: $first\n filter: $filter\n orderBy: $orderBy\n includeArchived: false\n ) {\n nodes {\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 }\n }\n";
4
- export declare const BATCH_RESOLVE_FOR_SEARCH_QUERY = "\n query BatchResolveForSearch(\n $teamKey: String\n $teamName: String\n $projectName: String\n $assigneeEmail: String\n ) {\n teams(\n filter: {\n or: [\n { key: { eq: $teamKey } }\n { name: { eqIgnoreCase: $teamName } }\n ]\n }\n first: 1\n ) {\n nodes {\n id\n key\n name\n }\n }\n\n projects(filter: { name: { eqIgnoreCase: $projectName } }, first: 1) {\n nodes {\n id\n name\n }\n }\n\n users(filter: { email: { eq: $assigneeEmail } }, first: 1) {\n nodes {\n id\n name\n email\n }\n }\n }\n";
5
- export declare const GET_ISSUE_BY_ID_QUERY = "\n query GetIssue($id: String!) {\n issue(id: $id) {\n \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\n }\n }\n";
6
- export declare const GET_ISSUE_BY_IDENTIFIER_QUERY = "\n query GetIssueByIdentifier($teamKey: String!, $number: Float!) {\n issues(\n filter: {\n team: { key: { eq: $teamKey } }\n number: { eq: $number }\n }\n first: 1\n ) {\n nodes {\n \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\n }\n }\n }\n";
7
- export declare const BATCH_RESOLVE_FOR_UPDATE_QUERY = "\n query BatchResolveForUpdate(\n $projectName: String\n $teamKey: String\n $issueNumber: Float\n $milestoneName: String\n ) {\n projects(filter: { name: { eqIgnoreCase: $projectName } }, first: 1) {\n nodes {\n id\n name\n projectMilestones {\n nodes {\n id\n name\n }\n }\n }\n }\n\n milestones: projectMilestones(\n filter: { name: { eq: $milestoneName } }\n first: 1\n ) {\n nodes {\n id\n name\n }\n }\n\n issues(\n filter: {\n and: [\n { team: { key: { eq: $teamKey } } }\n { number: { eq: $issueNumber } }\n ]\n }\n first: 1\n ) {\n nodes {\n id\n identifier\n team {\n id\n key\n }\n labels {\n nodes {\n id\n name\n }\n }\n project {\n id\n projectMilestones {\n nodes {\n id\n name\n }\n }\n }\n }\n }\n }\n";
8
- export declare const CREATE_ISSUE_MUTATION = "\n mutation CreateIssue($input: IssueCreateInput!) {\n issueCreate(input: $input) {\n success\n issue {\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 }\n }\n";
9
- export declare const UPDATE_ISSUE_MUTATION = "\n mutation UpdateIssue($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue {\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 }\n }\n";
1
+ export declare const GET_ISSUES_QUERY = "\n query GetIssues($first: Int!, $orderBy: PaginationOrderBy) {\n issues(\n first: $first\n orderBy: $orderBy\n filter: {\n state: { type: { neq: \"completed\" } }\n }\n ) {\n nodes {\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 }\n }\n";
2
+ export declare const SEARCH_ISSUES_QUERY = "\n query SearchIssues($term: String!, $first: Int!) {\n searchIssues(term: $term, first: $first, includeArchived: false) {\n nodes {\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 }\n }\n";
3
+ export declare const FILTERED_SEARCH_ISSUES_QUERY = "\n query FilteredSearchIssues(\n $first: Int!\n $filter: IssueFilter\n $orderBy: PaginationOrderBy\n ) {\n issues(\n first: $first\n filter: $filter\n orderBy: $orderBy\n includeArchived: false\n ) {\n nodes {\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 }\n }\n";
4
+ /**
5
+ * Batch-resolves a search's team/project/assignee/delegate filter inputs.
6
+ *
7
+ * The `projects` block is `@include`-gated: Linear treats a null filter
8
+ * comparator as "no filter", so an always-on block with an unset
9
+ * `$projectName` would fetch an arbitrary project. (Search resolves a UUID
10
+ * `--project` directly without consulting this block, so only the
11
+ * name-resolution arm is needed here.)
12
+ */
13
+ export declare const BATCH_RESOLVE_FOR_SEARCH_QUERY = "\n query BatchResolveForSearch(\n $teamKey: String\n $teamName: String\n $projectName: String\n $hasProjectName: Boolean = false\n $assigneeEmail: String\n $delegateEmail: String\n ) {\n teams(\n filter: {\n or: [\n { key: { eq: $teamKey } }\n { name: { eqIgnoreCase: $teamName } }\n ]\n }\n first: 1\n ) {\n nodes {\n id\n key\n name\n }\n }\n\n projects(\n filter: { name: { eqIgnoreCase: $projectName } }\n first: 1\n ) @include(if: $hasProjectName) {\n nodes {\n id\n name\n }\n }\n\n users(filter: { email: { eq: $assigneeEmail } }, first: 1) {\n nodes {\n id\n name\n email\n }\n }\n\n delegates: users(filter: { email: { eq: $delegateEmail } }, first: 1) {\n nodes {\n id\n name\n email\n }\n }\n }\n";
14
+ export declare const GET_ISSUE_BY_ID_QUERY = "\n query GetIssue($id: String!) {\n issue(id: $id) {\n \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\n }\n }\n";
15
+ export declare const GET_ISSUE_BY_IDENTIFIER_QUERY = "\n query GetIssueByIdentifier($teamKey: String!, $number: Float!) {\n issues(\n filter: {\n team: { key: { eq: $teamKey } }\n number: { eq: $number }\n }\n first: 1\n ) {\n nodes {\n \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\n }\n }\n }\n";
16
+ /**
17
+ * Batch-resolves an update's project/milestone/issue inputs.
18
+ *
19
+ * The project and milestone blocks are `@include`-gated for the same
20
+ * reason as `BATCH_RESOLVE_FOR_CREATE_QUERY`: a null filter comparator is
21
+ * a no-op that returns an arbitrary record. A UUID `--project` is resolved
22
+ * by `id` (`projectsById`) so its milestones are still fetched for
23
+ * `--project-milestone` name resolution; a name uses `projectsByName`.
24
+ */
25
+ export declare const BATCH_RESOLVE_FOR_UPDATE_QUERY = "\n query BatchResolveForUpdate(\n $projectName: String\n $projectId: ID\n $hasProjectName: Boolean = false\n $hasProjectId: Boolean = false\n $teamKey: String\n $issueNumber: Float\n $milestoneName: String\n $hasMilestoneName: Boolean = false\n ) {\n projectsByName: projects(\n filter: { name: { eqIgnoreCase: $projectName } }\n first: 1\n ) @include(if: $hasProjectName) {\n nodes {\n id\n name\n projectMilestones {\n nodes {\n id\n name\n }\n }\n }\n }\n\n projectsById: projects(\n filter: { id: { eq: $projectId } }\n first: 1\n ) @include(if: $hasProjectId) {\n nodes {\n id\n name\n projectMilestones {\n nodes {\n id\n name\n }\n }\n }\n }\n\n milestones: projectMilestones(\n filter: { name: { eq: $milestoneName } }\n first: 1\n ) @include(if: $hasMilestoneName) {\n nodes {\n id\n name\n }\n }\n\n issues(\n filter: {\n and: [\n { team: { key: { eq: $teamKey } } }\n { number: { eq: $issueNumber } }\n ]\n }\n first: 1\n ) {\n nodes {\n id\n identifier\n team {\n id\n key\n }\n labels {\n nodes {\n id\n name\n }\n }\n project {\n id\n projectMilestones {\n nodes {\n id\n name\n }\n }\n }\n }\n }\n }\n";
26
+ export declare const CREATE_ISSUE_MUTATION = "\n mutation CreateIssue($input: IssueCreateInput!) {\n issueCreate(input: $input) {\n success\n issue {\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 }\n }\n";
27
+ export declare const UPDATE_ISSUE_MUTATION = "\n mutation UpdateIssue($id: String!, $input: IssueUpdateInput!) {\n issueUpdate(id: $id, input: $input) {\n success\n issue {\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 }\n }\n";
10
28
  export declare const ARCHIVE_ISSUE_MUTATION = "\n mutation ArchiveIssue($id: String!) {\n issueArchive(id: $id) {\n success\n lastSyncId\n entity {\n id\n }\n }\n }\n";
11
29
  export declare const DELETE_ISSUE_MUTATION = "\n mutation DeleteIssue($id: String!, $permanentlyDelete: Boolean) {\n issueDelete(id: $id, permanentlyDelete: $permanentlyDelete) {\n success\n lastSyncId\n entity {\n id\n }\n }\n }\n";
12
- export declare const BATCH_RESOLVE_FOR_CREATE_QUERY = "\n query BatchResolveForCreate(\n $teamKey: String\n $teamName: String\n $projectName: String\n $parentTeamKey: String\n $parentIssueNumber: Float\n $milestoneName: String\n ) {\n teams(\n filter: {\n or: [\n { key: { eq: $teamKey } }\n { name: { eqIgnoreCase: $teamName } }\n ]\n }\n first: 1\n ) {\n nodes {\n id\n key\n name\n }\n }\n\n projects(filter: { name: { eqIgnoreCase: $projectName } }, first: 1) {\n nodes {\n id\n name\n teams {\n nodes { id key }\n }\n projectMilestones {\n nodes { id name }\n }\n }\n }\n\n milestones: projectMilestones(\n filter: { name: { eq: $milestoneName } }\n first: 1\n ) {\n nodes {\n id\n name\n }\n }\n\n parentIssues: issues(\n filter: {\n and: [\n { team: { key: { eq: $parentTeamKey } } }\n { number: { eq: $parentIssueNumber } }\n ]\n }\n first: 1\n ) {\n nodes {\n id\n identifier\n }\n }\n }\n";
30
+ /**
31
+ * Batch-resolves a create's team/project/milestone/parent inputs in one
32
+ * round-trip.
33
+ *
34
+ * The project and milestone blocks are gated behind `@include` directives
35
+ * rather than left always-on. Linear treats a null filter comparator
36
+ * (`{ name: { eqIgnoreCase: null } }`) as "no filter" — so an always-on
37
+ * `projects` block with an unset `$projectName` returns an *arbitrary*
38
+ * project, which the caller would then mistake for the user's project
39
+ * (e.g. auto-switching the team to that unrelated project's team). The
40
+ * `has*` booleans ensure a block is fetched only when its input exists.
41
+ *
42
+ * A UUID `--project` is resolved by `id` (`projectsById`) so its team
43
+ * associations are still fetched for team-project validation; a name is
44
+ * resolved by `name` (`projectsByName`). The two are mutually exclusive,
45
+ * but GraphQL forbids two same-aliased fields with differing arguments,
46
+ * so they carry distinct aliases and the service folds whichever ran
47
+ * into `resolveResult.projects`.
48
+ */
49
+ export declare const BATCH_RESOLVE_FOR_CREATE_QUERY = "\n query BatchResolveForCreate(\n $teamKey: String\n $teamName: String\n $projectName: String\n $projectId: ID\n $hasProjectName: Boolean = false\n $hasProjectId: Boolean = false\n $parentTeamKey: String\n $parentIssueNumber: Float\n $milestoneName: String\n $hasMilestoneName: Boolean = false\n ) {\n teams(\n filter: {\n or: [\n { key: { eq: $teamKey } }\n { name: { eqIgnoreCase: $teamName } }\n ]\n }\n first: 1\n ) {\n nodes {\n id\n key\n name\n }\n }\n\n projectsByName: projects(\n filter: { name: { eqIgnoreCase: $projectName } }\n first: 1\n ) @include(if: $hasProjectName) {\n nodes {\n id\n name\n teams {\n nodes { id key }\n }\n projectMilestones {\n nodes { id name }\n }\n }\n }\n\n projectsById: projects(\n filter: { id: { eq: $projectId } }\n first: 1\n ) @include(if: $hasProjectId) {\n nodes {\n id\n name\n teams {\n nodes { id key }\n }\n projectMilestones {\n nodes { id name }\n }\n }\n }\n\n milestones: projectMilestones(\n filter: { name: { eq: $milestoneName } }\n first: 1\n ) @include(if: $hasMilestoneName) {\n nodes {\n id\n name\n }\n }\n\n parentIssues: issues(\n filter: {\n and: [\n { team: { key: { eq: $parentTeamKey } } }\n { number: { eq: $parentIssueNumber } }\n ]\n }\n first: 1\n ) {\n nodes {\n id\n identifier\n }\n }\n }\n";
13
50
  /**
14
51
  * Build a label-resolution query filtered by names (case-insensitive).
15
52
  * Uses `or` + `eqIgnoreCase` since Linear's `in` filter may be case-sensitive.
@@ -20,6 +57,8 @@ export declare function buildResolveLabelsByNameQuery(labelNames: string[]): {
20
57
  };
21
58
  export declare const GET_ISSUE_STATE_HISTORY_QUERY = "\n query GetIssueStateHistory($id: String!) {\n issue(id: $id) {\n id\n identifier\n title\n stateHistory {\n nodes {\n state { id name type }\n startedAt\n endedAt\n }\n }\n }\n }\n";
22
59
  export declare const GET_ISSUE_TEAM_QUERY = "\n query GetIssueTeam($issueId: String!) {\n issue(id: $issueId) {\n team { id }\n }\n }\n";
60
+ export declare const GET_ISSUE_START_CONTEXT_QUERY = "\n query GetIssueStartContext($id: String!) {\n issue(id: $id) {\n id\n identifier\n state { id name type }\n team { id key name }\n delegate { id name url }\n }\n }\n";
61
+ export declare const TEAM_STARTED_STATUSES_QUERY = "\n query TeamStartedStatuses($teamId: String!) {\n team(id: $teamId) {\n states(filter: { type: { eq: \"started\" } }) {\n nodes {\n id\n name\n position\n }\n }\n }\n }\n";
23
62
  export declare const ISSUE_RELATION_CREATE_MUTATION = "\n mutation IssueRelationCreate($input: IssueRelationCreateInput!) {\n issueRelationCreate(input: $input) {\n success\n issueRelation {\n id\n type\n issue {\n id\n identifier\n title\n }\n relatedIssue {\n id\n identifier\n title\n }\n }\n }\n }\n";
24
63
  export declare const GET_ISSUE_RELATIONS_QUERY = "\n query GetIssueRelations($id: String!) {\n issue(id: $id) {\n id\n identifier\n title\n description\n relations {\n nodes {\n id\n type\n relatedIssue {\n id\n identifier\n title\n state { id name }\n priority\n assignee { id name }\n team { id key name }\n }\n }\n }\n inverseRelations {\n nodes {\n id\n type\n issue {\n id\n identifier\n title\n state { id name }\n priority\n assignee { id name }\n team { id key name }\n }\n }\n }\n }\n }\n";
25
64
  export declare const SCAN_ISSUES_QUERY = "\n query ScanIssues($filter: IssueFilter, $first: Int) {\n issues(filter: $filter, first: $first, orderBy: updatedAt) {\n nodes { id identifier description }\n }\n }\n";
@@ -41,12 +41,23 @@ export const FILTERED_SEARCH_ISSUES_QUERY = `
41
41
  }
42
42
  }
43
43
  `;
44
+ /**
45
+ * Batch-resolves a search's team/project/assignee/delegate filter inputs.
46
+ *
47
+ * The `projects` block is `@include`-gated: Linear treats a null filter
48
+ * comparator as "no filter", so an always-on block with an unset
49
+ * `$projectName` would fetch an arbitrary project. (Search resolves a UUID
50
+ * `--project` directly without consulting this block, so only the
51
+ * name-resolution arm is needed here.)
52
+ */
44
53
  export const BATCH_RESOLVE_FOR_SEARCH_QUERY = `
45
54
  query BatchResolveForSearch(
46
55
  $teamKey: String
47
56
  $teamName: String
48
57
  $projectName: String
58
+ $hasProjectName: Boolean = false
49
59
  $assigneeEmail: String
60
+ $delegateEmail: String
50
61
  ) {
51
62
  teams(
52
63
  filter: {
@@ -64,7 +75,10 @@ export const BATCH_RESOLVE_FOR_SEARCH_QUERY = `
64
75
  }
65
76
  }
66
77
 
67
- projects(filter: { name: { eqIgnoreCase: $projectName } }, first: 1) {
78
+ projects(
79
+ filter: { name: { eqIgnoreCase: $projectName } }
80
+ first: 1
81
+ ) @include(if: $hasProjectName) {
68
82
  nodes {
69
83
  id
70
84
  name
@@ -78,6 +92,14 @@ export const BATCH_RESOLVE_FOR_SEARCH_QUERY = `
78
92
  email
79
93
  }
80
94
  }
95
+
96
+ delegates: users(filter: { email: { eq: $delegateEmail } }, first: 1) {
97
+ nodes {
98
+ id
99
+ name
100
+ email
101
+ }
102
+ }
81
103
  }
82
104
  `;
83
105
  export const GET_ISSUE_BY_ID_QUERY = `
@@ -102,14 +124,46 @@ export const GET_ISSUE_BY_IDENTIFIER_QUERY = `
102
124
  }
103
125
  }
104
126
  `;
127
+ /**
128
+ * Batch-resolves an update's project/milestone/issue inputs.
129
+ *
130
+ * The project and milestone blocks are `@include`-gated for the same
131
+ * reason as `BATCH_RESOLVE_FOR_CREATE_QUERY`: a null filter comparator is
132
+ * a no-op that returns an arbitrary record. A UUID `--project` is resolved
133
+ * by `id` (`projectsById`) so its milestones are still fetched for
134
+ * `--project-milestone` name resolution; a name uses `projectsByName`.
135
+ */
105
136
  export const BATCH_RESOLVE_FOR_UPDATE_QUERY = `
106
137
  query BatchResolveForUpdate(
107
138
  $projectName: String
139
+ $projectId: ID
140
+ $hasProjectName: Boolean = false
141
+ $hasProjectId: Boolean = false
108
142
  $teamKey: String
109
143
  $issueNumber: Float
110
144
  $milestoneName: String
145
+ $hasMilestoneName: Boolean = false
111
146
  ) {
112
- projects(filter: { name: { eqIgnoreCase: $projectName } }, first: 1) {
147
+ projectsByName: projects(
148
+ filter: { name: { eqIgnoreCase: $projectName } }
149
+ first: 1
150
+ ) @include(if: $hasProjectName) {
151
+ nodes {
152
+ id
153
+ name
154
+ projectMilestones {
155
+ nodes {
156
+ id
157
+ name
158
+ }
159
+ }
160
+ }
161
+ }
162
+
163
+ projectsById: projects(
164
+ filter: { id: { eq: $projectId } }
165
+ first: 1
166
+ ) @include(if: $hasProjectId) {
113
167
  nodes {
114
168
  id
115
169
  name
@@ -125,7 +179,7 @@ export const BATCH_RESOLVE_FOR_UPDATE_QUERY = `
125
179
  milestones: projectMilestones(
126
180
  filter: { name: { eq: $milestoneName } }
127
181
  first: 1
128
- ) {
182
+ ) @include(if: $hasMilestoneName) {
129
183
  nodes {
130
184
  id
131
185
  name
@@ -209,14 +263,37 @@ export const DELETE_ISSUE_MUTATION = `
209
263
  }
210
264
  }
211
265
  `;
266
+ /**
267
+ * Batch-resolves a create's team/project/milestone/parent inputs in one
268
+ * round-trip.
269
+ *
270
+ * The project and milestone blocks are gated behind `@include` directives
271
+ * rather than left always-on. Linear treats a null filter comparator
272
+ * (`{ name: { eqIgnoreCase: null } }`) as "no filter" — so an always-on
273
+ * `projects` block with an unset `$projectName` returns an *arbitrary*
274
+ * project, which the caller would then mistake for the user's project
275
+ * (e.g. auto-switching the team to that unrelated project's team). The
276
+ * `has*` booleans ensure a block is fetched only when its input exists.
277
+ *
278
+ * A UUID `--project` is resolved by `id` (`projectsById`) so its team
279
+ * associations are still fetched for team-project validation; a name is
280
+ * resolved by `name` (`projectsByName`). The two are mutually exclusive,
281
+ * but GraphQL forbids two same-aliased fields with differing arguments,
282
+ * so they carry distinct aliases and the service folds whichever ran
283
+ * into `resolveResult.projects`.
284
+ */
212
285
  export const BATCH_RESOLVE_FOR_CREATE_QUERY = `
213
286
  query BatchResolveForCreate(
214
287
  $teamKey: String
215
288
  $teamName: String
216
289
  $projectName: String
290
+ $projectId: ID
291
+ $hasProjectName: Boolean = false
292
+ $hasProjectId: Boolean = false
217
293
  $parentTeamKey: String
218
294
  $parentIssueNumber: Float
219
295
  $milestoneName: String
296
+ $hasMilestoneName: Boolean = false
220
297
  ) {
221
298
  teams(
222
299
  filter: {
@@ -234,7 +311,26 @@ export const BATCH_RESOLVE_FOR_CREATE_QUERY = `
234
311
  }
235
312
  }
236
313
 
237
- projects(filter: { name: { eqIgnoreCase: $projectName } }, first: 1) {
314
+ projectsByName: projects(
315
+ filter: { name: { eqIgnoreCase: $projectName } }
316
+ first: 1
317
+ ) @include(if: $hasProjectName) {
318
+ nodes {
319
+ id
320
+ name
321
+ teams {
322
+ nodes { id key }
323
+ }
324
+ projectMilestones {
325
+ nodes { id name }
326
+ }
327
+ }
328
+ }
329
+
330
+ projectsById: projects(
331
+ filter: { id: { eq: $projectId } }
332
+ first: 1
333
+ ) @include(if: $hasProjectId) {
238
334
  nodes {
239
335
  id
240
336
  name
@@ -250,7 +346,7 @@ export const BATCH_RESOLVE_FOR_CREATE_QUERY = `
250
346
  milestones: projectMilestones(
251
347
  filter: { name: { eq: $milestoneName } }
252
348
  first: 1
253
- ) {
349
+ ) @include(if: $hasMilestoneName) {
254
350
  nodes {
255
351
  id
256
352
  name
@@ -332,6 +428,30 @@ export const GET_ISSUE_TEAM_QUERY = `
332
428
  }
333
429
  }
334
430
  `;
431
+ export const GET_ISSUE_START_CONTEXT_QUERY = `
432
+ query GetIssueStartContext($id: String!) {
433
+ issue(id: $id) {
434
+ id
435
+ identifier
436
+ state { id name type }
437
+ team { id key name }
438
+ delegate { id name url }
439
+ }
440
+ }
441
+ `;
442
+ export const TEAM_STARTED_STATUSES_QUERY = `
443
+ query TeamStartedStatuses($teamId: String!) {
444
+ team(id: $teamId) {
445
+ states(filter: { type: { eq: "started" } }) {
446
+ nodes {
447
+ id
448
+ name
449
+ position
450
+ }
451
+ }
452
+ }
453
+ }
454
+ `;
335
455
  export const ISSUE_RELATION_CREATE_MUTATION = `
336
456
  mutation IssueRelationCreate($input: IssueRelationCreateInput!) {
337
457
  issueRelationCreate(input: $input) {
@@ -2,17 +2,17 @@
2
2
  * Typed response shapes for the queries in `./labels.ts`.
3
3
  * See `./issues-types.ts` for the rationale (ALL-937).
4
4
  */
5
- export interface LabelTeamRef {
5
+ interface LabelTeamRef {
6
6
  id: string;
7
7
  key: string;
8
8
  name: string;
9
9
  }
10
- export interface LabelParentRef {
10
+ interface LabelParentRef {
11
11
  id: string;
12
12
  name: string;
13
13
  }
14
14
  /** Mirrors the issueLabel selection set on `CREATE_LABEL_MUTATION`. */
15
- export interface CreatedLabelNode {
15
+ interface CreatedLabelNode {
16
16
  id: string;
17
17
  name: string;
18
18
  color: string;
@@ -20,7 +20,7 @@ export interface CreatedLabelNode {
20
20
  parent: LabelParentRef | null;
21
21
  }
22
22
  /** Mirrors the issueLabel selection set on `RETIRE_LABEL_MUTATION`. */
23
- export interface RetiredLabelNode {
23
+ interface RetiredLabelNode {
24
24
  id: string;
25
25
  name: string;
26
26
  color: string;
@@ -28,13 +28,13 @@ export interface RetiredLabelNode {
28
28
  team: LabelTeamRef | null;
29
29
  }
30
30
  /** Mirrors the issueLabel selection set on `RESTORE_LABEL_MUTATION`. */
31
- export interface RestoredLabelNode {
31
+ interface RestoredLabelNode {
32
32
  id: string;
33
33
  name: string;
34
34
  color: string;
35
35
  team: LabelTeamRef | null;
36
36
  }
37
- export interface ParentLabelNode {
37
+ interface ParentLabelNode {
38
38
  id: string;
39
39
  name: string;
40
40
  isGroup: boolean;
@@ -62,3 +62,4 @@ export interface RestoreLabelResponse {
62
62
  issueLabel: RestoredLabelNode | null;
63
63
  };
64
64
  }
65
+ export {};
@@ -8,7 +8,7 @@
8
8
  * consumer reads only what was actually selected.
9
9
  */
10
10
  import type { IssueNode } from "./issues-types.js";
11
- export interface MilestoneProjectRef {
11
+ interface MilestoneProjectRef {
12
12
  id: string;
13
13
  name: string;
14
14
  }
@@ -16,7 +16,7 @@ export interface MilestoneProjectRef {
16
16
  * Mirrors the milestone selection set in `LIST_PROJECT_MILESTONES_QUERY`
17
17
  * — full milestone fields without the project-back-reference.
18
18
  */
19
- export interface MilestoneListNode {
19
+ interface MilestoneListNode {
20
20
  id: string;
21
21
  name: string;
22
22
  description: string | null;
@@ -29,7 +29,7 @@ export interface MilestoneListNode {
29
29
  * Mirrors the milestone selection set in `GET_PROJECT_MILESTONE_BY_ID_QUERY`
30
30
  * — list shape + project + issues connection.
31
31
  */
32
- export interface MilestoneDetailNode extends MilestoneListNode {
32
+ interface MilestoneDetailNode extends MilestoneListNode {
33
33
  project: MilestoneProjectRef;
34
34
  issues: {
35
35
  nodes: IssueNode[];
@@ -50,7 +50,7 @@ export interface MilestoneLookupNode {
50
50
  * Mirrors the milestone selection set on the create / update mutations —
51
51
  * list shape + project (no issues connection).
52
52
  */
53
- export interface MutatedMilestoneNode extends MilestoneListNode {
53
+ interface MutatedMilestoneNode extends MilestoneListNode {
54
54
  project: MilestoneProjectRef;
55
55
  }
56
56
  export interface ListProjectMilestonesResponse {
@@ -89,3 +89,4 @@ export interface UpdateProjectMilestoneResponse {
89
89
  projectMilestone: MutatedMilestoneNode | null;
90
90
  };
91
91
  }
92
+ export {};
@@ -1,5 +1,5 @@
1
1
  export declare const LIST_PROJECT_MILESTONES_QUERY = "\n query ListProjectMilestones($projectId: String!, $first: Int!) {\n project(id: $projectId) {\n id\n name\n projectMilestones(first: $first) {\n nodes {\n id\n name\n description\n targetDate\n sortOrder\n createdAt\n updatedAt\n }\n }\n }\n }\n";
2
- export declare const GET_PROJECT_MILESTONE_BY_ID_QUERY = "\n query GetProjectMilestone($id: String!, $issuesFirst: Int) {\n projectMilestone(id: $id) {\n id\n name\n description\n targetDate\n sortOrder\n createdAt\n updatedAt\n project {\n id\n name\n }\n issues(first: $issuesFirst) {\n nodes {\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 }\n }\n }\n";
2
+ export declare const GET_PROJECT_MILESTONE_BY_ID_QUERY = "\n query GetProjectMilestone($id: String!, $issuesFirst: Int) {\n projectMilestone(id: $id) {\n id\n name\n description\n targetDate\n sortOrder\n createdAt\n updatedAt\n project {\n id\n name\n }\n issues(first: $issuesFirst) {\n nodes {\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 }\n }\n }\n";
3
3
  export declare const FIND_PROJECT_MILESTONE_BY_NAME_SCOPED = "\n query FindProjectMilestoneScoped($name: String!, $projectId: String!) {\n project(id: $projectId) {\n projectMilestones(filter: { name: { eq: $name } }, first: 10) {\n nodes {\n id\n name\n targetDate\n sortOrder\n project {\n id\n name\n }\n }\n }\n }\n }\n";
4
4
  export declare const FIND_PROJECT_MILESTONE_BY_NAME_GLOBAL = "\n query FindProjectMilestoneGlobal($name: String!) {\n projectMilestones(filter: { name: { eq: $name } }, first: 10) {\n nodes {\n id\n name\n targetDate\n sortOrder\n project {\n id\n name\n }\n }\n }\n }\n";
5
5
  export declare const CREATE_PROJECT_MILESTONE_MUTATION = "\n mutation CreateProjectMilestone($projectId: String!, $name: String!, $description: String, $targetDate: TimelessDate) {\n projectMilestoneCreate(input: {\n projectId: $projectId\n name: $name\n description: $description\n targetDate: $targetDate\n }) {\n success\n projectMilestone {\n id\n name\n description\n targetDate\n sortOrder\n createdAt\n updatedAt\n project {\n id\n name\n }\n }\n }\n }\n";
@@ -2,12 +2,12 @@
2
2
  * Typed response shapes for the queries in `./projects.ts`.
3
3
  * See `./issues-types.ts` for the rationale (ALL-937).
4
4
  */
5
- export interface ProjectTeamRef {
5
+ interface ProjectTeamRef {
6
6
  id: string;
7
7
  key: string;
8
8
  name: string;
9
9
  }
10
- export interface ProjectBaseNode {
10
+ interface ProjectBaseNode {
11
11
  id: string;
12
12
  name: string;
13
13
  teams: {
@@ -18,15 +18,15 @@ export interface ProjectBaseNode {
18
18
  * Mirrors the project selection set used by `SEARCH_PROJECTS_BY_NAME_QUERY`
19
19
  * and `CREATE_PROJECT_MUTATION` — base fields + state.
20
20
  */
21
- export interface ProjectWithStateNode extends ProjectBaseNode {
21
+ interface ProjectWithStateNode extends ProjectBaseNode {
22
22
  state: string;
23
23
  }
24
- export interface ProjectIssueRef {
24
+ interface ProjectIssueRef {
25
25
  id: string;
26
26
  identifier: string;
27
27
  title: string;
28
28
  }
29
- export interface ProjectWithIssuesNode extends ProjectBaseNode {
29
+ interface ProjectWithIssuesNode extends ProjectBaseNode {
30
30
  issues: {
31
31
  nodes: ProjectIssueRef[];
32
32
  };
@@ -59,10 +59,10 @@ export interface UpdateProjectResponse {
59
59
  project: ProjectBaseNode | null;
60
60
  };
61
61
  }
62
- export interface ProjectArchiveEntity {
62
+ interface ProjectArchiveEntity {
63
63
  id: string;
64
64
  }
65
- export interface ProjectArchivePayload {
65
+ interface ProjectArchivePayload {
66
66
  success: boolean;
67
67
  lastSyncId: number;
68
68
  entity: ProjectArchiveEntity | null;
@@ -73,3 +73,4 @@ export interface ArchiveProjectResponse {
73
73
  export interface DeleteProjectResponse {
74
74
  projectDelete: ProjectArchivePayload;
75
75
  }
76
+ export {};
@@ -2,17 +2,17 @@
2
2
  * Typed response shapes for the queries in `./releases.ts`.
3
3
  * See `./issues-types.ts` for the rationale (ALL-937).
4
4
  */
5
- export interface ReleaseStageRef {
5
+ interface ReleaseStageRef {
6
6
  id: string;
7
7
  name: string;
8
8
  type: string;
9
9
  color: string | null;
10
10
  }
11
- export interface ReleasePipelineRef {
11
+ interface ReleasePipelineRef {
12
12
  id: string;
13
13
  name: string;
14
14
  }
15
- export interface ReleaseDocumentRef {
15
+ interface ReleaseDocumentRef {
16
16
  id: string;
17
17
  title: string;
18
18
  slugId: string;
@@ -56,7 +56,7 @@ export interface CreatedReleaseNode {
56
56
  createdAt: string;
57
57
  updatedAt: string;
58
58
  }
59
- export interface ReleasePipelineNode {
59
+ interface ReleasePipelineNode {
60
60
  id: string;
61
61
  name: string;
62
62
  stages: {
@@ -82,3 +82,4 @@ export interface GetReleasePipelinesResponse {
82
82
  nodes: ReleasePipelineNode[];
83
83
  };
84
84
  }
85
+ export {};
@@ -3,11 +3,12 @@
3
3
  * templates listing in `commands/search.ts`. See `./issues-types.ts`
4
4
  * for the rationale (ALL-937).
5
5
  */
6
- export interface SearchIssueRef {
6
+ import type { LinearPriority } from "../types/linear.js";
7
+ interface SearchIssueRef {
7
8
  id: string;
8
9
  identifier: string;
9
10
  title: string;
10
- priority: number | null;
11
+ priority: LinearPriority | null;
11
12
  state: {
12
13
  id: string;
13
14
  name: string;
@@ -27,17 +28,17 @@ export interface SearchIssueRef {
27
28
  name: string;
28
29
  } | null;
29
30
  }
30
- export interface SearchProjectRef {
31
+ interface SearchProjectRef {
31
32
  id: string;
32
33
  name: string;
33
34
  state: string;
34
35
  }
35
- export interface SearchInitiativeRef {
36
+ interface SearchInitiativeRef {
36
37
  id: string;
37
38
  name: string;
38
39
  status: string | null;
39
40
  }
40
- export interface SearchDocumentRef {
41
+ interface SearchDocumentRef {
41
42
  id: string;
42
43
  title: string;
43
44
  slugId: string | null;
@@ -47,18 +48,32 @@ export interface SearchDocumentRef {
47
48
  } | null;
48
49
  }
49
50
  /**
50
- * Mirrors a single semanticSearch result. The discriminator is `type`,
51
- * but Linear returns *all* sub-objects nullable per row — only the one
52
- * matching `type` is populated. Modelled as fully-optional sub-objects
53
- * to match runtime reality.
51
+ * A single semanticSearch result. Discriminated union on `type` — given
52
+ * a row, only the field named by `type` is meaningful (the other three
53
+ * are absent / null on the wire). Consumers `switch (r.type)` and access
54
+ * the corresponding payload directly; the compiler statically rejects
55
+ * cross-arm access like `r.project` in a `case "issue"` branch.
56
+ *
57
+ * The payload itself is `| null` because Linear can return null when
58
+ * the underlying entity was deleted between indexing and query time —
59
+ * that's an orthogonal concern from the discriminant.
60
+ *
61
+ * The four `type` literals match Linear's `semanticSearch.results.type`
62
+ * enum verbatim — keep in lock-step with the GraphQL schema's enum.
54
63
  */
55
- export interface SemanticSearchResult {
56
- type: string;
64
+ export type SemanticSearchResult = {
65
+ type: "issue";
57
66
  issue: SearchIssueRef | null;
67
+ } | {
68
+ type: "project";
58
69
  project: SearchProjectRef | null;
70
+ } | {
71
+ type: "initiative";
59
72
  initiative: SearchInitiativeRef | null;
73
+ } | {
74
+ type: "document";
60
75
  document: SearchDocumentRef | null;
61
- }
76
+ };
62
77
  export interface SemanticSearchResponse {
63
78
  semanticSearch: {
64
79
  results: SemanticSearchResult[];
@@ -84,3 +99,4 @@ export interface SearchTemplateNode {
84
99
  export interface SearchTemplatesResponse {
85
100
  templates: SearchTemplateNode[];
86
101
  }
102
+ export {};
@@ -6,12 +6,12 @@
6
6
  * than wrapped in `{ nodes: ... }`. The response type below mirrors
7
7
  * what the API actually returns, not the connection convention.
8
8
  */
9
- export interface TemplateTeamRef {
9
+ interface TemplateTeamRef {
10
10
  id: string;
11
11
  key: string;
12
12
  name: string;
13
13
  }
14
- export interface TemplateCreatorRef {
14
+ interface TemplateCreatorRef {
15
15
  id: string;
16
16
  name: string;
17
17
  }
@@ -59,3 +59,4 @@ export interface DeleteTemplateResponse {
59
59
  lastSyncId?: number;
60
60
  };
61
61
  }
62
+ export {};
@@ -3,6 +3,17 @@
3
3
  * These represent the public API surface — GraphQL responses are
4
4
  * transformed into these shapes at the service boundary.
5
5
  */
6
+ /**
7
+ * Linear priority levels — `0` = no priority, `1` = urgent, `2` = high,
8
+ * `3` = medium (alias: normal), `4` = low. Sourced from Linear's
9
+ * `Issue.priority` enum; the GraphQL API returns a number in this range.
10
+ * Use this instead of `number` at every API boundary so an out-of-range
11
+ * value (`9`) fails to compile.
12
+ *
13
+ * The runtime parser is `validatePriority` in `src/utils/validators.ts`
14
+ * — it narrows arbitrary `string` input to this union.
15
+ */
16
+ export type LinearPriority = 0 | 1 | 2 | 3 | 4;
6
17
  interface TeamRef {
7
18
  id: string;
8
19
  key: string;
@@ -87,6 +98,7 @@ export interface LinearIssue {
87
98
  comments?: LinearComment[];
88
99
  createdAt: string;
89
100
  cycle?: CycleRef;
101
+ delegate?: UserRef;
90
102
  description?: string;
91
103
  dueDate?: string;
92
104
  embeds?: import("../utils/embed-parser.js").Embed[];
@@ -95,7 +107,7 @@ export interface LinearIssue {
95
107
  identifier: string;
96
108
  labels: LabelRef[];
97
109
  parentIssue?: IssueRef;
98
- priority: number;
110
+ priority: LinearPriority;
99
111
  project?: ProjectRef;
100
112
  projectMilestone?: MilestoneRef;
101
113
  state?: StateRef;