runline 0.16.0 → 0.16.2

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.
@@ -1,5 +1,15 @@
1
1
  import * as t from "typebox";
2
2
  import { assertIssueInScope, buildConnArgs, COMMENT_FIELDS, ensureScopeLabelsOnCreateOrReplace, forbidScopeLabelRemoval, gql, ISSUE_FIELDS, ISSUE_LITE, issueHasScope, key, LIST_INPUT_SCHEMA, mergeIssueScopeFilter, } from "./shared.js";
3
+ /**
4
+ * Linear's IssueUpdateInput accepts explicit null for clearable relations
5
+ * (e.g. cycleId: null removes the issue from its cycle). Omitted = leave
6
+ * unchanged, null = clear — the schema must express both.
7
+ */
8
+ function clearable(schema, description) {
9
+ return t.Optional(t.Union([schema, t.Null()], {
10
+ description: `${description}. Pass null to clear`,
11
+ }));
12
+ }
3
13
  export function registerIssueActions(rl) {
4
14
  rl.registerAction("issue.create", {
5
15
  access: "write",
@@ -86,7 +96,7 @@ export function registerIssueActions(rl) {
86
96
  ...LIST_INPUT_SCHEMA,
87
97
  teamId: t.Optional(t.String({ description: "Convenience: filter by team" })),
88
98
  assigneeId: t.Optional(t.String({ description: "Convenience: filter by assignee" })),
89
- }),
99
+ }, { additionalProperties: false }),
90
100
  async execute(input, ctx) {
91
101
  const opts = (input ?? {});
92
102
  // Merge convenience filters into `filter`
@@ -111,9 +121,7 @@ export function registerIssueActions(rl) {
111
121
  }),
112
122
  title: t.Optional(t.String({ description: "The issue title" })),
113
123
  description: t.Optional(t.String({ description: "The issue description in markdown format" })),
114
- assigneeId: t.Optional(t.String({
115
- description: "The identifier of the user to assign the issue to",
116
- })),
124
+ assigneeId: clearable(t.String(), "The identifier of the user to assign the issue to"),
117
125
  stateId: t.Optional(t.String({ description: "The team workflow state of the issue" })),
118
126
  priority: t.Optional(t.Number({
119
127
  description: "Priority. 0=No priority, 1=Urgent, 2=High, 3=Medium, 4=Low",
@@ -127,23 +135,15 @@ export function registerIssueActions(rl) {
127
135
  removedLabelIds: t.Optional(t.Array(t.Unknown(), {
128
136
  description: "The identifiers of issue labels to be removed from this issue",
129
137
  })),
130
- projectId: t.Optional(t.String({ description: "The project associated with the issue" })),
131
- projectMilestoneId: t.Optional(t.String({
132
- description: "The project milestone associated with the issue",
133
- })),
134
- cycleId: t.Optional(t.String({ description: "The cycle associated with the issue" })),
135
- parentId: t.Optional(t.String({
136
- description: "The identifier of the parent issue. UUID or issue identifier (e.g., 'LIN-123')",
137
- })),
138
+ projectId: clearable(t.String(), "The project associated with the issue"),
139
+ projectMilestoneId: clearable(t.String(), "The project milestone associated with the issue"),
140
+ cycleId: clearable(t.String(), "The cycle associated with the issue"),
141
+ parentId: clearable(t.String(), "The identifier of the parent issue. UUID or issue identifier (e.g., 'LIN-123')"),
138
142
  teamId: t.Optional(t.String({
139
143
  description: "The identifier of the team associated with the issue (move issue to a different team)",
140
144
  })),
141
- estimate: t.Optional(t.Number({
142
- description: "The estimated complexity of the issue (Int)",
143
- })),
144
- dueDate: t.Optional(t.String({
145
- description: "The date at which the issue is due (TimelessDate, YYYY-MM-DD)",
146
- })),
145
+ estimate: clearable(t.Number(), "The estimated complexity of the issue (Int)"),
146
+ dueDate: clearable(t.String(), "The date at which the issue is due (TimelessDate, YYYY-MM-DD)"),
147
147
  subscriberIds: t.Optional(t.Array(t.Unknown(), {
148
148
  description: "The identifiers of the users subscribing to this ticket",
149
149
  })),
@@ -153,9 +153,7 @@ export function registerIssueActions(rl) {
153
153
  subIssueSortOrder: t.Optional(t.Number({
154
154
  description: "The position of the issue in its parent's sub-issue list (Float)",
155
155
  })),
156
- snoozedUntilAt: t.Optional(t.String({
157
- description: "The time until which the issue will be snoozed in Triage view (DateTime)",
158
- })),
156
+ snoozedUntilAt: clearable(t.String(), "The time until which the issue will be snoozed in Triage view (DateTime)"),
159
157
  releaseIds: t.Optional(t.Array(t.Unknown(), {
160
158
  description: "The identifiers of the releases associated with this issue (replaces all)",
161
159
  })),
@@ -112,7 +112,7 @@ export const ISSUE_FIELDS = `id identifier title description url priority estima
112
112
  projectMilestone { id name } parent { id identifier }
113
113
  labels { nodes { id name color } }
114
114
  createdAt updatedAt completedAt canceledAt archivedAt`;
115
- export const ISSUE_LITE = `id identifier title url priority state { id name type } assignee { id name } team { key } updatedAt`;
115
+ export const ISSUE_LITE = `id identifier title url priority state { id name type } assignee { id name } team { key } cycle { id number name } updatedAt`;
116
116
  export const COMMENT_FIELDS = `id body url issue { id identifier } user { id name } parent { id } createdAt updatedAt editedAt resolvedAt`;
117
117
  export const STATE_FIELDS = `id name type color position description team { id key }`;
118
118
  export const LABEL_FIELDS = `id name color description isGroup parent { id name } team { id key } createdAt`;
@@ -180,7 +180,9 @@ export function buildConnArgs(opts, filterTypeName) {
180
180
  };
181
181
  }
182
182
  export const LIST_INPUT_SCHEMA = {
183
- limit: t.Optional(t.Number({ description: "Max results (default 50, max 250)" })),
183
+ limit: t.Optional(t.Number({
184
+ description: "Max results per page (default 50, max 250). For more, paginate with `after` = pageInfo.endCursor",
185
+ })),
184
186
  filter: t.Optional(t.Object({}, { description: "Linear filter object (see schema for the resource)" })),
185
187
  includeArchived: t.Optional(t.Boolean({ description: "Include archived items" })),
186
188
  orderBy: t.Optional(t.String({ description: "createdAt | updatedAt" })),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runline",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "description": "Code mode for agents — turn any API or command into a callable action",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -66,8 +66,8 @@
66
66
  "@react-email/components": "^1.0.12",
67
67
  "@react-email/render": "^2.1.0",
68
68
  "playwright": "^1.57.0",
69
- "react": "^19.2.7",
70
- "react-dom": "^19.2.7",
69
+ "react": "^19.0.0",
70
+ "react-dom": "^19.0.0",
71
71
  "sucrase": "^3.35.1"
72
72
  },
73
73
  "peerDependenciesMeta": {