opencode-swarm-plugin 0.15.0 → 0.16.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/dist/index.js CHANGED
@@ -29668,6 +29668,96 @@ var SwarmStatusSchema = exports_external.object({
29668
29668
  agents: exports_external.array(SpawnedAgentSchema),
29669
29669
  last_update: exports_external.string().datetime({ offset: true })
29670
29670
  });
29671
+ // src/schemas/mandate.ts
29672
+ init_zod();
29673
+ var MandateContentTypeSchema = exports_external.enum([
29674
+ "idea",
29675
+ "tip",
29676
+ "lore",
29677
+ "snippet",
29678
+ "feature_request"
29679
+ ]);
29680
+ var MandateStatusSchema = exports_external.enum([
29681
+ "candidate",
29682
+ "established",
29683
+ "mandate",
29684
+ "rejected"
29685
+ ]);
29686
+ var VoteTypeSchema = exports_external.enum(["upvote", "downvote"]);
29687
+ var MandateEntrySchema = exports_external.object({
29688
+ id: exports_external.string(),
29689
+ content: exports_external.string().min(1, "Content required"),
29690
+ content_type: MandateContentTypeSchema,
29691
+ author_agent: exports_external.string(),
29692
+ created_at: exports_external.string().datetime({ offset: true }),
29693
+ status: MandateStatusSchema.default("candidate"),
29694
+ tags: exports_external.array(exports_external.string()).default([]),
29695
+ metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
29696
+ });
29697
+ var VoteSchema = exports_external.object({
29698
+ id: exports_external.string(),
29699
+ mandate_id: exports_external.string(),
29700
+ agent_name: exports_external.string(),
29701
+ vote_type: VoteTypeSchema,
29702
+ timestamp: exports_external.string().datetime({ offset: true }),
29703
+ weight: exports_external.number().min(0).max(1).default(1)
29704
+ });
29705
+ var MandateScoreSchema = exports_external.object({
29706
+ mandate_id: exports_external.string(),
29707
+ net_votes: exports_external.number(),
29708
+ vote_ratio: exports_external.number().min(0).max(1),
29709
+ decayed_score: exports_external.number(),
29710
+ last_calculated: exports_external.string().datetime({ offset: true }),
29711
+ raw_upvotes: exports_external.number().int().min(0),
29712
+ raw_downvotes: exports_external.number().int().min(0),
29713
+ decayed_upvotes: exports_external.number().min(0),
29714
+ decayed_downvotes: exports_external.number().min(0)
29715
+ });
29716
+ var DEFAULT_MANDATE_DECAY_CONFIG = {
29717
+ halfLifeDays: 90,
29718
+ mandateNetVotesThreshold: 5,
29719
+ mandateVoteRatioThreshold: 0.7,
29720
+ establishedNetVotesThreshold: 2,
29721
+ rejectedNetVotesThreshold: -3
29722
+ };
29723
+ var CreateMandateArgsSchema = exports_external.object({
29724
+ content: exports_external.string().min(1, "Content required"),
29725
+ content_type: MandateContentTypeSchema,
29726
+ tags: exports_external.array(exports_external.string()).default([]),
29727
+ metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
29728
+ });
29729
+ var CastVoteArgsSchema = exports_external.object({
29730
+ mandate_id: exports_external.string(),
29731
+ vote_type: VoteTypeSchema,
29732
+ weight: exports_external.number().min(0).max(1).default(1)
29733
+ });
29734
+ var QueryMandatesArgsSchema = exports_external.object({
29735
+ status: MandateStatusSchema.optional(),
29736
+ content_type: MandateContentTypeSchema.optional(),
29737
+ tags: exports_external.array(exports_external.string()).optional(),
29738
+ author_agent: exports_external.string().optional(),
29739
+ limit: exports_external.number().int().positive().default(20),
29740
+ min_score: exports_external.number().optional()
29741
+ });
29742
+ var ScoreCalculationResultSchema = exports_external.object({
29743
+ mandate_id: exports_external.string(),
29744
+ previous_status: MandateStatusSchema,
29745
+ new_status: MandateStatusSchema,
29746
+ score: MandateScoreSchema,
29747
+ status_changed: exports_external.boolean()
29748
+ });
29749
+ var mandateSchemas = {
29750
+ MandateContentTypeSchema,
29751
+ MandateStatusSchema,
29752
+ VoteTypeSchema,
29753
+ MandateEntrySchema,
29754
+ VoteSchema,
29755
+ MandateScoreSchema,
29756
+ CreateMandateArgsSchema,
29757
+ CastVoteArgsSchema,
29758
+ QueryMandatesArgsSchema,
29759
+ ScoreCalculationResultSchema
29760
+ };
29671
29761
  // src/beads.ts
29672
29762
  var beadsWorkingDirectory = null;
29673
29763
  function setBeadsWorkingDirectory(directory) {
@@ -35150,6 +35240,762 @@ var repoCrawlTools = {
35150
35240
  // src/index.ts
35151
35241
  init_skills();
35152
35242
 
35243
+ // src/mandates.ts
35244
+ init_dist();
35245
+
35246
+ // src/mandate-storage.ts
35247
+ var cachedCommand = null;
35248
+ async function resolveSemanticMemoryCommand() {
35249
+ if (cachedCommand)
35250
+ return cachedCommand;
35251
+ const nativeResult = await Bun.$`which semantic-memory`.quiet().nothrow();
35252
+ if (nativeResult.exitCode === 0) {
35253
+ cachedCommand = ["semantic-memory"];
35254
+ return cachedCommand;
35255
+ }
35256
+ cachedCommand = ["bunx", "semantic-memory"];
35257
+ return cachedCommand;
35258
+ }
35259
+ async function execSemanticMemory(args) {
35260
+ try {
35261
+ const cmd = await resolveSemanticMemoryCommand();
35262
+ const fullCmd = [...cmd, ...args];
35263
+ const proc = Bun.spawn(fullCmd, {
35264
+ stdout: "pipe",
35265
+ stderr: "pipe"
35266
+ });
35267
+ try {
35268
+ const stdout = Buffer.from(await new Response(proc.stdout).arrayBuffer());
35269
+ const stderr = Buffer.from(await new Response(proc.stderr).arrayBuffer());
35270
+ const exitCode = await proc.exited;
35271
+ return { exitCode, stdout, stderr };
35272
+ } finally {
35273
+ proc.kill();
35274
+ }
35275
+ } catch (error45) {
35276
+ const errorMessage = error45 instanceof Error ? error45.message : String(error45);
35277
+ return {
35278
+ exitCode: 1,
35279
+ stdout: Buffer.from(""),
35280
+ stderr: Buffer.from(`Error executing semantic-memory: ${errorMessage}`)
35281
+ };
35282
+ }
35283
+ }
35284
+ var DEFAULT_MANDATE_STORAGE_CONFIG = {
35285
+ backend: "semantic-memory",
35286
+ collections: {
35287
+ mandates: "swarm-mandates",
35288
+ votes: "swarm-votes"
35289
+ },
35290
+ decay: DEFAULT_MANDATE_DECAY_CONFIG,
35291
+ useSemanticSearch: true
35292
+ };
35293
+
35294
+ class SemanticMemoryMandateStorage {
35295
+ config;
35296
+ constructor(config2 = {}) {
35297
+ this.config = { ...DEFAULT_MANDATE_STORAGE_CONFIG, ...config2 };
35298
+ }
35299
+ async storeInternal(collection, data, metadata) {
35300
+ const content = typeof data === "string" ? data : JSON.stringify(data);
35301
+ const args = ["store", content, "--collection", collection];
35302
+ if (metadata) {
35303
+ args.push("--metadata", JSON.stringify(metadata));
35304
+ }
35305
+ await execSemanticMemory(args);
35306
+ }
35307
+ async findInternal(collection, query, limit = 10, useFts = false) {
35308
+ const args = [
35309
+ "find",
35310
+ query,
35311
+ "--collection",
35312
+ collection,
35313
+ "--limit",
35314
+ String(limit),
35315
+ "--json"
35316
+ ];
35317
+ if (useFts) {
35318
+ args.push("--fts");
35319
+ }
35320
+ const result = await execSemanticMemory(args);
35321
+ if (result.exitCode !== 0) {
35322
+ console.warn(`[mandate-storage] semantic-memory find() failed with exit code ${result.exitCode}: ${result.stderr.toString().trim()}`);
35323
+ return [];
35324
+ }
35325
+ try {
35326
+ const output = result.stdout.toString().trim();
35327
+ if (!output)
35328
+ return [];
35329
+ const parsed = JSON.parse(output);
35330
+ const results = Array.isArray(parsed) ? parsed : parsed.results || [];
35331
+ return results.map((r) => {
35332
+ const content = r.content || r.information || "";
35333
+ try {
35334
+ return JSON.parse(content);
35335
+ } catch {
35336
+ return content;
35337
+ }
35338
+ });
35339
+ } catch (error45) {
35340
+ console.warn(`[mandate-storage] Failed to parse semantic-memory find() output: ${error45 instanceof Error ? error45.message : String(error45)}`);
35341
+ return [];
35342
+ }
35343
+ }
35344
+ async listInternal(collection) {
35345
+ const result = await execSemanticMemory([
35346
+ "list",
35347
+ "--collection",
35348
+ collection,
35349
+ "--json"
35350
+ ]);
35351
+ if (result.exitCode !== 0) {
35352
+ console.warn(`[mandate-storage] semantic-memory list() failed with exit code ${result.exitCode}: ${result.stderr.toString().trim()}`);
35353
+ return [];
35354
+ }
35355
+ try {
35356
+ const output = result.stdout.toString().trim();
35357
+ if (!output)
35358
+ return [];
35359
+ const parsed = JSON.parse(output);
35360
+ const items = Array.isArray(parsed) ? parsed : parsed.items || [];
35361
+ return items.map((item) => {
35362
+ const content = item.content || item.information || "";
35363
+ try {
35364
+ return JSON.parse(content);
35365
+ } catch {
35366
+ return content;
35367
+ }
35368
+ });
35369
+ } catch (error45) {
35370
+ console.warn(`[mandate-storage] Failed to parse semantic-memory list() output: ${error45 instanceof Error ? error45.message : String(error45)}`);
35371
+ return [];
35372
+ }
35373
+ }
35374
+ async store(entry) {
35375
+ await this.storeInternal(this.config.collections.mandates, entry, {
35376
+ id: entry.id,
35377
+ content_type: entry.content_type,
35378
+ author_agent: entry.author_agent,
35379
+ status: entry.status,
35380
+ tags: entry.tags.join(","),
35381
+ created_at: entry.created_at
35382
+ });
35383
+ }
35384
+ async get(id) {
35385
+ const all = await this.listInternal(this.config.collections.mandates);
35386
+ return all.find((entry) => entry.id === id) || null;
35387
+ }
35388
+ async find(query, limit = 10) {
35389
+ return this.findInternal(this.config.collections.mandates, query, limit, !this.config.useSemanticSearch);
35390
+ }
35391
+ async list(filter2) {
35392
+ const all = await this.listInternal(this.config.collections.mandates);
35393
+ if (!filter2)
35394
+ return all;
35395
+ return all.filter((entry) => {
35396
+ if (filter2.status && entry.status !== filter2.status)
35397
+ return false;
35398
+ if (filter2.content_type && entry.content_type !== filter2.content_type)
35399
+ return false;
35400
+ return true;
35401
+ });
35402
+ }
35403
+ async update(id, updates) {
35404
+ const existing = await this.get(id);
35405
+ if (!existing) {
35406
+ throw new Error(`Mandate ${id} not found`);
35407
+ }
35408
+ const updated = { ...existing, ...updates };
35409
+ await this.store(updated);
35410
+ }
35411
+ async vote(vote) {
35412
+ const existing = await this.hasVoted(vote.mandate_id, vote.agent_name);
35413
+ if (existing) {
35414
+ throw new Error(`Agent ${vote.agent_name} has already voted on mandate ${vote.mandate_id}`);
35415
+ }
35416
+ await this.storeInternal(this.config.collections.votes, vote, {
35417
+ id: vote.id,
35418
+ mandate_id: vote.mandate_id,
35419
+ agent_name: vote.agent_name,
35420
+ vote_type: vote.vote_type,
35421
+ timestamp: vote.timestamp,
35422
+ weight: vote.weight
35423
+ });
35424
+ }
35425
+ async getVotes(mandateId) {
35426
+ const all = await this.listInternal(this.config.collections.votes);
35427
+ return all.filter((vote) => vote.mandate_id === mandateId);
35428
+ }
35429
+ async hasVoted(mandateId, agentName) {
35430
+ const votes = await this.getVotes(mandateId);
35431
+ return votes.some((vote) => vote.agent_name === agentName);
35432
+ }
35433
+ async calculateScore(mandateId) {
35434
+ const votes = await this.getVotes(mandateId);
35435
+ const now = new Date;
35436
+ let rawUpvotes = 0;
35437
+ let rawDownvotes = 0;
35438
+ let decayedUpvotes = 0;
35439
+ let decayedDownvotes = 0;
35440
+ for (const vote of votes) {
35441
+ const decayed = calculateDecayedValue(vote.timestamp, now, this.config.decay.halfLifeDays);
35442
+ const value = vote.weight * decayed;
35443
+ if (vote.vote_type === "upvote") {
35444
+ rawUpvotes++;
35445
+ decayedUpvotes += value;
35446
+ } else {
35447
+ rawDownvotes++;
35448
+ decayedDownvotes += value;
35449
+ }
35450
+ }
35451
+ const totalDecayed = decayedUpvotes + decayedDownvotes;
35452
+ const voteRatio = totalDecayed > 0 ? decayedUpvotes / totalDecayed : 0;
35453
+ const netVotes = decayedUpvotes - decayedDownvotes;
35454
+ const decayedScore = netVotes * voteRatio;
35455
+ return {
35456
+ mandate_id: mandateId,
35457
+ net_votes: netVotes,
35458
+ vote_ratio: voteRatio,
35459
+ decayed_score: decayedScore,
35460
+ last_calculated: now.toISOString(),
35461
+ raw_upvotes: rawUpvotes,
35462
+ raw_downvotes: rawDownvotes,
35463
+ decayed_upvotes: decayedUpvotes,
35464
+ decayed_downvotes: decayedDownvotes
35465
+ };
35466
+ }
35467
+ async close() {}
35468
+ }
35469
+
35470
+ class InMemoryMandateStorage {
35471
+ entries = new Map;
35472
+ votes = new Map;
35473
+ config;
35474
+ constructor(config2 = {}) {
35475
+ const fullConfig = { ...DEFAULT_MANDATE_STORAGE_CONFIG, ...config2 };
35476
+ this.config = fullConfig.decay;
35477
+ }
35478
+ async store(entry) {
35479
+ this.entries.set(entry.id, entry);
35480
+ }
35481
+ async get(id) {
35482
+ return this.entries.get(id) || null;
35483
+ }
35484
+ async find(query, limit = 10) {
35485
+ const lowerQuery = query.toLowerCase();
35486
+ const results = Array.from(this.entries.values()).filter((entry) => entry.content.toLowerCase().includes(lowerQuery) || entry.tags.some((tag) => tag.toLowerCase().includes(lowerQuery)));
35487
+ return results.slice(0, limit);
35488
+ }
35489
+ async list(filter2) {
35490
+ let results = Array.from(this.entries.values());
35491
+ if (filter2) {
35492
+ results = results.filter((entry) => {
35493
+ if (filter2.status && entry.status !== filter2.status)
35494
+ return false;
35495
+ if (filter2.content_type && entry.content_type !== filter2.content_type)
35496
+ return false;
35497
+ return true;
35498
+ });
35499
+ }
35500
+ return results;
35501
+ }
35502
+ async update(id, updates) {
35503
+ const existing = await this.get(id);
35504
+ if (!existing) {
35505
+ throw new Error(`Mandate ${id} not found`);
35506
+ }
35507
+ const updated = { ...existing, ...updates };
35508
+ this.entries.set(id, updated);
35509
+ }
35510
+ async vote(vote) {
35511
+ const existing = await this.hasVoted(vote.mandate_id, vote.agent_name);
35512
+ if (existing) {
35513
+ throw new Error(`Agent ${vote.agent_name} has already voted on mandate ${vote.mandate_id}`);
35514
+ }
35515
+ this.votes.set(vote.id, vote);
35516
+ }
35517
+ async getVotes(mandateId) {
35518
+ return Array.from(this.votes.values()).filter((vote) => vote.mandate_id === mandateId);
35519
+ }
35520
+ async hasVoted(mandateId, agentName) {
35521
+ const votes = await this.getVotes(mandateId);
35522
+ return votes.some((vote) => vote.agent_name === agentName);
35523
+ }
35524
+ async calculateScore(mandateId) {
35525
+ const votes = await this.getVotes(mandateId);
35526
+ const now = new Date;
35527
+ let rawUpvotes = 0;
35528
+ let rawDownvotes = 0;
35529
+ let decayedUpvotes = 0;
35530
+ let decayedDownvotes = 0;
35531
+ for (const vote of votes) {
35532
+ const decayed = calculateDecayedValue(vote.timestamp, now, this.config.halfLifeDays);
35533
+ const value = vote.weight * decayed;
35534
+ if (vote.vote_type === "upvote") {
35535
+ rawUpvotes++;
35536
+ decayedUpvotes += value;
35537
+ } else {
35538
+ rawDownvotes++;
35539
+ decayedDownvotes += value;
35540
+ }
35541
+ }
35542
+ const totalDecayed = decayedUpvotes + decayedDownvotes;
35543
+ const voteRatio = totalDecayed > 0 ? decayedUpvotes / totalDecayed : 0;
35544
+ const netVotes = decayedUpvotes - decayedDownvotes;
35545
+ const decayedScore = netVotes * voteRatio;
35546
+ return {
35547
+ mandate_id: mandateId,
35548
+ net_votes: netVotes,
35549
+ vote_ratio: voteRatio,
35550
+ decayed_score: decayedScore,
35551
+ last_calculated: now.toISOString(),
35552
+ raw_upvotes: rawUpvotes,
35553
+ raw_downvotes: rawDownvotes,
35554
+ decayed_upvotes: decayedUpvotes,
35555
+ decayed_downvotes: decayedDownvotes
35556
+ };
35557
+ }
35558
+ async close() {}
35559
+ }
35560
+ function createMandateStorage(config2 = {}) {
35561
+ const fullConfig = { ...DEFAULT_MANDATE_STORAGE_CONFIG, ...config2 };
35562
+ switch (fullConfig.backend) {
35563
+ case "semantic-memory":
35564
+ return new SemanticMemoryMandateStorage(fullConfig);
35565
+ case "memory":
35566
+ return new InMemoryMandateStorage(fullConfig);
35567
+ default:
35568
+ throw new Error(`Unknown storage backend: ${fullConfig.backend}`);
35569
+ }
35570
+ }
35571
+ async function updateMandateStatus(mandateId, storage) {
35572
+ const entry = await storage.get(mandateId);
35573
+ if (!entry) {
35574
+ throw new Error(`Mandate ${mandateId} not found`);
35575
+ }
35576
+ const score = await storage.calculateScore(mandateId);
35577
+ const previousStatus = entry.status;
35578
+ let newStatus;
35579
+ const config2 = DEFAULT_MANDATE_DECAY_CONFIG;
35580
+ if (score.net_votes >= config2.mandateNetVotesThreshold && score.vote_ratio >= config2.mandateVoteRatioThreshold) {
35581
+ newStatus = "mandate";
35582
+ } else if (score.net_votes <= config2.rejectedNetVotesThreshold) {
35583
+ newStatus = "rejected";
35584
+ } else if (score.net_votes >= config2.establishedNetVotesThreshold) {
35585
+ newStatus = "established";
35586
+ } else {
35587
+ newStatus = "candidate";
35588
+ }
35589
+ if (newStatus !== previousStatus) {
35590
+ await storage.update(mandateId, { status: newStatus });
35591
+ }
35592
+ return {
35593
+ mandate_id: mandateId,
35594
+ previous_status: previousStatus,
35595
+ new_status: newStatus,
35596
+ score,
35597
+ status_changed: newStatus !== previousStatus
35598
+ };
35599
+ }
35600
+ async function updateAllMandateStatuses(storage) {
35601
+ const allEntries = await storage.list();
35602
+ const results = [];
35603
+ for (const entry of allEntries) {
35604
+ const result = await updateMandateStatus(entry.id, storage);
35605
+ results.push(result);
35606
+ }
35607
+ return results;
35608
+ }
35609
+ var globalMandateStorage = null;
35610
+ function getMandateStorage() {
35611
+ if (!globalMandateStorage) {
35612
+ globalMandateStorage = createMandateStorage();
35613
+ }
35614
+ return globalMandateStorage;
35615
+ }
35616
+ function setMandateStorage(storage) {
35617
+ globalMandateStorage = storage;
35618
+ }
35619
+ async function resetMandateStorage() {
35620
+ if (globalMandateStorage) {
35621
+ await globalMandateStorage.close();
35622
+ globalMandateStorage = null;
35623
+ }
35624
+ }
35625
+
35626
+ // src/mandate-promotion.ts
35627
+ function shouldPromote(score, currentStatus, config2 = DEFAULT_MANDATE_DECAY_CONFIG) {
35628
+ if (currentStatus === "rejected") {
35629
+ return "rejected";
35630
+ }
35631
+ if (currentStatus === "mandate") {
35632
+ return "mandate";
35633
+ }
35634
+ if (score.net_votes <= config2.rejectedNetVotesThreshold) {
35635
+ return "rejected";
35636
+ }
35637
+ if (currentStatus === "established") {
35638
+ if (score.net_votes >= config2.mandateNetVotesThreshold && score.vote_ratio >= config2.mandateVoteRatioThreshold) {
35639
+ return "mandate";
35640
+ }
35641
+ return "established";
35642
+ }
35643
+ if (score.net_votes >= config2.establishedNetVotesThreshold) {
35644
+ return "established";
35645
+ }
35646
+ return "candidate";
35647
+ }
35648
+ function evaluatePromotion(entry, score, config2 = DEFAULT_MANDATE_DECAY_CONFIG) {
35649
+ const previousStatus = entry.status;
35650
+ const newStatus = shouldPromote(score, previousStatus, config2);
35651
+ const promoted = newStatus !== previousStatus;
35652
+ let reason;
35653
+ if (newStatus === "rejected" && previousStatus === "rejected") {
35654
+ reason = `Remains rejected (permanent)`;
35655
+ } else if (newStatus === "rejected") {
35656
+ reason = `Rejected due to negative consensus (net_votes: ${score.net_votes.toFixed(2)} ≤ ${config2.rejectedNetVotesThreshold})`;
35657
+ } else if (newStatus === "mandate" && previousStatus === "mandate") {
35658
+ reason = `Remains mandate (no demotion)`;
35659
+ } else if (newStatus === "mandate" && previousStatus === "established") {
35660
+ reason = `Promoted to mandate (net_votes: ${score.net_votes.toFixed(2)} ≥ ${config2.mandateNetVotesThreshold}, ratio: ${score.vote_ratio.toFixed(2)} ≥ ${config2.mandateVoteRatioThreshold})`;
35661
+ } else if (newStatus === "established" && previousStatus === "established") {
35662
+ reason = `Remains established (net_votes: ${score.net_votes.toFixed(2)}, ratio: ${score.vote_ratio.toFixed(2)} below mandate threshold)`;
35663
+ } else if (newStatus === "established" && previousStatus === "candidate") {
35664
+ reason = `Promoted to established (net_votes: ${score.net_votes.toFixed(2)} ≥ ${config2.establishedNetVotesThreshold})`;
35665
+ } else if (newStatus === "candidate") {
35666
+ reason = `Remains candidate (net_votes: ${score.net_votes.toFixed(2)} below threshold)`;
35667
+ } else {
35668
+ reason = `No status change (current: ${previousStatus})`;
35669
+ }
35670
+ return {
35671
+ mandate_id: entry.id,
35672
+ previous_status: previousStatus,
35673
+ new_status: newStatus,
35674
+ score,
35675
+ promoted,
35676
+ reason
35677
+ };
35678
+ }
35679
+ function formatPromotionResult(result) {
35680
+ const arrow = result.promoted ? `${result.previous_status} → ${result.new_status}` : result.new_status;
35681
+ return `[${result.mandate_id}] ${arrow}: ${result.reason}`;
35682
+ }
35683
+ function evaluateBatchPromotions(entries, scores, config2 = DEFAULT_MANDATE_DECAY_CONFIG) {
35684
+ const results = [];
35685
+ for (const [id, entry] of entries) {
35686
+ const score = scores.get(id);
35687
+ if (!score) {
35688
+ continue;
35689
+ }
35690
+ const result = evaluatePromotion(entry, score, config2);
35691
+ results.push(result);
35692
+ }
35693
+ return results;
35694
+ }
35695
+ function getStatusChanges(results) {
35696
+ return results.filter((r) => r.promoted);
35697
+ }
35698
+ function groupByTransition(results) {
35699
+ const groups = new Map;
35700
+ for (const result of results) {
35701
+ const key = result.promoted ? `${result.previous_status}→${result.new_status}` : result.new_status;
35702
+ const existing = groups.get(key);
35703
+ if (existing) {
35704
+ existing.push(result);
35705
+ } else {
35706
+ groups.set(key, [result]);
35707
+ }
35708
+ }
35709
+ return groups;
35710
+ }
35711
+
35712
+ // src/mandates.ts
35713
+ class MandateError extends Error {
35714
+ operation;
35715
+ details;
35716
+ constructor(message, operation, details) {
35717
+ super(message);
35718
+ this.operation = operation;
35719
+ this.details = details;
35720
+ this.name = "MandateError";
35721
+ }
35722
+ }
35723
+ function generateMandateId() {
35724
+ const timestamp = Date.now().toString(36);
35725
+ const random = Math.random().toString(36).substring(2, 8);
35726
+ return `mandate-${timestamp}-${random}`;
35727
+ }
35728
+ function generateVoteId() {
35729
+ const timestamp = Date.now().toString(36);
35730
+ const random = Math.random().toString(36).substring(2, 8);
35731
+ return `vote-${timestamp}-${random}`;
35732
+ }
35733
+ var mandate_file = tool({
35734
+ description: "Submit a new idea, tip, lore, snippet, or feature request to the mandate system",
35735
+ args: {
35736
+ content: tool.schema.string().min(1).describe("The content to submit"),
35737
+ content_type: tool.schema.enum(["idea", "tip", "lore", "snippet", "feature_request"]).describe("Type of content"),
35738
+ tags: tool.schema.array(tool.schema.string()).optional().describe("Optional tags for categorization"),
35739
+ metadata: tool.schema.record(tool.schema.string(), tool.schema.unknown()).optional().describe("Optional metadata (e.g., code language for snippets)")
35740
+ },
35741
+ async execute(args) {
35742
+ const validated = CreateMandateArgsSchema.parse(args);
35743
+ const agentName = "system";
35744
+ const entry = {
35745
+ id: generateMandateId(),
35746
+ content: validated.content,
35747
+ content_type: validated.content_type,
35748
+ author_agent: agentName,
35749
+ created_at: new Date().toISOString(),
35750
+ status: "candidate",
35751
+ tags: validated.tags || [],
35752
+ metadata: validated.metadata
35753
+ };
35754
+ const validatedEntry = MandateEntrySchema.parse(entry);
35755
+ const storage = getMandateStorage();
35756
+ try {
35757
+ await storage.store(validatedEntry);
35758
+ } catch (error45) {
35759
+ throw new MandateError(`Failed to store mandate: ${error45 instanceof Error ? error45.message : String(error45)}`, "mandate_file", error45);
35760
+ }
35761
+ return JSON.stringify({
35762
+ success: true,
35763
+ mandate: validatedEntry,
35764
+ message: `Mandate ${validatedEntry.id} filed successfully`
35765
+ }, null, 2);
35766
+ }
35767
+ });
35768
+ var mandate_vote = tool({
35769
+ description: "Cast a vote (upvote or downvote) on an existing mandate",
35770
+ args: {
35771
+ mandate_id: tool.schema.string().describe("Mandate ID to vote on"),
35772
+ vote_type: tool.schema.enum(["upvote", "downvote"]).describe("Type of vote"),
35773
+ agent_name: tool.schema.string().describe("Agent name casting the vote")
35774
+ },
35775
+ async execute(args) {
35776
+ const validated = CastVoteArgsSchema.parse({
35777
+ mandate_id: args.mandate_id,
35778
+ vote_type: args.vote_type,
35779
+ weight: 1
35780
+ });
35781
+ const storage = getMandateStorage();
35782
+ const mandate = await storage.get(validated.mandate_id);
35783
+ if (!mandate) {
35784
+ throw new MandateError(`Mandate ${validated.mandate_id} not found`, "mandate_vote");
35785
+ }
35786
+ const hasVoted = await storage.hasVoted(validated.mandate_id, args.agent_name);
35787
+ if (hasVoted) {
35788
+ throw new MandateError(`Agent ${args.agent_name} has already voted on mandate ${validated.mandate_id}`, "mandate_vote");
35789
+ }
35790
+ const vote = {
35791
+ id: generateVoteId(),
35792
+ mandate_id: validated.mandate_id,
35793
+ agent_name: args.agent_name,
35794
+ vote_type: validated.vote_type,
35795
+ timestamp: new Date().toISOString(),
35796
+ weight: validated.weight
35797
+ };
35798
+ const validatedVote = VoteSchema.parse(vote);
35799
+ try {
35800
+ await storage.vote(validatedVote);
35801
+ } catch (error45) {
35802
+ throw new MandateError(`Failed to cast vote: ${error45 instanceof Error ? error45.message : String(error45)}`, "mandate_vote", error45);
35803
+ }
35804
+ const promotion = await updateMandateStatus(validated.mandate_id, storage);
35805
+ return JSON.stringify({
35806
+ success: true,
35807
+ vote: validatedVote,
35808
+ promotion: {
35809
+ previous_status: promotion.previous_status,
35810
+ new_status: promotion.new_status,
35811
+ status_changed: promotion.status_changed,
35812
+ score: promotion.score
35813
+ },
35814
+ message: formatPromotionResult({
35815
+ mandate_id: promotion.mandate_id,
35816
+ previous_status: promotion.previous_status,
35817
+ new_status: promotion.new_status,
35818
+ score: promotion.score,
35819
+ promoted: promotion.status_changed,
35820
+ reason: evaluatePromotion(mandate, promotion.score).reason || "Vote recorded"
35821
+ })
35822
+ }, null, 2);
35823
+ }
35824
+ });
35825
+ var mandate_query = tool({
35826
+ description: "Search for relevant mandates using semantic search (by meaning, not keywords)",
35827
+ args: {
35828
+ query: tool.schema.string().min(1).describe("Natural language query"),
35829
+ limit: tool.schema.number().int().positive().optional().describe("Max results to return (default: 5)"),
35830
+ status: tool.schema.enum(["candidate", "established", "mandate", "rejected"]).optional().describe("Filter by status"),
35831
+ content_type: tool.schema.enum(["idea", "tip", "lore", "snippet", "feature_request"]).optional().describe("Filter by content type")
35832
+ },
35833
+ async execute(args) {
35834
+ const storage = getMandateStorage();
35835
+ const limit = args.limit ?? 5;
35836
+ try {
35837
+ let results = await storage.find(args.query, limit * 2);
35838
+ if (args.status) {
35839
+ results = results.filter((m) => m.status === args.status);
35840
+ }
35841
+ if (args.content_type) {
35842
+ results = results.filter((m) => m.content_type === args.content_type);
35843
+ }
35844
+ results = results.slice(0, limit);
35845
+ const resultsWithScores = await Promise.all(results.map(async (mandate) => {
35846
+ const score = await storage.calculateScore(mandate.id);
35847
+ return { mandate, score };
35848
+ }));
35849
+ resultsWithScores.sort((a, b) => b.score.decayed_score - a.score.decayed_score);
35850
+ return JSON.stringify({
35851
+ query: args.query,
35852
+ count: resultsWithScores.length,
35853
+ results: resultsWithScores.map(({ mandate, score }) => ({
35854
+ id: mandate.id,
35855
+ content: mandate.content,
35856
+ content_type: mandate.content_type,
35857
+ status: mandate.status,
35858
+ author: mandate.author_agent,
35859
+ created_at: mandate.created_at,
35860
+ tags: mandate.tags,
35861
+ score: {
35862
+ net_votes: score.net_votes,
35863
+ vote_ratio: score.vote_ratio,
35864
+ decayed_score: score.decayed_score
35865
+ }
35866
+ }))
35867
+ }, null, 2);
35868
+ } catch (error45) {
35869
+ throw new MandateError(`Failed to query mandates: ${error45 instanceof Error ? error45.message : String(error45)}`, "mandate_query", error45);
35870
+ }
35871
+ }
35872
+ });
35873
+ var mandate_list = tool({
35874
+ description: "List mandates with optional filters (status, content type)",
35875
+ args: {
35876
+ status: tool.schema.enum(["candidate", "established", "mandate", "rejected"]).optional().describe("Filter by status"),
35877
+ content_type: tool.schema.enum(["idea", "tip", "lore", "snippet", "feature_request"]).optional().describe("Filter by content type"),
35878
+ limit: tool.schema.number().int().positive().optional().describe("Max results to return (default: 20)")
35879
+ },
35880
+ async execute(args) {
35881
+ const storage = getMandateStorage();
35882
+ const limit = args.limit ?? 20;
35883
+ try {
35884
+ let results = await storage.list({
35885
+ status: args.status,
35886
+ content_type: args.content_type
35887
+ });
35888
+ results = results.slice(0, limit);
35889
+ const resultsWithScores = await Promise.all(results.map(async (mandate) => {
35890
+ const score = await storage.calculateScore(mandate.id);
35891
+ return { mandate, score };
35892
+ }));
35893
+ resultsWithScores.sort((a, b) => b.score.decayed_score - a.score.decayed_score);
35894
+ return JSON.stringify({
35895
+ filters: {
35896
+ status: args.status || "all",
35897
+ content_type: args.content_type || "all"
35898
+ },
35899
+ count: resultsWithScores.length,
35900
+ results: resultsWithScores.map(({ mandate, score }) => ({
35901
+ id: mandate.id,
35902
+ content: mandate.content.slice(0, 200),
35903
+ content_type: mandate.content_type,
35904
+ status: mandate.status,
35905
+ author: mandate.author_agent,
35906
+ created_at: mandate.created_at,
35907
+ tags: mandate.tags,
35908
+ score: {
35909
+ net_votes: score.net_votes,
35910
+ vote_ratio: score.vote_ratio,
35911
+ decayed_score: score.decayed_score
35912
+ }
35913
+ }))
35914
+ }, null, 2);
35915
+ } catch (error45) {
35916
+ throw new MandateError(`Failed to list mandates: ${error45 instanceof Error ? error45.message : String(error45)}`, "mandate_list", error45);
35917
+ }
35918
+ }
35919
+ });
35920
+ var mandate_stats = tool({
35921
+ description: "Get voting statistics for a specific mandate or overall system",
35922
+ args: {
35923
+ mandate_id: tool.schema.string().optional().describe("Mandate ID (omit for overall stats)")
35924
+ },
35925
+ async execute(args) {
35926
+ const storage = getMandateStorage();
35927
+ try {
35928
+ if (args.mandate_id) {
35929
+ const mandate = await storage.get(args.mandate_id);
35930
+ if (!mandate) {
35931
+ throw new MandateError(`Mandate ${args.mandate_id} not found`, "mandate_stats");
35932
+ }
35933
+ const score = await storage.calculateScore(args.mandate_id);
35934
+ const votes = await storage.getVotes(args.mandate_id);
35935
+ return JSON.stringify({
35936
+ mandate_id: args.mandate_id,
35937
+ status: mandate.status,
35938
+ content_type: mandate.content_type,
35939
+ author: mandate.author_agent,
35940
+ created_at: mandate.created_at,
35941
+ votes: {
35942
+ total: votes.length,
35943
+ raw_upvotes: score.raw_upvotes,
35944
+ raw_downvotes: score.raw_downvotes,
35945
+ decayed_upvotes: score.decayed_upvotes,
35946
+ decayed_downvotes: score.decayed_downvotes,
35947
+ net_votes: score.net_votes,
35948
+ vote_ratio: score.vote_ratio,
35949
+ decayed_score: score.decayed_score
35950
+ },
35951
+ voters: votes.map((v) => ({
35952
+ agent: v.agent_name,
35953
+ vote_type: v.vote_type,
35954
+ timestamp: v.timestamp
35955
+ }))
35956
+ }, null, 2);
35957
+ } else {
35958
+ const allMandates = await storage.list();
35959
+ const stats = {
35960
+ total_mandates: allMandates.length,
35961
+ by_status: {
35962
+ candidate: 0,
35963
+ established: 0,
35964
+ mandate: 0,
35965
+ rejected: 0
35966
+ },
35967
+ by_content_type: {
35968
+ idea: 0,
35969
+ tip: 0,
35970
+ lore: 0,
35971
+ snippet: 0,
35972
+ feature_request: 0
35973
+ },
35974
+ total_votes: 0
35975
+ };
35976
+ for (const mandate of allMandates) {
35977
+ stats.by_status[mandate.status]++;
35978
+ stats.by_content_type[mandate.content_type]++;
35979
+ const votes = await storage.getVotes(mandate.id);
35980
+ stats.total_votes += votes.length;
35981
+ }
35982
+ return JSON.stringify(stats, null, 2);
35983
+ }
35984
+ } catch (error45) {
35985
+ if (error45 instanceof MandateError) {
35986
+ throw error45;
35987
+ }
35988
+ throw new MandateError(`Failed to get mandate stats: ${error45 instanceof Error ? error45.message : String(error45)}`, "mandate_stats", error45);
35989
+ }
35990
+ }
35991
+ });
35992
+ var mandateTools = {
35993
+ mandate_file,
35994
+ mandate_vote,
35995
+ mandate_query,
35996
+ mandate_list,
35997
+ mandate_stats
35998
+ };
35153
35999
  // src/anti-patterns.ts
35154
36000
  init_zod();
35155
36001
  var PatternKindSchema = exports_external.enum(["pattern", "anti_pattern"]);
@@ -35241,21 +36087,21 @@ class InMemoryMaturityStorage {
35241
36087
  }
35242
36088
 
35243
36089
  // src/storage.ts
35244
- var cachedCommand = null;
35245
- async function resolveSemanticMemoryCommand() {
35246
- if (cachedCommand)
35247
- return cachedCommand;
36090
+ var cachedCommand2 = null;
36091
+ async function resolveSemanticMemoryCommand2() {
36092
+ if (cachedCommand2)
36093
+ return cachedCommand2;
35248
36094
  const nativeResult = await Bun.$`which semantic-memory`.quiet().nothrow();
35249
36095
  if (nativeResult.exitCode === 0) {
35250
- cachedCommand = ["semantic-memory"];
35251
- return cachedCommand;
36096
+ cachedCommand2 = ["semantic-memory"];
36097
+ return cachedCommand2;
35252
36098
  }
35253
- cachedCommand = ["bunx", "semantic-memory"];
35254
- return cachedCommand;
36099
+ cachedCommand2 = ["bunx", "semantic-memory"];
36100
+ return cachedCommand2;
35255
36101
  }
35256
- async function execSemanticMemory(args) {
36102
+ async function execSemanticMemory2(args) {
35257
36103
  try {
35258
- const cmd = await resolveSemanticMemoryCommand();
36104
+ const cmd = await resolveSemanticMemoryCommand2();
35259
36105
  const fullCmd = [...cmd, ...args];
35260
36106
  const proc = Bun.spawn(fullCmd, {
35261
36107
  stdout: "pipe",
@@ -35299,7 +36145,7 @@ class SemanticMemoryStorage {
35299
36145
  if (metadata) {
35300
36146
  args.push("--metadata", JSON.stringify(metadata));
35301
36147
  }
35302
- await execSemanticMemory(args);
36148
+ await execSemanticMemory2(args);
35303
36149
  }
35304
36150
  async find(collection, query, limit = 10, useFts = false) {
35305
36151
  const args = [
@@ -35314,7 +36160,7 @@ class SemanticMemoryStorage {
35314
36160
  if (useFts) {
35315
36161
  args.push("--fts");
35316
36162
  }
35317
- const result = await execSemanticMemory(args);
36163
+ const result = await execSemanticMemory2(args);
35318
36164
  if (result.exitCode !== 0) {
35319
36165
  console.warn(`[storage] semantic-memory find() failed with exit code ${result.exitCode}: ${result.stderr.toString().trim()}`);
35320
36166
  return [];
@@ -35339,7 +36185,7 @@ class SemanticMemoryStorage {
35339
36185
  }
35340
36186
  }
35341
36187
  async list(collection) {
35342
- const result = await execSemanticMemory([
36188
+ const result = await execSemanticMemory2([
35343
36189
  "list",
35344
36190
  "--collection",
35345
36191
  collection,
@@ -35524,7 +36370,7 @@ function createStorage(config2 = {}) {
35524
36370
  }
35525
36371
  async function isSemanticMemoryAvailable() {
35526
36372
  try {
35527
- const result = await execSemanticMemory(["stats"]);
36373
+ const result = await execSemanticMemory2(["stats"]);
35528
36374
  return result.exitCode === 0;
35529
36375
  } catch {
35530
36376
  return false;
@@ -35609,7 +36455,8 @@ var SwarmPlugin = async (input) => {
35609
36455
  ...structuredTools,
35610
36456
  ...swarmTools,
35611
36457
  ...repoCrawlTools,
35612
- ...skillsTools
36458
+ ...skillsTools,
36459
+ ...mandateTools
35613
36460
  },
35614
36461
  event: async ({ event }) => {
35615
36462
  if (event.type === "session.idle") {
@@ -35656,27 +36503,35 @@ var allTools = {
35656
36503
  ...structuredTools,
35657
36504
  ...swarmTools,
35658
36505
  ...repoCrawlTools,
35659
- ...skillsTools
36506
+ ...skillsTools,
36507
+ ...mandateTools
35660
36508
  };
35661
36509
  export {
35662
36510
  withToolFallback,
35663
36511
  warnMissingTool,
36512
+ updateMandateStatus,
36513
+ updateAllMandateStatuses,
35664
36514
  swarmTools,
35665
36515
  swarmMailTools,
35666
36516
  structuredTools,
35667
36517
  skillsTools,
36518
+ shouldPromote,
35668
36519
  setSwarmMailProjectDirectory,
35669
36520
  setStorage,
35670
36521
  setSkillsProjectDirectory,
36522
+ setMandateStorage,
35671
36523
  setBeadsWorkingDirectory,
35672
36524
  setAgentMailProjectDirectory,
35673
36525
  selectStrategy,
35674
36526
  resetToolCache,
35675
36527
  resetStorage,
36528
+ resetMandateStorage,
35676
36529
  requireTool,
35677
36530
  repoCrawlTools,
35678
36531
  parseFrontmatter,
35679
36532
  mcpCallWithAutoInit,
36533
+ mandateTools,
36534
+ mandateSchemas,
35680
36535
  listSkills,
35681
36536
  isToolAvailable,
35682
36537
  isSemanticMemoryAvailable,
@@ -35684,12 +36539,15 @@ export {
35684
36539
  isAgentNotFoundError,
35685
36540
  invalidateSkillsCache,
35686
36541
  ifToolAvailable,
36542
+ groupByTransition,
35687
36543
  getToolAvailability,
35688
36544
  getSwarmMailProjectDirectory,
35689
36545
  getStorage,
36546
+ getStatusChanges,
35690
36547
  getSkillsContextForSwarm,
35691
36548
  getSkill,
35692
36549
  getSchemaByName,
36550
+ getMandateStorage,
35693
36551
  getBeadsWorkingDirectory,
35694
36552
  getAgentMailProjectDirectory,
35695
36553
  formatZodErrors,
@@ -35697,13 +36555,17 @@ export {
35697
36555
  formatSubtaskPromptV2,
35698
36556
  formatSubtaskPrompt,
35699
36557
  formatStrategyGuidelines,
36558
+ formatPromotionResult,
35700
36559
  formatEvaluationPrompt,
35701
36560
  findRelevantSkills,
35702
36561
  extractJsonFromText,
36562
+ evaluatePromotion,
36563
+ evaluateBatchPromotions,
35703
36564
  discoverSkills,
35704
36565
  src_default as default,
35705
36566
  createStorageWithFallback,
35706
36567
  createStorage,
36568
+ createMandateStorage,
35707
36569
  createAgentMailError,
35708
36570
  clearSessionState,
35709
36571
  checkTool,
@@ -35722,6 +36584,8 @@ export {
35722
36584
  agentMailTools,
35723
36585
  WeightedEvaluationSchema,
35724
36586
  WeightedCriterionEvaluationSchema,
36587
+ VoteTypeSchema,
36588
+ VoteSchema,
35725
36589
  ValidationResultSchema,
35726
36590
  TaskDecompositionSchema,
35727
36591
  SwarmStatusSchema,
@@ -35733,10 +36597,19 @@ export {
35733
36597
  SubtaskDependencySchema,
35734
36598
  SpawnedAgentSchema,
35735
36599
  SemanticMemoryStorage,
36600
+ SemanticMemoryMandateStorage,
36601
+ ScoreCalculationResultSchema,
35736
36602
  SUBTASK_PROMPT_V2,
35737
36603
  STRATEGIES,
35738
36604
  RepoCrawlError,
36605
+ QueryMandatesArgsSchema,
36606
+ MandateStatusSchema,
36607
+ MandateScoreSchema,
36608
+ MandateError,
36609
+ MandateEntrySchema,
36610
+ MandateContentTypeSchema,
35739
36611
  InMemoryStorage,
36612
+ InMemoryMandateStorage,
35740
36613
  FileReservationConflictError,
35741
36614
  EvaluationSchema,
35742
36615
  EvaluationRequestSchema,
@@ -35748,8 +36621,12 @@ export {
35748
36621
  DecomposedSubtaskSchema,
35749
36622
  DecomposeArgsSchema,
35750
36623
  DEFAULT_STORAGE_CONFIG,
36624
+ DEFAULT_MANDATE_STORAGE_CONFIG,
36625
+ DEFAULT_MANDATE_DECAY_CONFIG,
35751
36626
  DEFAULT_CRITERIA,
35752
36627
  CriterionEvaluationSchema,
36628
+ CreateMandateArgsSchema,
36629
+ CastVoteArgsSchema,
35753
36630
  BeadValidationError,
35754
36631
  BeadUpdateArgsSchema,
35755
36632
  BeadTypeSchema,