harmony-mcp 1.13.0 → 1.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +338 -118
- package/dist/index.js +338 -118
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -25371,6 +25371,31 @@ async function extractMidSessionLearnings(client2, ctx) {
|
|
|
25371
25371
|
const now = Date.now();
|
|
25372
25372
|
const entityIds = [];
|
|
25373
25373
|
const history = sessionTaskHistory.get(ctx.cardId);
|
|
25374
|
+
if (ctx.currentTask) {
|
|
25375
|
+
const previousTask = history?.lastTask || "";
|
|
25376
|
+
const similarity = levenshteinSimilarity(previousTask, ctx.currentTask);
|
|
25377
|
+
const existingSteps = history?.steps || [];
|
|
25378
|
+
if (existingSteps.length === 0 || similarity < 0.6 && previousTask.length > 0) {
|
|
25379
|
+
const newStep = {
|
|
25380
|
+
task: ctx.currentTask,
|
|
25381
|
+
progress: ctx.progressPercent ?? 0,
|
|
25382
|
+
timestamp: now
|
|
25383
|
+
};
|
|
25384
|
+
if (existingSteps.length === 0 && previousTask.length > 0) {
|
|
25385
|
+
existingSteps.push({
|
|
25386
|
+
task: previousTask,
|
|
25387
|
+
progress: 0,
|
|
25388
|
+
timestamp: history?.lastExtractionAt ?? now
|
|
25389
|
+
});
|
|
25390
|
+
}
|
|
25391
|
+
existingSteps.push(newStep);
|
|
25392
|
+
sessionTaskHistory.set(ctx.cardId, {
|
|
25393
|
+
lastTask: ctx.currentTask,
|
|
25394
|
+
lastExtractionAt: history?.lastExtractionAt ?? 0,
|
|
25395
|
+
steps: existingSteps
|
|
25396
|
+
});
|
|
25397
|
+
}
|
|
25398
|
+
}
|
|
25374
25399
|
if (history && now - history.lastExtractionAt < MID_SESSION_RATE_LIMIT_MS) {
|
|
25375
25400
|
if (ctx.status !== "blocked" || !ctx.blockers?.length) {
|
|
25376
25401
|
return { count: 0, entityIds: [] };
|
|
@@ -25408,7 +25433,8 @@ Progress: ${ctx.progressPercent ?? "unknown"}%`,
|
|
|
25408
25433
|
}
|
|
25409
25434
|
sessionTaskHistory.set(ctx.cardId, {
|
|
25410
25435
|
lastTask: ctx.currentTask || "",
|
|
25411
|
-
lastExtractionAt: now
|
|
25436
|
+
lastExtractionAt: now,
|
|
25437
|
+
steps: history?.steps || []
|
|
25412
25438
|
});
|
|
25413
25439
|
return { count: entityIds.length, entityIds };
|
|
25414
25440
|
}
|
|
@@ -25444,9 +25470,11 @@ Progress: ${ctx.progressPercent ?? "unknown"}%`,
|
|
|
25444
25470
|
entityIds.push(entity.id);
|
|
25445
25471
|
} catch {}
|
|
25446
25472
|
}
|
|
25473
|
+
const currentHistory = sessionTaskHistory.get(ctx.cardId);
|
|
25447
25474
|
sessionTaskHistory.set(ctx.cardId, {
|
|
25448
25475
|
lastTask: ctx.currentTask,
|
|
25449
|
-
lastExtractionAt: entityIds.length > 0 ? now :
|
|
25476
|
+
lastExtractionAt: entityIds.length > 0 ? now : currentHistory?.lastExtractionAt ?? 0,
|
|
25477
|
+
steps: currentHistory?.steps || []
|
|
25450
25478
|
});
|
|
25451
25479
|
}
|
|
25452
25480
|
return { count: entityIds.length, entityIds };
|
|
@@ -25454,6 +25482,128 @@ Progress: ${ctx.progressPercent ?? "unknown"}%`,
|
|
|
25454
25482
|
function clearMidSessionTracking(cardId) {
|
|
25455
25483
|
sessionTaskHistory.delete(cardId);
|
|
25456
25484
|
}
|
|
25485
|
+
function enrichSteps(steps) {
|
|
25486
|
+
return steps.map((step, i) => {
|
|
25487
|
+
const prevProgress = i > 0 ? steps[i - 1].progress : 0;
|
|
25488
|
+
const prevTimestamp = i > 0 ? steps[i - 1].timestamp : step.timestamp;
|
|
25489
|
+
const progressDelta = step.progress - prevProgress;
|
|
25490
|
+
return {
|
|
25491
|
+
task: step.task,
|
|
25492
|
+
progress: step.progress,
|
|
25493
|
+
progressDelta,
|
|
25494
|
+
durationMs: step.timestamp - prevTimestamp,
|
|
25495
|
+
isKeyDecision: progressDelta >= 20
|
|
25496
|
+
};
|
|
25497
|
+
});
|
|
25498
|
+
}
|
|
25499
|
+
function buildProcedureContent(session, enrichedSteps, wikiLinksLine) {
|
|
25500
|
+
const triggerLabels = session.cardLabels.length > 0 ? `Labels: ${session.cardLabels.join(", ")}` : "";
|
|
25501
|
+
const stepsMarkdown = enrichedSteps.map((s, i) => {
|
|
25502
|
+
const marker = s.isKeyDecision ? " **[key step]**" : "";
|
|
25503
|
+
const duration3 = s.durationMs > 0 ? ` (~${Math.round(s.durationMs / 60000)}min)` : "";
|
|
25504
|
+
return `${i + 1}. ${s.task} (${s.progress}%, +${s.progressDelta}%)${marker}${duration3}`;
|
|
25505
|
+
}).join(`
|
|
25506
|
+
`);
|
|
25507
|
+
const subtaskSection = session.cardSubtasks && session.cardSubtasks.length > 0 ? [
|
|
25508
|
+
"",
|
|
25509
|
+
"## Subtasks Completed",
|
|
25510
|
+
...session.cardSubtasks.map((s) => `- [${s.done ? "x" : " "}] ${s.title}`)
|
|
25511
|
+
].join(`
|
|
25512
|
+
`) : "";
|
|
25513
|
+
const durationInfo = session.sessionDurationMs ? `
|
|
25514
|
+
Duration: ${Math.round(session.sessionDurationMs / 60000)} minutes` : "";
|
|
25515
|
+
return [
|
|
25516
|
+
"## Trigger",
|
|
25517
|
+
`When working on: "${session.cardTitle}"`,
|
|
25518
|
+
triggerLabels,
|
|
25519
|
+
"",
|
|
25520
|
+
"## Steps",
|
|
25521
|
+
stepsMarkdown,
|
|
25522
|
+
subtaskSection,
|
|
25523
|
+
"",
|
|
25524
|
+
"## Outcome",
|
|
25525
|
+
`Completed at ${session.progressPercent ?? "unknown"}%`,
|
|
25526
|
+
session.currentTask ? `Final state: ${session.currentTask}` : "",
|
|
25527
|
+
`Agent: ${session.agentName}`,
|
|
25528
|
+
durationInfo,
|
|
25529
|
+
wikiLinksLine
|
|
25530
|
+
].filter((line) => line !== undefined).join(`
|
|
25531
|
+
`);
|
|
25532
|
+
}
|
|
25533
|
+
async function extractOrReinforceProcedure(client2, session, steps, workspaceId, projectId, wikiLinksLine = "") {
|
|
25534
|
+
const enrichedSteps = enrichSteps(steps);
|
|
25535
|
+
const newContent = buildProcedureContent(session, enrichedSteps, wikiLinksLine);
|
|
25536
|
+
const tags = [
|
|
25537
|
+
"auto-extracted",
|
|
25538
|
+
"procedure",
|
|
25539
|
+
...session.cardLabels.slice(0, 3)
|
|
25540
|
+
];
|
|
25541
|
+
try {
|
|
25542
|
+
const similar = await findSimilarEntities(client2, `Procedure: ${session.cardTitle}`, newContent, workspaceId, { projectId, limit: 5, minRrfScore: 0.03 });
|
|
25543
|
+
const matchingProcedure = similar.find((e) => e.type === "procedure" && (e.rrf_score ?? 0) >= 0.05);
|
|
25544
|
+
if (matchingProcedure) {
|
|
25545
|
+
const { entity: rawEntity } = await client2.getMemoryEntity(matchingProcedure.id);
|
|
25546
|
+
const fullEntity = rawEntity;
|
|
25547
|
+
const currentMeta = fullEntity.metadata || {};
|
|
25548
|
+
const sourceCards = (currentMeta.source_cards || []).slice();
|
|
25549
|
+
if (!sourceCards.includes(session.cardId)) {
|
|
25550
|
+
sourceCards.push(session.cardId);
|
|
25551
|
+
}
|
|
25552
|
+
const reuseCount = (currentMeta.reuse_count || 0) + 1;
|
|
25553
|
+
const currentConfidence = fullEntity.confidence ?? 0.7;
|
|
25554
|
+
const newConfidence = Math.min(0.95, currentConfidence + 0.05);
|
|
25555
|
+
const stepsAppendix = enrichedSteps.map((s, i) => `${i + 1}. ${s.task} (${s.progress}%)`).join(`
|
|
25556
|
+
`);
|
|
25557
|
+
const appendix = `
|
|
25558
|
+
|
|
25559
|
+
---
|
|
25560
|
+
### Execution ${reuseCount + 1}: ${session.cardTitle}
|
|
25561
|
+
${stepsAppendix}
|
|
25562
|
+
Agent: ${session.agentName} | ${new Date().toISOString().split("T")[0]}`;
|
|
25563
|
+
const updatedMeta = {
|
|
25564
|
+
...currentMeta,
|
|
25565
|
+
reuse_count: reuseCount,
|
|
25566
|
+
source_cards: sourceCards,
|
|
25567
|
+
last_reinforced_at: new Date().toISOString(),
|
|
25568
|
+
step_count: Math.max(currentMeta.step_count || 0, steps.length)
|
|
25569
|
+
};
|
|
25570
|
+
const shouldPromote = reuseCount >= 2 && fullEntity.memory_tier !== "reference";
|
|
25571
|
+
await client2.updateMemoryEntity(fullEntity.id, {
|
|
25572
|
+
content: (fullEntity.content || "") + appendix,
|
|
25573
|
+
confidence: newConfidence,
|
|
25574
|
+
metadata: {
|
|
25575
|
+
...updatedMeta,
|
|
25576
|
+
...shouldPromote ? {
|
|
25577
|
+
promoted_reason: `Reinforced by ${reuseCount + 1} successful sessions`,
|
|
25578
|
+
promoted_at: new Date().toISOString()
|
|
25579
|
+
} : {}
|
|
25580
|
+
},
|
|
25581
|
+
...shouldPromote ? { memory_tier: "reference" } : {}
|
|
25582
|
+
});
|
|
25583
|
+
return { mode: "reinforced", entityId: fullEntity.id };
|
|
25584
|
+
}
|
|
25585
|
+
} catch {}
|
|
25586
|
+
return {
|
|
25587
|
+
mode: "created",
|
|
25588
|
+
learning: {
|
|
25589
|
+
title: `Procedure: ${session.cardTitle}`,
|
|
25590
|
+
content: newContent,
|
|
25591
|
+
type: "procedure",
|
|
25592
|
+
tier: "episode",
|
|
25593
|
+
confidence: 0.7,
|
|
25594
|
+
tags,
|
|
25595
|
+
metadata: {
|
|
25596
|
+
source: "active_learning",
|
|
25597
|
+
card_id: session.cardId,
|
|
25598
|
+
source_cards: [session.cardId],
|
|
25599
|
+
step_count: steps.length,
|
|
25600
|
+
key_step_count: enrichedSteps.filter((s) => s.isKeyDecision).length,
|
|
25601
|
+
reuse_count: 0,
|
|
25602
|
+
review_status: "pending"
|
|
25603
|
+
}
|
|
25604
|
+
}
|
|
25605
|
+
};
|
|
25606
|
+
}
|
|
25457
25607
|
async function extractLearnings(client2, session) {
|
|
25458
25608
|
const workspaceId = getActiveWorkspaceId();
|
|
25459
25609
|
if (!workspaceId) {
|
|
@@ -25554,6 +25704,19 @@ Agent: ${session.agentName}`,
|
|
|
25554
25704
|
});
|
|
25555
25705
|
}
|
|
25556
25706
|
const entityIds = [];
|
|
25707
|
+
const stepHistory = sessionTaskHistory.get(session.cardId);
|
|
25708
|
+
const hasEnoughSteps = stepHistory && stepHistory.steps.length >= 2;
|
|
25709
|
+
const isSuccessful = session.status === "completed" && (session.progressPercent === undefined || session.progressPercent >= 85) && !session.blockers?.length;
|
|
25710
|
+
if (isSuccessful && hasEnoughSteps) {
|
|
25711
|
+
const procedureResult = await extractOrReinforceProcedure(client2, session, stepHistory.steps, workspaceId, projectId, wikiLinksLine);
|
|
25712
|
+
if (procedureResult) {
|
|
25713
|
+
if (procedureResult.mode === "created") {
|
|
25714
|
+
learnings.push(procedureResult.learning);
|
|
25715
|
+
} else {
|
|
25716
|
+
entityIds.push(procedureResult.entityId);
|
|
25717
|
+
}
|
|
25718
|
+
}
|
|
25719
|
+
}
|
|
25557
25720
|
const createdPairs = [];
|
|
25558
25721
|
for (const learning of learnings) {
|
|
25559
25722
|
try {
|
|
@@ -26456,75 +26619,6 @@ function deriveClusterTitle(cluster, type) {
|
|
|
26456
26619
|
return `Consolidated ${type}: ${suffix}`;
|
|
26457
26620
|
}
|
|
26458
26621
|
|
|
26459
|
-
// src/lifecycle-maintenance.ts
|
|
26460
|
-
async function runLifecycleMaintenance(client3, workspaceId, projectId) {
|
|
26461
|
-
const result = {
|
|
26462
|
-
archived: 0,
|
|
26463
|
-
pruned: 0,
|
|
26464
|
-
promoted: 0,
|
|
26465
|
-
reviewed: 0,
|
|
26466
|
-
errors: 0
|
|
26467
|
-
};
|
|
26468
|
-
let entities;
|
|
26469
|
-
try {
|
|
26470
|
-
const listResult = await client3.listMemoryEntities({
|
|
26471
|
-
workspace_id: workspaceId,
|
|
26472
|
-
project_id: projectId,
|
|
26473
|
-
limit: 200
|
|
26474
|
-
});
|
|
26475
|
-
entities = listResult.entities || [];
|
|
26476
|
-
} catch {
|
|
26477
|
-
return result;
|
|
26478
|
-
}
|
|
26479
|
-
if (entities.length === 0)
|
|
26480
|
-
return result;
|
|
26481
|
-
const now = Date.now();
|
|
26482
|
-
const STALE_DRAFT_MAX_AGE_DAYS = 30;
|
|
26483
|
-
for (const entity of entities) {
|
|
26484
|
-
try {
|
|
26485
|
-
const lifecycle2 = evaluateLifecycle(entity);
|
|
26486
|
-
if (lifecycle2.shouldArchive) {
|
|
26487
|
-
await client3.deleteMemoryEntity(entity.id);
|
|
26488
|
-
result.archived++;
|
|
26489
|
-
continue;
|
|
26490
|
-
}
|
|
26491
|
-
if (entity.memory_tier === "draft") {
|
|
26492
|
-
const ageDays = (now - new Date(entity.created_at).getTime()) / (1000 * 60 * 60 * 24);
|
|
26493
|
-
if (ageDays > STALE_DRAFT_MAX_AGE_DAYS && lifecycle2.decay.score < 0.3) {
|
|
26494
|
-
await client3.deleteMemoryEntity(entity.id);
|
|
26495
|
-
result.pruned++;
|
|
26496
|
-
continue;
|
|
26497
|
-
}
|
|
26498
|
-
}
|
|
26499
|
-
if (lifecycle2.promotion.eligible && lifecycle2.promotion.targetTier) {
|
|
26500
|
-
await client3.updateMemoryEntity(entity.id, {
|
|
26501
|
-
memory_tier: lifecycle2.promotion.targetTier,
|
|
26502
|
-
metadata: {
|
|
26503
|
-
promoted_at: new Date().toISOString(),
|
|
26504
|
-
promotion_reason: lifecycle2.promotion.reason,
|
|
26505
|
-
promoted_from: entity.memory_tier
|
|
26506
|
-
}
|
|
26507
|
-
});
|
|
26508
|
-
result.promoted++;
|
|
26509
|
-
continue;
|
|
26510
|
-
}
|
|
26511
|
-
if (lifecycle2.shouldFlagForReview) {
|
|
26512
|
-
await client3.updateMemoryEntity(entity.id, {
|
|
26513
|
-
metadata: {
|
|
26514
|
-
needs_review: true,
|
|
26515
|
-
review_reason: lifecycle2.reviewReason,
|
|
26516
|
-
flagged_at: new Date().toISOString()
|
|
26517
|
-
}
|
|
26518
|
-
});
|
|
26519
|
-
result.reviewed++;
|
|
26520
|
-
}
|
|
26521
|
-
} catch {
|
|
26522
|
-
result.errors++;
|
|
26523
|
-
}
|
|
26524
|
-
}
|
|
26525
|
-
return result;
|
|
26526
|
-
}
|
|
26527
|
-
|
|
26528
26622
|
// src/context-assembly.ts
|
|
26529
26623
|
var DEFAULT_TOKEN_BUDGET = 4000;
|
|
26530
26624
|
var MAX_TOKENS_PER_ENTITY = 500;
|
|
@@ -26931,6 +27025,75 @@ async function recordContextFeedback(client3, cardId, sessionStatus, progressPer
|
|
|
26931
27025
|
return { adjusted };
|
|
26932
27026
|
}
|
|
26933
27027
|
|
|
27028
|
+
// src/lifecycle-maintenance.ts
|
|
27029
|
+
async function runLifecycleMaintenance(client3, workspaceId, projectId) {
|
|
27030
|
+
const result = {
|
|
27031
|
+
archived: 0,
|
|
27032
|
+
pruned: 0,
|
|
27033
|
+
promoted: 0,
|
|
27034
|
+
reviewed: 0,
|
|
27035
|
+
errors: 0
|
|
27036
|
+
};
|
|
27037
|
+
let entities;
|
|
27038
|
+
try {
|
|
27039
|
+
const listResult = await client3.listMemoryEntities({
|
|
27040
|
+
workspace_id: workspaceId,
|
|
27041
|
+
project_id: projectId,
|
|
27042
|
+
limit: 200
|
|
27043
|
+
});
|
|
27044
|
+
entities = listResult.entities || [];
|
|
27045
|
+
} catch {
|
|
27046
|
+
return result;
|
|
27047
|
+
}
|
|
27048
|
+
if (entities.length === 0)
|
|
27049
|
+
return result;
|
|
27050
|
+
const now = Date.now();
|
|
27051
|
+
const STALE_DRAFT_MAX_AGE_DAYS = 30;
|
|
27052
|
+
for (const entity of entities) {
|
|
27053
|
+
try {
|
|
27054
|
+
const lifecycle2 = evaluateLifecycle(entity);
|
|
27055
|
+
if (lifecycle2.shouldArchive) {
|
|
27056
|
+
await client3.deleteMemoryEntity(entity.id);
|
|
27057
|
+
result.archived++;
|
|
27058
|
+
continue;
|
|
27059
|
+
}
|
|
27060
|
+
if (entity.memory_tier === "draft") {
|
|
27061
|
+
const ageDays = (now - new Date(entity.created_at).getTime()) / (1000 * 60 * 60 * 24);
|
|
27062
|
+
if (ageDays > STALE_DRAFT_MAX_AGE_DAYS && lifecycle2.decay.score < 0.3) {
|
|
27063
|
+
await client3.deleteMemoryEntity(entity.id);
|
|
27064
|
+
result.pruned++;
|
|
27065
|
+
continue;
|
|
27066
|
+
}
|
|
27067
|
+
}
|
|
27068
|
+
if (lifecycle2.promotion.eligible && lifecycle2.promotion.targetTier) {
|
|
27069
|
+
await client3.updateMemoryEntity(entity.id, {
|
|
27070
|
+
memory_tier: lifecycle2.promotion.targetTier,
|
|
27071
|
+
metadata: {
|
|
27072
|
+
promoted_at: new Date().toISOString(),
|
|
27073
|
+
promotion_reason: lifecycle2.promotion.reason,
|
|
27074
|
+
promoted_from: entity.memory_tier
|
|
27075
|
+
}
|
|
27076
|
+
});
|
|
27077
|
+
result.promoted++;
|
|
27078
|
+
continue;
|
|
27079
|
+
}
|
|
27080
|
+
if (lifecycle2.shouldFlagForReview) {
|
|
27081
|
+
await client3.updateMemoryEntity(entity.id, {
|
|
27082
|
+
metadata: {
|
|
27083
|
+
needs_review: true,
|
|
27084
|
+
review_reason: lifecycle2.reviewReason,
|
|
27085
|
+
flagged_at: new Date().toISOString()
|
|
27086
|
+
}
|
|
27087
|
+
});
|
|
27088
|
+
result.reviewed++;
|
|
27089
|
+
}
|
|
27090
|
+
} catch {
|
|
27091
|
+
result.errors++;
|
|
27092
|
+
}
|
|
27093
|
+
}
|
|
27094
|
+
return result;
|
|
27095
|
+
}
|
|
27096
|
+
|
|
26934
27097
|
// src/prompt-builder.ts
|
|
26935
27098
|
var LABEL_CATEGORY_MAP = {
|
|
26936
27099
|
bug: "bug",
|
|
@@ -27233,6 +27396,12 @@ ${assembledContext}`);
|
|
|
27233
27396
|
sections.push(memory.content);
|
|
27234
27397
|
}
|
|
27235
27398
|
}
|
|
27399
|
+
const oneThingLine = synthesizeOneThing(card, subtasks, links);
|
|
27400
|
+
if (oneThingLine) {
|
|
27401
|
+
sections.push(`
|
|
27402
|
+
## Recommended Next Step
|
|
27403
|
+
${oneThingLine}`);
|
|
27404
|
+
}
|
|
27236
27405
|
if (variant === "execute") {
|
|
27237
27406
|
sections.push(`
|
|
27238
27407
|
## Progress Tracking
|
|
@@ -27272,6 +27441,32 @@ ${customConstraints}`);
|
|
|
27272
27441
|
...assemblyId && { assemblyId }
|
|
27273
27442
|
};
|
|
27274
27443
|
}
|
|
27444
|
+
function synthesizeOneThing(card, subtasks, links) {
|
|
27445
|
+
if (card.done)
|
|
27446
|
+
return null;
|
|
27447
|
+
const blockers = links.filter((l) => l.display_type === "is_blocked_by" && l.direction === "incoming");
|
|
27448
|
+
if (blockers.length > 0) {
|
|
27449
|
+
const blocker = blockers[0];
|
|
27450
|
+
return `Unblock first: resolve #${blocker.target_card.short_id} "${blocker.target_card.title}" which is blocking this card.`;
|
|
27451
|
+
}
|
|
27452
|
+
if (subtasks.length > 0) {
|
|
27453
|
+
const completed = subtasks.filter((s) => s.completed).length;
|
|
27454
|
+
if (completed === subtasks.length) {
|
|
27455
|
+
return "All subtasks completed. Review the work and mark the card as done.";
|
|
27456
|
+
}
|
|
27457
|
+
const nextSubtask = subtasks.find((s) => !s.completed);
|
|
27458
|
+
if (nextSubtask) {
|
|
27459
|
+
return `Work on next subtask: "${nextSubtask.title}" (${completed}/${subtasks.length} done).`;
|
|
27460
|
+
}
|
|
27461
|
+
}
|
|
27462
|
+
if (card.due_date && (card.priority === "urgent" || card.priority === "high")) {
|
|
27463
|
+
return `High-priority task with deadline ${card.due_date}. Start implementation immediately.`;
|
|
27464
|
+
}
|
|
27465
|
+
if (card.description) {
|
|
27466
|
+
return "Analyze the description, identify the approach, and begin implementation.";
|
|
27467
|
+
}
|
|
27468
|
+
return null;
|
|
27469
|
+
}
|
|
27275
27470
|
|
|
27276
27471
|
// src/server.ts
|
|
27277
27472
|
var TOOLS = {
|
|
@@ -27834,7 +28029,8 @@ var TOOLS = {
|
|
|
27834
28029
|
"commitment",
|
|
27835
28030
|
"lesson",
|
|
27836
28031
|
"project",
|
|
27837
|
-
"handoff"
|
|
28032
|
+
"handoff",
|
|
28033
|
+
"procedure"
|
|
27838
28034
|
],
|
|
27839
28035
|
description: "Entity type (default: context)"
|
|
27840
28036
|
},
|
|
@@ -27893,7 +28089,8 @@ var TOOLS = {
|
|
|
27893
28089
|
"commitment",
|
|
27894
28090
|
"lesson",
|
|
27895
28091
|
"project",
|
|
27896
|
-
"handoff"
|
|
28092
|
+
"handoff",
|
|
28093
|
+
"procedure"
|
|
27897
28094
|
],
|
|
27898
28095
|
description: "Filter by entity type"
|
|
27899
28096
|
},
|
|
@@ -27953,7 +28150,8 @@ var TOOLS = {
|
|
|
27953
28150
|
"commitment",
|
|
27954
28151
|
"lesson",
|
|
27955
28152
|
"project",
|
|
27956
|
-
"handoff"
|
|
28153
|
+
"handoff",
|
|
28154
|
+
"procedure"
|
|
27957
28155
|
],
|
|
27958
28156
|
description: "New entity type"
|
|
27959
28157
|
},
|
|
@@ -28051,7 +28249,8 @@ var TOOLS = {
|
|
|
28051
28249
|
"commitment",
|
|
28052
28250
|
"lesson",
|
|
28053
28251
|
"project",
|
|
28054
|
-
"handoff"
|
|
28252
|
+
"handoff",
|
|
28253
|
+
"procedure"
|
|
28055
28254
|
],
|
|
28056
28255
|
description: "Filter results by entity type"
|
|
28057
28256
|
},
|
|
@@ -28096,7 +28295,8 @@ var TOOLS = {
|
|
|
28096
28295
|
"commitment",
|
|
28097
28296
|
"lesson",
|
|
28098
28297
|
"project",
|
|
28099
|
-
"handoff"
|
|
28298
|
+
"handoff",
|
|
28299
|
+
"procedure"
|
|
28100
28300
|
],
|
|
28101
28301
|
description: "Filter by entity type"
|
|
28102
28302
|
},
|
|
@@ -28683,7 +28883,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
28683
28883
|
};
|
|
28684
28884
|
switch (name) {
|
|
28685
28885
|
case "harmony_create_card": {
|
|
28686
|
-
const title = exports_external.string().min(1).parse(args.title);
|
|
28886
|
+
const title = exports_external.string().min(1).max(500).parse(args.title);
|
|
28687
28887
|
const projectId = args.projectId || getProjectId();
|
|
28688
28888
|
const result = await client3.createCard(projectId, {
|
|
28689
28889
|
title,
|
|
@@ -28709,7 +28909,8 @@ async function handleToolCall(name, args, deps) {
|
|
|
28709
28909
|
case "harmony_move_card": {
|
|
28710
28910
|
const cardId = exports_external.string().uuid().parse(args.cardId);
|
|
28711
28911
|
const columnId = exports_external.string().uuid().parse(args.columnId);
|
|
28712
|
-
const
|
|
28912
|
+
const position = args.position !== undefined ? exports_external.number().int().min(0).parse(args.position) : undefined;
|
|
28913
|
+
const result = await client3.moveCard(cardId, columnId, position);
|
|
28713
28914
|
let sessionEnded = false;
|
|
28714
28915
|
try {
|
|
28715
28916
|
const { card } = result;
|
|
@@ -28754,7 +28955,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
28754
28955
|
return { success: true, ...result };
|
|
28755
28956
|
}
|
|
28756
28957
|
case "harmony_search_cards": {
|
|
28757
|
-
const query = exports_external.string().min(1).parse(args.query);
|
|
28958
|
+
const query = exports_external.string().min(1).max(500).parse(args.query);
|
|
28758
28959
|
const result = await client3.searchCards(query, {
|
|
28759
28960
|
projectId: args.projectId
|
|
28760
28961
|
});
|
|
@@ -28772,14 +28973,14 @@ async function handleToolCall(name, args, deps) {
|
|
|
28772
28973
|
return { success: true, ...result };
|
|
28773
28974
|
}
|
|
28774
28975
|
case "harmony_create_column": {
|
|
28775
|
-
const name2 = exports_external.string().min(1).parse(args.name);
|
|
28976
|
+
const name2 = exports_external.string().min(1).max(100).parse(args.name);
|
|
28776
28977
|
const projectId = args.projectId || getProjectId();
|
|
28777
28978
|
const result = await client3.createColumn(projectId, name2);
|
|
28778
28979
|
return { success: true, ...result };
|
|
28779
28980
|
}
|
|
28780
28981
|
case "harmony_update_column": {
|
|
28781
28982
|
const columnId = exports_external.string().uuid().parse(args.columnId);
|
|
28782
|
-
const name2 = exports_external.string().min(1).parse(args.name);
|
|
28983
|
+
const name2 = exports_external.string().min(1).max(100).parse(args.name);
|
|
28783
28984
|
const result = await client3.updateColumn(columnId, name2);
|
|
28784
28985
|
return { success: true, ...result };
|
|
28785
28986
|
}
|
|
@@ -28789,7 +28990,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
28789
28990
|
return { success: true };
|
|
28790
28991
|
}
|
|
28791
28992
|
case "harmony_create_label": {
|
|
28792
|
-
const name2 = exports_external.string().min(1).parse(args.name);
|
|
28993
|
+
const name2 = exports_external.string().min(1).max(50).parse(args.name);
|
|
28793
28994
|
const color = exports_external.string().regex(/^#[0-9a-fA-F]{6}$/).parse(args.color);
|
|
28794
28995
|
const projectId = args.projectId || getProjectId();
|
|
28795
28996
|
const board = await client3.getBoard(projectId, { summary: true });
|
|
@@ -28831,7 +29032,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
28831
29032
|
}
|
|
28832
29033
|
case "harmony_create_subtask": {
|
|
28833
29034
|
const cardId = exports_external.string().uuid().parse(args.cardId);
|
|
28834
|
-
const title = exports_external.string().min(1).parse(args.title);
|
|
29035
|
+
const title = exports_external.string().min(1).max(500).parse(args.title);
|
|
28835
29036
|
const result = await client3.createSubtask(cardId, title);
|
|
28836
29037
|
return { success: true, ...result };
|
|
28837
29038
|
}
|
|
@@ -28895,7 +29096,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
28895
29096
|
};
|
|
28896
29097
|
}
|
|
28897
29098
|
case "harmony_process_command": {
|
|
28898
|
-
const command = exports_external.string().min(1).parse(args.command);
|
|
29099
|
+
const command = exports_external.string().min(1).max(500).parse(args.command);
|
|
28899
29100
|
const result = await client3.processNLU({
|
|
28900
29101
|
command,
|
|
28901
29102
|
projectId: args.projectId || deps.getActiveProjectId() || undefined,
|
|
@@ -28907,8 +29108,8 @@ async function handleToolCall(name, args, deps) {
|
|
|
28907
29108
|
}
|
|
28908
29109
|
case "harmony_start_agent_session": {
|
|
28909
29110
|
const cardId = exports_external.string().uuid().parse(args.cardId);
|
|
28910
|
-
const agentIdentifier = exports_external.string().min(1).parse(args.agentIdentifier);
|
|
28911
|
-
const agentName = exports_external.string().min(1).parse(args.agentName);
|
|
29111
|
+
const agentIdentifier = exports_external.string().min(1).max(100).parse(args.agentIdentifier);
|
|
29112
|
+
const agentName = exports_external.string().min(1).max(100).parse(args.agentName);
|
|
28912
29113
|
const moveToColumn = args.moveToColumn;
|
|
28913
29114
|
const addLabels = args.addLabels;
|
|
28914
29115
|
let movedTo = null;
|
|
@@ -29007,13 +29208,14 @@ async function handleToolCall(name, args, deps) {
|
|
|
29007
29208
|
}
|
|
29008
29209
|
case "harmony_update_agent_progress": {
|
|
29009
29210
|
const cardId = exports_external.string().uuid().parse(args.cardId);
|
|
29010
|
-
const agentIdentifier = exports_external.string().min(1).parse(args.agentIdentifier);
|
|
29011
|
-
const agentName = exports_external.string().min(1).parse(args.agentName);
|
|
29211
|
+
const agentIdentifier = exports_external.string().min(1).max(100).parse(args.agentIdentifier);
|
|
29212
|
+
const agentName = exports_external.string().min(1).max(100).parse(args.agentName);
|
|
29213
|
+
const progressPercent = args.progressPercent !== undefined ? exports_external.number().min(0).max(100).parse(args.progressPercent) : undefined;
|
|
29012
29214
|
const result = await client3.updateAgentProgress(cardId, {
|
|
29013
29215
|
agentIdentifier,
|
|
29014
29216
|
agentName,
|
|
29015
29217
|
status: args.status,
|
|
29016
|
-
progressPercent
|
|
29218
|
+
progressPercent,
|
|
29017
29219
|
currentTask: args.currentTask,
|
|
29018
29220
|
blockers: args.blockers,
|
|
29019
29221
|
estimatedMinutesRemaining: args.estimatedMinutesRemaining
|
|
@@ -29030,7 +29232,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29030
29232
|
currentTask: args.currentTask,
|
|
29031
29233
|
status: args.status,
|
|
29032
29234
|
blockers: args.blockers,
|
|
29033
|
-
progressPercent
|
|
29235
|
+
progressPercent
|
|
29034
29236
|
});
|
|
29035
29237
|
midSessionLearnings = midResult.count;
|
|
29036
29238
|
} catch {}
|
|
@@ -29040,19 +29242,27 @@ async function handleToolCall(name, args, deps) {
|
|
|
29040
29242
|
const cardId = exports_external.string().uuid().parse(args.cardId);
|
|
29041
29243
|
const moveToColumn = args.moveToColumn;
|
|
29042
29244
|
const sessionStatus = args.status || "completed";
|
|
29245
|
+
const endProgressPercent = args.progressPercent !== undefined ? exports_external.number().min(0).max(100).parse(args.progressPercent) : undefined;
|
|
29043
29246
|
const result = await client3.endAgentSession(cardId, {
|
|
29044
29247
|
status: sessionStatus,
|
|
29045
|
-
progressPercent:
|
|
29248
|
+
progressPercent: endProgressPercent
|
|
29046
29249
|
});
|
|
29047
29250
|
let movedTo = null;
|
|
29048
29251
|
let learningsExtracted = 0;
|
|
29049
29252
|
let cardTitle = "";
|
|
29050
29253
|
let cardLabels = [];
|
|
29254
|
+
let cardDescription = "";
|
|
29255
|
+
let cardSubtasks = [];
|
|
29051
29256
|
try {
|
|
29052
29257
|
const { card } = await client3.getCard(cardId);
|
|
29053
29258
|
const typedCard = card;
|
|
29054
29259
|
cardTitle = typedCard.title || "";
|
|
29055
29260
|
cardLabels = (typedCard.labels || []).map((l) => l.name);
|
|
29261
|
+
cardDescription = typedCard.description || "";
|
|
29262
|
+
cardSubtasks = (typedCard.subtasks || []).map((s) => ({
|
|
29263
|
+
title: s.title,
|
|
29264
|
+
done: s.done
|
|
29265
|
+
}));
|
|
29056
29266
|
const projectId = typedCard.project_id;
|
|
29057
29267
|
if (moveToColumn && projectId) {
|
|
29058
29268
|
const board = await client3.getBoard(projectId, {
|
|
@@ -29068,6 +29278,13 @@ async function handleToolCall(name, args, deps) {
|
|
|
29068
29278
|
} catch {}
|
|
29069
29279
|
try {
|
|
29070
29280
|
const session = result.session;
|
|
29281
|
+
let sessionDurationMs;
|
|
29282
|
+
if (session?.created_at) {
|
|
29283
|
+
const startTime = new Date(session.created_at).getTime();
|
|
29284
|
+
if (!Number.isNaN(startTime)) {
|
|
29285
|
+
sessionDurationMs = Date.now() - startTime;
|
|
29286
|
+
}
|
|
29287
|
+
}
|
|
29071
29288
|
const sessionContext = {
|
|
29072
29289
|
cardId,
|
|
29073
29290
|
cardTitle,
|
|
@@ -29075,9 +29292,12 @@ async function handleToolCall(name, args, deps) {
|
|
|
29075
29292
|
agentIdentifier: session?.agent_identifier || "unknown",
|
|
29076
29293
|
agentName: session?.agent_name || "Unknown Agent",
|
|
29077
29294
|
status: sessionStatus,
|
|
29078
|
-
progressPercent:
|
|
29295
|
+
progressPercent: endProgressPercent,
|
|
29079
29296
|
blockers: session?.blockers || undefined,
|
|
29080
|
-
currentTask: session?.current_task || undefined
|
|
29297
|
+
currentTask: session?.current_task || undefined,
|
|
29298
|
+
sessionDurationMs,
|
|
29299
|
+
cardDescription: cardDescription || undefined,
|
|
29300
|
+
cardSubtasks: cardSubtasks.length > 0 ? cardSubtasks : undefined
|
|
29081
29301
|
};
|
|
29082
29302
|
const learningResult = await extractLearnings(client3, sessionContext);
|
|
29083
29303
|
learningsExtracted = learningResult.count;
|
|
@@ -29085,7 +29305,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29085
29305
|
let feedbackAdjusted = 0;
|
|
29086
29306
|
try {
|
|
29087
29307
|
const session = result.session;
|
|
29088
|
-
const feedbackResult = await recordContextFeedback(client3, cardId, sessionStatus,
|
|
29308
|
+
const feedbackResult = await recordContextFeedback(client3, cardId, sessionStatus, endProgressPercent, (session?.blockers?.length ?? 0) > 0);
|
|
29089
29309
|
feedbackAdjusted = feedbackResult.adjusted;
|
|
29090
29310
|
} catch {}
|
|
29091
29311
|
let maintenanceResult;
|
|
@@ -29233,8 +29453,8 @@ async function handleToolCall(name, args, deps) {
|
|
|
29233
29453
|
};
|
|
29234
29454
|
}
|
|
29235
29455
|
case "harmony_remember": {
|
|
29236
|
-
const title = exports_external.string().min(1).parse(args.title);
|
|
29237
|
-
const content = exports_external.string().min(1).parse(args.content);
|
|
29456
|
+
const title = exports_external.string().min(1).max(300).parse(args.title);
|
|
29457
|
+
const content = exports_external.string().min(1).max(50000).parse(args.content);
|
|
29238
29458
|
const workspaceId = args.workspaceId || deps.getActiveWorkspaceId();
|
|
29239
29459
|
if (!workspaceId) {
|
|
29240
29460
|
throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
|
|
@@ -29250,7 +29470,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29250
29470
|
title,
|
|
29251
29471
|
content,
|
|
29252
29472
|
metadata: args.metadata,
|
|
29253
|
-
confidence: args.confidence,
|
|
29473
|
+
confidence: args.confidence !== undefined ? exports_external.number().min(0).max(1).parse(args.confidence) : undefined,
|
|
29254
29474
|
tags: entityTags.length > 0 ? entityTags : undefined,
|
|
29255
29475
|
agent_identifier: "claude-code"
|
|
29256
29476
|
});
|
|
@@ -29334,9 +29554,9 @@ async function handleToolCall(name, args, deps) {
|
|
|
29334
29554
|
const entityId = exports_external.string().uuid().parse(args.entityId);
|
|
29335
29555
|
const updates = {};
|
|
29336
29556
|
if (args.title !== undefined)
|
|
29337
|
-
updates.title = args.title;
|
|
29557
|
+
updates.title = exports_external.string().min(1).max(300).parse(args.title);
|
|
29338
29558
|
if (args.content !== undefined)
|
|
29339
|
-
updates.content = args.content;
|
|
29559
|
+
updates.content = exports_external.string().max(50000).parse(args.content);
|
|
29340
29560
|
if (args.type !== undefined)
|
|
29341
29561
|
updates.type = args.type;
|
|
29342
29562
|
if (args.scope !== undefined)
|
|
@@ -29344,7 +29564,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29344
29564
|
if (args.tags !== undefined)
|
|
29345
29565
|
updates.tags = args.tags;
|
|
29346
29566
|
if (args.confidence !== undefined)
|
|
29347
|
-
updates.confidence = args.confidence;
|
|
29567
|
+
updates.confidence = exports_external.number().min(0).max(1).parse(args.confidence);
|
|
29348
29568
|
if (args.metadata !== undefined)
|
|
29349
29569
|
updates.metadata = args.metadata;
|
|
29350
29570
|
const result = await client3.updateMemoryEntity(entityId, updates);
|
|
@@ -29372,12 +29592,12 @@ async function handleToolCall(name, args, deps) {
|
|
|
29372
29592
|
source_id: sourceId,
|
|
29373
29593
|
target_id: targetId,
|
|
29374
29594
|
relation_type: relationType,
|
|
29375
|
-
confidence: args.confidence
|
|
29595
|
+
confidence: args.confidence !== undefined ? exports_external.number().min(0).max(1).parse(args.confidence) : undefined
|
|
29376
29596
|
});
|
|
29377
29597
|
return { success: true, ...result };
|
|
29378
29598
|
}
|
|
29379
29599
|
case "harmony_memory_search": {
|
|
29380
|
-
const query = exports_external.string().min(1).parse(args.query);
|
|
29600
|
+
const query = exports_external.string().min(1).max(500).parse(args.query);
|
|
29381
29601
|
const workspaceId = args.workspaceId || deps.getActiveWorkspaceId();
|
|
29382
29602
|
if (!workspaceId) {
|
|
29383
29603
|
throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
|
|
@@ -29474,7 +29694,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29474
29694
|
};
|
|
29475
29695
|
}
|
|
29476
29696
|
case "harmony_create_plan": {
|
|
29477
|
-
const title = exports_external.string().min(1).parse(args.title);
|
|
29697
|
+
const title = exports_external.string().min(1).max(200).parse(args.title);
|
|
29478
29698
|
const projectId = args.projectId || getProjectId();
|
|
29479
29699
|
const result = await client3.createPlan(projectId, {
|
|
29480
29700
|
title,
|
|
@@ -29521,7 +29741,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29521
29741
|
const planId = exports_external.string().uuid().parse(args.planId);
|
|
29522
29742
|
const updates = {};
|
|
29523
29743
|
if (args.title !== undefined)
|
|
29524
|
-
updates.title = exports_external.string().min(1).parse(args.title);
|
|
29744
|
+
updates.title = exports_external.string().min(1).max(200).parse(args.title);
|
|
29525
29745
|
if (args.content !== undefined)
|
|
29526
29746
|
updates.content = args.content;
|
|
29527
29747
|
if (args.status !== undefined) {
|
|
@@ -29661,7 +29881,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29661
29881
|
}
|
|
29662
29882
|
case "harmony_debug_context": {
|
|
29663
29883
|
const entityId = exports_external.string().uuid().parse(args.entityId);
|
|
29664
|
-
const taskContext = exports_external.string().min(1).parse(args.taskContext);
|
|
29884
|
+
const taskContext = exports_external.string().min(1).max(2000).parse(args.taskContext);
|
|
29665
29885
|
const cardLabels = args.cardLabels || [];
|
|
29666
29886
|
const entityResult = await client3.getMemoryEntity(entityId);
|
|
29667
29887
|
const entity = mapToContextEntity(entityResult.entity);
|
|
@@ -29875,7 +30095,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29875
30095
|
const entityId = exports_external.string().uuid().parse(args.entityId);
|
|
29876
30096
|
const action = exports_external.enum(["approve", "reject"]).parse(args.action);
|
|
29877
30097
|
if (action === "approve") {
|
|
29878
|
-
await approveLearning(client3, entityId, args.confidence);
|
|
30098
|
+
await approveLearning(client3, entityId, args.confidence !== undefined ? exports_external.number().min(0).max(1).parse(args.confidence) : undefined);
|
|
29879
30099
|
return {
|
|
29880
30100
|
success: true,
|
|
29881
30101
|
action: "approved",
|
|
@@ -29890,7 +30110,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29890
30110
|
};
|
|
29891
30111
|
}
|
|
29892
30112
|
case "harmony_get_context_manifest": {
|
|
29893
|
-
const assemblyId = exports_external.string().min(1).parse(args.assemblyId);
|
|
30113
|
+
const assemblyId = exports_external.string().min(1).max(100).parse(args.assemblyId);
|
|
29894
30114
|
const manifest = getCachedManifest(assemblyId);
|
|
29895
30115
|
if (!manifest) {
|
|
29896
30116
|
throw new Error(`Manifest not found for assembly '${assemblyId}'. Manifests are cached in-memory and expire after server restart.`);
|
|
@@ -29909,7 +30129,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29909
30129
|
case "harmony_promote_memory": {
|
|
29910
30130
|
const entityId = exports_external.string().uuid().parse(args.entityId);
|
|
29911
30131
|
const targetTier = exports_external.enum(["episode", "reference"]).parse(args.targetTier);
|
|
29912
|
-
const reason = exports_external.string().min(1).parse(args.reason);
|
|
30132
|
+
const reason = exports_external.string().min(1).max(500).parse(args.reason);
|
|
29913
30133
|
const entityResult = await client3.getMemoryEntity(entityId);
|
|
29914
30134
|
const entity = entityResult.entity;
|
|
29915
30135
|
const currentTier = entity.memory_tier || "reference";
|
|
@@ -29936,9 +30156,9 @@ async function handleToolCall(name, args, deps) {
|
|
|
29936
30156
|
};
|
|
29937
30157
|
}
|
|
29938
30158
|
case "harmony_signup": {
|
|
29939
|
-
const email3 = exports_external.string().email().parse(args.email);
|
|
29940
|
-
const password = exports_external.string().min(8).parse(args.password);
|
|
29941
|
-
const fullName = exports_external.string().min(1).parse(args.fullName);
|
|
30159
|
+
const email3 = exports_external.string().email().max(254).parse(args.email);
|
|
30160
|
+
const password = exports_external.string().min(8).max(128).parse(args.password);
|
|
30161
|
+
const fullName = exports_external.string().min(1).max(100).parse(args.fullName);
|
|
29942
30162
|
const apiUrl = deps.getApiUrl();
|
|
29943
30163
|
const result = await signupUser(apiUrl, {
|
|
29944
30164
|
email: email3,
|
|
@@ -29952,7 +30172,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29952
30172
|
};
|
|
29953
30173
|
}
|
|
29954
30174
|
case "harmony_create_workspace": {
|
|
29955
|
-
const name2 = exports_external.string().min(1).parse(args.name);
|
|
30175
|
+
const name2 = exports_external.string().min(1).max(100).parse(args.name);
|
|
29956
30176
|
const result = await client3.createWorkspace({
|
|
29957
30177
|
name: name2,
|
|
29958
30178
|
description: args.description
|
|
@@ -29961,7 +30181,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29961
30181
|
}
|
|
29962
30182
|
case "harmony_create_project": {
|
|
29963
30183
|
const workspaceId = exports_external.string().uuid().parse(args.workspaceId);
|
|
29964
|
-
const name2 = exports_external.string().min(1).parse(args.name);
|
|
30184
|
+
const name2 = exports_external.string().min(1).max(100).parse(args.name);
|
|
29965
30185
|
const result = await client3.createProject({
|
|
29966
30186
|
workspaceId,
|
|
29967
30187
|
name: name2,
|
|
@@ -29973,7 +30193,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
29973
30193
|
}
|
|
29974
30194
|
case "harmony_send_invitations": {
|
|
29975
30195
|
const workspaceId = exports_external.string().uuid().parse(args.workspaceId);
|
|
29976
|
-
const emails = exports_external.array(exports_external.string().email()).min(1).parse(args.emails);
|
|
30196
|
+
const emails = exports_external.array(exports_external.string().email().max(254)).min(1).parse(args.emails);
|
|
29977
30197
|
const result = await client3.sendInvitations({
|
|
29978
30198
|
workspaceId,
|
|
29979
30199
|
emails,
|
|
@@ -29983,14 +30203,14 @@ async function handleToolCall(name, args, deps) {
|
|
|
29983
30203
|
return { success: true, ...result };
|
|
29984
30204
|
}
|
|
29985
30205
|
case "harmony_generate_api_key": {
|
|
29986
|
-
const name2 = exports_external.string().min(1).parse(args.name);
|
|
30206
|
+
const name2 = exports_external.string().min(1).max(100).parse(args.name);
|
|
29987
30207
|
const result = await client3.generateApiKey(name2);
|
|
29988
30208
|
return { success: true, ...result };
|
|
29989
30209
|
}
|
|
29990
30210
|
case "harmony_onboard": {
|
|
29991
|
-
const email3 = exports_external.string().email().parse(args.email);
|
|
29992
|
-
const password = exports_external.string().min(8).parse(args.password);
|
|
29993
|
-
const fullName = exports_external.string().min(1).parse(args.fullName);
|
|
30211
|
+
const email3 = exports_external.string().email().max(254).parse(args.email);
|
|
30212
|
+
const password = exports_external.string().min(8).max(128).parse(args.password);
|
|
30213
|
+
const fullName = exports_external.string().min(1).max(100).parse(args.fullName);
|
|
29994
30214
|
const workspaceName = args.workspaceName || `${fullName}'s Workspace`;
|
|
29995
30215
|
const projectName = args.projectName || "My First Project";
|
|
29996
30216
|
const template = args.template || "kanban";
|