@alasano/pi-linear 0.3.0 → 0.3.1

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.
@@ -23,6 +23,36 @@ import {
23
23
  renderLinearUpdateDocumentCall,
24
24
  } from '../renderers/documents';
25
25
 
26
+ const DOCUMENT_RELATED_CONTEXT_FIELDS = [
27
+ 'cycleId',
28
+ 'initiativeId',
29
+ 'issueId',
30
+ 'projectId',
31
+ 'releaseId',
32
+ 'resourceFolderId',
33
+ ] as const;
34
+
35
+ type DocumentRelatedContextField = (typeof DOCUMENT_RELATED_CONTEXT_FIELDS)[number];
36
+
37
+ function hasDocumentRelatedContext(
38
+ params: Partial<Record<DocumentRelatedContextField, unknown>>,
39
+ rawInput: JsonObject,
40
+ ): boolean {
41
+ return DOCUMENT_RELATED_CONTEXT_FIELDS.some((field) =>
42
+ Boolean(asString(params[field]) || asString(rawInput[field])),
43
+ );
44
+ }
45
+
46
+ function documentInputBase(rawInput: JsonObject, omitTeamId: boolean): JsonObject {
47
+ if (!omitTeamId) return rawInput;
48
+
49
+ // Linear rejects document inputs with multiple parent/context IDs (for example
50
+ // issueId + teamId). Treat teamId/teamKey as the document context only when no
51
+ // more specific relation is provided; issue/project/etc. imply their context.
52
+ const { teamId: _teamId, ...inputWithoutTeamId } = rawInput;
53
+ return inputWithoutTeamId;
54
+ }
55
+
26
56
  export function documentTools() {
27
57
  return [
28
58
  defineTool({
@@ -124,7 +154,7 @@ export function documentTools() {
124
154
  name: 'linear_create_document',
125
155
  label: 'Linear Create Document',
126
156
  description:
127
- 'Create a document. Supports top-level DocumentCreateInput fields and raw input.',
157
+ 'Create a document. Supports top-level DocumentCreateInput fields and raw input. Use issueId/projectId/etc. for related documents; teamId/teamKey are only for team-scoped documents.',
128
158
  parameters: Type.Object({
129
159
  color: Type.Optional(Type.String()),
130
160
  content: Type.Optional(Type.String()),
@@ -147,9 +177,10 @@ export function documentTools() {
147
177
  async execute(_toolCallId, params, signal, _onUpdate, ctx) {
148
178
  return withLinearAuth(ctx, signal, async (apiKey) => {
149
179
  const rawInput = asObject(params.input) || {};
150
- const rawInputTeamId = asString(rawInput.teamId);
180
+ const hasRelatedContext = hasDocumentRelatedContext(params, rawInput);
181
+ const rawInputTeamId = hasRelatedContext ? undefined : asString(rawInput.teamId);
151
182
  const teamId =
152
- params.teamId || params.teamKey || rawInputTeamId
183
+ !hasRelatedContext && (params.teamId || params.teamKey || rawInputTeamId)
153
184
  ? await resolveTeamId(
154
185
  apiKey,
155
186
  {
@@ -161,7 +192,7 @@ export function documentTools() {
161
192
  : undefined;
162
193
 
163
194
  const input = {
164
- ...rawInput,
195
+ ...documentInputBase(rawInput, hasRelatedContext),
165
196
  ...compactObject({
166
197
  color: params.color,
167
198
  content: params.content,
@@ -218,7 +249,7 @@ export function documentTools() {
218
249
  name: 'linear_update_document',
219
250
  label: 'Linear Update Document',
220
251
  description:
221
- 'Update a document by id. Supports top-level DocumentUpdateInput fields and raw input.',
252
+ 'Update a document by id. Supports top-level DocumentUpdateInput fields and raw input. Use issueId/projectId/etc. for related documents; teamId/teamKey are only for team-scoped documents.',
222
253
  parameters: Type.Object({
223
254
  documentId: Type.String(),
224
255
  color: Type.Optional(Type.String()),
@@ -243,9 +274,10 @@ export function documentTools() {
243
274
  async execute(_toolCallId, params, signal, _onUpdate, ctx) {
244
275
  return withLinearAuth(ctx, signal, async (apiKey) => {
245
276
  const rawInput = asObject(params.input) || {};
246
- const rawInputTeamId = asString(rawInput.teamId);
277
+ const hasRelatedContext = hasDocumentRelatedContext(params, rawInput);
278
+ const rawInputTeamId = hasRelatedContext ? undefined : asString(rawInput.teamId);
247
279
  const teamId =
248
- params.teamId || params.teamKey || rawInputTeamId
280
+ !hasRelatedContext && (params.teamId || params.teamKey || rawInputTeamId)
249
281
  ? await resolveTeamId(
250
282
  apiKey,
251
283
  {
@@ -257,7 +289,7 @@ export function documentTools() {
257
289
  : undefined;
258
290
 
259
291
  const input = {
260
- ...rawInput,
292
+ ...documentInputBase(rawInput, hasRelatedContext),
261
293
  ...compactObject({
262
294
  color: params.color,
263
295
  content: params.content,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alasano/pi-linear",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Linear integration for pi with 55+ tools, multi-workspace auth, and per-tool settings",
5
5
  "keywords": [
6
6
  "pi-package"