@usewhisper/sdk 1.0.1 → 2.0.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 (6) hide show
  1. package/README.md +256 -256
  2. package/index.d.mts +208 -2
  3. package/index.d.ts +208 -2
  4. package/index.js +232 -15
  5. package/index.mjs +228 -15
  6. package/package.json +56 -56
package/index.js CHANGED
@@ -20,11 +20,173 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // ../src/sdk/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ Whisper: () => Whisper,
23
24
  WhisperContext: () => WhisperContext,
25
+ WhisperDefault: () => whisper_agent_default,
24
26
  WhisperError: () => WhisperError,
25
27
  default: () => index_default
26
28
  });
27
29
  module.exports = __toCommonJS(index_exports);
30
+
31
+ // ../src/sdk/whisper-agent.ts
32
+ var Whisper = class {
33
+ client;
34
+ options;
35
+ sessionId;
36
+ userId;
37
+ constructor(options) {
38
+ if (!options.apiKey) {
39
+ throw new Error("API key is required");
40
+ }
41
+ const clientConfig = {
42
+ apiKey: options.apiKey,
43
+ baseUrl: options.baseUrl,
44
+ project: options.project || "default"
45
+ };
46
+ if (options.orgId) clientConfig.orgId = options.orgId;
47
+ if (options.timeoutMs) clientConfig.timeoutMs = options.timeoutMs;
48
+ if (options.retry) clientConfig.retry = options.retry;
49
+ this.client = new WhisperContext(clientConfig);
50
+ const finalRetry = options.retry || { maxAttempts: 3, baseDelayMs: 250, maxDelayMs: 2e3 };
51
+ this.options = {
52
+ apiKey: options.apiKey,
53
+ baseUrl: options.baseUrl || "https://context.usewhisper.dev",
54
+ project: options.project || "default",
55
+ orgId: options.orgId || "",
56
+ timeoutMs: options.timeoutMs || 15e3,
57
+ retry: finalRetry,
58
+ contextLimit: options.contextLimit ?? 10,
59
+ memoryTypes: options.memoryTypes ?? ["factual", "preference", "event", "goal", "relationship", "opinion", "instruction"],
60
+ contextPrefix: options.contextPrefix ?? "Relevant context:"
61
+ };
62
+ }
63
+ /**
64
+ * Set session ID for conversation tracking
65
+ */
66
+ session(sessionId) {
67
+ this.sessionId = sessionId;
68
+ return this;
69
+ }
70
+ /**
71
+ * Set user ID for user-specific memories
72
+ */
73
+ user(userId) {
74
+ this.userId = userId;
75
+ return this;
76
+ }
77
+ /**
78
+ * Get relevant context BEFORE your LLM call
79
+ *
80
+ * @param query - What you want to know / user question
81
+ * @returns Context string and raw results
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const { context, results, count } = await whisper.getContext(
86
+ * "What are user's preferences?",
87
+ * { userId: "user-123" }
88
+ * );
89
+ *
90
+ * // Results: [
91
+ * // { content: "User prefers dark mode", type: "preference", score: 0.95 },
92
+ * // { content: "Allergic to nuts", type: "factual", score: 0.89 }
93
+ * // ]
94
+ * ```
95
+ */
96
+ async getContext(query, options) {
97
+ const result = await this.client.query({
98
+ project: options?.project ?? this.options.project,
99
+ query,
100
+ top_k: options?.limit ?? this.options.contextLimit,
101
+ include_memories: true,
102
+ user_id: options?.userId ?? this.userId,
103
+ session_id: options?.sessionId ?? this.sessionId
104
+ });
105
+ const context = result.results.map((r, i) => `[${i + 1}] ${r.content}`).join("\n");
106
+ return {
107
+ context: context ? `${this.options.contextPrefix}
108
+ ${context}` : "",
109
+ results: result.results,
110
+ count: result.meta.total
111
+ };
112
+ }
113
+ /**
114
+ * Remember what happened AFTER your LLM response
115
+ *
116
+ * Fire-and-forget - doesn't block your response
117
+ *
118
+ * @param content - What your LLM responded with
119
+ * @returns Promise that resolves when stored (or fails silently)
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const llmResponse = "I've set your theme to dark mode and removed nuts from recommendations.";
124
+ *
125
+ * await whisper.remember(llmResponse, { userId: "user-123" });
126
+ * // → Auto-extracts: "theme set to dark mode", "nut allergy"
127
+ * // → Stored as preferences
128
+ * ```
129
+ */
130
+ async remember(content, options) {
131
+ if (!content || content.length < 5) {
132
+ return { success: false };
133
+ }
134
+ try {
135
+ const result = await this.client.addMemory({
136
+ project: options?.project ?? this.options.project,
137
+ content,
138
+ user_id: options?.userId ?? this.userId,
139
+ session_id: options?.sessionId ?? this.sessionId
140
+ });
141
+ return {
142
+ success: true,
143
+ memoryId: result?.id
144
+ };
145
+ } catch (error) {
146
+ console.error("[Whisper] Remember failed:", error);
147
+ return { success: false };
148
+ }
149
+ }
150
+ /**
151
+ * Alias for remember() - same thing
152
+ */
153
+ async capture(content, options) {
154
+ return this.remember(content, options);
155
+ }
156
+ /**
157
+ * Capture from multiple messages (e.g., full conversation)
158
+ */
159
+ async captureSession(messages, options) {
160
+ try {
161
+ const result = await this.client.ingestSession({
162
+ project: options?.project ?? this.options.project,
163
+ session_id: options?.sessionId ?? this.sessionId ?? "default",
164
+ user_id: options?.userId ?? this.userId,
165
+ messages: messages.filter((m) => m.role !== "system").map((m) => ({
166
+ role: m.role,
167
+ content: m.content,
168
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
169
+ }))
170
+ });
171
+ return {
172
+ success: true,
173
+ extracted: result?.memories_created ?? 0
174
+ };
175
+ } catch (error) {
176
+ console.error("[Whisper] Session capture failed:", error);
177
+ return { success: false, extracted: 0 };
178
+ }
179
+ }
180
+ /**
181
+ * Direct access to WhisperContext for advanced usage
182
+ */
183
+ raw() {
184
+ return this.client;
185
+ }
186
+ };
187
+ var whisper_agent_default = Whisper;
188
+
189
+ // ../src/sdk/index.ts
28
190
  var WhisperError = class extends Error {
29
191
  code;
30
192
  status;
@@ -332,13 +494,40 @@ var WhisperContext = class _WhisperContext {
332
494
  async addMemory(params) {
333
495
  const projectRef = this.getRequiredProject(params.project);
334
496
  return this.withProjectRefFallback(projectRef, async (project) => {
497
+ const toSotaType = (memoryType) => {
498
+ switch (memoryType) {
499
+ case "episodic":
500
+ return "event";
501
+ case "semantic":
502
+ return "factual";
503
+ case "procedural":
504
+ return "instruction";
505
+ default:
506
+ return memoryType;
507
+ }
508
+ };
509
+ const toLegacyType = (memoryType) => {
510
+ switch (memoryType) {
511
+ case "event":
512
+ return "episodic";
513
+ case "instruction":
514
+ return "procedural";
515
+ case "preference":
516
+ case "relationship":
517
+ case "opinion":
518
+ case "goal":
519
+ return "semantic";
520
+ default:
521
+ return memoryType;
522
+ }
523
+ };
335
524
  try {
336
525
  const direct = await this.request("/v1/memory", {
337
526
  method: "POST",
338
527
  body: JSON.stringify({
339
528
  project,
340
529
  content: params.content,
341
- memory_type: params.memory_type,
530
+ memory_type: toSotaType(params.memory_type),
342
531
  user_id: params.user_id,
343
532
  session_id: params.session_id,
344
533
  agent_id: params.agent_id,
@@ -346,28 +535,37 @@ var WhisperContext = class _WhisperContext {
346
535
  metadata: params.metadata
347
536
  })
348
537
  });
349
- const id = direct?.memory?.id || direct?.id || direct?.memory_id;
350
- if (id) {
351
- return { id, success: true };
538
+ const id2 = direct?.memory?.id || direct?.id || direct?.memory_id;
539
+ if (id2) {
540
+ return { id: id2, success: true, path: "sota", fallback_used: false };
541
+ }
542
+ } catch (error) {
543
+ if (params.allow_legacy_fallback === false) {
544
+ throw error;
352
545
  }
353
- } catch {
354
546
  }
355
- await this.request("/v1/memory/ingest/session", {
547
+ const legacy = await this.request("/v1/memories", {
356
548
  method: "POST",
357
549
  body: JSON.stringify({
358
550
  project,
359
- session_id: params.session_id || `single-${Date.now()}`,
551
+ content: params.content,
552
+ memory_type: toLegacyType(params.memory_type),
360
553
  user_id: params.user_id,
361
- messages: [
362
- {
363
- role: "user",
364
- content: params.content,
365
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
366
- }
367
- ]
554
+ session_id: params.session_id,
555
+ agent_id: params.agent_id,
556
+ importance: params.importance,
557
+ metadata: params.metadata,
558
+ expires_in_seconds: params.expires_in_seconds
368
559
  })
369
560
  });
370
- return { id: `session-${Date.now()}`, success: true };
561
+ const id = legacy?.memory?.id || legacy?.id || legacy?.memory_id;
562
+ if (!id) {
563
+ throw new WhisperError({
564
+ code: "REQUEST_FAILED",
565
+ message: "Memory create succeeded but no memory id was returned by the API"
566
+ });
567
+ }
568
+ return { id, success: true, path: "legacy", fallback_used: true };
371
569
  });
372
570
  }
373
571
  async searchMemories(params) {
@@ -526,6 +724,23 @@ var WhisperContext = class _WhisperContext {
526
724
  });
527
725
  return this.request(`/v1/cost/breakdown?${query}`);
528
726
  }
727
+ /**
728
+ * Semantic search over raw documents without pre-indexing.
729
+ * Send file contents/summaries directly — the API embeds them in-memory and ranks by similarity.
730
+ * Perfect for AI agents to semantically explore a codebase on-the-fly.
731
+ */
732
+ async semanticSearch(params) {
733
+ return this.request("/v1/search/semantic", {
734
+ method: "POST",
735
+ body: JSON.stringify(params)
736
+ });
737
+ }
738
+ async searchFiles(params) {
739
+ return this.request("/v1/search/files", {
740
+ method: "POST",
741
+ body: JSON.stringify(params)
742
+ });
743
+ }
529
744
  async getCostSavings(params = {}) {
530
745
  const resolvedProject = params.project ? await this.resolveProjectId(params.project) : void 0;
531
746
  const query = new URLSearchParams({
@@ -587,6 +802,8 @@ var WhisperContext = class _WhisperContext {
587
802
  var index_default = WhisperContext;
588
803
  // Annotate the CommonJS export names for ESM import in node:
589
804
  0 && (module.exports = {
805
+ Whisper,
590
806
  WhisperContext,
807
+ WhisperDefault,
591
808
  WhisperError
592
809
  });
package/index.mjs CHANGED
@@ -1,3 +1,161 @@
1
+ // ../src/sdk/whisper-agent.ts
2
+ var Whisper = class {
3
+ client;
4
+ options;
5
+ sessionId;
6
+ userId;
7
+ constructor(options) {
8
+ if (!options.apiKey) {
9
+ throw new Error("API key is required");
10
+ }
11
+ const clientConfig = {
12
+ apiKey: options.apiKey,
13
+ baseUrl: options.baseUrl,
14
+ project: options.project || "default"
15
+ };
16
+ if (options.orgId) clientConfig.orgId = options.orgId;
17
+ if (options.timeoutMs) clientConfig.timeoutMs = options.timeoutMs;
18
+ if (options.retry) clientConfig.retry = options.retry;
19
+ this.client = new WhisperContext(clientConfig);
20
+ const finalRetry = options.retry || { maxAttempts: 3, baseDelayMs: 250, maxDelayMs: 2e3 };
21
+ this.options = {
22
+ apiKey: options.apiKey,
23
+ baseUrl: options.baseUrl || "https://context.usewhisper.dev",
24
+ project: options.project || "default",
25
+ orgId: options.orgId || "",
26
+ timeoutMs: options.timeoutMs || 15e3,
27
+ retry: finalRetry,
28
+ contextLimit: options.contextLimit ?? 10,
29
+ memoryTypes: options.memoryTypes ?? ["factual", "preference", "event", "goal", "relationship", "opinion", "instruction"],
30
+ contextPrefix: options.contextPrefix ?? "Relevant context:"
31
+ };
32
+ }
33
+ /**
34
+ * Set session ID for conversation tracking
35
+ */
36
+ session(sessionId) {
37
+ this.sessionId = sessionId;
38
+ return this;
39
+ }
40
+ /**
41
+ * Set user ID for user-specific memories
42
+ */
43
+ user(userId) {
44
+ this.userId = userId;
45
+ return this;
46
+ }
47
+ /**
48
+ * Get relevant context BEFORE your LLM call
49
+ *
50
+ * @param query - What you want to know / user question
51
+ * @returns Context string and raw results
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const { context, results, count } = await whisper.getContext(
56
+ * "What are user's preferences?",
57
+ * { userId: "user-123" }
58
+ * );
59
+ *
60
+ * // Results: [
61
+ * // { content: "User prefers dark mode", type: "preference", score: 0.95 },
62
+ * // { content: "Allergic to nuts", type: "factual", score: 0.89 }
63
+ * // ]
64
+ * ```
65
+ */
66
+ async getContext(query, options) {
67
+ const result = await this.client.query({
68
+ project: options?.project ?? this.options.project,
69
+ query,
70
+ top_k: options?.limit ?? this.options.contextLimit,
71
+ include_memories: true,
72
+ user_id: options?.userId ?? this.userId,
73
+ session_id: options?.sessionId ?? this.sessionId
74
+ });
75
+ const context = result.results.map((r, i) => `[${i + 1}] ${r.content}`).join("\n");
76
+ return {
77
+ context: context ? `${this.options.contextPrefix}
78
+ ${context}` : "",
79
+ results: result.results,
80
+ count: result.meta.total
81
+ };
82
+ }
83
+ /**
84
+ * Remember what happened AFTER your LLM response
85
+ *
86
+ * Fire-and-forget - doesn't block your response
87
+ *
88
+ * @param content - What your LLM responded with
89
+ * @returns Promise that resolves when stored (or fails silently)
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const llmResponse = "I've set your theme to dark mode and removed nuts from recommendations.";
94
+ *
95
+ * await whisper.remember(llmResponse, { userId: "user-123" });
96
+ * // → Auto-extracts: "theme set to dark mode", "nut allergy"
97
+ * // → Stored as preferences
98
+ * ```
99
+ */
100
+ async remember(content, options) {
101
+ if (!content || content.length < 5) {
102
+ return { success: false };
103
+ }
104
+ try {
105
+ const result = await this.client.addMemory({
106
+ project: options?.project ?? this.options.project,
107
+ content,
108
+ user_id: options?.userId ?? this.userId,
109
+ session_id: options?.sessionId ?? this.sessionId
110
+ });
111
+ return {
112
+ success: true,
113
+ memoryId: result?.id
114
+ };
115
+ } catch (error) {
116
+ console.error("[Whisper] Remember failed:", error);
117
+ return { success: false };
118
+ }
119
+ }
120
+ /**
121
+ * Alias for remember() - same thing
122
+ */
123
+ async capture(content, options) {
124
+ return this.remember(content, options);
125
+ }
126
+ /**
127
+ * Capture from multiple messages (e.g., full conversation)
128
+ */
129
+ async captureSession(messages, options) {
130
+ try {
131
+ const result = await this.client.ingestSession({
132
+ project: options?.project ?? this.options.project,
133
+ session_id: options?.sessionId ?? this.sessionId ?? "default",
134
+ user_id: options?.userId ?? this.userId,
135
+ messages: messages.filter((m) => m.role !== "system").map((m) => ({
136
+ role: m.role,
137
+ content: m.content,
138
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
139
+ }))
140
+ });
141
+ return {
142
+ success: true,
143
+ extracted: result?.memories_created ?? 0
144
+ };
145
+ } catch (error) {
146
+ console.error("[Whisper] Session capture failed:", error);
147
+ return { success: false, extracted: 0 };
148
+ }
149
+ }
150
+ /**
151
+ * Direct access to WhisperContext for advanced usage
152
+ */
153
+ raw() {
154
+ return this.client;
155
+ }
156
+ };
157
+ var whisper_agent_default = Whisper;
158
+
1
159
  // ../src/sdk/index.ts
2
160
  var WhisperError = class extends Error {
3
161
  code;
@@ -306,13 +464,40 @@ var WhisperContext = class _WhisperContext {
306
464
  async addMemory(params) {
307
465
  const projectRef = this.getRequiredProject(params.project);
308
466
  return this.withProjectRefFallback(projectRef, async (project) => {
467
+ const toSotaType = (memoryType) => {
468
+ switch (memoryType) {
469
+ case "episodic":
470
+ return "event";
471
+ case "semantic":
472
+ return "factual";
473
+ case "procedural":
474
+ return "instruction";
475
+ default:
476
+ return memoryType;
477
+ }
478
+ };
479
+ const toLegacyType = (memoryType) => {
480
+ switch (memoryType) {
481
+ case "event":
482
+ return "episodic";
483
+ case "instruction":
484
+ return "procedural";
485
+ case "preference":
486
+ case "relationship":
487
+ case "opinion":
488
+ case "goal":
489
+ return "semantic";
490
+ default:
491
+ return memoryType;
492
+ }
493
+ };
309
494
  try {
310
495
  const direct = await this.request("/v1/memory", {
311
496
  method: "POST",
312
497
  body: JSON.stringify({
313
498
  project,
314
499
  content: params.content,
315
- memory_type: params.memory_type,
500
+ memory_type: toSotaType(params.memory_type),
316
501
  user_id: params.user_id,
317
502
  session_id: params.session_id,
318
503
  agent_id: params.agent_id,
@@ -320,28 +505,37 @@ var WhisperContext = class _WhisperContext {
320
505
  metadata: params.metadata
321
506
  })
322
507
  });
323
- const id = direct?.memory?.id || direct?.id || direct?.memory_id;
324
- if (id) {
325
- return { id, success: true };
508
+ const id2 = direct?.memory?.id || direct?.id || direct?.memory_id;
509
+ if (id2) {
510
+ return { id: id2, success: true, path: "sota", fallback_used: false };
511
+ }
512
+ } catch (error) {
513
+ if (params.allow_legacy_fallback === false) {
514
+ throw error;
326
515
  }
327
- } catch {
328
516
  }
329
- await this.request("/v1/memory/ingest/session", {
517
+ const legacy = await this.request("/v1/memories", {
330
518
  method: "POST",
331
519
  body: JSON.stringify({
332
520
  project,
333
- session_id: params.session_id || `single-${Date.now()}`,
521
+ content: params.content,
522
+ memory_type: toLegacyType(params.memory_type),
334
523
  user_id: params.user_id,
335
- messages: [
336
- {
337
- role: "user",
338
- content: params.content,
339
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
340
- }
341
- ]
524
+ session_id: params.session_id,
525
+ agent_id: params.agent_id,
526
+ importance: params.importance,
527
+ metadata: params.metadata,
528
+ expires_in_seconds: params.expires_in_seconds
342
529
  })
343
530
  });
344
- return { id: `session-${Date.now()}`, success: true };
531
+ const id = legacy?.memory?.id || legacy?.id || legacy?.memory_id;
532
+ if (!id) {
533
+ throw new WhisperError({
534
+ code: "REQUEST_FAILED",
535
+ message: "Memory create succeeded but no memory id was returned by the API"
536
+ });
537
+ }
538
+ return { id, success: true, path: "legacy", fallback_used: true };
345
539
  });
346
540
  }
347
541
  async searchMemories(params) {
@@ -500,6 +694,23 @@ var WhisperContext = class _WhisperContext {
500
694
  });
501
695
  return this.request(`/v1/cost/breakdown?${query}`);
502
696
  }
697
+ /**
698
+ * Semantic search over raw documents without pre-indexing.
699
+ * Send file contents/summaries directly — the API embeds them in-memory and ranks by similarity.
700
+ * Perfect for AI agents to semantically explore a codebase on-the-fly.
701
+ */
702
+ async semanticSearch(params) {
703
+ return this.request("/v1/search/semantic", {
704
+ method: "POST",
705
+ body: JSON.stringify(params)
706
+ });
707
+ }
708
+ async searchFiles(params) {
709
+ return this.request("/v1/search/files", {
710
+ method: "POST",
711
+ body: JSON.stringify(params)
712
+ });
713
+ }
503
714
  async getCostSavings(params = {}) {
504
715
  const resolvedProject = params.project ? await this.resolveProjectId(params.project) : void 0;
505
716
  const query = new URLSearchParams({
@@ -560,7 +771,9 @@ var WhisperContext = class _WhisperContext {
560
771
  };
561
772
  var index_default = WhisperContext;
562
773
  export {
774
+ Whisper,
563
775
  WhisperContext,
776
+ whisper_agent_default as WhisperDefault,
564
777
  WhisperError,
565
778
  index_default as default
566
779
  };
package/package.json CHANGED
@@ -1,56 +1,56 @@
1
- {
2
- "name": "@usewhisper/sdk",
3
- "version": "1.0.1",
4
- "scripts": {
5
- "build": "tsup ../src/sdk/index.ts --format esm,cjs --dts --out-dir .",
6
- "prepublishOnly": "npm run build"
7
- },
8
- "description": "TypeScript SDK for Whisper Context API - Add reliable context to your AI agents",
9
- "main": "index.js",
10
- "module": "index.mjs",
11
- "types": "index.d.ts",
12
- "exports": {
13
- ".": {
14
- "types": "./index.d.ts",
15
- "import": "./index.mjs",
16
- "require": "./index.js"
17
- }
18
- },
19
- "files": [
20
- "index.js",
21
- "index.mjs",
22
- "index.d.ts",
23
- "index.d.mts",
24
- "README.md"
25
- ],
26
- "keywords": [
27
- "whisper",
28
- "context",
29
- "ai",
30
- "llm",
31
- "rag",
32
- "embeddings",
33
- "vector-search",
34
- "knowledge-graph",
35
- "semantic-search"
36
- ],
37
- "author": "Whisper",
38
- "license": "MIT",
39
- "repository": {
40
- "type": "git",
41
- "url": "https://github.com/Alixus/"
42
- },
43
- "homepage": "https://usewhisper.dev",
44
- "bugs": {
45
- "url": "https://github.com/Alinxus/whisper/issues"
46
- },
47
- "devDependencies": {
48
- "@types/node": "^22.0.0",
49
- "tsup": "^8.3.0",
50
- "typescript": "^5.7.0"
51
- },
52
- "peerDependencies": {},
53
- "engines": {
54
- "node": ">=18.0.0"
55
- }
56
- }
1
+ {
2
+ "name": "@usewhisper/sdk",
3
+ "version": "2.0.0",
4
+ "scripts": {
5
+ "build": "tsup ../src/sdk/index.ts --format esm,cjs --dts --out-dir .",
6
+ "prepublishOnly": "npm run build"
7
+ },
8
+ "description": "TypeScript SDK for Whisper Context API - Add reliable context to your AI agents",
9
+ "main": "index.js",
10
+ "module": "index.mjs",
11
+ "types": "index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./index.d.ts",
15
+ "import": "./index.mjs",
16
+ "require": "./index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "index.js",
21
+ "index.mjs",
22
+ "index.d.ts",
23
+ "index.d.mts",
24
+ "README.md"
25
+ ],
26
+ "keywords": [
27
+ "whisper",
28
+ "context",
29
+ "ai",
30
+ "llm",
31
+ "rag",
32
+ "embeddings",
33
+ "vector-search",
34
+ "knowledge-graph",
35
+ "semantic-search"
36
+ ],
37
+ "author": "Whisper",
38
+ "license": "MIT",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/Alixus/"
42
+ },
43
+ "homepage": "https://usewhisper.dev",
44
+ "bugs": {
45
+ "url": "https://github.com/Alinxus/whisper/issues"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.0.0",
49
+ "tsup": "^8.3.0",
50
+ "typescript": "^5.7.0"
51
+ },
52
+ "peerDependencies": {},
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ }
56
+ }