@plur-ai/core 0.6.0 → 0.7.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.
package/dist/index.d.ts CHANGED
@@ -545,13 +545,60 @@ declare const PackManifestSchema: z.ZodObject<{
545
545
  }>;
546
546
  type PackManifest = z.infer<typeof PackManifestSchema>;
547
547
 
548
+ interface InstallResult {
549
+ installed: number;
550
+ name: string;
551
+ conflicts: ConflictItem[];
552
+ }
553
+ interface ConflictItem {
554
+ pack_engram_id: string;
555
+ pack_statement: string;
556
+ existing_engram_id: string;
557
+ existing_statement: string;
558
+ type: 'contradiction' | 'duplicate';
559
+ }
560
+ declare function installPack(packsDir: string, source: string, existingEngrams?: Engram[]): InstallResult;
561
+ interface UninstallResult {
562
+ name: string;
563
+ removed: boolean;
564
+ engram_count: number;
565
+ }
566
+ declare function uninstallPack(packsDir: string, name: string): UninstallResult;
548
567
  interface PackInfo {
549
568
  name: string;
550
569
  path: string;
551
570
  engram_count: number;
552
571
  manifest?: PackManifest;
572
+ integrity?: string;
553
573
  }
554
574
  declare function listPacks(packsDir: string): PackInfo[];
575
+ interface ExportOptions {
576
+ name: string;
577
+ version: string;
578
+ description?: string;
579
+ creator?: string;
580
+ domain?: string;
581
+ scope?: string;
582
+ tags?: string[];
583
+ type?: string;
584
+ }
585
+ interface PrivacyScanResult {
586
+ clean: boolean;
587
+ issues: PrivacyIssue[];
588
+ }
589
+ interface PrivacyIssue {
590
+ engram_id: string;
591
+ type: 'secret' | 'private_visibility' | 'personal_path' | 'email' | 'ip_address';
592
+ detail: string;
593
+ }
594
+ interface ExportResult {
595
+ path: string;
596
+ engram_count: number;
597
+ privacy: PrivacyScanResult;
598
+ match_terms: string[];
599
+ integrity: string;
600
+ }
601
+ declare function exportPack(engrams: Engram[], outputDir: string, manifest: ExportOptions): ExportResult;
555
602
 
556
603
  interface SyncStatus {
557
604
  initialized: boolean;
@@ -804,14 +851,14 @@ declare const StructuralTemplateSchema: z.ZodObject<{
804
851
  goal_type: string;
805
852
  constraint_type: string;
806
853
  outcome_type: string;
807
- structure_type: "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "recursive" | "tradeoff" | "freeform";
854
+ structure_type: "recursive" | "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "tradeoff" | "freeform";
808
855
  freeform_structure?: string | undefined;
809
856
  }, {
810
857
  template: string;
811
858
  goal_type: string;
812
859
  constraint_type: string;
813
860
  outcome_type: string;
814
- structure_type?: "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "recursive" | "tradeoff" | "freeform" | undefined;
861
+ structure_type?: "recursive" | "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "tradeoff" | "freeform" | undefined;
815
862
  freeform_structure?: string | undefined;
816
863
  }>;
817
864
  declare const EvidenceEntrySchema: z.ZodObject<{
@@ -904,14 +951,14 @@ declare const MetaFieldSchema: z.ZodObject<{
904
951
  goal_type: string;
905
952
  constraint_type: string;
906
953
  outcome_type: string;
907
- structure_type: "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "recursive" | "tradeoff" | "freeform";
954
+ structure_type: "recursive" | "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "tradeoff" | "freeform";
908
955
  freeform_structure?: string | undefined;
909
956
  }, {
910
957
  template: string;
911
958
  goal_type: string;
912
959
  constraint_type: string;
913
960
  outcome_type: string;
914
- structure_type?: "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "recursive" | "tradeoff" | "freeform" | undefined;
961
+ structure_type?: "recursive" | "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "tradeoff" | "freeform" | undefined;
915
962
  freeform_structure?: string | undefined;
916
963
  }>;
917
964
  evidence: z.ZodArray<z.ZodObject<{
@@ -1003,7 +1050,7 @@ declare const MetaFieldSchema: z.ZodObject<{
1003
1050
  goal_type: string;
1004
1051
  constraint_type: string;
1005
1052
  outcome_type: string;
1006
- structure_type: "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "recursive" | "tradeoff" | "freeform";
1053
+ structure_type: "recursive" | "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "tradeoff" | "freeform";
1007
1054
  freeform_structure?: string | undefined;
1008
1055
  };
1009
1056
  evidence: {
@@ -1042,7 +1089,7 @@ declare const MetaFieldSchema: z.ZodObject<{
1042
1089
  goal_type: string;
1043
1090
  constraint_type: string;
1044
1091
  outcome_type: string;
1045
- structure_type?: "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "recursive" | "tradeoff" | "freeform" | undefined;
1092
+ structure_type?: "recursive" | "goal-constraint-outcome" | "feedback-loop" | "causal-chain" | "tradeoff" | "freeform" | undefined;
1046
1093
  freeform_structure?: string | undefined;
1047
1094
  };
1048
1095
  evidence: {
@@ -1385,22 +1432,18 @@ declare class Plur {
1385
1432
  timeline(query?: TimelineQuery): Episode[];
1386
1433
  /** Rule-based extraction of engram candidates from content. */
1387
1434
  ingest(content: string, options?: IngestOptions): IngestCandidate[];
1388
- /** Install a pack from a source path. */
1389
- installPack(source: string): {
1390
- installed: number;
1391
- name: string;
1392
- };
1393
- /** Export engrams as a shareable pack. */
1435
+ /** Install a pack from a source path. Detects conflicts with existing engrams. */
1436
+ installPack(source: string): ReturnType<typeof installPack>;
1437
+ /** Uninstall a pack by name. */
1438
+ uninstallPack(name: string): ReturnType<typeof uninstallPack>;
1439
+ /** Export engrams as a shareable pack with privacy scanning and integrity hash. */
1394
1440
  exportPack(engrams: Engram[], outputDir: string, manifest: {
1395
1441
  name: string;
1396
1442
  version: string;
1397
1443
  description?: string;
1398
1444
  creator?: string;
1399
- }): {
1400
- path: string;
1401
- engram_count: number;
1402
- };
1403
- /** List all installed packs. */
1445
+ }): ReturnType<typeof exportPack>;
1446
+ /** List all installed packs (with integrity hashes). */
1404
1447
  listPacks(): ReturnType<typeof listPacks>;
1405
1448
  /** Sync engrams to git. Initializes repo on first call, commits + push/pull on subsequent calls. */
1406
1449
  sync(remote?: string): SyncResult;
package/dist/index.js CHANGED
@@ -1062,25 +1062,110 @@ async function expandedSearch(engrams, query, limit, llm, storagePath) {
1062
1062
  // src/packs.ts
1063
1063
  import * as fs2 from "fs";
1064
1064
  import * as path from "path";
1065
+ import * as crypto from "crypto";
1065
1066
  import yaml4 from "js-yaml";
1066
- function installPack(packsDir, source) {
1067
+
1068
+ // src/secrets.ts
1069
+ var SECRET_PATTERNS = [
1070
+ { name: "aws_access_key", regex: /AKIA[0-9A-Z]{16}/ },
1071
+ { name: "aws_secret_key", regex: /(?:aws_secret_access_key|secret_access_key)\s*[=:]\s*[A-Za-z0-9/+=]{40}/i },
1072
+ { name: "generic_api_key", regex: /(?:^|[^a-z])(sk|pk)[-_][a-z0-9]{20,}/i },
1073
+ { name: "api_key_assignment", regex: /(?:api[_-]?key|api[_-]?secret|secret[_-]?key)\s*[=:]\s*\S{20,}/i },
1074
+ { name: "password_assignment", regex: /password\s*[=:]\s*\S{8,}/i },
1075
+ { name: "connection_string", regex: /(?:postgres|mysql|mongodb|redis):\/\/\S+/ },
1076
+ { name: "jwt", regex: /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}/ },
1077
+ { name: "private_key", regex: /-----BEGIN\s+\S+\s+PRIVATE KEY-----/ },
1078
+ { name: "bearer_token", regex: /Bearer\s+[A-Za-z0-9._~+/=-]{20,}/ }
1079
+ ];
1080
+ function detectSecrets(text) {
1081
+ const matches = [];
1082
+ for (const { name, regex } of SECRET_PATTERNS) {
1083
+ const m = text.match(regex);
1084
+ if (m) {
1085
+ matches.push({ pattern: name, match: m[0].slice(0, 20) + "..." });
1086
+ }
1087
+ }
1088
+ return matches;
1089
+ }
1090
+
1091
+ // src/packs.ts
1092
+ function detectConflicts2(newEngrams, existingEngrams) {
1093
+ const conflicts = [];
1094
+ for (const ne of newEngrams) {
1095
+ for (const ee of existingEngrams) {
1096
+ const nNorm = ne.statement.toLowerCase().replace(/\s+/g, " ").trim();
1097
+ const eNorm = ee.statement.toLowerCase().replace(/\s+/g, " ").trim();
1098
+ if (nNorm === eNorm) {
1099
+ conflicts.push({
1100
+ pack_engram_id: ne.id,
1101
+ pack_statement: ne.statement.slice(0, 120),
1102
+ existing_engram_id: ee.id,
1103
+ existing_statement: ee.statement.slice(0, 120),
1104
+ type: "duplicate"
1105
+ });
1106
+ continue;
1107
+ }
1108
+ if (ne.domain && ee.domain && ne.domain === ee.domain) {
1109
+ const nHasNever = /\b(never|don't|do not|avoid|stop)\b/i.test(ne.statement);
1110
+ const eHasNever = /\b(never|don't|do not|avoid|stop)\b/i.test(ee.statement);
1111
+ const nHasAlways = /\b(always|must|should|prefer|use)\b/i.test(ne.statement);
1112
+ const eHasAlways = /\b(always|must|should|prefer|use)\b/i.test(ee.statement);
1113
+ if (nHasNever && eHasAlways || nHasAlways && eHasNever) {
1114
+ const nWords = new Set(nNorm.split(" ").filter((w) => w.length > 4));
1115
+ const eWords = new Set(eNorm.split(" ").filter((w) => w.length > 4));
1116
+ const overlap = [...nWords].filter((w) => eWords.has(w));
1117
+ if (overlap.length >= 2) {
1118
+ conflicts.push({
1119
+ pack_engram_id: ne.id,
1120
+ pack_statement: ne.statement.slice(0, 120),
1121
+ existing_engram_id: ee.id,
1122
+ existing_statement: ee.statement.slice(0, 120),
1123
+ type: "contradiction"
1124
+ });
1125
+ }
1126
+ }
1127
+ }
1128
+ }
1129
+ }
1130
+ return conflicts;
1131
+ }
1132
+ function installPack(packsDir, source, existingEngrams) {
1067
1133
  if (!fs2.existsSync(source)) throw new Error(`Pack source not found: ${source}`);
1068
1134
  const sourceName = path.basename(source);
1069
1135
  const destDir = path.join(packsDir, sourceName);
1070
1136
  if (!fs2.existsSync(destDir)) fs2.mkdirSync(destDir, { recursive: true });
1071
1137
  const files = fs2.readdirSync(source);
1072
- let copied = 0;
1073
1138
  for (const file of files) {
1074
1139
  const srcPath = path.join(source, file);
1075
1140
  const destPath = path.join(destDir, file);
1076
1141
  if (fs2.statSync(srcPath).isFile()) {
1077
1142
  fs2.copyFileSync(srcPath, destPath);
1078
- copied++;
1079
1143
  }
1080
1144
  }
1081
1145
  const engramsPath = path.join(destDir, "engrams.yaml");
1082
- const engrams = fs2.existsSync(engramsPath) ? loadEngrams(engramsPath) : [];
1083
- return { installed: engrams.length, name: sourceName };
1146
+ const newEngrams = fs2.existsSync(engramsPath) ? loadEngrams(engramsPath) : [];
1147
+ const conflicts = existingEngrams ? detectConflicts2(newEngrams, existingEngrams) : [];
1148
+ return { installed: newEngrams.length, name: sourceName, conflicts };
1149
+ }
1150
+ function uninstallPack(packsDir, name) {
1151
+ let packDir = path.join(packsDir, name);
1152
+ if (!fs2.existsSync(packDir)) {
1153
+ const entries = fs2.existsSync(packsDir) ? fs2.readdirSync(packsDir) : [];
1154
+ const match = entries.find((e) => e.toLowerCase() === name.toLowerCase());
1155
+ if (match) {
1156
+ packDir = path.join(packsDir, match);
1157
+ } else {
1158
+ throw new Error(`Pack not found: ${name}. Use 'plur packs list' to see installed packs.`);
1159
+ }
1160
+ }
1161
+ const engramsPath = path.join(packDir, "engrams.yaml");
1162
+ let count = 0;
1163
+ try {
1164
+ count = loadEngrams(engramsPath).length;
1165
+ } catch {
1166
+ }
1167
+ fs2.rmSync(packDir, { recursive: true, force: true });
1168
+ return { name, removed: true, engram_count: count };
1084
1169
  }
1085
1170
  function listPacks(packsDir) {
1086
1171
  if (!fs2.existsSync(packsDir)) return [];
@@ -1094,7 +1179,8 @@ function listPacks(packsDir) {
1094
1179
  name: pack.manifest.name,
1095
1180
  path: packDir,
1096
1181
  engram_count: pack.engrams.length,
1097
- manifest: pack.manifest
1182
+ manifest: pack.manifest,
1183
+ integrity: computePackHash(packDir)
1098
1184
  });
1099
1185
  } catch {
1100
1186
  const engramsPath = path.join(packDir, "engrams.yaml");
@@ -1108,7 +1194,83 @@ function listPacks(packsDir) {
1108
1194
  }
1109
1195
  return result;
1110
1196
  }
1197
+ var PERSONAL_PATH_RE = /(?:\/Users\/\w+|\/home\/\w+|~\/|C:\\Users\\\w+)/;
1198
+ var EMAIL_RE = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/;
1199
+ var IP_RE = /\b(?:10|172\.(?:1[6-9]|2\d|3[01])|192\.168)\.\d{1,3}\.\d{1,3}\b/;
1200
+ function scanPrivacy(engrams) {
1201
+ const issues = [];
1202
+ for (const e of engrams) {
1203
+ if (e.visibility === "private") {
1204
+ issues.push({
1205
+ engram_id: e.id,
1206
+ type: "private_visibility",
1207
+ detail: `Engram marked as private \u2014 skipped from export`
1208
+ });
1209
+ continue;
1210
+ }
1211
+ const text = `${e.statement} ${e.rationale ?? ""} ${e.source ?? ""}`;
1212
+ const secrets = detectSecrets(text);
1213
+ for (const s of secrets) {
1214
+ issues.push({
1215
+ engram_id: e.id,
1216
+ type: "secret",
1217
+ detail: `${s.pattern}: ${s.match}`
1218
+ });
1219
+ }
1220
+ if (PERSONAL_PATH_RE.test(text)) {
1221
+ issues.push({
1222
+ engram_id: e.id,
1223
+ type: "personal_path",
1224
+ detail: `Contains personal path: ${text.match(PERSONAL_PATH_RE)?.[0]}`
1225
+ });
1226
+ }
1227
+ const emailMatch = text.match(EMAIL_RE);
1228
+ if (emailMatch) {
1229
+ issues.push({
1230
+ engram_id: e.id,
1231
+ type: "email",
1232
+ detail: `Contains email: ${emailMatch[0]}`
1233
+ });
1234
+ }
1235
+ const ipMatch = text.match(IP_RE);
1236
+ if (ipMatch) {
1237
+ issues.push({
1238
+ engram_id: e.id,
1239
+ type: "ip_address",
1240
+ detail: `Contains private IP: ${ipMatch[0]}`
1241
+ });
1242
+ }
1243
+ }
1244
+ return { clean: issues.length === 0, issues };
1245
+ }
1246
+ function deriveMatchTerms(engrams) {
1247
+ const termCounts = /* @__PURE__ */ new Map();
1248
+ for (const e of engrams) {
1249
+ if (e.tags) {
1250
+ for (const t of e.tags) {
1251
+ termCounts.set(t, (termCounts.get(t) || 0) + 1);
1252
+ }
1253
+ }
1254
+ if (e.domain) {
1255
+ for (const part of e.domain.split(".")) {
1256
+ if (part.length > 2) {
1257
+ termCounts.set(part, (termCounts.get(part) || 0) + 1);
1258
+ }
1259
+ }
1260
+ }
1261
+ if (e.type) {
1262
+ termCounts.set(e.type, (termCounts.get(e.type) || 0) + 1);
1263
+ }
1264
+ }
1265
+ return [...termCounts.entries()].filter(([, count]) => count >= 2).sort((a, b) => b[1] - a[1]).slice(0, 20).map(([term]) => term);
1266
+ }
1111
1267
  function exportPack(engrams, outputDir, manifest) {
1268
+ const allPrivacy = scanPrivacy(engrams);
1269
+ const blockedIds = new Set(
1270
+ allPrivacy.issues.filter((i) => i.type === "secret" || i.type === "private_visibility").map((i) => i.engram_id)
1271
+ );
1272
+ const safeEngrams = engrams.filter((e) => !blockedIds.has(e.id));
1273
+ const matchTerms = deriveMatchTerms(safeEngrams);
1112
1274
  if (!fs2.existsSync(outputDir)) fs2.mkdirSync(outputDir, { recursive: true });
1113
1275
  const frontmatter = yaml4.dump({
1114
1276
  name: manifest.name,
@@ -1117,8 +1279,8 @@ function exportPack(engrams, outputDir, manifest) {
1117
1279
  creator: manifest.creator,
1118
1280
  metadata: {
1119
1281
  injection_policy: "on_match",
1120
- match_terms: [],
1121
- engram_count: engrams.length
1282
+ match_terms: matchTerms,
1283
+ engram_count: safeEngrams.length
1122
1284
  }
1123
1285
  });
1124
1286
  fs2.writeFileSync(
@@ -1131,32 +1293,60 @@ ${frontmatter}---
1131
1293
  ${manifest.description || ""}
1132
1294
  `
1133
1295
  );
1134
- const content = yaml4.dump({ engrams }, { lineWidth: 120, noRefs: true, quotingType: '"' });
1296
+ const exportEngrams = safeEngrams.map((e) => {
1297
+ const cleaned = { ...e };
1298
+ if (cleaned.relations) {
1299
+ cleaned.relations = {
1300
+ ...cleaned.relations,
1301
+ conflicts: [],
1302
+ related: []
1303
+ };
1304
+ }
1305
+ if (cleaned.associations) {
1306
+ cleaned.associations = [];
1307
+ }
1308
+ if (cleaned.knowledge_anchors) {
1309
+ cleaned.knowledge_anchors = [];
1310
+ }
1311
+ if (cleaned.activation) {
1312
+ cleaned.activation = {
1313
+ ...cleaned.activation,
1314
+ frequency: 0,
1315
+ retrieval_strength: 0.7
1316
+ };
1317
+ }
1318
+ if (cleaned.feedback_signals) {
1319
+ cleaned.feedback_signals = { positive: 0, negative: 0, neutral: 0 };
1320
+ }
1321
+ return cleaned;
1322
+ });
1323
+ const content = yaml4.dump({ engrams: exportEngrams }, { lineWidth: 120, noRefs: true, quotingType: '"' });
1135
1324
  fs2.writeFileSync(path.join(outputDir, "engrams.yaml"), content);
1136
- return { path: outputDir, engram_count: engrams.length };
1325
+ const integrity = computePackHash(outputDir);
1326
+ fs2.writeFileSync(path.join(outputDir, "INTEGRITY"), `sha256:${integrity}
1327
+ `);
1328
+ return {
1329
+ path: outputDir,
1330
+ engram_count: safeEngrams.length,
1331
+ privacy: allPrivacy,
1332
+ match_terms: matchTerms,
1333
+ integrity: `sha256:${integrity}`
1334
+ };
1137
1335
  }
1138
-
1139
- // src/secrets.ts
1140
- var SECRET_PATTERNS = [
1141
- { name: "aws_access_key", regex: /AKIA[0-9A-Z]{16}/ },
1142
- { name: "aws_secret_key", regex: /(?:aws_secret_access_key|secret_access_key)\s*[=:]\s*[A-Za-z0-9/+=]{40}/i },
1143
- { name: "generic_api_key", regex: /(?:^|[^a-z])(sk|pk)[-_][a-z0-9]{20,}/i },
1144
- { name: "api_key_assignment", regex: /(?:api[_-]?key|api[_-]?secret|secret[_-]?key)\s*[=:]\s*\S{20,}/i },
1145
- { name: "password_assignment", regex: /password\s*[=:]\s*\S{8,}/i },
1146
- { name: "connection_string", regex: /(?:postgres|mysql|mongodb|redis):\/\/\S+/ },
1147
- { name: "jwt", regex: /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}/ },
1148
- { name: "private_key", regex: /-----BEGIN\s+\S+\s+PRIVATE KEY-----/ },
1149
- { name: "bearer_token", regex: /Bearer\s+[A-Za-z0-9._~+/=-]{20,}/ }
1150
- ];
1151
- function detectSecrets(text) {
1152
- const matches = [];
1153
- for (const { name, regex } of SECRET_PATTERNS) {
1154
- const m = text.match(regex);
1155
- if (m) {
1156
- matches.push({ pattern: name, match: m[0].slice(0, 20) + "..." });
1157
- }
1336
+ function computePackHash(packDir) {
1337
+ const hash = crypto.createHash("sha256");
1338
+ const skillMd = path.join(packDir, "SKILL.md");
1339
+ const manifestYaml = path.join(packDir, "manifest.yaml");
1340
+ if (fs2.existsSync(skillMd)) {
1341
+ hash.update(fs2.readFileSync(skillMd));
1342
+ } else if (fs2.existsSync(manifestYaml)) {
1343
+ hash.update(fs2.readFileSync(manifestYaml));
1158
1344
  }
1159
- return matches;
1345
+ const engramsPath = path.join(packDir, "engrams.yaml");
1346
+ if (fs2.existsSync(engramsPath)) {
1347
+ hash.update(fs2.readFileSync(engramsPath));
1348
+ }
1349
+ return hash.digest("hex");
1160
1350
  }
1161
1351
 
1162
1352
  // src/meta/sanitize.ts
@@ -2555,15 +2745,20 @@ var Plur = class {
2555
2745
  }
2556
2746
  return candidates;
2557
2747
  }
2558
- /** Install a pack from a source path. */
2748
+ /** Install a pack from a source path. Detects conflicts with existing engrams. */
2559
2749
  installPack(source) {
2560
- return installPack(this.paths.packs, source);
2750
+ const existing = this._loadAllEngrams();
2751
+ return installPack(this.paths.packs, source, existing);
2752
+ }
2753
+ /** Uninstall a pack by name. */
2754
+ uninstallPack(name) {
2755
+ return uninstallPack(this.paths.packs, name);
2561
2756
  }
2562
- /** Export engrams as a shareable pack. */
2757
+ /** Export engrams as a shareable pack with privacy scanning and integrity hash. */
2563
2758
  exportPack(engrams, outputDir, manifest) {
2564
2759
  return exportPack(engrams, outputDir, manifest);
2565
2760
  }
2566
- /** List all installed packs. */
2761
+ /** List all installed packs (with integrity hashes). */
2567
2762
  listPacks() {
2568
2763
  return listPacks(this.paths.packs);
2569
2764
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plur-ai/core",
3
- "version": "0.6.0",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",