harmony-mcp 1.9.4 → 1.9.6

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.js CHANGED
@@ -30470,6 +30470,9 @@ class HarmonyApiClient {
30470
30470
  async deleteMemoryEntity(entityId) {
30471
30471
  return this.request("DELETE", `/memory/entities/${entityId}`);
30472
30472
  }
30473
+ async touchMemoryEntity(entityId) {
30474
+ return this.request("POST", `/memory/entities/${entityId}/touch`);
30475
+ }
30473
30476
  async createMemoryRelation(data) {
30474
30477
  return this.request("POST", "/memory/relations", data);
30475
30478
  }
@@ -30577,6 +30580,9 @@ class HarmonyApiClient {
30577
30580
  async updatePlan(planId, updates) {
30578
30581
  return this.request("PATCH", `/plans/${planId}`, updates);
30579
30582
  }
30583
+ async updatePlanTask(planId, taskId, updates) {
30584
+ return this.request("PATCH", `/plans/${planId}/tasks/${taskId}`, updates);
30585
+ }
30580
30586
  }
30581
30587
  var client = null;
30582
30588
  function getClient() {
@@ -31056,6 +31062,11 @@ function evaluateLifecycle(entity) {
31056
31062
  reviewReason
31057
31063
  };
31058
31064
  }
31065
+ function buildContradictionQuery(type, tags) {
31066
+ if (tags.length === 0)
31067
+ return null;
31068
+ return { type, tags };
31069
+ }
31059
31070
  // ../memory/src/graph-walk.ts
31060
31071
  async function discoverRelatedContext(client2, startIds, maxDepth = 2, maxEntities = 20, minConfidence = 0.5) {
31061
31072
  const visited = new Set;
@@ -31735,15 +31746,7 @@ function mapToContextEntity(raw) {
31735
31746
  };
31736
31747
  }
31737
31748
  async function incrementAccessCounts(client3, entityIds) {
31738
- for (const id of entityIds) {
31739
- try {
31740
- await client3.updateMemoryEntity(id, {
31741
- metadata: {
31742
- _last_context_load: new Date().toISOString()
31743
- }
31744
- });
31745
- } catch {}
31746
- }
31749
+ await Promise.allSettled(entityIds.map((id) => client3.touchMemoryEntity(id)));
31747
31750
  }
31748
31751
  var manifestCache = new Map;
31749
31752
  var MAX_CACHE_SIZE = 50;
@@ -32770,6 +32773,11 @@ var TOOLS = {
32770
32773
  enum: ["user", "agent", "imported"],
32771
32774
  description: "Plan source: agent for AI-generated plans (default: agent)"
32772
32775
  },
32776
+ workflowPhase: {
32777
+ type: "string",
32778
+ enum: ["plan", "execute", "verify", "done"],
32779
+ description: "GSD workflow phase (default: plan)"
32780
+ },
32773
32781
  tasks: {
32774
32782
  type: "array",
32775
32783
  items: {
@@ -32810,7 +32818,7 @@ var TOOLS = {
32810
32818
  }
32811
32819
  },
32812
32820
  harmony_update_plan: {
32813
- description: "Update an existing plan. Can update title, content, or status.",
32821
+ description: "Update an existing plan. Can update title, content, status, or workflow phase.",
32814
32822
  inputSchema: {
32815
32823
  type: "object",
32816
32824
  properties: {
@@ -32824,11 +32832,35 @@ var TOOLS = {
32824
32832
  type: "string",
32825
32833
  enum: ["draft", "active", "archived"],
32826
32834
  description: "New status"
32835
+ },
32836
+ workflowPhase: {
32837
+ type: "string",
32838
+ enum: ["plan", "execute", "verify", "done"],
32839
+ description: "GSD workflow phase"
32827
32840
  }
32828
32841
  },
32829
32842
  required: ["planId"]
32830
32843
  }
32831
32844
  },
32845
+ harmony_advance_plan: {
32846
+ description: "Advance a plan to the next GSD workflow phase with side effects. plan→execute: auto-creates cards from tasks, sets plan active. execute→verify: checks card status. verify→done: archives plan. Creates memory entities at each transition.",
32847
+ inputSchema: {
32848
+ type: "object",
32849
+ properties: {
32850
+ planId: { type: "string", description: "Plan ID to advance" },
32851
+ phase: {
32852
+ type: "string",
32853
+ enum: ["execute", "verify", "done"],
32854
+ description: "Target phase to advance to"
32855
+ },
32856
+ summary: {
32857
+ type: "string",
32858
+ description: "Summary of what happened in the current phase. Stored as a memory entity (decision/pattern/lesson)."
32859
+ }
32860
+ },
32861
+ required: ["planId", "phase"]
32862
+ }
32863
+ },
32832
32864
  harmony_review_learnings: {
32833
32865
  description: "List pending auto-extracted memories awaiting human review. These are memories automatically created from agent work sessions.",
32834
32866
  inputSchema: {
@@ -33553,6 +33585,7 @@ class HarmonyMCPServer {
33553
33585
  throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
33554
33586
  }
33555
33587
  const entityType = args.type || "context";
33588
+ const entityTags = args.tags || [];
33556
33589
  const result = await client3.createMemoryEntity({
33557
33590
  workspace_id: workspaceId,
33558
33591
  project_id: args.projectId || getActiveProjectId() || undefined,
@@ -33563,10 +33596,39 @@ class HarmonyMCPServer {
33563
33596
  content,
33564
33597
  metadata: args.metadata,
33565
33598
  confidence: args.confidence,
33566
- tags: args.tags,
33599
+ tags: entityTags.length > 0 ? entityTags : undefined,
33567
33600
  agent_identifier: "claude-code"
33568
33601
  });
33569
- return { success: true, ...result };
33602
+ const contradictionQuery = buildContradictionQuery(entityType, entityTags);
33603
+ let potentialContradictions = [];
33604
+ if (contradictionQuery) {
33605
+ try {
33606
+ const newEntityId = result.entity?.id;
33607
+ const { entities: candidates } = await client3.listMemoryEntities({
33608
+ workspace_id: workspaceId,
33609
+ type: contradictionQuery.type,
33610
+ tags: contradictionQuery.tags,
33611
+ limit: 10
33612
+ });
33613
+ potentialContradictions = candidates.filter((c) => c.id !== newEntityId).map((c) => ({ id: c.id, title: c.title, tags: c.tags || [] }));
33614
+ if (newEntityId && potentialContradictions.length > 0) {
33615
+ Promise.all(potentialContradictions.map((c) => client3.createMemoryRelation({
33616
+ source_id: newEntityId,
33617
+ target_id: c.id,
33618
+ relation_type: "contradicts",
33619
+ confidence: 0.5
33620
+ }).catch(() => {}))).catch(() => {});
33621
+ }
33622
+ } catch {}
33623
+ }
33624
+ return {
33625
+ success: true,
33626
+ ...result,
33627
+ ...potentialContradictions.length > 0 && {
33628
+ potentialContradictions,
33629
+ contradictionNote: `Found ${potentialContradictions.length} existing memor${potentialContradictions.length === 1 ? "y" : "ies"} with same type and overlapping tags. 'contradicts' relations created automatically. Review these to resolve or confirm.`
33630
+ }
33631
+ };
33570
33632
  }
33571
33633
  case "harmony_recall": {
33572
33634
  const workspaceId = args.workspaceId || getActiveWorkspaceId();
@@ -33750,6 +33812,7 @@ class HarmonyMCPServer {
33750
33812
  title,
33751
33813
  content: args.content,
33752
33814
  source: args.source || "agent",
33815
+ workflowPhase: args.workflowPhase || "plan",
33753
33816
  tasks: args.tasks
33754
33817
  });
33755
33818
  const planUrl = `https://gethmy.com/plans/${result.plan.id}`;
@@ -33796,9 +33859,114 @@ class HarmonyMCPServer {
33796
33859
  if (args.status !== undefined) {
33797
33860
  updates.status = exports_external.enum(["draft", "active", "archived"]).parse(args.status);
33798
33861
  }
33862
+ if (args.workflowPhase !== undefined) {
33863
+ updates.workflowPhase = exports_external.enum(["plan", "execute", "verify", "done"]).parse(args.workflowPhase);
33864
+ }
33799
33865
  const result = await client3.updatePlan(planId, updates);
33800
33866
  return { success: true, plan: result.plan };
33801
33867
  }
33868
+ case "harmony_advance_plan": {
33869
+ const planId = exports_external.string().uuid().parse(args.planId);
33870
+ const targetPhase = exports_external.enum(["execute", "verify", "done"]).parse(args.phase);
33871
+ const summary = args.summary;
33872
+ const planResult = await client3.getPlan(planId);
33873
+ const plan = planResult.plan;
33874
+ const tasks = planResult.tasks;
33875
+ const currentPhase = plan.workflow_phase || "plan";
33876
+ const validTransitions = {
33877
+ plan: "execute",
33878
+ execute: "verify",
33879
+ verify: "done"
33880
+ };
33881
+ if (validTransitions[currentPhase] !== targetPhase) {
33882
+ throw new Error(`Invalid transition: cannot advance from "${currentPhase}" to "${targetPhase}". Expected "${validTransitions[currentPhase]}".`);
33883
+ }
33884
+ const results = {};
33885
+ const workspaceId = getActiveWorkspaceId() || "";
33886
+ if (targetPhase === "execute") {
33887
+ const projectId = plan.project_id;
33888
+ const boardResult = await client3.getBoard(projectId, { summary: true });
33889
+ const columns = boardResult.columns || [];
33890
+ const todoColumn = columns.find((c) => c.name.toLowerCase().includes("to do") || c.name.toLowerCase() === "todo") || columns[0];
33891
+ if (todoColumn && tasks.length > 0) {
33892
+ let cardsCreated = 0;
33893
+ for (const task of tasks) {
33894
+ if (task.card_id)
33895
+ continue;
33896
+ try {
33897
+ const cardResult = await client3.createCard(projectId, {
33898
+ title: task.content,
33899
+ columnId: todoColumn.id,
33900
+ description: `From plan: ${plan.title}`,
33901
+ priority: task.priority || "medium"
33902
+ });
33903
+ const card = cardResult.card;
33904
+ await client3.updatePlanTask(planId, task.id, { cardId: card.id });
33905
+ cardsCreated++;
33906
+ } catch (e) {}
33907
+ }
33908
+ results.cardsCreated = cardsCreated;
33909
+ }
33910
+ await client3.updatePlan(planId, { status: "active", workflowPhase: "execute" });
33911
+ results.planStatus = "active";
33912
+ if (summary && workspaceId) {
33913
+ try {
33914
+ const memResult = await client3.createMemoryEntity({
33915
+ title: `Decision: ${plan.title}`,
33916
+ content: summary,
33917
+ type: "decision",
33918
+ scope: "project",
33919
+ workspaceId,
33920
+ projectId,
33921
+ tags: ["gsd", "plan"],
33922
+ confidence: 0.8
33923
+ });
33924
+ results.memoryEntityId = memResult.entity?.id;
33925
+ } catch (_) {}
33926
+ }
33927
+ } else if (targetPhase === "verify") {
33928
+ await client3.updatePlan(planId, { workflowPhase: "verify" });
33929
+ if (summary && workspaceId) {
33930
+ try {
33931
+ const memResult = await client3.createMemoryEntity({
33932
+ title: `Pattern: ${plan.title}`,
33933
+ content: summary,
33934
+ type: "pattern",
33935
+ scope: "project",
33936
+ workspaceId,
33937
+ projectId: plan.project_id,
33938
+ tags: ["gsd", "execute"],
33939
+ confidence: 0.8
33940
+ });
33941
+ results.memoryEntityId = memResult.entity?.id;
33942
+ } catch (_) {}
33943
+ }
33944
+ } else if (targetPhase === "done") {
33945
+ await client3.updatePlan(planId, { status: "archived", workflowPhase: "done" });
33946
+ results.planStatus = "archived";
33947
+ if (summary && workspaceId) {
33948
+ try {
33949
+ const memResult = await client3.createMemoryEntity({
33950
+ title: `Lesson: ${plan.title}`,
33951
+ content: summary,
33952
+ type: "lesson",
33953
+ scope: "project",
33954
+ workspaceId,
33955
+ projectId: plan.project_id,
33956
+ tags: ["gsd", "verify"],
33957
+ confidence: 0.8
33958
+ });
33959
+ results.memoryEntityId = memResult.entity?.id;
33960
+ } catch (_) {}
33961
+ }
33962
+ }
33963
+ return {
33964
+ success: true,
33965
+ previousPhase: currentPhase,
33966
+ newPhase: targetPhase,
33967
+ ...results
33968
+ };
33969
+ }
33802
33970
  case "harmony_debug_context": {
33803
33971
  const entityId = exports_external.string().uuid().parse(args.entityId);
33804
33972
  const taskContext = exports_external.string().min(1).parse(args.taskContext);
package/dist/index.js CHANGED
@@ -28230,6 +28230,9 @@ class HarmonyApiClient {
28230
28230
  async deleteMemoryEntity(entityId) {
28231
28231
  return this.request("DELETE", `/memory/entities/${entityId}`);
28232
28232
  }
28233
+ async touchMemoryEntity(entityId) {
28234
+ return this.request("POST", `/memory/entities/${entityId}/touch`);
28235
+ }
28233
28236
  async createMemoryRelation(data) {
28234
28237
  return this.request("POST", "/memory/relations", data);
28235
28238
  }
@@ -28337,6 +28340,9 @@ class HarmonyApiClient {
28337
28340
  async updatePlan(planId, updates) {
28338
28341
  return this.request("PATCH", `/plans/${planId}`, updates);
28339
28342
  }
28343
+ async updatePlanTask(planId, taskId, updates) {
28344
+ return this.request("PATCH", `/plans/${planId}/tasks/${taskId}`, updates);
28345
+ }
28340
28346
  }
28341
28347
  var client = null;
28342
28348
  function getClient() {
@@ -28816,6 +28822,11 @@ function evaluateLifecycle(entity) {
28816
28822
  reviewReason
28817
28823
  };
28818
28824
  }
28825
+ function buildContradictionQuery(type, tags) {
28826
+ if (tags.length === 0)
28827
+ return null;
28828
+ return { type, tags };
28829
+ }
28819
28830
  // ../memory/src/graph-walk.ts
28820
28831
  async function discoverRelatedContext(client2, startIds, maxDepth = 2, maxEntities = 20, minConfidence = 0.5) {
28821
28832
  const visited = new Set;
@@ -29495,15 +29506,7 @@ function mapToContextEntity(raw) {
29495
29506
  };
29496
29507
  }
29497
29508
  async function incrementAccessCounts(client3, entityIds) {
29498
- for (const id of entityIds) {
29499
- try {
29500
- await client3.updateMemoryEntity(id, {
29501
- metadata: {
29502
- _last_context_load: new Date().toISOString()
29503
- }
29504
- });
29505
- } catch {}
29506
- }
29509
+ await Promise.allSettled(entityIds.map((id) => client3.touchMemoryEntity(id)));
29507
29510
  }
29508
29511
  var manifestCache = new Map;
29509
29512
  var MAX_CACHE_SIZE = 50;
@@ -30530,6 +30533,11 @@ var TOOLS = {
30530
30533
  enum: ["user", "agent", "imported"],
30531
30534
  description: "Plan source: agent for AI-generated plans (default: agent)"
30532
30535
  },
30536
+ workflowPhase: {
30537
+ type: "string",
30538
+ enum: ["plan", "execute", "verify", "done"],
30539
+ description: "GSD workflow phase (default: plan)"
30540
+ },
30533
30541
  tasks: {
30534
30542
  type: "array",
30535
30543
  items: {
@@ -30570,7 +30578,7 @@ var TOOLS = {
30570
30578
  }
30571
30579
  },
30572
30580
  harmony_update_plan: {
30573
- description: "Update an existing plan. Can update title, content, or status.",
30581
+ description: "Update an existing plan. Can update title, content, status, or workflow phase.",
30574
30582
  inputSchema: {
30575
30583
  type: "object",
30576
30584
  properties: {
@@ -30584,11 +30592,35 @@ var TOOLS = {
30584
30592
  type: "string",
30585
30593
  enum: ["draft", "active", "archived"],
30586
30594
  description: "New status"
30595
+ },
30596
+ workflowPhase: {
30597
+ type: "string",
30598
+ enum: ["plan", "execute", "verify", "done"],
30599
+ description: "GSD workflow phase"
30587
30600
  }
30588
30601
  },
30589
30602
  required: ["planId"]
30590
30603
  }
30591
30604
  },
30605
+ harmony_advance_plan: {
30606
+ description: "Advance a plan to the next GSD workflow phase with side effects. plan→execute: auto-creates cards from tasks, sets plan active. execute→verify: checks card status. verify→done: archives plan. Creates memory entities at each transition.",
30607
+ inputSchema: {
30608
+ type: "object",
30609
+ properties: {
30610
+ planId: { type: "string", description: "Plan ID to advance" },
30611
+ phase: {
30612
+ type: "string",
30613
+ enum: ["execute", "verify", "done"],
30614
+ description: "Target phase to advance to"
30615
+ },
30616
+ summary: {
30617
+ type: "string",
30618
+ description: "Summary of what happened in the current phase. Stored as a memory entity (decision/pattern/lesson)."
30619
+ }
30620
+ },
30621
+ required: ["planId", "phase"]
30622
+ }
30623
+ },
30592
30624
  harmony_review_learnings: {
30593
30625
  description: "List pending auto-extracted memories awaiting human review. These are memories automatically created from agent work sessions.",
30594
30626
  inputSchema: {
@@ -31313,6 +31345,7 @@ class HarmonyMCPServer {
31313
31345
  throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
31314
31346
  }
31315
31347
  const entityType = args.type || "context";
31348
+ const entityTags = args.tags || [];
31316
31349
  const result = await client3.createMemoryEntity({
31317
31350
  workspace_id: workspaceId,
31318
31351
  project_id: args.projectId || getActiveProjectId() || undefined,
@@ -31323,10 +31356,39 @@ class HarmonyMCPServer {
31323
31356
  content,
31324
31357
  metadata: args.metadata,
31325
31358
  confidence: args.confidence,
31326
- tags: args.tags,
31359
+ tags: entityTags.length > 0 ? entityTags : undefined,
31327
31360
  agent_identifier: "claude-code"
31328
31361
  });
31329
- return { success: true, ...result };
31362
+ const contradictionQuery = buildContradictionQuery(entityType, entityTags);
31363
+ let potentialContradictions = [];
31364
+ if (contradictionQuery) {
31365
+ try {
31366
+ const newEntityId = result.entity?.id;
31367
+ const { entities: candidates } = await client3.listMemoryEntities({
31368
+ workspace_id: workspaceId,
31369
+ type: contradictionQuery.type,
31370
+ tags: contradictionQuery.tags,
31371
+ limit: 10
31372
+ });
31373
+ potentialContradictions = candidates.filter((c) => c.id !== newEntityId).map((c) => ({ id: c.id, title: c.title, tags: c.tags || [] }));
31374
+ if (newEntityId && potentialContradictions.length > 0) {
31375
+ Promise.all(potentialContradictions.map((c) => client3.createMemoryRelation({
31376
+ source_id: newEntityId,
31377
+ target_id: c.id,
31378
+ relation_type: "contradicts",
31379
+ confidence: 0.5
31380
+ }).catch(() => {}))).catch(() => {});
31381
+ }
31382
+ } catch {}
31383
+ }
31384
+ return {
31385
+ success: true,
31386
+ ...result,
31387
+ ...potentialContradictions.length > 0 && {
31388
+ potentialContradictions,
31389
+ contradictionNote: `Found ${potentialContradictions.length} existing memor${potentialContradictions.length === 1 ? "y" : "ies"} with same type and overlapping tags. 'contradicts' relations created automatically. Review these to resolve or confirm.`
31390
+ }
31391
+ };
31330
31392
  }
31331
31393
  case "harmony_recall": {
31332
31394
  const workspaceId = args.workspaceId || getActiveWorkspaceId();
@@ -31510,6 +31572,7 @@ class HarmonyMCPServer {
31510
31572
  title,
31511
31573
  content: args.content,
31512
31574
  source: args.source || "agent",
31575
+ workflowPhase: args.workflowPhase || "plan",
31513
31576
  tasks: args.tasks
31514
31577
  });
31515
31578
  const planUrl = `https://gethmy.com/plans/${result.plan.id}`;
@@ -31556,9 +31619,114 @@ class HarmonyMCPServer {
31556
31619
  if (args.status !== undefined) {
31557
31620
  updates.status = exports_external.enum(["draft", "active", "archived"]).parse(args.status);
31558
31621
  }
31622
+ if (args.workflowPhase !== undefined) {
31623
+ updates.workflowPhase = exports_external.enum(["plan", "execute", "verify", "done"]).parse(args.workflowPhase);
31624
+ }
31559
31625
  const result = await client3.updatePlan(planId, updates);
31560
31626
  return { success: true, plan: result.plan };
31561
31627
  }
31628
+ case "harmony_advance_plan": {
31629
+ const planId = exports_external.string().uuid().parse(args.planId);
31630
+ const targetPhase = exports_external.enum(["execute", "verify", "done"]).parse(args.phase);
31631
+ const summary = args.summary;
31632
+ const planResult = await client3.getPlan(planId);
31633
+ const plan = planResult.plan;
31634
+ const tasks = planResult.tasks;
31635
+ const currentPhase = plan.workflow_phase || "plan";
31636
+ const validTransitions = {
31637
+ plan: "execute",
31638
+ execute: "verify",
31639
+ verify: "done"
31640
+ };
31641
+ if (validTransitions[currentPhase] !== targetPhase) {
31642
+ throw new Error(`Invalid transition: cannot advance from "${currentPhase}" to "${targetPhase}". Expected "${validTransitions[currentPhase]}".`);
31643
+ }
31644
+ const results = {};
31645
+ const workspaceId = getActiveWorkspaceId() || "";
31646
+ if (targetPhase === "execute") {
31647
+ const projectId = plan.project_id;
31648
+ const boardResult = await client3.getBoard(projectId, { summary: true });
31649
+ const columns = boardResult.columns || [];
31650
+ const todoColumn = columns.find((c) => c.name.toLowerCase().includes("to do") || c.name.toLowerCase() === "todo") || columns[0];
31651
+ if (todoColumn && tasks.length > 0) {
31652
+ let cardsCreated = 0;
31653
+ for (const task of tasks) {
31654
+ if (task.card_id)
31655
+ continue;
31656
+ try {
31657
+ const cardResult = await client3.createCard(projectId, {
31658
+ title: task.content,
31659
+ columnId: todoColumn.id,
31660
+ description: `From plan: ${plan.title}`,
31661
+ priority: task.priority || "medium"
31662
+ });
31663
+ const card = cardResult.card;
31664
+ await client3.updatePlanTask(planId, task.id, { cardId: card.id });
31665
+ cardsCreated++;
31666
+ } catch (e) {}
31667
+ }
31668
+ results.cardsCreated = cardsCreated;
31669
+ }
31670
+ await client3.updatePlan(planId, { status: "active", workflowPhase: "execute" });
31671
+ results.planStatus = "active";
31672
+ if (summary && workspaceId) {
31673
+ try {
31674
+ const memResult = await client3.createMemoryEntity({
31675
+ title: `Decision: ${plan.title}`,
31676
+ content: summary,
31677
+ type: "decision",
31678
+ scope: "project",
31679
+ workspaceId,
31680
+ projectId,
31681
+ tags: ["gsd", "plan"],
31682
+ confidence: 0.8
31683
+ });
31684
+ results.memoryEntityId = memResult.entity?.id;
31685
+ } catch (_) {}
31686
+ }
31687
+ } else if (targetPhase === "verify") {
31688
+ await client3.updatePlan(planId, { workflowPhase: "verify" });
31689
+ if (summary && workspaceId) {
31690
+ try {
31691
+ const memResult = await client3.createMemoryEntity({
31692
+ title: `Pattern: ${plan.title}`,
31693
+ content: summary,
31694
+ type: "pattern",
31695
+ scope: "project",
31696
+ workspaceId,
31697
+ projectId: plan.project_id,
31698
+ tags: ["gsd", "execute"],
31699
+ confidence: 0.8
31700
+ });
31701
+ results.memoryEntityId = memResult.entity?.id;
31702
+ } catch (_) {}
31703
+ }
31704
+ } else if (targetPhase === "done") {
31705
+ await client3.updatePlan(planId, { status: "archived", workflowPhase: "done" });
31706
+ results.planStatus = "archived";
31707
+ if (summary && workspaceId) {
31708
+ try {
31709
+ const memResult = await client3.createMemoryEntity({
31710
+ title: `Lesson: ${plan.title}`,
31711
+ content: summary,
31712
+ type: "lesson",
31713
+ scope: "project",
31714
+ workspaceId,
31715
+ projectId: plan.project_id,
31716
+ tags: ["gsd", "verify"],
31717
+ confidence: 0.8
31718
+ });
31719
+ results.memoryEntityId = memResult.entity?.id;
31720
+ } catch (_) {}
31721
+ }
31722
+ }
31723
+ return {
31724
+ success: true,
31725
+ previousPhase: currentPhase,
31726
+ newPhase: targetPhase,
31727
+ ...results
31728
+ };
31729
+ }
31562
31730
  case "harmony_debug_context": {
31563
31731
  const entityId = exports_external.string().uuid().parse(args.entityId);
31564
31732
  const taskContext = exports_external.string().min(1).parse(args.taskContext);