harmony-mcp 1.10.0 → 1.10.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.
Files changed (3) hide show
  1. package/dist/cli.js +228 -202
  2. package/dist/index.js +221 -195
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -14371,6 +14371,187 @@ function getMemoryDir() {
14371
14371
  return config.memoryDir;
14372
14372
  return join(homedir(), ".harmony", "memory");
14373
14373
  }
14374
+ // ../memory/src/graph-walk.ts
14375
+ async function discoverRelatedContext(client, startIds, maxDepth = 2, maxEntities = 20, minConfidence = 0.5) {
14376
+ const visited = new Set;
14377
+ const collectedEntities = [];
14378
+ const collectedRelations = [];
14379
+ let truncated = false;
14380
+ const queue = startIds.map((id) => [id, 0]);
14381
+ for (const id of startIds) {
14382
+ visited.add(id);
14383
+ }
14384
+ while (queue.length > 0) {
14385
+ const [entityId, depth] = queue.shift();
14386
+ if (collectedEntities.length >= maxEntities) {
14387
+ truncated = true;
14388
+ break;
14389
+ }
14390
+ if (depth > maxDepth)
14391
+ continue;
14392
+ try {
14393
+ const entityResult = await client.getMemoryEntity(entityId);
14394
+ const entity = entityResult.entity;
14395
+ if (entity) {
14396
+ collectedEntities.push({
14397
+ id: entity.id,
14398
+ type: entity.type,
14399
+ title: entity.title,
14400
+ confidence: entity.confidence ?? 1,
14401
+ memory_tier: entity.memory_tier || "reference"
14402
+ });
14403
+ }
14404
+ if (depth >= maxDepth)
14405
+ continue;
14406
+ const related = await client.getRelatedEntities(entityId);
14407
+ for (const raw of related.outgoing || []) {
14408
+ const rel = raw;
14409
+ const relConfidence = rel.confidence ?? 1;
14410
+ if (relConfidence < minConfidence)
14411
+ continue;
14412
+ const target = rel.target;
14413
+ const targetId = target?.id ?? rel.target_id;
14414
+ if (targetId && !visited.has(targetId)) {
14415
+ visited.add(targetId);
14416
+ queue.push([targetId, depth + 1]);
14417
+ collectedRelations.push({
14418
+ id: rel.id,
14419
+ source_id: entityId,
14420
+ target_id: targetId,
14421
+ relation_type: rel.relation_type,
14422
+ confidence: relConfidence
14423
+ });
14424
+ }
14425
+ }
14426
+ for (const raw of related.incoming || []) {
14427
+ const rel = raw;
14428
+ const relConfidence = rel.confidence ?? 1;
14429
+ if (relConfidence < minConfidence)
14430
+ continue;
14431
+ const source = rel.source;
14432
+ const sourceId = source?.id ?? rel.source_id;
14433
+ if (sourceId && !visited.has(sourceId)) {
14434
+ visited.add(sourceId);
14435
+ queue.push([sourceId, depth + 1]);
14436
+ collectedRelations.push({
14437
+ id: rel.id,
14438
+ source_id: sourceId,
14439
+ target_id: entityId,
14440
+ relation_type: rel.relation_type,
14441
+ confidence: relConfidence
14442
+ });
14443
+ }
14444
+ }
14445
+ } catch {}
14446
+ }
14447
+ return {
14448
+ entities: collectedEntities,
14449
+ relations: collectedRelations,
14450
+ depth: maxDepth,
14451
+ truncated
14452
+ };
14453
+ }
14454
+ // ../memory/src/lifecycle.ts
14455
+ var DECAY_HALF_LIVES = {
14456
+ draft: 7,
14457
+ episode: 30,
14458
+ reference: 180
14459
+ };
14460
+ var PROMOTION_RULES = {
14461
+ draftToEpisode: {
14462
+ minAccessCount: 5,
14463
+ minConfidence: 0.8,
14464
+ minAgeDays: 1
14465
+ },
14466
+ episodeToReference: {
14467
+ minAccessCount: 10,
14468
+ minConfidence: 0.9,
14469
+ minAgeDays: 7
14470
+ }
14471
+ };
14472
+ var ARCHIVE_THRESHOLD = 0.3;
14473
+ var STALE_DAYS = 90;
14474
+ var STALE_MIN_ACCESS = 3;
14475
+ function computeDecayScore(tier, lastAccessedAt, accessCount) {
14476
+ const halfLife = DECAY_HALF_LIVES[tier];
14477
+ const now = Date.now();
14478
+ let daysSinceAccess = 0;
14479
+ if (lastAccessedAt) {
14480
+ daysSinceAccess = (now - new Date(lastAccessedAt).getTime()) / (1000 * 60 * 60 * 24);
14481
+ }
14482
+ const timeDecay = 0.5 ** (daysSinceAccess / halfLife);
14483
+ const accessBonus = Math.log10(accessCount + 1) * 0.1;
14484
+ const score = Math.min(timeDecay + accessBonus, 1);
14485
+ return { score, daysSinceAccess, halfLife, accessBonus };
14486
+ }
14487
+ function checkPromotion(currentTier, accessCount, confidence, createdAt) {
14488
+ const ageDays = (Date.now() - new Date(createdAt).getTime()) / (1000 * 60 * 60 * 24);
14489
+ const base = {
14490
+ eligible: false,
14491
+ targetTier: null,
14492
+ reason: null,
14493
+ currentTier,
14494
+ accessCount,
14495
+ confidence,
14496
+ ageDays
14497
+ };
14498
+ if (currentTier === "draft") {
14499
+ const rules = PROMOTION_RULES.draftToEpisode;
14500
+ if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
14501
+ return {
14502
+ ...base,
14503
+ eligible: true,
14504
+ targetTier: "episode",
14505
+ reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
14506
+ };
14507
+ }
14508
+ }
14509
+ if (currentTier === "episode") {
14510
+ const rules = PROMOTION_RULES.episodeToReference;
14511
+ if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
14512
+ return {
14513
+ ...base,
14514
+ eligible: true,
14515
+ targetTier: "reference",
14516
+ reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
14517
+ };
14518
+ }
14519
+ }
14520
+ return base;
14521
+ }
14522
+ function evaluateLifecycle(entity) {
14523
+ const decay = computeDecayScore(entity.memory_tier, entity.last_accessed_at, entity.access_count);
14524
+ const promotion = checkPromotion(entity.memory_tier, entity.access_count, entity.confidence, entity.created_at);
14525
+ const shouldArchive = entity.confidence < ARCHIVE_THRESHOLD;
14526
+ const archiveReason = shouldArchive ? `Confidence ${entity.confidence} below threshold ${ARCHIVE_THRESHOLD}` : undefined;
14527
+ const shouldFlagForReview = decay.daysSinceAccess >= STALE_DAYS && entity.access_count < STALE_MIN_ACCESS;
14528
+ const reviewReason = shouldFlagForReview ? `Not accessed in ${Math.round(decay.daysSinceAccess)} days with only ${entity.access_count} accesses` : undefined;
14529
+ return {
14530
+ decay,
14531
+ promotion,
14532
+ shouldArchive,
14533
+ shouldFlagForReview,
14534
+ archiveReason,
14535
+ reviewReason
14536
+ };
14537
+ }
14538
+ function buildContradictionQuery(type, tags) {
14539
+ if (tags.length === 0)
14540
+ return null;
14541
+ return { type, tags };
14542
+ }
14543
+ // ../memory/src/sync.ts
14544
+ import { createHash } from "node:crypto";
14545
+ import {
14546
+ existsSync as existsSync2,
14547
+ mkdirSync as mkdirSync2,
14548
+ readdirSync,
14549
+ readFileSync as readFileSync2,
14550
+ rmSync,
14551
+ writeFileSync as writeFileSync2
14552
+ } from "node:fs";
14553
+ import { join as join2, relative, sep } from "node:path";
14554
+
14374
14555
  // ../memory/src/sync-storage.ts
14375
14556
  function parseSyncMarkdown(markdown) {
14376
14557
  const trimmed = markdown.trim();
@@ -14486,17 +14667,8 @@ function parseYamlArray(value) {
14486
14667
  return [];
14487
14668
  return match[1].split(",").map((s) => s.trim()).filter(Boolean);
14488
14669
  }
14670
+
14489
14671
  // ../memory/src/sync.ts
14490
- import { createHash } from "node:crypto";
14491
- import {
14492
- existsSync as existsSync2,
14493
- mkdirSync as mkdirSync2,
14494
- readdirSync,
14495
- readFileSync as readFileSync2,
14496
- rmSync,
14497
- writeFileSync as writeFileSync2
14498
- } from "node:fs";
14499
- import { join as join2, relative, sep } from "node:path";
14500
14672
  function computeFileHash(content) {
14501
14673
  return `sha256:${createHash("sha256").update(content).digest("hex")}`;
14502
14674
  }
@@ -14758,177 +14930,6 @@ async function syncFull(client, config, workspaceId, projectId) {
14758
14930
  errors: [...pullResult.errors, ...pushResult.errors]
14759
14931
  };
14760
14932
  }
14761
- // ../memory/src/lifecycle.ts
14762
- var DECAY_HALF_LIVES = {
14763
- draft: 7,
14764
- episode: 30,
14765
- reference: 180
14766
- };
14767
- var PROMOTION_RULES = {
14768
- draftToEpisode: {
14769
- minAccessCount: 5,
14770
- minConfidence: 0.8,
14771
- minAgeDays: 1
14772
- },
14773
- episodeToReference: {
14774
- minAccessCount: 10,
14775
- minConfidence: 0.9,
14776
- minAgeDays: 7
14777
- }
14778
- };
14779
- var ARCHIVE_THRESHOLD = 0.3;
14780
- var STALE_DAYS = 90;
14781
- var STALE_MIN_ACCESS = 3;
14782
- function computeDecayScore(tier, lastAccessedAt, accessCount) {
14783
- const halfLife = DECAY_HALF_LIVES[tier];
14784
- const now = Date.now();
14785
- let daysSinceAccess = 0;
14786
- if (lastAccessedAt) {
14787
- daysSinceAccess = (now - new Date(lastAccessedAt).getTime()) / (1000 * 60 * 60 * 24);
14788
- }
14789
- const timeDecay = Math.pow(0.5, daysSinceAccess / halfLife);
14790
- const accessBonus = Math.log10(accessCount + 1) * 0.1;
14791
- const score = Math.min(timeDecay + accessBonus, 1);
14792
- return { score, daysSinceAccess, halfLife, accessBonus };
14793
- }
14794
- function checkPromotion(currentTier, accessCount, confidence, createdAt) {
14795
- const ageDays = (Date.now() - new Date(createdAt).getTime()) / (1000 * 60 * 60 * 24);
14796
- const base = {
14797
- eligible: false,
14798
- targetTier: null,
14799
- reason: null,
14800
- currentTier,
14801
- accessCount,
14802
- confidence,
14803
- ageDays
14804
- };
14805
- if (currentTier === "draft") {
14806
- const rules = PROMOTION_RULES.draftToEpisode;
14807
- if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
14808
- return {
14809
- ...base,
14810
- eligible: true,
14811
- targetTier: "episode",
14812
- reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
14813
- };
14814
- }
14815
- }
14816
- if (currentTier === "episode") {
14817
- const rules = PROMOTION_RULES.episodeToReference;
14818
- if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
14819
- return {
14820
- ...base,
14821
- eligible: true,
14822
- targetTier: "reference",
14823
- reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
14824
- };
14825
- }
14826
- }
14827
- return base;
14828
- }
14829
- function evaluateLifecycle(entity) {
14830
- const decay = computeDecayScore(entity.memory_tier, entity.last_accessed_at, entity.access_count);
14831
- const promotion = checkPromotion(entity.memory_tier, entity.access_count, entity.confidence, entity.created_at);
14832
- const shouldArchive = entity.confidence < ARCHIVE_THRESHOLD;
14833
- const archiveReason = shouldArchive ? `Confidence ${entity.confidence} below threshold ${ARCHIVE_THRESHOLD}` : undefined;
14834
- const shouldFlagForReview = decay.daysSinceAccess >= STALE_DAYS && entity.access_count < STALE_MIN_ACCESS;
14835
- const reviewReason = shouldFlagForReview ? `Not accessed in ${Math.round(decay.daysSinceAccess)} days with only ${entity.access_count} accesses` : undefined;
14836
- return {
14837
- decay,
14838
- promotion,
14839
- shouldArchive,
14840
- shouldFlagForReview,
14841
- archiveReason,
14842
- reviewReason
14843
- };
14844
- }
14845
- function buildContradictionQuery(type, tags) {
14846
- if (tags.length === 0)
14847
- return null;
14848
- return { type, tags };
14849
- }
14850
- // ../memory/src/graph-walk.ts
14851
- async function discoverRelatedContext(client, startIds, maxDepth = 2, maxEntities = 20, minConfidence = 0.5) {
14852
- const visited = new Set;
14853
- const collectedEntities = [];
14854
- const collectedRelations = [];
14855
- let truncated = false;
14856
- const queue = startIds.map((id) => [id, 0]);
14857
- for (const id of startIds) {
14858
- visited.add(id);
14859
- }
14860
- while (queue.length > 0) {
14861
- const [entityId, depth] = queue.shift();
14862
- if (collectedEntities.length >= maxEntities) {
14863
- truncated = true;
14864
- break;
14865
- }
14866
- if (depth > maxDepth)
14867
- continue;
14868
- try {
14869
- const entityResult = await client.getMemoryEntity(entityId);
14870
- const entity = entityResult.entity;
14871
- if (entity) {
14872
- collectedEntities.push({
14873
- id: entity.id,
14874
- type: entity.type,
14875
- title: entity.title,
14876
- confidence: entity.confidence ?? 1,
14877
- memory_tier: entity.memory_tier || "reference"
14878
- });
14879
- }
14880
- if (depth >= maxDepth)
14881
- continue;
14882
- const related = await client.getRelatedEntities(entityId);
14883
- for (const raw of related.outgoing || []) {
14884
- const rel = raw;
14885
- const relConfidence = rel.confidence ?? 1;
14886
- if (relConfidence < minConfidence)
14887
- continue;
14888
- const target = rel.target;
14889
- const targetId = target?.id ?? rel.target_id;
14890
- if (targetId && !visited.has(targetId)) {
14891
- visited.add(targetId);
14892
- queue.push([targetId, depth + 1]);
14893
- collectedRelations.push({
14894
- id: rel.id,
14895
- source_id: entityId,
14896
- target_id: targetId,
14897
- relation_type: rel.relation_type,
14898
- confidence: relConfidence
14899
- });
14900
- }
14901
- }
14902
- for (const raw of related.incoming || []) {
14903
- const rel = raw;
14904
- const relConfidence = rel.confidence ?? 1;
14905
- if (relConfidence < minConfidence)
14906
- continue;
14907
- const source = rel.source;
14908
- const sourceId = source?.id ?? rel.source_id;
14909
- if (sourceId && !visited.has(sourceId)) {
14910
- visited.add(sourceId);
14911
- queue.push([sourceId, depth + 1]);
14912
- collectedRelations.push({
14913
- id: rel.id,
14914
- source_id: sourceId,
14915
- target_id: entityId,
14916
- relation_type: rel.relation_type,
14917
- confidence: relConfidence
14918
- });
14919
- }
14920
- }
14921
- } catch {
14922
- continue;
14923
- }
14924
- }
14925
- return {
14926
- entities: collectedEntities,
14927
- relations: collectedRelations,
14928
- depth: maxDepth,
14929
- truncated
14930
- };
14931
- }
14932
14933
  // ../../node_modules/zod/v4/core/index.js
14933
14934
  var exports_core2 = {};
14934
14935
  __export(exports_core2, {
@@ -30731,7 +30732,7 @@ class StdioServerTransport {
30731
30732
  }
30732
30733
  }
30733
30734
  // src/graph-expansion.ts
30734
- async function autoExpandGraph(client2, entityId, title, content, tags, workspaceId, projectId, maxRelations = 5) {
30735
+ async function autoExpandGraph(client2, entityId, title, content, _tags, workspaceId, projectId, maxRelations = 5) {
30735
30736
  try {
30736
30737
  const contentSnippet = content.slice(0, 200).trim();
30737
30738
  const query = [title, contentSnippet].filter(Boolean).join(" ");
@@ -30809,7 +30810,11 @@ Agent: ${session.agentName}`
30809
30810
  type: "lesson",
30810
30811
  tier: "episode",
30811
30812
  confidence: 0.7,
30812
- tags: ["auto-extracted", "session-summary", ...session.cardLabels.slice(0, 3)],
30813
+ tags: [
30814
+ "auto-extracted",
30815
+ "session-summary",
30816
+ ...session.cardLabels.slice(0, 3)
30817
+ ],
30813
30818
  metadata: {
30814
30819
  source: "active_learning",
30815
30820
  card_id: session.cardId,
@@ -31003,7 +31008,7 @@ function isRetryableError(error48, status) {
31003
31008
  return msg.includes("ECONNRESET") || msg.includes("ETIMEDOUT") || msg.includes("fetch failed");
31004
31009
  }
31005
31010
  function getRetryDelay(attempt) {
31006
- const delay = Math.min(RETRY_CONFIG.baseDelayMs * Math.pow(2, attempt), RETRY_CONFIG.maxDelayMs);
31011
+ const delay = Math.min(RETRY_CONFIG.baseDelayMs * 2 ** attempt, RETRY_CONFIG.maxDelayMs);
31007
31012
  return Math.round(delay + delay * 0.25 * (Math.random() * 2 - 1));
31008
31013
  }
31009
31014
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -31122,7 +31127,6 @@ class HarmonyApiClient {
31122
31127
  throw lastError;
31123
31128
  if (attempt < RETRY_CONFIG.maxRetries) {
31124
31129
  await sleep(getRetryDelay(attempt));
31125
- continue;
31126
31130
  }
31127
31131
  }
31128
31132
  }
@@ -31169,7 +31173,6 @@ class HarmonyApiClient {
31169
31173
  throw lastError;
31170
31174
  if (attempt < RETRY_CONFIG.maxRetries) {
31171
31175
  await sleep(getRetryDelay(attempt));
31172
- continue;
31173
31176
  }
31174
31177
  }
31175
31178
  }
@@ -31567,7 +31570,7 @@ function computeRelevanceScore(entity, taskContext, cardLabels) {
31567
31570
  if (entity.last_accessed_at) {
31568
31571
  const daysSinceAccess = (Date.now() - new Date(entity.last_accessed_at).getTime()) / (1000 * 60 * 60 * 24);
31569
31572
  const halfLife = { draft: 7, episode: 30, reference: 180 }[entity.memory_tier];
31570
- const recencyScore = Math.pow(0.5, daysSinceAccess / halfLife) * 0.1;
31573
+ const recencyScore = 0.5 ** (daysSinceAccess / halfLife) * 0.1;
31571
31574
  score += recencyScore;
31572
31575
  if (daysSinceAccess < 7)
31573
31576
  reasons.push("recently_accessed");
@@ -31644,7 +31647,11 @@ async function assembleContext(options) {
31644
31647
  episode: Math.floor(tokenBudget * TIER_BUDGET_ALLOCATION.episode),
31645
31648
  draft: Math.floor(tokenBudget * TIER_BUDGET_ALLOCATION.draft)
31646
31649
  };
31647
- const tierUsed = { reference: 0, episode: 0, draft: 0 };
31650
+ const tierUsed = {
31651
+ reference: 0,
31652
+ episode: 0,
31653
+ draft: 0
31654
+ };
31648
31655
  const included = [];
31649
31656
  let totalUsed = 0;
31650
31657
  let referenceCount = 0;
@@ -31714,9 +31721,18 @@ ${text}`);
31714
31721
  }
31715
31722
  manifest.budgetUsed = totalUsed;
31716
31723
  manifest.tierBreakdown = {
31717
- reference: { count: included.filter((i) => i.entity.memory_tier === "reference").length, tokens: tierUsed.reference },
31718
- episode: { count: included.filter((i) => i.entity.memory_tier === "episode").length, tokens: tierUsed.episode },
31719
- draft: { count: included.filter((i) => i.entity.memory_tier === "draft").length, tokens: tierUsed.draft }
31724
+ reference: {
31725
+ count: included.filter((i) => i.entity.memory_tier === "reference").length,
31726
+ tokens: tierUsed.reference
31727
+ },
31728
+ episode: {
31729
+ count: included.filter((i) => i.entity.memory_tier === "episode").length,
31730
+ tokens: tierUsed.episode
31731
+ },
31732
+ draft: {
31733
+ count: included.filter((i) => i.entity.memory_tier === "draft").length,
31734
+ tokens: tierUsed.draft
31735
+ }
31720
31736
  };
31721
31737
  for (const item of included) {
31722
31738
  manifest.included.push({
@@ -32008,7 +32024,15 @@ ${lines.join(`
32008
32024
  `)}`;
32009
32025
  }
32010
32026
  function generatePrompt(options) {
32011
- const { card, column, variant, customConstraints, memories, assembledContext, assemblyId } = options;
32027
+ const {
32028
+ card,
32029
+ column,
32030
+ variant,
32031
+ customConstraints,
32032
+ memories,
32033
+ assembledContext,
32034
+ assemblyId
32035
+ } = options;
32012
32036
  const contextOpts = {
32013
32037
  includeTitle: true,
32014
32038
  includeDescription: true,
@@ -32162,7 +32186,8 @@ var TOOLS = {
32162
32186
  description: { type: "string" },
32163
32187
  priority: { type: "string", enum: ["low", "medium", "high", "urgent"] },
32164
32188
  assigneeId: { type: "string", nullable: true },
32165
- dueDate: { type: "string", nullable: true }
32189
+ dueDate: { type: "string", nullable: true },
32190
+ done: { type: "boolean", description: "Mark card as done or not done" }
32166
32191
  },
32167
32192
  required: ["cardId"]
32168
32193
  }
@@ -33482,7 +33507,8 @@ async function handleToolCall(name, args, deps) {
33482
33507
  description: args.description,
33483
33508
  priority: args.priority,
33484
33509
  assigneeId: args.assigneeId,
33485
- dueDate: args.dueDate
33510
+ dueDate: args.dueDate,
33511
+ done: args.done
33486
33512
  });
33487
33513
  return { success: true, ...result };
33488
33514
  }
@@ -34299,7 +34325,7 @@ async function handleToolCall(name, args, deps) {
34299
34325
  const card = cardResult.card;
34300
34326
  await client3.updatePlanTask(planId, task.id, { cardId: card.id });
34301
34327
  cardsCreated++;
34302
- } catch (e) {}
34328
+ } catch (_e) {}
34303
34329
  }
34304
34330
  results.cardsCreated = cardsCreated;
34305
34331
  }
@@ -34783,7 +34809,7 @@ import {
34783
34809
  unlinkSync
34784
34810
  } from "node:fs";
34785
34811
  import { homedir as homedir4 } from "node:os";
34786
- import { dirname as dirname3, join as join4 } from "node:path";
34812
+ import { dirname as dirname2, join as join4 } from "node:path";
34787
34813
 
34788
34814
  // ../../node_modules/@clack/core/dist/index.mjs
34789
34815
  var import_sisteransi = __toESM(require_src(), 1);
@@ -35617,7 +35643,7 @@ function formatPath(path, homeDir) {
35617
35643
  // src/tui/writer.ts
35618
35644
  import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
35619
35645
  import { homedir as homedir3 } from "node:os";
35620
- import { dirname as dirname2 } from "node:path";
35646
+ import { dirname } from "node:path";
35621
35647
  function ensureDir(dirPath) {
35622
35648
  if (!existsSync4(dirPath)) {
35623
35649
  mkdirSync3(dirPath, { recursive: true, mode: 493 });
@@ -35629,7 +35655,7 @@ function writeFile(filePath, content, options = {}) {
35629
35655
  return { path: filePath, action: "skip" };
35630
35656
  }
35631
35657
  try {
35632
- ensureDir(dirname2(filePath));
35658
+ ensureDir(dirname(filePath));
35633
35659
  const mode = filePath.includes(".harmony-mcp") ? 384 : 420;
35634
35660
  writeFileSync3(filePath, content, { mode });
35635
35661
  return { path: filePath, action: exists ? "update" : "create" };
@@ -35645,7 +35671,7 @@ function mergeJsonFile(filePath, updates, options = {}) {
35645
35671
  const exists = existsSync4(filePath);
35646
35672
  if (!exists) {
35647
35673
  try {
35648
- ensureDir(dirname2(filePath));
35674
+ ensureDir(dirname(filePath));
35649
35675
  writeFileSync3(filePath, JSON.stringify(updates, null, 2), {
35650
35676
  mode: 420
35651
35677
  });
@@ -35695,7 +35721,7 @@ function appendToToml(filePath, section, content, options = {}) {
35695
35721
  const exists = existsSync4(filePath);
35696
35722
  if (!exists) {
35697
35723
  try {
35698
- ensureDir(dirname2(filePath));
35724
+ ensureDir(dirname(filePath));
35699
35725
  writeFileSync3(filePath, content, { mode: 420 });
35700
35726
  return { path: filePath, action: "create" };
35701
35727
  } catch (error48) {
@@ -36010,7 +36036,7 @@ async function registerMcpServer() {
36010
36036
  async function writeMcpConfigFallback(home) {
36011
36037
  const { readFileSync: readFileSync4, writeFileSync: writeFileSync4, mkdirSync: mkdirSync5, existsSync: existsSync6 } = await import("node:fs");
36012
36038
  const settingsPath = join4(home, ".claude", "settings.json");
36013
- const settingsDir = dirname3(settingsPath);
36039
+ const settingsDir = dirname2(settingsPath);
36014
36040
  if (!existsSync6(settingsDir)) {
36015
36041
  mkdirSync5(settingsDir, { recursive: true });
36016
36042
  }
@@ -36578,7 +36604,7 @@ async function runSetup(options = {}) {
36578
36604
  if (allSymlinks.length > 0) {
36579
36605
  for (const symlink of allSymlinks) {
36580
36606
  try {
36581
- const linkDir = dirname3(symlink.link);
36607
+ const linkDir = dirname2(symlink.link);
36582
36608
  if (!existsSync5(linkDir)) {
36583
36609
  mkdirSync4(linkDir, { recursive: true });
36584
36610
  }
package/dist/index.js CHANGED
@@ -11946,6 +11946,187 @@ var require_dist = __commonJS((exports, module) => {
11946
11946
  Object.defineProperty(exports, "__esModule", { value: true });
11947
11947
  exports.default = formatsPlugin;
11948
11948
  });
11949
+ // ../memory/src/graph-walk.ts
11950
+ async function discoverRelatedContext(client, startIds, maxDepth = 2, maxEntities = 20, minConfidence = 0.5) {
11951
+ const visited = new Set;
11952
+ const collectedEntities = [];
11953
+ const collectedRelations = [];
11954
+ let truncated = false;
11955
+ const queue = startIds.map((id) => [id, 0]);
11956
+ for (const id of startIds) {
11957
+ visited.add(id);
11958
+ }
11959
+ while (queue.length > 0) {
11960
+ const [entityId, depth] = queue.shift();
11961
+ if (collectedEntities.length >= maxEntities) {
11962
+ truncated = true;
11963
+ break;
11964
+ }
11965
+ if (depth > maxDepth)
11966
+ continue;
11967
+ try {
11968
+ const entityResult = await client.getMemoryEntity(entityId);
11969
+ const entity = entityResult.entity;
11970
+ if (entity) {
11971
+ collectedEntities.push({
11972
+ id: entity.id,
11973
+ type: entity.type,
11974
+ title: entity.title,
11975
+ confidence: entity.confidence ?? 1,
11976
+ memory_tier: entity.memory_tier || "reference"
11977
+ });
11978
+ }
11979
+ if (depth >= maxDepth)
11980
+ continue;
11981
+ const related = await client.getRelatedEntities(entityId);
11982
+ for (const raw of related.outgoing || []) {
11983
+ const rel = raw;
11984
+ const relConfidence = rel.confidence ?? 1;
11985
+ if (relConfidence < minConfidence)
11986
+ continue;
11987
+ const target = rel.target;
11988
+ const targetId = target?.id ?? rel.target_id;
11989
+ if (targetId && !visited.has(targetId)) {
11990
+ visited.add(targetId);
11991
+ queue.push([targetId, depth + 1]);
11992
+ collectedRelations.push({
11993
+ id: rel.id,
11994
+ source_id: entityId,
11995
+ target_id: targetId,
11996
+ relation_type: rel.relation_type,
11997
+ confidence: relConfidence
11998
+ });
11999
+ }
12000
+ }
12001
+ for (const raw of related.incoming || []) {
12002
+ const rel = raw;
12003
+ const relConfidence = rel.confidence ?? 1;
12004
+ if (relConfidence < minConfidence)
12005
+ continue;
12006
+ const source = rel.source;
12007
+ const sourceId = source?.id ?? rel.source_id;
12008
+ if (sourceId && !visited.has(sourceId)) {
12009
+ visited.add(sourceId);
12010
+ queue.push([sourceId, depth + 1]);
12011
+ collectedRelations.push({
12012
+ id: rel.id,
12013
+ source_id: sourceId,
12014
+ target_id: entityId,
12015
+ relation_type: rel.relation_type,
12016
+ confidence: relConfidence
12017
+ });
12018
+ }
12019
+ }
12020
+ } catch {}
12021
+ }
12022
+ return {
12023
+ entities: collectedEntities,
12024
+ relations: collectedRelations,
12025
+ depth: maxDepth,
12026
+ truncated
12027
+ };
12028
+ }
12029
+ // ../memory/src/lifecycle.ts
12030
+ var DECAY_HALF_LIVES = {
12031
+ draft: 7,
12032
+ episode: 30,
12033
+ reference: 180
12034
+ };
12035
+ var PROMOTION_RULES = {
12036
+ draftToEpisode: {
12037
+ minAccessCount: 5,
12038
+ minConfidence: 0.8,
12039
+ minAgeDays: 1
12040
+ },
12041
+ episodeToReference: {
12042
+ minAccessCount: 10,
12043
+ minConfidence: 0.9,
12044
+ minAgeDays: 7
12045
+ }
12046
+ };
12047
+ var ARCHIVE_THRESHOLD = 0.3;
12048
+ var STALE_DAYS = 90;
12049
+ var STALE_MIN_ACCESS = 3;
12050
+ function computeDecayScore(tier, lastAccessedAt, accessCount) {
12051
+ const halfLife = DECAY_HALF_LIVES[tier];
12052
+ const now = Date.now();
12053
+ let daysSinceAccess = 0;
12054
+ if (lastAccessedAt) {
12055
+ daysSinceAccess = (now - new Date(lastAccessedAt).getTime()) / (1000 * 60 * 60 * 24);
12056
+ }
12057
+ const timeDecay = 0.5 ** (daysSinceAccess / halfLife);
12058
+ const accessBonus = Math.log10(accessCount + 1) * 0.1;
12059
+ const score = Math.min(timeDecay + accessBonus, 1);
12060
+ return { score, daysSinceAccess, halfLife, accessBonus };
12061
+ }
12062
+ function checkPromotion(currentTier, accessCount, confidence, createdAt) {
12063
+ const ageDays = (Date.now() - new Date(createdAt).getTime()) / (1000 * 60 * 60 * 24);
12064
+ const base = {
12065
+ eligible: false,
12066
+ targetTier: null,
12067
+ reason: null,
12068
+ currentTier,
12069
+ accessCount,
12070
+ confidence,
12071
+ ageDays
12072
+ };
12073
+ if (currentTier === "draft") {
12074
+ const rules = PROMOTION_RULES.draftToEpisode;
12075
+ if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
12076
+ return {
12077
+ ...base,
12078
+ eligible: true,
12079
+ targetTier: "episode",
12080
+ reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
12081
+ };
12082
+ }
12083
+ }
12084
+ if (currentTier === "episode") {
12085
+ const rules = PROMOTION_RULES.episodeToReference;
12086
+ if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
12087
+ return {
12088
+ ...base,
12089
+ eligible: true,
12090
+ targetTier: "reference",
12091
+ reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
12092
+ };
12093
+ }
12094
+ }
12095
+ return base;
12096
+ }
12097
+ function evaluateLifecycle(entity) {
12098
+ const decay = computeDecayScore(entity.memory_tier, entity.last_accessed_at, entity.access_count);
12099
+ const promotion = checkPromotion(entity.memory_tier, entity.access_count, entity.confidence, entity.created_at);
12100
+ const shouldArchive = entity.confidence < ARCHIVE_THRESHOLD;
12101
+ const archiveReason = shouldArchive ? `Confidence ${entity.confidence} below threshold ${ARCHIVE_THRESHOLD}` : undefined;
12102
+ const shouldFlagForReview = decay.daysSinceAccess >= STALE_DAYS && entity.access_count < STALE_MIN_ACCESS;
12103
+ const reviewReason = shouldFlagForReview ? `Not accessed in ${Math.round(decay.daysSinceAccess)} days with only ${entity.access_count} accesses` : undefined;
12104
+ return {
12105
+ decay,
12106
+ promotion,
12107
+ shouldArchive,
12108
+ shouldFlagForReview,
12109
+ archiveReason,
12110
+ reviewReason
12111
+ };
12112
+ }
12113
+ function buildContradictionQuery(type, tags) {
12114
+ if (tags.length === 0)
12115
+ return null;
12116
+ return { type, tags };
12117
+ }
12118
+ // ../memory/src/sync.ts
12119
+ import { createHash } from "node:crypto";
12120
+ import {
12121
+ existsSync,
12122
+ mkdirSync,
12123
+ readdirSync,
12124
+ readFileSync,
12125
+ rmSync,
12126
+ writeFileSync
12127
+ } from "node:fs";
12128
+ import { join, relative, sep } from "node:path";
12129
+
11949
12130
  // ../memory/src/sync-storage.ts
11950
12131
  function parseSyncMarkdown(markdown) {
11951
12132
  const trimmed = markdown.trim();
@@ -12061,17 +12242,8 @@ function parseYamlArray(value) {
12061
12242
  return [];
12062
12243
  return match[1].split(",").map((s) => s.trim()).filter(Boolean);
12063
12244
  }
12245
+
12064
12246
  // ../memory/src/sync.ts
12065
- import { createHash } from "node:crypto";
12066
- import {
12067
- existsSync,
12068
- mkdirSync,
12069
- readdirSync,
12070
- readFileSync,
12071
- rmSync,
12072
- writeFileSync
12073
- } from "node:fs";
12074
- import { join, relative, sep } from "node:path";
12075
12247
  function computeFileHash(content) {
12076
12248
  return `sha256:${createHash("sha256").update(content).digest("hex")}`;
12077
12249
  }
@@ -12333,177 +12505,6 @@ async function syncFull(client, config, workspaceId, projectId) {
12333
12505
  errors: [...pullResult.errors, ...pushResult.errors]
12334
12506
  };
12335
12507
  }
12336
- // ../memory/src/lifecycle.ts
12337
- var DECAY_HALF_LIVES = {
12338
- draft: 7,
12339
- episode: 30,
12340
- reference: 180
12341
- };
12342
- var PROMOTION_RULES = {
12343
- draftToEpisode: {
12344
- minAccessCount: 5,
12345
- minConfidence: 0.8,
12346
- minAgeDays: 1
12347
- },
12348
- episodeToReference: {
12349
- minAccessCount: 10,
12350
- minConfidence: 0.9,
12351
- minAgeDays: 7
12352
- }
12353
- };
12354
- var ARCHIVE_THRESHOLD = 0.3;
12355
- var STALE_DAYS = 90;
12356
- var STALE_MIN_ACCESS = 3;
12357
- function computeDecayScore(tier, lastAccessedAt, accessCount) {
12358
- const halfLife = DECAY_HALF_LIVES[tier];
12359
- const now = Date.now();
12360
- let daysSinceAccess = 0;
12361
- if (lastAccessedAt) {
12362
- daysSinceAccess = (now - new Date(lastAccessedAt).getTime()) / (1000 * 60 * 60 * 24);
12363
- }
12364
- const timeDecay = Math.pow(0.5, daysSinceAccess / halfLife);
12365
- const accessBonus = Math.log10(accessCount + 1) * 0.1;
12366
- const score = Math.min(timeDecay + accessBonus, 1);
12367
- return { score, daysSinceAccess, halfLife, accessBonus };
12368
- }
12369
- function checkPromotion(currentTier, accessCount, confidence, createdAt) {
12370
- const ageDays = (Date.now() - new Date(createdAt).getTime()) / (1000 * 60 * 60 * 24);
12371
- const base = {
12372
- eligible: false,
12373
- targetTier: null,
12374
- reason: null,
12375
- currentTier,
12376
- accessCount,
12377
- confidence,
12378
- ageDays
12379
- };
12380
- if (currentTier === "draft") {
12381
- const rules = PROMOTION_RULES.draftToEpisode;
12382
- if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
12383
- return {
12384
- ...base,
12385
- eligible: true,
12386
- targetTier: "episode",
12387
- reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
12388
- };
12389
- }
12390
- }
12391
- if (currentTier === "episode") {
12392
- const rules = PROMOTION_RULES.episodeToReference;
12393
- if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
12394
- return {
12395
- ...base,
12396
- eligible: true,
12397
- targetTier: "reference",
12398
- reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
12399
- };
12400
- }
12401
- }
12402
- return base;
12403
- }
12404
- function evaluateLifecycle(entity) {
12405
- const decay = computeDecayScore(entity.memory_tier, entity.last_accessed_at, entity.access_count);
12406
- const promotion = checkPromotion(entity.memory_tier, entity.access_count, entity.confidence, entity.created_at);
12407
- const shouldArchive = entity.confidence < ARCHIVE_THRESHOLD;
12408
- const archiveReason = shouldArchive ? `Confidence ${entity.confidence} below threshold ${ARCHIVE_THRESHOLD}` : undefined;
12409
- const shouldFlagForReview = decay.daysSinceAccess >= STALE_DAYS && entity.access_count < STALE_MIN_ACCESS;
12410
- const reviewReason = shouldFlagForReview ? `Not accessed in ${Math.round(decay.daysSinceAccess)} days with only ${entity.access_count} accesses` : undefined;
12411
- return {
12412
- decay,
12413
- promotion,
12414
- shouldArchive,
12415
- shouldFlagForReview,
12416
- archiveReason,
12417
- reviewReason
12418
- };
12419
- }
12420
- function buildContradictionQuery(type, tags) {
12421
- if (tags.length === 0)
12422
- return null;
12423
- return { type, tags };
12424
- }
12425
- // ../memory/src/graph-walk.ts
12426
- async function discoverRelatedContext(client, startIds, maxDepth = 2, maxEntities = 20, minConfidence = 0.5) {
12427
- const visited = new Set;
12428
- const collectedEntities = [];
12429
- const collectedRelations = [];
12430
- let truncated = false;
12431
- const queue = startIds.map((id) => [id, 0]);
12432
- for (const id of startIds) {
12433
- visited.add(id);
12434
- }
12435
- while (queue.length > 0) {
12436
- const [entityId, depth] = queue.shift();
12437
- if (collectedEntities.length >= maxEntities) {
12438
- truncated = true;
12439
- break;
12440
- }
12441
- if (depth > maxDepth)
12442
- continue;
12443
- try {
12444
- const entityResult = await client.getMemoryEntity(entityId);
12445
- const entity = entityResult.entity;
12446
- if (entity) {
12447
- collectedEntities.push({
12448
- id: entity.id,
12449
- type: entity.type,
12450
- title: entity.title,
12451
- confidence: entity.confidence ?? 1,
12452
- memory_tier: entity.memory_tier || "reference"
12453
- });
12454
- }
12455
- if (depth >= maxDepth)
12456
- continue;
12457
- const related = await client.getRelatedEntities(entityId);
12458
- for (const raw of related.outgoing || []) {
12459
- const rel = raw;
12460
- const relConfidence = rel.confidence ?? 1;
12461
- if (relConfidence < minConfidence)
12462
- continue;
12463
- const target = rel.target;
12464
- const targetId = target?.id ?? rel.target_id;
12465
- if (targetId && !visited.has(targetId)) {
12466
- visited.add(targetId);
12467
- queue.push([targetId, depth + 1]);
12468
- collectedRelations.push({
12469
- id: rel.id,
12470
- source_id: entityId,
12471
- target_id: targetId,
12472
- relation_type: rel.relation_type,
12473
- confidence: relConfidence
12474
- });
12475
- }
12476
- }
12477
- for (const raw of related.incoming || []) {
12478
- const rel = raw;
12479
- const relConfidence = rel.confidence ?? 1;
12480
- if (relConfidence < minConfidence)
12481
- continue;
12482
- const source = rel.source;
12483
- const sourceId = source?.id ?? rel.source_id;
12484
- if (sourceId && !visited.has(sourceId)) {
12485
- visited.add(sourceId);
12486
- queue.push([sourceId, depth + 1]);
12487
- collectedRelations.push({
12488
- id: rel.id,
12489
- source_id: sourceId,
12490
- target_id: entityId,
12491
- relation_type: rel.relation_type,
12492
- confidence: relConfidence
12493
- });
12494
- }
12495
- }
12496
- } catch {
12497
- continue;
12498
- }
12499
- }
12500
- return {
12501
- entities: collectedEntities,
12502
- relations: collectedRelations,
12503
- depth: maxDepth,
12504
- truncated
12505
- };
12506
- }
12507
12508
  // ../../node_modules/zod/v4/core/index.js
12508
12509
  var exports_core2 = {};
12509
12510
  __export(exports_core2, {
@@ -28491,7 +28492,7 @@ function getMemoryDir() {
28491
28492
  }
28492
28493
 
28493
28494
  // src/graph-expansion.ts
28494
- async function autoExpandGraph(client2, entityId, title, content, tags, workspaceId, projectId, maxRelations = 5) {
28495
+ async function autoExpandGraph(client2, entityId, title, content, _tags, workspaceId, projectId, maxRelations = 5) {
28495
28496
  try {
28496
28497
  const contentSnippet = content.slice(0, 200).trim();
28497
28498
  const query = [title, contentSnippet].filter(Boolean).join(" ");
@@ -28569,7 +28570,11 @@ Agent: ${session.agentName}`
28569
28570
  type: "lesson",
28570
28571
  tier: "episode",
28571
28572
  confidence: 0.7,
28572
- tags: ["auto-extracted", "session-summary", ...session.cardLabels.slice(0, 3)],
28573
+ tags: [
28574
+ "auto-extracted",
28575
+ "session-summary",
28576
+ ...session.cardLabels.slice(0, 3)
28577
+ ],
28573
28578
  metadata: {
28574
28579
  source: "active_learning",
28575
28580
  card_id: session.cardId,
@@ -28763,7 +28768,7 @@ function isRetryableError(error48, status) {
28763
28768
  return msg.includes("ECONNRESET") || msg.includes("ETIMEDOUT") || msg.includes("fetch failed");
28764
28769
  }
28765
28770
  function getRetryDelay(attempt) {
28766
- const delay = Math.min(RETRY_CONFIG.baseDelayMs * Math.pow(2, attempt), RETRY_CONFIG.maxDelayMs);
28771
+ const delay = Math.min(RETRY_CONFIG.baseDelayMs * 2 ** attempt, RETRY_CONFIG.maxDelayMs);
28767
28772
  return Math.round(delay + delay * 0.25 * (Math.random() * 2 - 1));
28768
28773
  }
28769
28774
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -28882,7 +28887,6 @@ class HarmonyApiClient {
28882
28887
  throw lastError;
28883
28888
  if (attempt < RETRY_CONFIG.maxRetries) {
28884
28889
  await sleep(getRetryDelay(attempt));
28885
- continue;
28886
28890
  }
28887
28891
  }
28888
28892
  }
@@ -28929,7 +28933,6 @@ class HarmonyApiClient {
28929
28933
  throw lastError;
28930
28934
  if (attempt < RETRY_CONFIG.maxRetries) {
28931
28935
  await sleep(getRetryDelay(attempt));
28932
- continue;
28933
28936
  }
28934
28937
  }
28935
28938
  }
@@ -29327,7 +29330,7 @@ function computeRelevanceScore(entity, taskContext, cardLabels) {
29327
29330
  if (entity.last_accessed_at) {
29328
29331
  const daysSinceAccess = (Date.now() - new Date(entity.last_accessed_at).getTime()) / (1000 * 60 * 60 * 24);
29329
29332
  const halfLife = { draft: 7, episode: 30, reference: 180 }[entity.memory_tier];
29330
- const recencyScore = Math.pow(0.5, daysSinceAccess / halfLife) * 0.1;
29333
+ const recencyScore = 0.5 ** (daysSinceAccess / halfLife) * 0.1;
29331
29334
  score += recencyScore;
29332
29335
  if (daysSinceAccess < 7)
29333
29336
  reasons.push("recently_accessed");
@@ -29404,7 +29407,11 @@ async function assembleContext(options) {
29404
29407
  episode: Math.floor(tokenBudget * TIER_BUDGET_ALLOCATION.episode),
29405
29408
  draft: Math.floor(tokenBudget * TIER_BUDGET_ALLOCATION.draft)
29406
29409
  };
29407
- const tierUsed = { reference: 0, episode: 0, draft: 0 };
29410
+ const tierUsed = {
29411
+ reference: 0,
29412
+ episode: 0,
29413
+ draft: 0
29414
+ };
29408
29415
  const included = [];
29409
29416
  let totalUsed = 0;
29410
29417
  let referenceCount = 0;
@@ -29474,9 +29481,18 @@ ${text}`);
29474
29481
  }
29475
29482
  manifest.budgetUsed = totalUsed;
29476
29483
  manifest.tierBreakdown = {
29477
- reference: { count: included.filter((i) => i.entity.memory_tier === "reference").length, tokens: tierUsed.reference },
29478
- episode: { count: included.filter((i) => i.entity.memory_tier === "episode").length, tokens: tierUsed.episode },
29479
- draft: { count: included.filter((i) => i.entity.memory_tier === "draft").length, tokens: tierUsed.draft }
29484
+ reference: {
29485
+ count: included.filter((i) => i.entity.memory_tier === "reference").length,
29486
+ tokens: tierUsed.reference
29487
+ },
29488
+ episode: {
29489
+ count: included.filter((i) => i.entity.memory_tier === "episode").length,
29490
+ tokens: tierUsed.episode
29491
+ },
29492
+ draft: {
29493
+ count: included.filter((i) => i.entity.memory_tier === "draft").length,
29494
+ tokens: tierUsed.draft
29495
+ }
29480
29496
  };
29481
29497
  for (const item of included) {
29482
29498
  manifest.included.push({
@@ -29768,7 +29784,15 @@ ${lines.join(`
29768
29784
  `)}`;
29769
29785
  }
29770
29786
  function generatePrompt(options) {
29771
- const { card, column, variant, customConstraints, memories, assembledContext, assemblyId } = options;
29787
+ const {
29788
+ card,
29789
+ column,
29790
+ variant,
29791
+ customConstraints,
29792
+ memories,
29793
+ assembledContext,
29794
+ assemblyId
29795
+ } = options;
29772
29796
  const contextOpts = {
29773
29797
  includeTitle: true,
29774
29798
  includeDescription: true,
@@ -29922,7 +29946,8 @@ var TOOLS = {
29922
29946
  description: { type: "string" },
29923
29947
  priority: { type: "string", enum: ["low", "medium", "high", "urgent"] },
29924
29948
  assigneeId: { type: "string", nullable: true },
29925
- dueDate: { type: "string", nullable: true }
29949
+ dueDate: { type: "string", nullable: true },
29950
+ done: { type: "boolean", description: "Mark card as done or not done" }
29926
29951
  },
29927
29952
  required: ["cardId"]
29928
29953
  }
@@ -31242,7 +31267,8 @@ async function handleToolCall(name, args, deps) {
31242
31267
  description: args.description,
31243
31268
  priority: args.priority,
31244
31269
  assigneeId: args.assigneeId,
31245
- dueDate: args.dueDate
31270
+ dueDate: args.dueDate,
31271
+ done: args.done
31246
31272
  });
31247
31273
  return { success: true, ...result };
31248
31274
  }
@@ -32059,7 +32085,7 @@ async function handleToolCall(name, args, deps) {
32059
32085
  const card = cardResult.card;
32060
32086
  await client3.updatePlanTask(planId, task.id, { cardId: card.id });
32061
32087
  cardsCreated++;
32062
- } catch (e) {}
32088
+ } catch (_e) {}
32063
32089
  }
32064
32090
  results.cardsCreated = cardsCreated;
32065
32091
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harmony-mcp",
3
- "version": "1.10.0",
3
+ "version": "1.10.2",
4
4
  "description": "MCP server for Harmony Kanban board - enables AI coding agents to manage your boards",
5
5
  "publishConfig": {
6
6
  "access": "public"