@plotday/tool-linear 0.2.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Plot Technologies Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # Linear Tool for Plot
2
+
3
+ Sync your Linear teams and issues with Plot.
4
+
5
+ ## Features
6
+
7
+ - OAuth authentication with Linear
8
+ - Sync issues from Linear teams to Plot activities
9
+ - Real-time updates via webhooks
10
+ - Issue comments synced as activity notes
11
+ - Automatic issue state mapping
12
+
13
+ ## Usage
14
+
15
+ ```typescript
16
+ import { Linear } from "@plotday/tool-linear";
17
+ import { Twist, type ToolBuilder } from "@plotday/twister";
18
+
19
+ export default class MyTwist extends Twist<MyTwist> {
20
+ build(build: ToolBuilder) {
21
+ return {
22
+ linear: build(Linear),
23
+ };
24
+ }
25
+
26
+ async activate() {
27
+ // Request Linear authorization
28
+ const authLink = await this.tools.linear.requestAuth(this.onAuthComplete);
29
+ // ... show authLink to user
30
+ }
31
+
32
+ async onAuthComplete(auth: { authToken: string }) {
33
+ // Get available teams
34
+ const projects = await this.tools.linear.getProjects(auth.authToken);
35
+
36
+ // Start syncing a team
37
+ await this.tools.linear.startSync(
38
+ auth.authToken,
39
+ projects[0].id,
40
+ this.onIssue
41
+ );
42
+ }
43
+
44
+ async onIssue(issue: NewActivityWithNotes) {
45
+ // Handle synced issue
46
+ await this.tools.plot.createActivity(issue);
47
+ }
48
+ }
49
+ ```
50
+
51
+ ## License
52
+
53
+ MIT
@@ -0,0 +1 @@
1
+ export { default, Linear } from "./linear";
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { default, Linear } from "./linear";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,88 @@
1
+ import { type ActivityLink, type NewActivityWithNotes } from "@plotday/twister";
2
+ import type { Project, ProjectAuth, ProjectSyncOptions, ProjectTool } from "@plotday/twister/common/projects";
3
+ import { Tool, type ToolBuilder } from "@plotday/twister/tool";
4
+ import { Callbacks } from "@plotday/twister/tools/callbacks";
5
+ import { Integrations } from "@plotday/twister/tools/integrations";
6
+ import { Network } from "@plotday/twister/tools/network";
7
+ import { Plot } from "@plotday/twister/tools/plot";
8
+ import { Tasks } from "@plotday/twister/tools/tasks";
9
+ /**
10
+ * Linear project management tool
11
+ *
12
+ * Implements the ProjectTool interface for syncing Linear teams and issues
13
+ * with Plot activities.
14
+ */
15
+ export declare class Linear extends Tool<Linear> implements ProjectTool {
16
+ build(build: ToolBuilder): {
17
+ integrations: Promise<Integrations>;
18
+ network: Promise<Network>;
19
+ callbacks: Promise<Callbacks>;
20
+ tasks: Promise<Tasks>;
21
+ plot: Promise<Plot>;
22
+ };
23
+ /**
24
+ * Create Linear API client with auth token
25
+ */
26
+ private getClient;
27
+ /**
28
+ * Request Linear OAuth authorization
29
+ */
30
+ requestAuth<TCallback extends (auth: ProjectAuth, ...args: any[]) => any>(callback: TCallback, ...extraArgs: TCallback extends (auth: any, ...rest: infer R) => any ? R : []): Promise<ActivityLink>;
31
+ /**
32
+ * Handle successful OAuth authorization
33
+ */
34
+ private onAuthSuccess;
35
+ /**
36
+ * Get list of Linear teams (projects)
37
+ */
38
+ getProjects(authToken: string): Promise<Project[]>;
39
+ /**
40
+ * Start syncing issues from a Linear team
41
+ */
42
+ startSync<TCallback extends (issue: NewActivityWithNotes, ...args: any[]) => any>(authToken: string, projectId: string, callback: TCallback, options?: ProjectSyncOptions, ...extraArgs: TCallback extends (issue: any, ...rest: infer R) => any ? R : []): Promise<void>;
43
+ /**
44
+ * Setup Linear webhook for real-time updates
45
+ */
46
+ private setupLinearWebhook;
47
+ /**
48
+ * Initialize batch sync process
49
+ */
50
+ private startBatchSync;
51
+ /**
52
+ * Process a batch of issues
53
+ */
54
+ private syncBatch;
55
+ /**
56
+ * Convert a Linear issue to a Plot Activity
57
+ */
58
+ private convertIssueToActivity;
59
+ /**
60
+ * Update issue with new values
61
+ *
62
+ * @param authToken - Authorization token
63
+ * @param update - ActivityUpdate with changed fields
64
+ */
65
+ updateIssue(authToken: string, update: import("@plotday/twister").ActivityUpdate): Promise<void>;
66
+ /**
67
+ * Add a comment to a Linear issue
68
+ *
69
+ * @param authToken - Authorization token
70
+ * @param issueId - Linear issue ID
71
+ * @param body - Comment text (markdown supported)
72
+ */
73
+ addIssueComment(authToken: string, issueId: string, body: string): Promise<void>;
74
+ /**
75
+ * Verify Linear webhook signature
76
+ * Linear uses HMAC-SHA256 with the webhook secret
77
+ */
78
+ private verifyLinearSignature;
79
+ /**
80
+ * Handle incoming webhook events from Linear
81
+ */
82
+ private onWebhook;
83
+ /**
84
+ * Stop syncing a Linear team
85
+ */
86
+ stopSync(authToken: string, projectId: string): Promise<void>;
87
+ }
88
+ export default Linear;
package/dist/linear.js ADDED
@@ -0,0 +1,378 @@
1
+ import { LinearClient } from "@linear/sdk";
2
+ import { ActivityType, } from "@plotday/twister";
3
+ import { Tool } from "@plotday/twister/tool";
4
+ import { Callbacks } from "@plotday/twister/tools/callbacks";
5
+ import { AuthLevel, AuthProvider, Integrations, } from "@plotday/twister/tools/integrations";
6
+ import { Network } from "@plotday/twister/tools/network";
7
+ import { ContactAccess, Plot } from "@plotday/twister/tools/plot";
8
+ import { Tasks } from "@plotday/twister/tools/tasks";
9
+ /**
10
+ * Linear project management tool
11
+ *
12
+ * Implements the ProjectTool interface for syncing Linear teams and issues
13
+ * with Plot activities.
14
+ */
15
+ export class Linear extends Tool {
16
+ build(build) {
17
+ return {
18
+ integrations: build(Integrations),
19
+ network: build(Network, { urls: ["https://api.linear.app/*"] }),
20
+ callbacks: build(Callbacks),
21
+ tasks: build(Tasks),
22
+ plot: build(Plot, { contact: { access: ContactAccess.Write } }),
23
+ };
24
+ }
25
+ /**
26
+ * Create Linear API client with auth token
27
+ */
28
+ async getClient(authToken) {
29
+ const authorization = await this.get(`authorization:${authToken}`);
30
+ if (!authorization) {
31
+ throw new Error("Authorization no longer available");
32
+ }
33
+ const token = await this.tools.integrations.get(authorization);
34
+ if (!token) {
35
+ throw new Error("Authorization no longer available");
36
+ }
37
+ return new LinearClient({ accessToken: token.token });
38
+ }
39
+ /**
40
+ * Request Linear OAuth authorization
41
+ */
42
+ async requestAuth(callback, ...extraArgs) {
43
+ const linearScopes = ["read", "write"];
44
+ // Generate opaque token for authorization
45
+ const authToken = crypto.randomUUID();
46
+ const callbackToken = await this.tools.callbacks.createFromParent(callback, ...extraArgs);
47
+ // Request auth and return the activity link
48
+ return await this.tools.integrations.request({
49
+ provider: AuthProvider.Linear,
50
+ level: AuthLevel.User,
51
+ scopes: linearScopes,
52
+ }, this.onAuthSuccess, authToken, callbackToken);
53
+ }
54
+ /**
55
+ * Handle successful OAuth authorization
56
+ */
57
+ async onAuthSuccess(authorization, authToken, callbackToken) {
58
+ // Store authorization for later use
59
+ await this.set(`authorization:${authToken}`, authorization);
60
+ // Execute the callback with the auth token
61
+ await this.run(callbackToken, { authToken });
62
+ }
63
+ /**
64
+ * Get list of Linear teams (projects)
65
+ */
66
+ async getProjects(authToken) {
67
+ const client = await this.getClient(authToken);
68
+ const teams = await client.teams();
69
+ return teams.nodes.map((team) => ({
70
+ id: team.id,
71
+ name: team.name,
72
+ description: team.description || null,
73
+ key: team.key,
74
+ }));
75
+ }
76
+ /**
77
+ * Start syncing issues from a Linear team
78
+ */
79
+ async startSync(authToken, projectId, callback, options, ...extraArgs) {
80
+ // Setup webhook for real-time updates
81
+ await this.setupLinearWebhook(authToken, projectId);
82
+ // Store callback for webhook processing
83
+ const callbackToken = await this.tools.callbacks.createFromParent(callback, ...extraArgs);
84
+ await this.set(`callback_${projectId}`, callbackToken);
85
+ // Start initial batch sync
86
+ await this.startBatchSync(authToken, projectId, options);
87
+ }
88
+ /**
89
+ * Setup Linear webhook for real-time updates
90
+ */
91
+ async setupLinearWebhook(authToken, projectId) {
92
+ try {
93
+ const client = await this.getClient(authToken);
94
+ // Create webhook URL first (Linear requires valid URL at creation time)
95
+ const webhookUrl = await this.tools.network.createWebhook({
96
+ callback: this.onWebhook,
97
+ extraArgs: [projectId, authToken],
98
+ });
99
+ // Skip webhook setup for localhost (development mode)
100
+ if (webhookUrl.includes("localhost") ||
101
+ webhookUrl.includes("127.0.0.1")) {
102
+ console.log("Skipping webhook setup for localhost URL:", webhookUrl);
103
+ return;
104
+ }
105
+ // Create webhook in Linear with the actual URL
106
+ const webhookPayload = await client.createWebhook({
107
+ url: webhookUrl,
108
+ teamId: projectId,
109
+ resourceTypes: ["Issue", "Comment"],
110
+ });
111
+ // Extract and store webhook ID and secret
112
+ const webhook = await webhookPayload.webhook;
113
+ if (webhook?.id) {
114
+ await this.set(`webhook_id_${projectId}`, webhook.id);
115
+ }
116
+ if (webhook?.secret) {
117
+ await this.set(`webhook_secret_${projectId}`, webhook.secret);
118
+ }
119
+ }
120
+ catch (error) {
121
+ console.warn("Failed to set up Linear webhook, continuing with sync:", error);
122
+ }
123
+ }
124
+ /**
125
+ * Initialize batch sync process
126
+ */
127
+ async startBatchSync(authToken, projectId, options) {
128
+ // Initialize sync state
129
+ await this.set(`sync_state_${projectId}`, {
130
+ after: null,
131
+ batchNumber: 1,
132
+ issuesProcessed: 0,
133
+ initialSync: true,
134
+ });
135
+ // Queue first batch
136
+ const batchCallback = await this.callback(this.syncBatch, authToken, projectId, options);
137
+ await this.tools.tasks.runTask(batchCallback);
138
+ }
139
+ /**
140
+ * Process a batch of issues
141
+ */
142
+ async syncBatch(authToken, projectId, options) {
143
+ const state = await this.get(`sync_state_${projectId}`);
144
+ if (!state) {
145
+ throw new Error(`Sync state not found for project ${projectId}`);
146
+ }
147
+ // Retrieve callback token from storage
148
+ const callbackToken = await this.get(`callback_${projectId}`);
149
+ if (!callbackToken) {
150
+ throw new Error(`Callback token not found for project ${projectId}`);
151
+ }
152
+ const client = await this.getClient(authToken);
153
+ const team = await client.team(projectId);
154
+ // Build filter
155
+ const filter = {};
156
+ if (options?.timeMin) {
157
+ filter.createdAt = { gte: options.timeMin };
158
+ }
159
+ // Fetch batch of issues (50 at a time)
160
+ const issuesConnection = await team.issues({
161
+ first: 50,
162
+ after: state.after || undefined,
163
+ filter: Object.keys(filter).length > 0 ? filter : undefined,
164
+ });
165
+ // Process each issue
166
+ for (const issue of issuesConnection.nodes) {
167
+ const activityWithNotes = await this.convertIssueToActivity(issue, projectId);
168
+ // Set unread based on sync type (false for initial sync to avoid notification overload)
169
+ activityWithNotes.unread = !state.initialSync;
170
+ // Execute the callback using the callback token
171
+ await this.tools.callbacks.run(callbackToken, activityWithNotes);
172
+ }
173
+ // Check if more pages
174
+ if (issuesConnection.pageInfo.hasNextPage) {
175
+ await this.set(`sync_state_${projectId}`, {
176
+ after: issuesConnection.pageInfo.endCursor,
177
+ batchNumber: state.batchNumber + 1,
178
+ issuesProcessed: state.issuesProcessed + issuesConnection.nodes.length,
179
+ initialSync: state.initialSync,
180
+ });
181
+ // Queue next batch
182
+ const nextBatch = await this.callback(this.syncBatch, authToken, projectId, options);
183
+ await this.tools.tasks.runTask(nextBatch);
184
+ }
185
+ else {
186
+ // Initial sync is complete - cleanup sync state
187
+ await this.clear(`sync_state_${projectId}`);
188
+ }
189
+ }
190
+ /**
191
+ * Convert a Linear issue to a Plot Activity
192
+ */
193
+ async convertIssueToActivity(issue, projectId) {
194
+ const state = await issue.state;
195
+ const assignee = await issue.assignee;
196
+ const comments = await issue.comments();
197
+ // Build notes array: description + comments
198
+ const notes = [];
199
+ if (issue.description) {
200
+ notes.push({ content: issue.description });
201
+ }
202
+ for (const comment of comments.nodes) {
203
+ notes.push({ content: comment.body });
204
+ }
205
+ // Ensure at least one note exists
206
+ if (notes.length === 0) {
207
+ notes.push({ content: "" });
208
+ }
209
+ return {
210
+ type: ActivityType.Action,
211
+ title: issue.title,
212
+ source: `linear:issue:${projectId}:${issue.id}`,
213
+ doneAt: state?.name === "Done" || state?.name === "Completed"
214
+ ? new Date()
215
+ : null,
216
+ notes,
217
+ };
218
+ }
219
+ /**
220
+ * Update issue with new values
221
+ *
222
+ * @param authToken - Authorization token
223
+ * @param update - ActivityUpdate with changed fields
224
+ */
225
+ async updateIssue(authToken, update) {
226
+ // Extract Linear issue ID from source
227
+ const issueId = update.source?.split(":").pop();
228
+ if (!issueId) {
229
+ throw new Error("Invalid source format for Linear issue");
230
+ }
231
+ const client = await this.getClient(authToken);
232
+ const issue = await client.issue(issueId);
233
+ const updateFields = {};
234
+ // Handle title
235
+ if (update.title !== undefined) {
236
+ updateFields.title = update.title;
237
+ }
238
+ // Handle assignee
239
+ if (update.assignee !== undefined) {
240
+ updateFields.assigneeId = update.assignee?.id || null;
241
+ }
242
+ // Handle state based on start + doneAt combination
243
+ if (update.start !== undefined || update.doneAt !== undefined) {
244
+ const team = await issue.team;
245
+ if (team) {
246
+ const states = await team.states();
247
+ let targetState;
248
+ // Determine target state based on combination
249
+ if (update.doneAt !== undefined && update.doneAt !== null) {
250
+ // Completed
251
+ targetState = states.nodes.find((s) => s.name === "Done" ||
252
+ s.name === "Completed" ||
253
+ s.type === "completed");
254
+ }
255
+ else if (update.start !== undefined && update.start !== null) {
256
+ // In Progress (has start date, not done)
257
+ targetState = states.nodes.find((s) => s.name === "In Progress" || s.type === "started");
258
+ }
259
+ else if ((update.start !== undefined && update.start === null) ||
260
+ (update.doneAt !== undefined && update.doneAt === null)) {
261
+ // Backlog/Todo (no start date, not done)
262
+ targetState = states.nodes.find((s) => s.name === "Todo" ||
263
+ s.name === "Backlog" ||
264
+ s.type === "unstarted");
265
+ }
266
+ if (targetState) {
267
+ updateFields.stateId = targetState.id;
268
+ }
269
+ }
270
+ }
271
+ // Apply updates if any fields changed
272
+ if (Object.keys(updateFields).length > 0) {
273
+ await client.updateIssue(issueId, updateFields);
274
+ }
275
+ }
276
+ /**
277
+ * Add a comment to a Linear issue
278
+ *
279
+ * @param authToken - Authorization token
280
+ * @param issueId - Linear issue ID
281
+ * @param body - Comment text (markdown supported)
282
+ */
283
+ async addIssueComment(authToken, issueId, body) {
284
+ const client = await this.getClient(authToken);
285
+ await client.createComment({
286
+ issueId,
287
+ body,
288
+ });
289
+ }
290
+ /**
291
+ * Verify Linear webhook signature
292
+ * Linear uses HMAC-SHA256 with the webhook secret
293
+ */
294
+ async verifyLinearSignature(signature, rawBody, secret, webhookTimestamp) {
295
+ if (!signature) {
296
+ console.warn("Linear webhook missing signature header");
297
+ return false;
298
+ }
299
+ // Verify timestamp to prevent replay attacks (within 60 seconds)
300
+ const currentTime = Date.now();
301
+ const timeDiff = Math.abs(currentTime - webhookTimestamp);
302
+ if (timeDiff > 60000) {
303
+ console.warn(`Linear webhook timestamp too old: ${timeDiff}ms (max 60000ms)`);
304
+ return false;
305
+ }
306
+ // Compute HMAC-SHA256 signature
307
+ const encoder = new TextEncoder();
308
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
309
+ const signatureBytes = await crypto.subtle.sign("HMAC", key, encoder.encode(rawBody));
310
+ // Convert to hex string
311
+ const expectedSignature = Array.from(new Uint8Array(signatureBytes))
312
+ .map((b) => b.toString(16).padStart(2, "0"))
313
+ .join("");
314
+ // Constant-time comparison
315
+ return signature === expectedSignature;
316
+ }
317
+ /**
318
+ * Handle incoming webhook events from Linear
319
+ */
320
+ async onWebhook(request, projectId, authToken, webhookSecret) {
321
+ const payload = request.body;
322
+ // Verify webhook signature
323
+ // Linear sends Linear-Signature header (not X-Linear-Signature)
324
+ const secret = webhookSecret || (await this.get(`webhook_secret_${projectId}`));
325
+ if (secret && request.rawBody) {
326
+ const signature = request.headers["linear-signature"];
327
+ const isValid = await this.verifyLinearSignature(signature, request.rawBody, secret, payload.webhookTimestamp);
328
+ if (!isValid) {
329
+ console.warn("Linear webhook signature verification failed");
330
+ return;
331
+ }
332
+ }
333
+ else if (!secret) {
334
+ console.warn("Linear webhook secret not found, skipping verification");
335
+ }
336
+ if (payload.type === "Issue" || payload.type === "Comment") {
337
+ const callbackToken = await this.get(`callback_${projectId}`);
338
+ if (!callbackToken)
339
+ return;
340
+ const client = await this.getClient(authToken);
341
+ const issue = await client.issue(payload.data.id);
342
+ const activityWithNotes = await this.convertIssueToActivity(issue, projectId);
343
+ // Webhooks are incremental updates - mark as unread
344
+ activityWithNotes.unread = true;
345
+ // Execute stored callback
346
+ await this.tools.callbacks.run(callbackToken, activityWithNotes);
347
+ }
348
+ }
349
+ /**
350
+ * Stop syncing a Linear team
351
+ */
352
+ async stopSync(authToken, projectId) {
353
+ // Remove webhook
354
+ const webhookId = await this.get(`webhook_id_${projectId}`);
355
+ if (webhookId) {
356
+ try {
357
+ const client = await this.getClient(authToken);
358
+ await client.deleteWebhook(webhookId);
359
+ }
360
+ catch (error) {
361
+ console.warn("Failed to delete Linear webhook:", error);
362
+ }
363
+ await this.clear(`webhook_id_${projectId}`);
364
+ }
365
+ // Cleanup webhook secret
366
+ await this.clear(`webhook_secret_${projectId}`);
367
+ // Cleanup callback
368
+ const callbackToken = await this.get(`callback_${projectId}`);
369
+ if (callbackToken) {
370
+ await this.deleteCallback(callbackToken);
371
+ await this.clear(`callback_${projectId}`);
372
+ }
373
+ // Cleanup sync state
374
+ await this.clear(`sync_state_${projectId}`);
375
+ }
376
+ }
377
+ export default Linear;
378
+ //# sourceMappingURL=linear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear.js","sourceRoot":"","sources":["../src/linear.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@plotday/tool-linear",
3
+ "displayName": "Linear",
4
+ "description": "Sync with Linear project management",
5
+ "author": "Plot <team@plot.day> (https://plot.day)",
6
+ "license": "MIT",
7
+ "version": "0.2.0",
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "@plotday/source": "./src/index.ts",
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "dependencies": {
24
+ "@linear/sdk": "^27.0.0",
25
+ "@plotday/twister": "^0.26.0"
26
+ },
27
+ "devDependencies": {
28
+ "typescript": "^5.9.3"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/plotday/plot.git",
33
+ "directory": "tools/linear"
34
+ },
35
+ "homepage": "https://plot.day",
36
+ "bugs": {
37
+ "url": "https://github.com/plotday/plot/issues"
38
+ },
39
+ "keywords": [
40
+ "plot",
41
+ "tool",
42
+ "linear",
43
+ "project-management"
44
+ ],
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "scripts": {
49
+ "build": "tsc",
50
+ "clean": "rm -rf dist"
51
+ }
52
+ }