@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
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,82 @@
1
+ /**
2
+ * Public output utilities — secondary entry point for cross-CLI reuse.
3
+ *
4
+ * Other Enrich Layer CLIs (el-slack, el-sheets, el-audit, el-git,
5
+ * el-elasticsearch — currently in the `tools` monorepo) should depend on
6
+ * `@enrichlayer/el-linear` and import this module to share the same
7
+ * `--jq` / `--fields` / `--raw` / `--format summary` behavior and the
8
+ * canonical `{ data, meta }` envelope shape. DEV-3799.
9
+ *
10
+ * Why this exists rather than a separate package: linctl is the OSS
11
+ * canonical source of these patterns (DEV-3619, DEV-3637, DEV-3798); it
12
+ * already publishes to npm and ships compiled JS in `dist/`. Treating it
13
+ * as the host of the shared utilities means there is exactly one
14
+ * implementation, exactly one set of tests, and exactly one place where
15
+ * the envelope contract is documented. Tools-repo CLIs pick it up via
16
+ * `pnpm add @enrichlayer/el-linear` and `import { outputSuccess, ... }
17
+ * from "@enrichlayer/el-linear/output"`.
18
+ *
19
+ * Stable API — semver-tracked. Anything re-exported here MUST stay
20
+ * backwards-compatible across minor releases. Adding exports is fine;
21
+ * renaming or removing them is a breaking change.
22
+ *
23
+ * # Wiring (consumer recipe)
24
+ *
25
+ * Each CLI's `main.ts` registers four global options and a `preAction`
26
+ * hook to read them into the shared state:
27
+ *
28
+ * ```ts
29
+ * import { Command } from "commander";
30
+ * import {
31
+ * setRawMode, setJqFilter, setFieldsFilter, setOutputFormat,
32
+ * } from "@enrichlayer/el-linear/output";
33
+ *
34
+ * const program = new Command()
35
+ * .option("--raw", "strip { data, meta } wrapper from list output")
36
+ * .option("--jq <filter>", "apply a jq filter to the JSON output")
37
+ * .option("--fields <fields>", "comma-separated field allow-list")
38
+ * .option("--format <fmt>", "json | summary", "json");
39
+ *
40
+ * program.hook("preAction", (_thisCommand, actionCommand) => {
41
+ * const o = actionCommand.optsWithGlobals();
42
+ * if (o.raw) setRawMode(true);
43
+ * if (o.jq) setJqFilter(o.jq);
44
+ * if (o.fields) {
45
+ * setFieldsFilter(o.fields.split(",").map((s: string) => s.trim()));
46
+ * }
47
+ * setOutputFormat(o.format === "summary" ? "summary" : "json");
48
+ * });
49
+ * ```
50
+ *
51
+ * Then in each subcommand handler emit results via `outputList(data)` /
52
+ * `outputSingle(data)` / `outputSuccess(payload)`, wrap async actions in
53
+ * `handleAsyncCommand`, and buffer informational messages via
54
+ * `outputWarning`. The shared state in this module takes care of `--jq`,
55
+ * `--fields`, `--raw`, and summary rendering uniformly.
56
+ *
57
+ * Adapt the option names and flags to your CLI's existing conventions —
58
+ * the contract is the four setter calls (`setRawMode`, `setJqFilter`,
59
+ * `setFieldsFilter`, `setOutputFormat`), not the literal `--jq` /
60
+ * `--fields` / `--raw` / `--format` names. A CLI that already exposes
61
+ * `--json` / `--summary` shorthands can keep them as long as the
62
+ * preAction hook ends up calling the same setters with equivalent values.
63
+ *
64
+ * # What is NOT exported
65
+ *
66
+ * - `--format summary` dispatch tables are linctl-specific (Linear
67
+ * resources). Other CLIs that want summary rendering should either
68
+ * ship `--format json` only or register their own per-command summary
69
+ * path that does not consume this module's `setOutputFormat("summary")`.
70
+ * - `outputError` is intentionally internal — it calls `process.exit(1)`
71
+ * directly. Consumers funnel errors through `handleAsyncCommand`, which
72
+ * in turn calls `outputError`. Don't re-export the bare function; the
73
+ * wrapper is the contract.
74
+ * - Token-sanitization (`sanitizeForLog`) is internal to the error path.
75
+ * Consumers that route errors through `handleAsyncCommand` automatically
76
+ * get token redaction on the error path — no separate redactor needed
77
+ * for that case. If a consumer wants sanitization for something OTHER
78
+ * than thrown errors (e.g. a custom debug log), it should pull a small
79
+ * redactor of its own; coupling token redaction to the output layer
80
+ * would make this API surface stickier than it needs to be.
81
+ */
82
+ export { type CliListEnvelope, getOutputFormat, handleAsyncCommand, type ListExtraMeta, type ListMeta, outputList, outputSingle, outputSuccess, outputWarning, resetWarnings, setFieldsFilter, setJqFilter, setOutputFormat, setRawMode, warnIfTruncated, } from "./utils/output.js";
package/dist/output.js ADDED
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Public output utilities — secondary entry point for cross-CLI reuse.
3
+ *
4
+ * Other Enrich Layer CLIs (el-slack, el-sheets, el-audit, el-git,
5
+ * el-elasticsearch — currently in the `tools` monorepo) should depend on
6
+ * `@enrichlayer/el-linear` and import this module to share the same
7
+ * `--jq` / `--fields` / `--raw` / `--format summary` behavior and the
8
+ * canonical `{ data, meta }` envelope shape. DEV-3799.
9
+ *
10
+ * Why this exists rather than a separate package: linctl is the OSS
11
+ * canonical source of these patterns (DEV-3619, DEV-3637, DEV-3798); it
12
+ * already publishes to npm and ships compiled JS in `dist/`. Treating it
13
+ * as the host of the shared utilities means there is exactly one
14
+ * implementation, exactly one set of tests, and exactly one place where
15
+ * the envelope contract is documented. Tools-repo CLIs pick it up via
16
+ * `pnpm add @enrichlayer/el-linear` and `import { outputSuccess, ... }
17
+ * from "@enrichlayer/el-linear/output"`.
18
+ *
19
+ * Stable API — semver-tracked. Anything re-exported here MUST stay
20
+ * backwards-compatible across minor releases. Adding exports is fine;
21
+ * renaming or removing them is a breaking change.
22
+ *
23
+ * # Wiring (consumer recipe)
24
+ *
25
+ * Each CLI's `main.ts` registers four global options and a `preAction`
26
+ * hook to read them into the shared state:
27
+ *
28
+ * ```ts
29
+ * import { Command } from "commander";
30
+ * import {
31
+ * setRawMode, setJqFilter, setFieldsFilter, setOutputFormat,
32
+ * } from "@enrichlayer/el-linear/output";
33
+ *
34
+ * const program = new Command()
35
+ * .option("--raw", "strip { data, meta } wrapper from list output")
36
+ * .option("--jq <filter>", "apply a jq filter to the JSON output")
37
+ * .option("--fields <fields>", "comma-separated field allow-list")
38
+ * .option("--format <fmt>", "json | summary", "json");
39
+ *
40
+ * program.hook("preAction", (_thisCommand, actionCommand) => {
41
+ * const o = actionCommand.optsWithGlobals();
42
+ * if (o.raw) setRawMode(true);
43
+ * if (o.jq) setJqFilter(o.jq);
44
+ * if (o.fields) {
45
+ * setFieldsFilter(o.fields.split(",").map((s: string) => s.trim()));
46
+ * }
47
+ * setOutputFormat(o.format === "summary" ? "summary" : "json");
48
+ * });
49
+ * ```
50
+ *
51
+ * Then in each subcommand handler emit results via `outputList(data)` /
52
+ * `outputSingle(data)` / `outputSuccess(payload)`, wrap async actions in
53
+ * `handleAsyncCommand`, and buffer informational messages via
54
+ * `outputWarning`. The shared state in this module takes care of `--jq`,
55
+ * `--fields`, `--raw`, and summary rendering uniformly.
56
+ *
57
+ * Adapt the option names and flags to your CLI's existing conventions —
58
+ * the contract is the four setter calls (`setRawMode`, `setJqFilter`,
59
+ * `setFieldsFilter`, `setOutputFormat`), not the literal `--jq` /
60
+ * `--fields` / `--raw` / `--format` names. A CLI that already exposes
61
+ * `--json` / `--summary` shorthands can keep them as long as the
62
+ * preAction hook ends up calling the same setters with equivalent values.
63
+ *
64
+ * # What is NOT exported
65
+ *
66
+ * - `--format summary` dispatch tables are linctl-specific (Linear
67
+ * resources). Other CLIs that want summary rendering should either
68
+ * ship `--format json` only or register their own per-command summary
69
+ * path that does not consume this module's `setOutputFormat("summary")`.
70
+ * - `outputError` is intentionally internal — it calls `process.exit(1)`
71
+ * directly. Consumers funnel errors through `handleAsyncCommand`, which
72
+ * in turn calls `outputError`. Don't re-export the bare function; the
73
+ * wrapper is the contract.
74
+ * - Token-sanitization (`sanitizeForLog`) is internal to the error path.
75
+ * Consumers that route errors through `handleAsyncCommand` automatically
76
+ * get token redaction on the error path — no separate redactor needed
77
+ * for that case. If a consumer wants sanitization for something OTHER
78
+ * than thrown errors (e.g. a custom debug log), it should pull a small
79
+ * redactor of its own; coupling token redaction to the output layer
80
+ * would make this API surface stickier than it needs to be.
81
+ */
82
+ export { getOutputFormat, handleAsyncCommand, outputList, outputSingle, outputSuccess, outputWarning, resetWarnings, setFieldsFilter, setJqFilter, setOutputFormat, setRawMode, warnIfTruncated, } from "./utils/output.js";
@@ -2,25 +2,30 @@
2
2
  * Typed response shapes for the queries in `./comments.ts`.
3
3
  * See `./issues-types.ts` for the rationale (ALL-937).
4
4
  */
5
- export interface CommentUserRef {
5
+ interface CommentUserRef {
6
6
  id: string;
7
7
  name: string;
8
8
  displayName: string | null;
9
9
  url: string | null;
10
10
  }
11
11
  /**
12
- * Mirrors the comment selection set used by `LIST_COMMENTS_QUERY`,
13
- * `CREATE_COMMENT_MUTATION`, and (with `issue` overlay)
14
- * `UPDATE_COMMENT_MUTATION`.
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.
15
20
  */
16
- export interface CommentNode {
21
+ export interface CommentResourceNode {
17
22
  id: string;
18
23
  body: string;
19
24
  createdAt: string;
20
25
  updatedAt: string;
21
26
  user: CommentUserRef;
22
27
  }
23
- export interface UpdatedCommentNode extends CommentNode {
28
+ interface UpdatedCommentResourceNode extends CommentResourceNode {
24
29
  issue: {
25
30
  id: string;
26
31
  identifier: string;
@@ -31,19 +36,20 @@ export interface ListCommentsResponse {
31
36
  id: string;
32
37
  identifier: string;
33
38
  comments: {
34
- nodes: CommentNode[];
39
+ nodes: CommentResourceNode[];
35
40
  };
36
41
  } | null;
37
42
  }
38
43
  export interface CreateCommentResponse {
39
44
  commentCreate: {
40
45
  success: boolean;
41
- comment: CommentNode | null;
46
+ comment: CommentResourceNode | null;
42
47
  };
43
48
  }
44
49
  export interface UpdateCommentResponse {
45
50
  commentUpdate: {
46
51
  success: boolean;
47
- comment: UpdatedCommentNode | null;
52
+ comment: UpdatedCommentResourceNode | null;
48
53
  };
49
54
  }
55
+ 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}
@@ -6,15 +6,15 @@
6
6
  * `Record<string, unknown>` casts. See `./issues-types.ts` for the
7
7
  * full rationale and pattern (ALL-937).
8
8
  */
9
- export interface DocumentCreatorRef {
9
+ interface DocumentCreatorRef {
10
10
  id: string;
11
11
  name: string;
12
12
  }
13
- export interface DocumentProjectRef {
13
+ interface DocumentProjectRef {
14
14
  id: string;
15
15
  name: string;
16
16
  }
17
- export interface DocumentIssueRef {
17
+ interface DocumentIssueRef {
18
18
  id: string;
19
19
  identifier: string;
20
20
  title: string;
@@ -59,3 +59,4 @@ export interface DeleteDocumentResponse {
59
59
  success: boolean;
60
60
  };
61
61
  }
62
+ export {};
@@ -7,38 +7,38 @@
7
7
  * fields whose types contain fields…). We model the recursion
8
8
  * shallowly — only as deep as the queries actually select.
9
9
  */
10
- export interface IntrospectTypeRefShallow {
10
+ interface IntrospectTypeRefShallow {
11
11
  name: string | null;
12
12
  kind: string;
13
13
  ofType: {
14
14
  name: string | null;
15
15
  } | null;
16
16
  }
17
- export interface IntrospectTypeRef {
17
+ interface IntrospectTypeRef {
18
18
  name: string | null;
19
19
  kind: string;
20
20
  ofType: IntrospectTypeRefShallow | null;
21
21
  }
22
- export interface IntrospectArg {
22
+ interface IntrospectArg {
23
23
  name: string;
24
24
  type: IntrospectTypeRef;
25
25
  }
26
- export interface IntrospectField {
26
+ interface IntrospectField {
27
27
  name: string;
28
28
  description: string | null;
29
29
  type: IntrospectTypeRef;
30
30
  args: IntrospectArg[];
31
31
  }
32
- export interface IntrospectEnumValue {
32
+ interface IntrospectEnumValue {
33
33
  name: string;
34
34
  description: string | null;
35
35
  }
36
- export interface IntrospectInputField {
36
+ interface IntrospectInputField {
37
37
  name: string;
38
38
  type: IntrospectTypeRef;
39
39
  }
40
40
  /** Mirrors the inner `__type` shape selected by `INTROSPECT_TYPE_QUERY`. */
41
- export interface IntrospectTypeNode {
41
+ interface IntrospectTypeNode {
42
42
  name: string;
43
43
  kind: string;
44
44
  description: string | null;
@@ -55,3 +55,4 @@ export interface IntrospectRootResponse {
55
55
  fields: IntrospectField[];
56
56
  } | null;
57
57
  }
58
+ export {};
@@ -20,46 +20,66 @@
20
20
  *
21
21
  * Refs ALL-937.
22
22
  */
23
+ import type { LinearPriority } from "../types/linear.js";
23
24
  /** A reference to a related entity — id + display fields. */
24
- export interface IdNameRef {
25
+ interface IdNameRef {
25
26
  id: string;
26
27
  name: string;
27
28
  }
28
- export interface IdKeyNameRef {
29
+ interface IdKeyNameRef {
29
30
  id: string;
30
31
  key: string;
31
32
  name: string;
32
33
  }
33
- export interface IdIdentifierTitleRef {
34
+ interface IdIdentifierTitleRef {
34
35
  id: string;
35
36
  identifier: string;
36
37
  title: string;
37
38
  }
38
- export interface AssigneeNode {
39
+ interface AssigneeNode {
39
40
  id: string;
40
41
  name: string;
41
42
  url?: string;
42
43
  }
43
- export interface CommentNode {
44
+ /**
45
+ * Comment shape as embedded inside `COMPLETE_ISSUE_WITH_COMMENTS_FRAGMENT`
46
+ * (i.e. comments fetched as part of an issue query). Distinct from
47
+ * `comments-types.ts:CommentResourceNode`, which is the shape returned by
48
+ * the standalone comment queries (`LIST_COMMENTS_QUERY`,
49
+ * `CREATE_COMMENT_MUTATION`, `UPDATE_COMMENT_MUTATION`). The two have
50
+ * incompatible `user` shapes — this one allows `null` and uses the
51
+ * issue-page \"assignee\"-style fields, while the standalone resource
52
+ * shape always populates `user` and includes the comment-author-only
53
+ * `CommentUserRef` fields (DEV-4068 T2).
54
+ */
55
+ export interface IssueCommentNode {
44
56
  id: string;
45
57
  body: string;
46
58
  createdAt: string;
47
59
  updatedAt: string;
48
60
  user: AssigneeNode | null;
49
61
  }
50
- export interface CycleNode {
62
+ interface CycleNode {
51
63
  id: string;
52
64
  name: string | null;
53
65
  number: number;
54
66
  }
55
- export interface ProjectMilestoneNode {
67
+ interface ProjectMilestoneNode {
56
68
  id: string;
57
69
  name: string;
58
70
  targetDate: string | null;
59
71
  }
60
- export interface IssueSummary {
72
+ /**
73
+ * Linear's documented generation states for issue summaries. If Linear
74
+ * adds a new state in the future the runtime API would deserialize the
75
+ * new string verbatim — TypeScript wouldn't catch the divergence, but
76
+ * the typical `=== "completed"` check keeps working safely. Widen the
77
+ * union here when Linear documents a new state.
78
+ */
79
+ type IssueSummaryGenerationStatus = "completed" | "pending" | "failed";
80
+ interface IssueSummary {
61
81
  content: unknown;
62
- generationStatus: "completed" | "pending" | "failed" | string;
82
+ generationStatus: IssueSummaryGenerationStatus;
63
83
  }
64
84
  /**
65
85
  * Mirrors `COMPLETE_ISSUE_FRAGMENT` from `src/queries/common.ts`.
@@ -74,7 +94,7 @@ export interface IssueNode {
74
94
  description: string | null;
75
95
  summary: IssueSummary | null;
76
96
  branchName: string;
77
- priority: number;
97
+ priority: LinearPriority;
78
98
  estimate: number | null;
79
99
  dueDate: string | null;
80
100
  url: string;
@@ -82,6 +102,7 @@ export interface IssueNode {
82
102
  updatedAt: string;
83
103
  state: IdNameRef | null;
84
104
  assignee: AssigneeNode | null;
105
+ delegate: AssigneeNode | null;
85
106
  team: IdKeyNameRef | null;
86
107
  project: IdNameRef | null;
87
108
  labels: {
@@ -100,7 +121,7 @@ export interface IssueNode {
100
121
  */
101
122
  export interface IssueWithCommentsNode extends IssueNode {
102
123
  comments: {
103
- nodes: CommentNode[];
124
+ nodes: IssueCommentNode[];
104
125
  };
105
126
  }
106
127
  /** Response shape for `GET_ISSUE_BY_ID_QUERY`. */
@@ -125,12 +146,6 @@ export interface SearchIssuesResponse {
125
146
  nodes: IssueNode[];
126
147
  };
127
148
  }
128
- /**
129
- * Response shape for `FILTERED_SEARCH_ISSUES_QUERY`. Same shape as
130
- * `GetIssuesResponse` (both return `issues.nodes`) but kept as a
131
- * named alias so the call site documents intent.
132
- */
133
- export type FilteredSearchIssuesResponse = GetIssuesResponse;
134
149
  /** Response shape for `CREATE_ISSUE_MUTATION`. */
135
150
  export interface CreateIssueResponse {
136
151
  issueCreate: {
@@ -148,7 +163,7 @@ export interface UpdateIssueResponse {
148
163
  export interface IssueArchiveEntity {
149
164
  id: string;
150
165
  }
151
- export interface IssueArchivePayload {
166
+ interface IssueArchivePayload {
152
167
  success: boolean;
153
168
  lastSyncId: number;
154
169
  entity: IssueArchiveEntity | null;
@@ -169,6 +184,35 @@ export interface GetIssueTeamResponse {
169
184
  } | null;
170
185
  } | null;
171
186
  }
187
+ type WorkflowStateType = "triage" | "backlog" | "unstarted" | "started" | "completed" | "canceled";
188
+ export interface IssueStartContextResponse {
189
+ issue: {
190
+ id: string;
191
+ identifier: string;
192
+ state: {
193
+ id: string;
194
+ name: string;
195
+ type: WorkflowStateType;
196
+ } | null;
197
+ team: {
198
+ id: string;
199
+ key: string;
200
+ name: string;
201
+ } | null;
202
+ delegate: AssigneeNode | null;
203
+ } | null;
204
+ }
205
+ export interface TeamStartedStatusesResponse {
206
+ team: {
207
+ states: {
208
+ nodes: {
209
+ id: string;
210
+ name: string;
211
+ position: number;
212
+ }[];
213
+ };
214
+ } | null;
215
+ }
172
216
  /**
173
217
  * Issue summary returned by `GET_ISSUE_RELATIONS_QUERY` on the
174
218
  * `relatedIssue` / `issue` peer of each relation. Smaller than
@@ -182,7 +226,7 @@ export interface RelationPeerNode {
182
226
  id: string;
183
227
  name: string;
184
228
  } | null;
185
- priority: number | null;
229
+ priority: LinearPriority | null;
186
230
  assignee: {
187
231
  id: string;
188
232
  name: string;
@@ -207,7 +251,7 @@ export interface BatchResolveProjectMilestoneRef {
207
251
  id: string;
208
252
  name: string;
209
253
  }
210
- export interface BatchResolveProjectNode {
254
+ interface BatchResolveProjectNode {
211
255
  id: string;
212
256
  name: string;
213
257
  /** Present on `BATCH_RESOLVE_FOR_CREATE_QUERY`. */
@@ -230,7 +274,7 @@ export interface BatchResolveLabelNode {
230
274
  id: string;
231
275
  } | null;
232
276
  }
233
- export interface BatchResolveIssueForUpdate {
277
+ interface BatchResolveIssueForUpdate {
234
278
  id: string;
235
279
  identifier: string;
236
280
  team: {
@@ -258,10 +302,13 @@ export interface BatchResolveForCreateResponse {
258
302
  name: string;
259
303
  }[];
260
304
  };
261
- projects: {
305
+ projectsByName?: {
306
+ nodes: BatchResolveProjectNode[];
307
+ };
308
+ projectsById?: {
262
309
  nodes: BatchResolveProjectNode[];
263
310
  };
264
- milestones: {
311
+ milestones?: {
265
312
  nodes: BatchResolveProjectMilestoneRef[];
266
313
  };
267
314
  parentIssues: {
@@ -272,6 +319,13 @@ export interface BatchResolveForCreateResponse {
272
319
  };
273
320
  }
274
321
  export interface BatchResolveForSearchResponse {
322
+ delegates?: {
323
+ nodes: {
324
+ id: string;
325
+ name: string;
326
+ email: string;
327
+ }[];
328
+ };
275
329
  teams: {
276
330
  nodes: {
277
331
  id: string;
@@ -279,7 +333,7 @@ export interface BatchResolveForSearchResponse {
279
333
  name: string;
280
334
  }[];
281
335
  };
282
- projects: {
336
+ projects?: {
283
337
  nodes: BatchResolveProjectNode[];
284
338
  };
285
339
  users: {
@@ -291,10 +345,13 @@ export interface BatchResolveForSearchResponse {
291
345
  };
292
346
  }
293
347
  export interface BatchResolveForUpdateResponse {
294
- projects: {
348
+ projectsByName?: {
349
+ nodes: BatchResolveProjectNode[];
350
+ };
351
+ projectsById?: {
295
352
  nodes: BatchResolveProjectNode[];
296
353
  };
297
- milestones: {
354
+ milestones?: {
298
355
  nodes: BatchResolveProjectMilestoneRef[];
299
356
  };
300
357
  issues: {
@@ -338,6 +395,13 @@ export interface BatchResolveResult {
338
395
  email: string;
339
396
  }[];
340
397
  };
398
+ delegates?: {
399
+ nodes: {
400
+ id: string;
401
+ name: string;
402
+ email: string;
403
+ }[];
404
+ };
341
405
  issues?: {
342
406
  nodes: BatchResolveIssueForUpdate[];
343
407
  };
@@ -394,7 +458,7 @@ export interface ScanIssuesResponse {
394
458
  }[];
395
459
  };
396
460
  }
397
- export interface IssueStateSpanNode {
461
+ interface IssueStateSpanNode {
398
462
  state: {
399
463
  id: string;
400
464
  name: string;
@@ -414,3 +478,4 @@ export interface GetIssueStateHistoryResponse {
414
478
  };
415
479
  } | null;
416
480
  }
481
+ export {};