opencode-swarm 6.86.3 → 6.86.5
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/cli/index.js +95 -3
- package/dist/index.js +116 -11
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -14230,11 +14230,17 @@ async function readLedgerEvents(directory) {
|
|
|
14230
14230
|
const lines = content.trim().split(`
|
|
14231
14231
|
`).filter((line) => line.trim() !== "");
|
|
14232
14232
|
const events = [];
|
|
14233
|
+
let skippedCount = 0;
|
|
14233
14234
|
for (const line of lines) {
|
|
14234
14235
|
try {
|
|
14235
14236
|
const event = JSON.parse(line);
|
|
14236
14237
|
events.push(event);
|
|
14237
|
-
} catch {
|
|
14238
|
+
} catch {
|
|
14239
|
+
skippedCount++;
|
|
14240
|
+
}
|
|
14241
|
+
}
|
|
14242
|
+
if (skippedCount > 0) {
|
|
14243
|
+
console.warn(`[ledger] Skipped ${skippedCount} malformed line(s) in plan-ledger.jsonl`);
|
|
14238
14244
|
}
|
|
14239
14245
|
events.sort((a, b) => a.seq - b.seq);
|
|
14240
14246
|
return events;
|
|
@@ -14331,10 +14337,13 @@ async function takeSnapshotEvent(directory, plan, options) {
|
|
|
14331
14337
|
}, { planHashAfter: options?.planHashAfter });
|
|
14332
14338
|
}
|
|
14333
14339
|
async function replayFromLedger(directory, _options) {
|
|
14334
|
-
const events = await
|
|
14340
|
+
const { events, truncated, badSuffix } = await readLedgerEventsWithIntegrity(directory);
|
|
14335
14341
|
if (events.length === 0) {
|
|
14336
14342
|
return null;
|
|
14337
14343
|
}
|
|
14344
|
+
if (truncated && badSuffix !== null) {
|
|
14345
|
+
await quarantineLedgerSuffix(directory, badSuffix);
|
|
14346
|
+
}
|
|
14338
14347
|
const targetPlanId = events[0].plan_id;
|
|
14339
14348
|
const relevantEvents = events.filter((e) => e.plan_id === targetPlanId);
|
|
14340
14349
|
{
|
|
@@ -14455,6 +14464,46 @@ function applyEventToPlan(plan, event) {
|
|
|
14455
14464
|
throw new Error(`applyEventToPlan: unhandled event type "${event.event_type}" at seq ${event.seq}`);
|
|
14456
14465
|
}
|
|
14457
14466
|
}
|
|
14467
|
+
async function readLedgerEventsWithIntegrity(directory) {
|
|
14468
|
+
const ledgerPath = getLedgerPath(directory);
|
|
14469
|
+
if (!fs.existsSync(ledgerPath)) {
|
|
14470
|
+
return { events: [], truncated: false, badSuffix: null };
|
|
14471
|
+
}
|
|
14472
|
+
try {
|
|
14473
|
+
const content = fs.readFileSync(ledgerPath, "utf8");
|
|
14474
|
+
const lines = content.split(`
|
|
14475
|
+
`);
|
|
14476
|
+
const events = [];
|
|
14477
|
+
let truncated = false;
|
|
14478
|
+
let badSuffix = null;
|
|
14479
|
+
for (let i = 0;i < lines.length; i++) {
|
|
14480
|
+
const line = lines[i];
|
|
14481
|
+
if (line.trim() === "") {
|
|
14482
|
+
continue;
|
|
14483
|
+
}
|
|
14484
|
+
try {
|
|
14485
|
+
const event = JSON.parse(line);
|
|
14486
|
+
events.push(event);
|
|
14487
|
+
} catch {
|
|
14488
|
+
truncated = true;
|
|
14489
|
+
badSuffix = lines.slice(i).join(`
|
|
14490
|
+
`);
|
|
14491
|
+
break;
|
|
14492
|
+
}
|
|
14493
|
+
}
|
|
14494
|
+
events.sort((a, b) => a.seq - b.seq);
|
|
14495
|
+
return { events, truncated, badSuffix };
|
|
14496
|
+
} catch {
|
|
14497
|
+
return { events: [], truncated: false, badSuffix: null };
|
|
14498
|
+
}
|
|
14499
|
+
}
|
|
14500
|
+
async function quarantineLedgerSuffix(directory, badSuffix) {
|
|
14501
|
+
try {
|
|
14502
|
+
const quarantinePath = path2.join(directory, ".swarm", "plan-ledger.quarantine");
|
|
14503
|
+
fs.writeFileSync(quarantinePath, badSuffix, "utf8");
|
|
14504
|
+
console.warn(`[ledger] Corrupted suffix quarantined to ${path2.relative(directory, quarantinePath)}`);
|
|
14505
|
+
} catch {}
|
|
14506
|
+
}
|
|
14458
14507
|
async function loadLastApprovedPlan(directory, expectedPlanId) {
|
|
14459
14508
|
const events = await readLedgerEvents(directory);
|
|
14460
14509
|
if (events.length === 0) {
|
|
@@ -44379,7 +44428,9 @@ ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
|
44379
44428
|
}
|
|
44380
44429
|
|
|
44381
44430
|
// src/commands/rollback.ts
|
|
44431
|
+
init_plan_schema();
|
|
44382
44432
|
init_utils2();
|
|
44433
|
+
init_ledger();
|
|
44383
44434
|
import * as fs21 from "fs";
|
|
44384
44435
|
import * as path32 from "path";
|
|
44385
44436
|
async function handleRollbackCommand(directory, args) {
|
|
@@ -44436,9 +44487,16 @@ async function handleRollbackCommand(directory, args) {
|
|
|
44436
44487
|
return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
|
|
44437
44488
|
}
|
|
44438
44489
|
const swarmDir = validateSwarmPath(directory, "");
|
|
44490
|
+
const EXCLUDE_FILES = new Set([
|
|
44491
|
+
"plan-ledger.jsonl",
|
|
44492
|
+
"plan-ledger.quarantine"
|
|
44493
|
+
]);
|
|
44439
44494
|
const successes = [];
|
|
44440
44495
|
const failures = [];
|
|
44441
44496
|
for (const file3 of checkpointFiles) {
|
|
44497
|
+
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
44498
|
+
continue;
|
|
44499
|
+
}
|
|
44442
44500
|
const src = path32.join(checkpointDir, file3);
|
|
44443
44501
|
const dest = path32.join(swarmDir, file3);
|
|
44444
44502
|
try {
|
|
@@ -44449,7 +44507,41 @@ async function handleRollbackCommand(directory, args) {
|
|
|
44449
44507
|
}
|
|
44450
44508
|
}
|
|
44451
44509
|
if (failures.length > 0) {
|
|
44452
|
-
return
|
|
44510
|
+
return [
|
|
44511
|
+
`Rollback partially completed. Successfully restored ${successes.length} files.`,
|
|
44512
|
+
`Failed on ${failures.length} files:`,
|
|
44513
|
+
...failures.map((f) => ` - ${f.file}: ${f.error}`),
|
|
44514
|
+
"",
|
|
44515
|
+
"Some files could not be restored. The .swarm/ directory may be in an inconsistent state.",
|
|
44516
|
+
"Check permissions and disk space, then retry the rollback."
|
|
44517
|
+
].join(`
|
|
44518
|
+
`);
|
|
44519
|
+
}
|
|
44520
|
+
const existingLedgerPath = path32.join(swarmDir, "plan-ledger.jsonl");
|
|
44521
|
+
if (fs21.existsSync(existingLedgerPath)) {
|
|
44522
|
+
fs21.unlinkSync(existingLedgerPath);
|
|
44523
|
+
}
|
|
44524
|
+
try {
|
|
44525
|
+
const planJsonPath = path32.join(swarmDir, "plan.json");
|
|
44526
|
+
if (fs21.existsSync(planJsonPath)) {
|
|
44527
|
+
const planRaw = fs21.readFileSync(planJsonPath, "utf-8");
|
|
44528
|
+
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
44529
|
+
const planId = `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
44530
|
+
const planHash = computePlanHash(plan);
|
|
44531
|
+
await initLedger(directory, planId, planHash, plan);
|
|
44532
|
+
await appendLedgerEvent(directory, {
|
|
44533
|
+
event_type: "plan_rebuilt",
|
|
44534
|
+
source: "rollback",
|
|
44535
|
+
plan_id: planId
|
|
44536
|
+
});
|
|
44537
|
+
}
|
|
44538
|
+
} catch (initError) {
|
|
44539
|
+
return [
|
|
44540
|
+
`Rollback restored files but failed to initialize ledger: ${initError instanceof Error ? initError.message : String(initError)}`,
|
|
44541
|
+
"The .swarm/plan.json has been restored but the ledger may be out of sync.",
|
|
44542
|
+
"Run /swarm reset-session to reinitialize the ledger."
|
|
44543
|
+
].join(`
|
|
44544
|
+
`);
|
|
44453
44545
|
}
|
|
44454
44546
|
const eventsPath = validateSwarmPath(directory, "events.jsonl");
|
|
44455
44547
|
const rollbackEvent = {
|
package/dist/index.js
CHANGED
|
@@ -16158,11 +16158,17 @@ async function readLedgerEvents(directory) {
|
|
|
16158
16158
|
const lines = content.trim().split(`
|
|
16159
16159
|
`).filter((line) => line.trim() !== "");
|
|
16160
16160
|
const events = [];
|
|
16161
|
+
let skippedCount = 0;
|
|
16161
16162
|
for (const line of lines) {
|
|
16162
16163
|
try {
|
|
16163
16164
|
const event = JSON.parse(line);
|
|
16164
16165
|
events.push(event);
|
|
16165
|
-
} catch {
|
|
16166
|
+
} catch {
|
|
16167
|
+
skippedCount++;
|
|
16168
|
+
}
|
|
16169
|
+
}
|
|
16170
|
+
if (skippedCount > 0) {
|
|
16171
|
+
console.warn(`[ledger] Skipped ${skippedCount} malformed line(s) in plan-ledger.jsonl`);
|
|
16166
16172
|
}
|
|
16167
16173
|
events.sort((a, b) => a.seq - b.seq);
|
|
16168
16174
|
return events;
|
|
@@ -16259,10 +16265,13 @@ async function takeSnapshotEvent(directory, plan, options) {
|
|
|
16259
16265
|
}, { planHashAfter: options?.planHashAfter });
|
|
16260
16266
|
}
|
|
16261
16267
|
async function replayFromLedger(directory, _options) {
|
|
16262
|
-
const events = await
|
|
16268
|
+
const { events, truncated, badSuffix } = await readLedgerEventsWithIntegrity(directory);
|
|
16263
16269
|
if (events.length === 0) {
|
|
16264
16270
|
return null;
|
|
16265
16271
|
}
|
|
16272
|
+
if (truncated && badSuffix !== null) {
|
|
16273
|
+
await quarantineLedgerSuffix(directory, badSuffix);
|
|
16274
|
+
}
|
|
16266
16275
|
const targetPlanId = events[0].plan_id;
|
|
16267
16276
|
const relevantEvents = events.filter((e) => e.plan_id === targetPlanId);
|
|
16268
16277
|
{
|
|
@@ -16383,6 +16392,46 @@ function applyEventToPlan(plan, event) {
|
|
|
16383
16392
|
throw new Error(`applyEventToPlan: unhandled event type "${event.event_type}" at seq ${event.seq}`);
|
|
16384
16393
|
}
|
|
16385
16394
|
}
|
|
16395
|
+
async function readLedgerEventsWithIntegrity(directory) {
|
|
16396
|
+
const ledgerPath = getLedgerPath(directory);
|
|
16397
|
+
if (!fs4.existsSync(ledgerPath)) {
|
|
16398
|
+
return { events: [], truncated: false, badSuffix: null };
|
|
16399
|
+
}
|
|
16400
|
+
try {
|
|
16401
|
+
const content = fs4.readFileSync(ledgerPath, "utf8");
|
|
16402
|
+
const lines = content.split(`
|
|
16403
|
+
`);
|
|
16404
|
+
const events = [];
|
|
16405
|
+
let truncated = false;
|
|
16406
|
+
let badSuffix = null;
|
|
16407
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
16408
|
+
const line = lines[i2];
|
|
16409
|
+
if (line.trim() === "") {
|
|
16410
|
+
continue;
|
|
16411
|
+
}
|
|
16412
|
+
try {
|
|
16413
|
+
const event = JSON.parse(line);
|
|
16414
|
+
events.push(event);
|
|
16415
|
+
} catch {
|
|
16416
|
+
truncated = true;
|
|
16417
|
+
badSuffix = lines.slice(i2).join(`
|
|
16418
|
+
`);
|
|
16419
|
+
break;
|
|
16420
|
+
}
|
|
16421
|
+
}
|
|
16422
|
+
events.sort((a, b) => a.seq - b.seq);
|
|
16423
|
+
return { events, truncated, badSuffix };
|
|
16424
|
+
} catch {
|
|
16425
|
+
return { events: [], truncated: false, badSuffix: null };
|
|
16426
|
+
}
|
|
16427
|
+
}
|
|
16428
|
+
async function quarantineLedgerSuffix(directory, badSuffix) {
|
|
16429
|
+
try {
|
|
16430
|
+
const quarantinePath = path4.join(directory, ".swarm", "plan-ledger.quarantine");
|
|
16431
|
+
fs4.writeFileSync(quarantinePath, badSuffix, "utf8");
|
|
16432
|
+
console.warn(`[ledger] Corrupted suffix quarantined to ${path4.relative(directory, quarantinePath)}`);
|
|
16433
|
+
} catch {}
|
|
16434
|
+
}
|
|
16386
16435
|
async function loadLastApprovedPlan(directory, expectedPlanId) {
|
|
16387
16436
|
const events = await readLedgerEvents(directory);
|
|
16388
16437
|
if (events.length === 0) {
|
|
@@ -53249,9 +53298,16 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
53249
53298
|
return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
|
|
53250
53299
|
}
|
|
53251
53300
|
const swarmDir = validateSwarmPath(directory, "");
|
|
53301
|
+
const EXCLUDE_FILES = new Set([
|
|
53302
|
+
"plan-ledger.jsonl",
|
|
53303
|
+
"plan-ledger.quarantine"
|
|
53304
|
+
]);
|
|
53252
53305
|
const successes = [];
|
|
53253
53306
|
const failures = [];
|
|
53254
53307
|
for (const file3 of checkpointFiles) {
|
|
53308
|
+
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
53309
|
+
continue;
|
|
53310
|
+
}
|
|
53255
53311
|
const src = path40.join(checkpointDir, file3);
|
|
53256
53312
|
const dest = path40.join(swarmDir, file3);
|
|
53257
53313
|
try {
|
|
@@ -53262,7 +53318,41 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
53262
53318
|
}
|
|
53263
53319
|
}
|
|
53264
53320
|
if (failures.length > 0) {
|
|
53265
|
-
return
|
|
53321
|
+
return [
|
|
53322
|
+
`Rollback partially completed. Successfully restored ${successes.length} files.`,
|
|
53323
|
+
`Failed on ${failures.length} files:`,
|
|
53324
|
+
...failures.map((f) => ` - ${f.file}: ${f.error}`),
|
|
53325
|
+
"",
|
|
53326
|
+
"Some files could not be restored. The .swarm/ directory may be in an inconsistent state.",
|
|
53327
|
+
"Check permissions and disk space, then retry the rollback."
|
|
53328
|
+
].join(`
|
|
53329
|
+
`);
|
|
53330
|
+
}
|
|
53331
|
+
const existingLedgerPath = path40.join(swarmDir, "plan-ledger.jsonl");
|
|
53332
|
+
if (fs28.existsSync(existingLedgerPath)) {
|
|
53333
|
+
fs28.unlinkSync(existingLedgerPath);
|
|
53334
|
+
}
|
|
53335
|
+
try {
|
|
53336
|
+
const planJsonPath = path40.join(swarmDir, "plan.json");
|
|
53337
|
+
if (fs28.existsSync(planJsonPath)) {
|
|
53338
|
+
const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
|
|
53339
|
+
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
53340
|
+
const planId = `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
53341
|
+
const planHash = computePlanHash(plan);
|
|
53342
|
+
await initLedger(directory, planId, planHash, plan);
|
|
53343
|
+
await appendLedgerEvent(directory, {
|
|
53344
|
+
event_type: "plan_rebuilt",
|
|
53345
|
+
source: "rollback",
|
|
53346
|
+
plan_id: planId
|
|
53347
|
+
});
|
|
53348
|
+
}
|
|
53349
|
+
} catch (initError) {
|
|
53350
|
+
return [
|
|
53351
|
+
`Rollback restored files but failed to initialize ledger: ${initError instanceof Error ? initError.message : String(initError)}`,
|
|
53352
|
+
"The .swarm/plan.json has been restored but the ledger may be out of sync.",
|
|
53353
|
+
"Run /swarm reset-session to reinitialize the ledger."
|
|
53354
|
+
].join(`
|
|
53355
|
+
`);
|
|
53266
53356
|
}
|
|
53267
53357
|
const eventsPath = validateSwarmPath(directory, "events.jsonl");
|
|
53268
53358
|
const rollbackEvent = {
|
|
@@ -53280,7 +53370,9 @@ async function handleRollbackCommand(directory, args2) {
|
|
|
53280
53370
|
return `Rolled back to phase ${targetPhase}: ${checkpoint2.label || "no label"}`;
|
|
53281
53371
|
}
|
|
53282
53372
|
var init_rollback = __esm(() => {
|
|
53373
|
+
init_plan_schema();
|
|
53283
53374
|
init_utils2();
|
|
53375
|
+
init_ledger();
|
|
53284
53376
|
});
|
|
53285
53377
|
|
|
53286
53378
|
// src/commands/simulate.ts
|
|
@@ -63247,7 +63339,7 @@ init_schema();
|
|
|
63247
63339
|
init_state();
|
|
63248
63340
|
init_utils();
|
|
63249
63341
|
init_utils2();
|
|
63250
|
-
import { renameSync as renameSync11, unlinkSync as
|
|
63342
|
+
import { renameSync as renameSync11, unlinkSync as unlinkSync8 } from "fs";
|
|
63251
63343
|
import * as nodePath2 from "path";
|
|
63252
63344
|
function createAgentActivityHooks(config3, directory) {
|
|
63253
63345
|
if (config3.hooks?.agent_activity === false) {
|
|
@@ -63324,7 +63416,7 @@ async function doFlush(directory) {
|
|
|
63324
63416
|
renameSync11(tempPath, path46);
|
|
63325
63417
|
} catch (writeError) {
|
|
63326
63418
|
try {
|
|
63327
|
-
|
|
63419
|
+
unlinkSync8(tempPath);
|
|
63328
63420
|
} catch {}
|
|
63329
63421
|
throw writeError;
|
|
63330
63422
|
}
|
|
@@ -85525,6 +85617,17 @@ init_state();
|
|
|
85525
85617
|
function slugify2(str) {
|
|
85526
85618
|
return str.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_");
|
|
85527
85619
|
}
|
|
85620
|
+
function extractJsonArray(text) {
|
|
85621
|
+
const trimmed = text.trim();
|
|
85622
|
+
const fenceMatch = trimmed.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
85623
|
+
if (fenceMatch)
|
|
85624
|
+
return fenceMatch[1].trim();
|
|
85625
|
+
const start2 = trimmed.search(/\[\s*[{["0-9\]tfn]/);
|
|
85626
|
+
const end = trimmed.lastIndexOf("]");
|
|
85627
|
+
if (start2 !== -1 && end > start2)
|
|
85628
|
+
return trimmed.slice(start2, end + 1);
|
|
85629
|
+
return trimmed;
|
|
85630
|
+
}
|
|
85528
85631
|
async function generateMutants(files, ctx) {
|
|
85529
85632
|
if (!ctx) {
|
|
85530
85633
|
console.warn("[generateMutants] No ToolContext \u2014 cannot call LLM; returning empty patch set");
|
|
@@ -85569,9 +85672,9 @@ Return a JSON array where each element has:
|
|
|
85569
85672
|
- id: unique string like "mut-001"
|
|
85570
85673
|
- mutationType: one of: ${mutationTypes}
|
|
85571
85674
|
- patch: unified diff format (--- a/file\\n+++ a/file\\n@@ ... @@\\n-old\\n+new)
|
|
85572
|
-
- Generate 5
|
|
85675
|
+
- Generate 3-5 mutations per function
|
|
85573
85676
|
|
|
85574
|
-
Return ONLY valid JSON array, no
|
|
85677
|
+
Return ONLY a valid JSON array. No markdown, no code fences, no explanation. Start your response with [ and end with ].`;
|
|
85575
85678
|
const promptResult = await client.session.prompt({
|
|
85576
85679
|
path: { id: ephemeralSessionId },
|
|
85577
85680
|
body: {
|
|
@@ -85589,9 +85692,11 @@ Return ONLY valid JSON array, no markdown, no explanation.`;
|
|
|
85589
85692
|
`);
|
|
85590
85693
|
let parsed;
|
|
85591
85694
|
try {
|
|
85592
|
-
parsed = JSON.parse(rawText);
|
|
85695
|
+
parsed = JSON.parse(extractJsonArray(rawText));
|
|
85593
85696
|
} catch (error93) {
|
|
85594
|
-
|
|
85697
|
+
const msg = error93 instanceof Error ? error93.message : String(error93);
|
|
85698
|
+
const hint = msg.includes("EOF") || msg.includes("Unexpected end") ? " (response appears truncated \u2014 LLM may have hit an output token limit)" : "";
|
|
85699
|
+
console.warn(`[generateMutants] Failed to parse LLM response as MutationPatch[]: ${msg}${hint}; returning empty patch set`);
|
|
85595
85700
|
return [];
|
|
85596
85701
|
}
|
|
85597
85702
|
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
@@ -85804,7 +85909,7 @@ import * as path95 from "path";
|
|
|
85804
85909
|
|
|
85805
85910
|
// src/mutation/engine.ts
|
|
85806
85911
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
85807
|
-
import { unlinkSync as
|
|
85912
|
+
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync18 } from "fs";
|
|
85808
85913
|
import * as path94 from "path";
|
|
85809
85914
|
|
|
85810
85915
|
// src/mutation/equivalence.ts
|
|
@@ -86038,7 +86143,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
86038
86143
|
revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
|
|
86039
86144
|
}
|
|
86040
86145
|
try {
|
|
86041
|
-
|
|
86146
|
+
unlinkSync13(patchFile);
|
|
86042
86147
|
} catch (_unlinkErr) {}
|
|
86043
86148
|
}
|
|
86044
86149
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "6.86.
|
|
3
|
+
"version": "6.86.5",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|