@codazen/harmonica-mcp 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +89 -358
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21587,6 +21587,18 @@ async function fetchProjectInOrg(client, projectId, orgId) {
|
|
|
21587
21587
|
}
|
|
21588
21588
|
return project;
|
|
21589
21589
|
}
|
|
21590
|
+
async function fetchSystemInOrg(client, systemId, orgId) {
|
|
21591
|
+
const system = await client.getSystem(systemId);
|
|
21592
|
+
if (!system) {
|
|
21593
|
+
throw new Error(`System not found: "${systemId}"`);
|
|
21594
|
+
}
|
|
21595
|
+
if (system.orgId !== orgId) {
|
|
21596
|
+
throw new Error(
|
|
21597
|
+
`System "${systemId}" does not belong to the configured organization. Access denied.`
|
|
21598
|
+
);
|
|
21599
|
+
}
|
|
21600
|
+
return system;
|
|
21601
|
+
}
|
|
21590
21602
|
async function fetchBeatInOrg(client, beatId, orgId) {
|
|
21591
21603
|
const beat = await client.getBeat(beatId);
|
|
21592
21604
|
if (!beat) {
|
|
@@ -21968,7 +21980,7 @@ function registerActivityTools(server, ctx, client) {
|
|
|
21968
21980
|
},
|
|
21969
21981
|
async ({ projectId, limit, importance }) => {
|
|
21970
21982
|
await assertProjectInOrg(client, projectId, ctx.orgId);
|
|
21971
|
-
const { entries, hasMore } = await client.
|
|
21983
|
+
const { entries, hasMore } = await client.listSystemActivities(projectId, {
|
|
21972
21984
|
limit: limit ?? 30,
|
|
21973
21985
|
minImportance: importance
|
|
21974
21986
|
});
|
|
@@ -22689,7 +22701,7 @@ function formatDeliveryPolicy(policy, unresolvedReason) {
|
|
|
22689
22701
|
}
|
|
22690
22702
|
function formatProjectContext(project, notes, orgCoda) {
|
|
22691
22703
|
const sections = [];
|
|
22692
|
-
sections.push(`#
|
|
22704
|
+
sections.push(`# System: ${project.title}`);
|
|
22693
22705
|
sections.push(`**ID:** ${project.projectId}`);
|
|
22694
22706
|
sections.push(`**Status:** ${project.status.replace("_", " ")}`);
|
|
22695
22707
|
if (project.repoOwner && project.repoName) {
|
|
@@ -23275,7 +23287,7 @@ ${formatBeatDetail(beat)}${similarityWarning}` }] };
|
|
|
23275
23287
|
async ({ projectId, beatId, status, includeArchived }) => {
|
|
23276
23288
|
try {
|
|
23277
23289
|
await assertProjectInOrg(client, projectId, ctx.orgId);
|
|
23278
|
-
const revisions = beatId ? await client.listBeatRevisions(projectId, beatId, { status, includeArchived }) : await client.
|
|
23290
|
+
const revisions = beatId ? await client.listBeatRevisions(projectId, beatId, { status, includeArchived }) : await client.listSystemRevisions(projectId, { status, includeArchived });
|
|
23279
23291
|
return { content: [{ type: "text", text: formatRevisionSummaryTable(revisions) }] };
|
|
23280
23292
|
} catch (err) {
|
|
23281
23293
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -23936,7 +23948,7 @@ function registerCheckTools(server, ctx, client) {
|
|
|
23936
23948
|
},
|
|
23937
23949
|
async ({ projectId }) => {
|
|
23938
23950
|
try {
|
|
23939
|
-
const checks = await client.
|
|
23951
|
+
const checks = await client.listLatestSystemChecks(projectId);
|
|
23940
23952
|
if (checks.length === 0) {
|
|
23941
23953
|
return { content: [{ type: "text", text: `No checks found for project ${projectId}.` }] };
|
|
23942
23954
|
}
|
|
@@ -24316,18 +24328,6 @@ ${g.acceptanceCriteria}` : null,
|
|
|
24316
24328
|
};
|
|
24317
24329
|
}
|
|
24318
24330
|
);
|
|
24319
|
-
server.tool(
|
|
24320
|
-
"list_deliverable_group_deliverables",
|
|
24321
|
-
'List all Deliverables assigned to a DeliverableGroup. Use to answer "what deliverables are in this phase/milestone?" or "what has the team committed to in this engagement group?"',
|
|
24322
|
-
{
|
|
24323
|
-
deliverableGroupId: external_exports.string().describe("The DeliverableGroup ID")
|
|
24324
|
-
},
|
|
24325
|
-
async ({ deliverableGroupId }) => {
|
|
24326
|
-
const items = await client.listDeliverableGroupDeliverables(deliverableGroupId);
|
|
24327
|
-
const text = items.length === 0 ? "No deliverables in this group." : items.map((d) => `[${d.deliverableId}] teamspace: ${d.teamspaceId}`).join("\n");
|
|
24328
|
-
return { content: [{ type: "text", text }] };
|
|
24329
|
-
}
|
|
24330
|
-
);
|
|
24331
24331
|
server.tool(
|
|
24332
24332
|
"list_deliverable_group_drops",
|
|
24333
24333
|
'List all Drops linked to a DeliverableGroup. Use to answer "what releases are part of this phase?" or "which software drops are tied to this engagement milestone?"',
|
|
@@ -24385,108 +24385,6 @@ ${g.acceptanceCriteria}` : null,
|
|
|
24385
24385
|
);
|
|
24386
24386
|
}
|
|
24387
24387
|
|
|
24388
|
-
// ../../libs/harmonica-services/src/mcp/tools/deliverable-tools.ts
|
|
24389
|
-
var import_node_crypto = require("node:crypto");
|
|
24390
|
-
function registerDeliverableTools(server, ctx, client) {
|
|
24391
|
-
server.tool(
|
|
24392
|
-
"list_deliverables",
|
|
24393
|
-
"List all Deliverables (tangible client-facing artifacts or milestones owed by a date \u2014 e.g. board deck, roadmap doc, audit report) for a Teamspace.",
|
|
24394
|
-
{
|
|
24395
|
-
teamspaceId: external_exports.string().describe("The teamspace ID")
|
|
24396
|
-
},
|
|
24397
|
-
async ({ teamspaceId }) => {
|
|
24398
|
-
const deliverables = await client.listTeamspaceDeliverables(teamspaceId);
|
|
24399
|
-
const text = deliverables.length === 0 ? "No deliverables found." : deliverables.map(
|
|
24400
|
-
(d) => `[${d.deliverableId}] ${d.title} \u2014 ${d.status}${d.dueDate ? ` (due ${d.dueDate})` : ""}${d.deliverableGroupId ? ` (group: ${d.deliverableGroupId})` : ""}`
|
|
24401
|
-
).join("\n");
|
|
24402
|
-
return { content: [{ type: "text", text }] };
|
|
24403
|
-
}
|
|
24404
|
-
);
|
|
24405
|
-
server.tool(
|
|
24406
|
-
"get_deliverable",
|
|
24407
|
-
"Get a Deliverable (tangible client-facing artifact or milestone) by ID.",
|
|
24408
|
-
{
|
|
24409
|
-
deliverableId: external_exports.string().describe("The deliverable ID")
|
|
24410
|
-
},
|
|
24411
|
-
async ({ deliverableId }) => {
|
|
24412
|
-
const d = await client.getDeliverable(deliverableId);
|
|
24413
|
-
if (!d) return { content: [{ type: "text", text: `Deliverable not found: ${deliverableId}` }] };
|
|
24414
|
-
const text = [
|
|
24415
|
-
`ID: ${d.deliverableId}`,
|
|
24416
|
-
`Title: ${d.title}`,
|
|
24417
|
-
`Teamspace: ${d.teamspaceId}`,
|
|
24418
|
-
`Status: ${d.status}`,
|
|
24419
|
-
d.description ? `Description: ${d.description}` : null,
|
|
24420
|
-
d.dueDate ? `Due: ${d.dueDate}` : null,
|
|
24421
|
-
d.deliverableGroupId ? `Group: ${d.deliverableGroupId}` : null,
|
|
24422
|
-
`Version: ${d.version}`,
|
|
24423
|
-
`Created: ${d.createdAt}`
|
|
24424
|
-
].filter(Boolean).join("\n");
|
|
24425
|
-
return { content: [{ type: "text", text }] };
|
|
24426
|
-
}
|
|
24427
|
-
);
|
|
24428
|
-
server.tool(
|
|
24429
|
-
"create_deliverable",
|
|
24430
|
-
'Create a Deliverable in a Teamspace. A Deliverable is a tangible commitment the agency owes the client by a date \u2014 board presentation, roadmap document, audit report, design mockups, training session, etc. Use this when the user describes something we will hand over. Do NOT use this for software capabilities the product provides to its end users \u2014 those are Beats (use create_beat). Do NOT use this for context, assumptions, constraints, or decisions \u2014 those are Notes (use create_note). Recognition cue: phrases like "we owe them\u2026", "due by\u2026", "the deck", "the report" \u2192 Deliverable. "Users will be able to\u2026", "the screen that\u2026" \u2192 Beat.',
|
|
24431
|
-
{
|
|
24432
|
-
teamspaceId: external_exports.string().describe("The teamspace ID"),
|
|
24433
|
-
title: external_exports.string().min(1).max(300).describe("Deliverable title"),
|
|
24434
|
-
description: external_exports.string().max(2e3).optional().describe("Optional description"),
|
|
24435
|
-
dueDate: external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("Due date (YYYY-MM-DD)"),
|
|
24436
|
-
status: external_exports.enum(["draft", "active", "delivered", "cancelled"]).optional().describe("Initial status (default: draft)"),
|
|
24437
|
-
deliverableGroupId: external_exports.string().optional().describe("Assign to a DeliverableGroup by ID at creation time")
|
|
24438
|
-
},
|
|
24439
|
-
async ({ teamspaceId, title, description, dueDate, status, deliverableGroupId }) => {
|
|
24440
|
-
const deliverableId = `dlv-${(0, import_node_crypto.randomUUID)()}`;
|
|
24441
|
-
const d = await client.createDeliverable({
|
|
24442
|
-
deliverableId,
|
|
24443
|
-
teamspaceId,
|
|
24444
|
-
orgId: ctx.orgId,
|
|
24445
|
-
title,
|
|
24446
|
-
description,
|
|
24447
|
-
dueDate,
|
|
24448
|
-
status,
|
|
24449
|
-
createdBy: ctx.user.userId,
|
|
24450
|
-
...deliverableGroupId !== void 0 && { deliverableGroupId }
|
|
24451
|
-
});
|
|
24452
|
-
return {
|
|
24453
|
-
content: [{
|
|
24454
|
-
type: "text",
|
|
24455
|
-
text: `Created deliverable: [${d.deliverableId}] ${d.title} \u2014 ${d.status}`
|
|
24456
|
-
}]
|
|
24457
|
-
};
|
|
24458
|
-
}
|
|
24459
|
-
);
|
|
24460
|
-
server.tool(
|
|
24461
|
-
"update_deliverable",
|
|
24462
|
-
"Update an existing Deliverable. Transition status as the artifact progresses: draft \u2192 active \u2192 delivered (or cancelled).",
|
|
24463
|
-
{
|
|
24464
|
-
deliverableId: external_exports.string().describe("The deliverable ID"),
|
|
24465
|
-
title: external_exports.string().min(1).max(300).optional().describe("New title"),
|
|
24466
|
-
description: external_exports.string().max(2e3).optional().describe("New description"),
|
|
24467
|
-
dueDate: external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional().describe("New due date (YYYY-MM-DD), or null to clear"),
|
|
24468
|
-
status: external_exports.enum(["draft", "active", "delivered", "cancelled"]).optional().describe("New status"),
|
|
24469
|
-
deliverableGroupId: external_exports.string().nullable().optional().describe("Assign to a DeliverableGroup by ID, or null to ungroup")
|
|
24470
|
-
},
|
|
24471
|
-
async ({ deliverableId, title, description, dueDate, status, deliverableGroupId }) => {
|
|
24472
|
-
const updates = {};
|
|
24473
|
-
if (title !== void 0) updates["title"] = title;
|
|
24474
|
-
if (description !== void 0) updates["description"] = description;
|
|
24475
|
-
if (dueDate !== void 0) updates["dueDate"] = dueDate;
|
|
24476
|
-
if (status !== void 0) updates["status"] = status;
|
|
24477
|
-
if (deliverableGroupId !== void 0) updates["deliverableGroupId"] = deliverableGroupId;
|
|
24478
|
-
const d = await client.updateDeliverable(deliverableId, updates);
|
|
24479
|
-
if (!d) return { content: [{ type: "text", text: `Deliverable not found: ${deliverableId}` }] };
|
|
24480
|
-
return {
|
|
24481
|
-
content: [{
|
|
24482
|
-
type: "text",
|
|
24483
|
-
text: `Updated deliverable: [${d.deliverableId}] ${d.title} \u2014 ${d.status}`
|
|
24484
|
-
}]
|
|
24485
|
-
};
|
|
24486
|
-
}
|
|
24487
|
-
);
|
|
24488
|
-
}
|
|
24489
|
-
|
|
24490
24388
|
// ../../libs/harmonica-services/src/mcp/tools/downbeat-harmony-report-tools.ts
|
|
24491
24389
|
function formatQualifyingBeat(b) {
|
|
24492
24390
|
return `- \`${b.beatId}\` ${b.title}: ${b.signals.join(", ")}`;
|
|
@@ -28513,7 +28411,7 @@ ${lines.join("\n")}` }] };
|
|
|
28513
28411
|
}
|
|
28514
28412
|
|
|
28515
28413
|
// ../../libs/harmonica-services/src/mcp/tools/onboarding-tools.ts
|
|
28516
|
-
var
|
|
28414
|
+
var import_node_crypto = require("node:crypto");
|
|
28517
28415
|
var OnboardingNoteInputSchema = external_exports.object({
|
|
28518
28416
|
noteType: external_exports.enum(["context", "assumption", "constraint", "guidance", "decision"]),
|
|
28519
28417
|
content: external_exports.string().min(1),
|
|
@@ -28525,11 +28423,6 @@ var OnboardingProjectInputSchema = external_exports.object({
|
|
|
28525
28423
|
description: external_exports.string().max(2e3).optional(),
|
|
28526
28424
|
notes: external_exports.array(OnboardingNoteInputSchema).optional()
|
|
28527
28425
|
});
|
|
28528
|
-
var OnboardingDeliverableInputSchema = external_exports.object({
|
|
28529
|
-
title: external_exports.string().min(1).max(300),
|
|
28530
|
-
description: external_exports.string().max(2e3).optional(),
|
|
28531
|
-
dueDate: external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional()
|
|
28532
|
-
});
|
|
28533
28426
|
function registerOnboardingTools(server, ctx, client) {
|
|
28534
28427
|
server.tool(
|
|
28535
28428
|
"initiate_teamspace_onboarding",
|
|
@@ -28627,7 +28520,7 @@ function registerOnboardingTools(server, ctx, client) {
|
|
|
28627
28520
|
server.tool(
|
|
28628
28521
|
"create_teamspace_onboarding_batch",
|
|
28629
28522
|
[
|
|
28630
|
-
"Create a Teamspace, Projects,
|
|
28523
|
+
"Create a Teamspace, Projects, and Notes",
|
|
28631
28524
|
"from a PM-approved onboarding payload in a single batch operation.",
|
|
28632
28525
|
"Call this after the PM approves the pre-flight review card from initiate_teamspace_onboarding.",
|
|
28633
28526
|
"Returns a creation receipt with IDs and counts for all created entities.",
|
|
@@ -28636,20 +28529,18 @@ function registerOnboardingTools(server, ctx, client) {
|
|
|
28636
28529
|
{
|
|
28637
28530
|
teamspaceName: external_exports.string().min(1).max(200).describe("Teamspace display name"),
|
|
28638
28531
|
projects: external_exports.array(OnboardingProjectInputSchema).min(1).describe("Phase 1 projects to create, each linked to the Teamspace"),
|
|
28639
|
-
teamspaceNotes: external_exports.array(OnboardingNoteInputSchema).describe("Constraints, assumptions, and context notes at the Teamspace/project level")
|
|
28640
|
-
deliverables: external_exports.array(OnboardingDeliverableInputSchema).describe("Deliverables detected from commitment language in documents")
|
|
28532
|
+
teamspaceNotes: external_exports.array(OnboardingNoteInputSchema).describe("Constraints, assumptions, and context notes at the Teamspace/project level")
|
|
28641
28533
|
},
|
|
28642
28534
|
async ({
|
|
28643
28535
|
teamspaceName,
|
|
28644
28536
|
projects,
|
|
28645
|
-
teamspaceNotes
|
|
28646
|
-
deliverables
|
|
28537
|
+
teamspaceNotes
|
|
28647
28538
|
}) => {
|
|
28648
28539
|
const lines = [];
|
|
28649
28540
|
let teamspace;
|
|
28650
28541
|
try {
|
|
28651
28542
|
teamspace = await client.createTeamspace({
|
|
28652
|
-
teamspaceId: (0,
|
|
28543
|
+
teamspaceId: (0, import_node_crypto.randomUUID)(),
|
|
28653
28544
|
slug: teamspaceName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""),
|
|
28654
28545
|
orgId: ctx.orgId,
|
|
28655
28546
|
name: teamspaceName,
|
|
@@ -28666,8 +28557,8 @@ Error: ${msg}`);
|
|
|
28666
28557
|
const createdProjects = [];
|
|
28667
28558
|
for (const p of projects) {
|
|
28668
28559
|
try {
|
|
28669
|
-
const project = await client.
|
|
28670
|
-
projectId: (0,
|
|
28560
|
+
const project = await client.createSystem({
|
|
28561
|
+
projectId: (0, import_node_crypto.randomUUID)(),
|
|
28671
28562
|
orgId: ctx.orgId,
|
|
28672
28563
|
teamspaceId: teamspace.teamspaceId,
|
|
28673
28564
|
ownerUserId: ctx.user?.userId ?? "system",
|
|
@@ -28711,7 +28602,7 @@ Projects (${createdProjects.length}):`);
|
|
|
28711
28602
|
for (const note of projects[i]?.notes ?? []) {
|
|
28712
28603
|
try {
|
|
28713
28604
|
const n = await client.createNote({
|
|
28714
|
-
noteId: `N-TEMP-${(0,
|
|
28605
|
+
noteId: `N-TEMP-${(0, import_node_crypto.randomUUID)()}`,
|
|
28715
28606
|
// overridden server-side
|
|
28716
28607
|
projectId: project.projectId,
|
|
28717
28608
|
noteType: note.noteType,
|
|
@@ -28728,24 +28619,6 @@ Projects (${createdProjects.length}):`);
|
|
|
28728
28619
|
}
|
|
28729
28620
|
lines.push(`
|
|
28730
28621
|
Notes filed: ${createdNotes.length}`);
|
|
28731
|
-
const createdDeliverables = [];
|
|
28732
|
-
for (const d of deliverables) {
|
|
28733
|
-
try {
|
|
28734
|
-
const del = await client.createDeliverable({
|
|
28735
|
-
deliverableId: (0, import_node_crypto2.randomUUID)(),
|
|
28736
|
-
// overridden server-side
|
|
28737
|
-
teamspaceId: teamspace.teamspaceId,
|
|
28738
|
-
orgId: ctx.orgId,
|
|
28739
|
-
title: d.title,
|
|
28740
|
-
description: d.description,
|
|
28741
|
-
dueDate: d.dueDate,
|
|
28742
|
-
createdBy: ctx.user?.userId ?? "mcp"
|
|
28743
|
-
});
|
|
28744
|
-
createdDeliverables.push(del.deliverableId);
|
|
28745
|
-
} catch {
|
|
28746
|
-
}
|
|
28747
|
-
}
|
|
28748
|
-
lines.push(`Deliverables: ${createdDeliverables.length}`);
|
|
28749
28622
|
lines.unshift(`\u2705 Onboarding batch created successfully.`);
|
|
28750
28623
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
28751
28624
|
}
|
|
@@ -30051,7 +29924,7 @@ function registerSessionTools(server, ctx, client) {
|
|
|
30051
29924
|
includeTerminal: external_exports.boolean().optional().describe("Include terminal (closed) sessions. Default false.")
|
|
30052
29925
|
},
|
|
30053
29926
|
async ({ systemId, status, includeTerminal }) => {
|
|
30054
|
-
const sessions = await client.
|
|
29927
|
+
const sessions = await client.listSystemSessions(systemId, {
|
|
30055
29928
|
status,
|
|
30056
29929
|
includeTerminal
|
|
30057
29930
|
});
|
|
@@ -30718,7 +30591,7 @@ function registerProjectTools(server, ctx, client) {
|
|
|
30718
30591
|
fetchProjectInOrg(client, systemId, ctx.orgId),
|
|
30719
30592
|
client.getOrg(ctx.orgId)
|
|
30720
30593
|
]);
|
|
30721
|
-
const notes = await client.
|
|
30594
|
+
const notes = await client.listSystemNotes(systemId, {
|
|
30722
30595
|
limit: noteLimit ?? DEFAULT_CONTEXT_NOTE_LIMIT
|
|
30723
30596
|
});
|
|
30724
30597
|
const text = formatProjectContext(project, notes, org?.coda);
|
|
@@ -30886,7 +30759,7 @@ function registerProjectTools(server, ctx, client) {
|
|
|
30886
30759
|
}
|
|
30887
30760
|
|
|
30888
30761
|
// ../../libs/harmonica-services/src/mcp/tools/teamspace-tools.ts
|
|
30889
|
-
var
|
|
30762
|
+
var import_node_crypto2 = require("node:crypto");
|
|
30890
30763
|
var EnsembleMemberSchema = external_exports.discriminatedUnion("type", [
|
|
30891
30764
|
external_exports.object({ type: external_exports.literal("human"), email: external_exports.string().email().max(254), name: external_exports.string().min(1).max(200) }),
|
|
30892
30765
|
external_exports.object({ type: external_exports.literal("agent"), agentId: external_exports.string().min(1).max(100), name: external_exports.string().min(1).max(200) })
|
|
@@ -30925,7 +30798,7 @@ function registerTeamspaceTools(server, ctx, client) {
|
|
|
30925
30798
|
if (!ts || ts.orgId !== ctx.orgId) {
|
|
30926
30799
|
return { content: [{ type: "text", text: `Teamspace not found: ${teamspaceId}` }], isError: true };
|
|
30927
30800
|
}
|
|
30928
|
-
const allProjects = await client.
|
|
30801
|
+
const allProjects = await client.listOrgSystems(ctx.orgId);
|
|
30929
30802
|
const tsProjects = allProjects.filter((p) => p.teamspaceId === teamspaceId);
|
|
30930
30803
|
const lines = [
|
|
30931
30804
|
`ID: ${ts.teamspaceId}`,
|
|
@@ -30962,7 +30835,7 @@ function registerTeamspaceTools(server, ctx, client) {
|
|
|
30962
30835
|
name: external_exports.string().min(1).max(200).describe("Teamspace name")
|
|
30963
30836
|
},
|
|
30964
30837
|
async ({ name }) => {
|
|
30965
|
-
const teamspaceId = `ts-${(0,
|
|
30838
|
+
const teamspaceId = `ts-${(0, import_node_crypto2.randomUUID)()}`;
|
|
30966
30839
|
const slug = generateTeamspaceSlug(name);
|
|
30967
30840
|
const ts = await client.createTeamspace({
|
|
30968
30841
|
teamspaceId,
|
|
@@ -31100,7 +30973,7 @@ function registerValueVelocityTools(server, ctx, client) {
|
|
|
31100
30973
|
try {
|
|
31101
30974
|
await assertProjectInOrg(client, systemId, ctx.orgId);
|
|
31102
30975
|
const [rankedResult, staleWResult] = await Promise.allSettled([
|
|
31103
|
-
withLeverage ? client.
|
|
30976
|
+
withLeverage ? client.rankSystemBeatVersionsWithLeverage(systemId, lens) : client.rankSystemBeatVersions(systemId, lens),
|
|
31104
30977
|
client.getStaleWBeatIds(systemId)
|
|
31105
30978
|
]);
|
|
31106
30979
|
if (rankedResult.status === "rejected") {
|
|
@@ -31594,7 +31467,7 @@ ${JSON.stringify(task.result, null, 2)}
|
|
|
31594
31467
|
},
|
|
31595
31468
|
async ({ projectId, status, limit }) => {
|
|
31596
31469
|
await assertProjectInOrg(client, projectId, ctx.orgId);
|
|
31597
|
-
const tasks = await client.
|
|
31470
|
+
const tasks = await client.listSystemTasks(projectId, {
|
|
31598
31471
|
status,
|
|
31599
31472
|
limit
|
|
31600
31473
|
});
|
|
@@ -31652,7 +31525,7 @@ ${JSON.stringify(task.result, null, 2)}
|
|
|
31652
31525
|
},
|
|
31653
31526
|
async ({ projectId, status, limit }) => {
|
|
31654
31527
|
await assertProjectInOrg(client, projectId, ctx.orgId);
|
|
31655
|
-
const tasks = await client.
|
|
31528
|
+
const tasks = await client.listSystemTasks(projectId, {
|
|
31656
31529
|
status,
|
|
31657
31530
|
limit
|
|
31658
31531
|
});
|
|
@@ -31954,7 +31827,6 @@ var TOOL_PROFILES = Object.freeze({
|
|
|
31954
31827
|
allow(registerBeatVersionTools, ["list_beat_versions", "get_beat_version"]),
|
|
31955
31828
|
allow(registerNoteTools, ["list_notes", "get_note", "create_note", "list_documents"]),
|
|
31956
31829
|
allow(registerDropTools, ["list_drops", "get_drop"]),
|
|
31957
|
-
allow(registerDeliverableTools, ["list_deliverables", "get_deliverable"]),
|
|
31958
31830
|
allow(registerEmbeddingTools, ["search", "find_similar_notes"])
|
|
31959
31831
|
])
|
|
31960
31832
|
});
|
|
@@ -32007,7 +31879,6 @@ function registerAllTools(server, ctx, client, profile) {
|
|
|
32007
31879
|
registerBaselineTools(server, ctx, client);
|
|
32008
31880
|
registerTeamspaceTools(server, ctx, client);
|
|
32009
31881
|
registerDeliverableGroupTools(server, ctx, client);
|
|
32010
|
-
registerDeliverableTools(server, ctx, client);
|
|
32011
31882
|
registerDropTools(server, ctx, client);
|
|
32012
31883
|
registerSessionTools(server, ctx, client);
|
|
32013
31884
|
registerOnboardingTools(server, ctx, client);
|
|
@@ -32026,12 +31897,12 @@ function registerAllTools(server, ctx, client, profile) {
|
|
|
32026
31897
|
// ../../libs/harmonica-services/src/mcp/resources/beat-resources.ts
|
|
32027
31898
|
function registerBeatResources(server, ctx, client) {
|
|
32028
31899
|
server.resource(
|
|
32029
|
-
"
|
|
32030
|
-
new ResourceTemplate("harmonica://
|
|
32031
|
-
async (uri, {
|
|
32032
|
-
const
|
|
32033
|
-
await
|
|
32034
|
-
const beats = await client.listSystemBeats(
|
|
31900
|
+
"system-beats",
|
|
31901
|
+
new ResourceTemplate("harmonica://system/{systemId}/beats", { list: void 0 }),
|
|
31902
|
+
async (uri, { systemId }) => {
|
|
31903
|
+
const sid = String(systemId);
|
|
31904
|
+
await fetchSystemInOrg(client, sid, ctx.orgId);
|
|
31905
|
+
const beats = await client.listSystemBeats(sid);
|
|
32035
31906
|
const text = formatBeatSummaryTable(beats);
|
|
32036
31907
|
return { contents: [{ uri: uri.href, text }] };
|
|
32037
31908
|
}
|
|
@@ -32066,14 +31937,14 @@ function registerGuidelinesResources(server, client) {
|
|
|
32066
31937
|
}
|
|
32067
31938
|
|
|
32068
31939
|
// ../../libs/harmonica-services/src/mcp/resources/system-resources.ts
|
|
32069
|
-
function
|
|
31940
|
+
function registerSystemResources(server, ctx, client) {
|
|
32070
31941
|
server.resource(
|
|
32071
|
-
"
|
|
32072
|
-
new ResourceTemplate("harmonica://
|
|
32073
|
-
async (uri, {
|
|
32074
|
-
const
|
|
32075
|
-
const project = await
|
|
32076
|
-
const notes = await client.listSystemNotes(
|
|
31942
|
+
"system-context",
|
|
31943
|
+
new ResourceTemplate("harmonica://system/{systemId}/context", { list: void 0 }),
|
|
31944
|
+
async (uri, { systemId }) => {
|
|
31945
|
+
const sid = String(systemId);
|
|
31946
|
+
const project = await fetchSystemInOrg(client, sid, ctx.orgId);
|
|
31947
|
+
const notes = await client.listSystemNotes(sid, { limit: DEFAULT_CONTEXT_NOTE_LIMIT });
|
|
32077
31948
|
const text = formatProjectContext(project, notes);
|
|
32078
31949
|
return { contents: [{ uri: uri.href, text }] };
|
|
32079
31950
|
}
|
|
@@ -32082,7 +31953,7 @@ function registerProjectResources(server, ctx, client) {
|
|
|
32082
31953
|
|
|
32083
31954
|
// ../../libs/harmonica-services/src/mcp/resources/index.ts
|
|
32084
31955
|
function registerAllResources(server, ctx, client) {
|
|
32085
|
-
|
|
31956
|
+
registerSystemResources(server, ctx, client);
|
|
32086
31957
|
registerBeatResources(server, ctx, client);
|
|
32087
31958
|
registerGuidelinesResources(server, client);
|
|
32088
31959
|
}
|
|
@@ -32353,46 +32224,11 @@ function createHttpClient(config2) {
|
|
|
32353
32224
|
if (!raw) return void 0;
|
|
32354
32225
|
return { ...raw, projectId: raw.id ?? raw.projectId, title: raw.name ?? raw.title, orgId: raw.organizationId ?? raw.orgId };
|
|
32355
32226
|
},
|
|
32356
|
-
// @deprecated aliases — remove in cleanup increment (BV2)
|
|
32357
|
-
listOrgProjects: async (orgId) => {
|
|
32358
|
-
const raw = await request("GET", `/api/organizations/${encodeURIComponent(orgId)}/projects/summaries`);
|
|
32359
|
-
return (raw ?? []).map((p) => ({ ...p, projectId: p.id, title: p.name, orgId: p.organizationId }));
|
|
32360
|
-
},
|
|
32361
|
-
getProject: async (projectId) => {
|
|
32362
|
-
const raw = await request("GET", `/api/systems/${encodeURIComponent(projectId)}`);
|
|
32363
|
-
if (!raw) return void 0;
|
|
32364
|
-
return {
|
|
32365
|
-
...raw,
|
|
32366
|
-
projectId: raw.id ?? raw.projectId,
|
|
32367
|
-
title: raw.name ?? raw.title,
|
|
32368
|
-
orgId: raw.organizationId ?? raw.orgId
|
|
32369
|
-
};
|
|
32370
|
-
},
|
|
32371
|
-
createProject: async (input) => {
|
|
32372
|
-
const raw = await request("POST", "/api/systems", {
|
|
32373
|
-
organizationId: input.orgId,
|
|
32374
|
-
teamspaceId: input.teamspaceId,
|
|
32375
|
-
name: input.title,
|
|
32376
|
-
description: input.description,
|
|
32377
|
-
strategy: input.strategy,
|
|
32378
|
-
// Without this the owning Account is dropped on the wire and the System
|
|
32379
|
-
// is created unlinked — invisible in the Account's Systems list.
|
|
32380
|
-
...input.accountId !== void 0 && { accountId: input.accountId }
|
|
32381
|
-
});
|
|
32382
|
-
return { ...raw, orgId: raw?.organizationId ?? raw?.orgId };
|
|
32383
|
-
},
|
|
32384
|
-
updateProject: (projectId, updates) => request("PATCH", `/api/systems/${encodeURIComponent(projectId)}`, updates),
|
|
32385
|
-
archiveProject: (projectId) => request("PATCH", `/api/systems/${encodeURIComponent(projectId)}/archive`),
|
|
32386
32227
|
getSystemFact: async (projectId) => {
|
|
32387
32228
|
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/facts`);
|
|
32388
32229
|
return result?.data;
|
|
32389
32230
|
},
|
|
32390
|
-
getProjectFact: async (projectId) => {
|
|
32391
|
-
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/facts`);
|
|
32392
|
-
return result?.data;
|
|
32393
|
-
},
|
|
32394
32231
|
saveSystemFact: (input) => request("PUT", `/api/systems/${encodeURIComponent(String(input.projectId))}/facts`, input),
|
|
32395
|
-
saveProjectFact: (input) => request("PUT", `/api/systems/${encodeURIComponent(String(input.projectId))}/facts`, input),
|
|
32396
32232
|
transitionSystemLifecycleState: async (projectId, targetState, options) => {
|
|
32397
32233
|
return request("POST", `/api/systems/${encodeURIComponent(projectId)}/lifecycle/transitions`, {
|
|
32398
32234
|
targetState,
|
|
@@ -32400,13 +32236,6 @@ function createHttpClient(config2) {
|
|
|
32400
32236
|
decisionNoteId: options.decisionNoteId
|
|
32401
32237
|
});
|
|
32402
32238
|
},
|
|
32403
|
-
transitionProjectLifecycleState: async (projectId, targetState, options) => {
|
|
32404
|
-
return request("POST", `/api/systems/${encodeURIComponent(projectId)}/lifecycle/transitions`, {
|
|
32405
|
-
targetState,
|
|
32406
|
-
reason: options.reason,
|
|
32407
|
-
decisionNoteId: options.decisionNoteId
|
|
32408
|
-
});
|
|
32409
|
-
},
|
|
32410
32239
|
// Beats
|
|
32411
32240
|
getNextBeatId: async (projectId) => {
|
|
32412
32241
|
const result = await request("POST", `/api/systems/${encodeURIComponent(projectId)}/beats/next-id`);
|
|
@@ -32584,22 +32413,6 @@ function createHttpClient(config2) {
|
|
|
32584
32413
|
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/notes${qs}`);
|
|
32585
32414
|
return result?.notes ?? [];
|
|
32586
32415
|
},
|
|
32587
|
-
listProjectNotes: async (projectId, filters) => {
|
|
32588
|
-
const params = new URLSearchParams();
|
|
32589
|
-
if (filters?.noteType) {
|
|
32590
|
-
const types = Array.isArray(filters.noteType) ? filters.noteType : [filters.noteType];
|
|
32591
|
-
types.forEach((t) => params.append("type", t));
|
|
32592
|
-
}
|
|
32593
|
-
if (filters?.status) params.set("status", filters.status);
|
|
32594
|
-
if (filters?.revisionId) params.set("revisionId", filters.revisionId);
|
|
32595
|
-
if (filters?.beatVersionId) params.set("beatVersionId", filters.beatVersionId);
|
|
32596
|
-
if (filters?.excludeChildren) params.set("excludeChildren", "true");
|
|
32597
|
-
if (filters?.significance) params.set("significance", filters.significance);
|
|
32598
|
-
if (filters?.limit !== void 0) params.set("limit", String(filters.limit));
|
|
32599
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
32600
|
-
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/notes${qs}`);
|
|
32601
|
-
return result?.notes ?? [];
|
|
32602
|
-
},
|
|
32603
32416
|
listAllSystemNotes: async (projectId, filters, limit, cursor) => {
|
|
32604
32417
|
const params = new URLSearchParams();
|
|
32605
32418
|
if (filters?.noteType) {
|
|
@@ -32618,24 +32431,6 @@ function createHttpClient(config2) {
|
|
|
32618
32431
|
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/notes/all${qs}`);
|
|
32619
32432
|
return { notes: result?.notes ?? [], cursor: result?.cursor, hasMore: result?.hasMore ?? false };
|
|
32620
32433
|
},
|
|
32621
|
-
listAllProjectNotes: async (projectId, filters, limit, cursor) => {
|
|
32622
|
-
const params = new URLSearchParams();
|
|
32623
|
-
if (filters?.noteType) {
|
|
32624
|
-
const types = Array.isArray(filters.noteType) ? filters.noteType : [filters.noteType];
|
|
32625
|
-
types.forEach((t) => params.append("type", t));
|
|
32626
|
-
}
|
|
32627
|
-
if (filters?.excludeNoteType) params.set("excludeType", filters.excludeNoteType);
|
|
32628
|
-
if (filters?.status) params.set("status", filters.status);
|
|
32629
|
-
if (filters?.revisionId) params.set("revisionId", filters.revisionId);
|
|
32630
|
-
if (filters?.beatVersionId) params.set("beatVersionId", filters.beatVersionId);
|
|
32631
|
-
if (filters?.excludeChildren) params.set("excludeChildren", "true");
|
|
32632
|
-
if (filters?.significance) params.set("significance", filters.significance);
|
|
32633
|
-
if (limit !== void 0) params.set("limit", String(limit));
|
|
32634
|
-
if (cursor !== void 0) params.set("cursor", cursor);
|
|
32635
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
32636
|
-
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/notes/all${qs}`);
|
|
32637
|
-
return { notes: result?.notes ?? [], cursor: result?.cursor, hasMore: result?.hasMore ?? false };
|
|
32638
|
-
},
|
|
32639
32434
|
listBeatNotes: async (beatId, filters) => {
|
|
32640
32435
|
const beat = await request("GET", `/api/beats/${encodeURIComponent(beatId)}`);
|
|
32641
32436
|
if (!beat) return [];
|
|
@@ -32728,7 +32523,6 @@ function createHttpClient(config2) {
|
|
|
32728
32523
|
},
|
|
32729
32524
|
// Gaps are deprecated — replaced by assumption Notes. Return empty results.
|
|
32730
32525
|
getSystemGaps: async () => [],
|
|
32731
|
-
getProjectGaps: async () => [],
|
|
32732
32526
|
updateInformationGap: async () => false,
|
|
32733
32527
|
// Revisions
|
|
32734
32528
|
createRevision: async (projectId, beatId, input) => {
|
|
@@ -32753,14 +32547,6 @@ function createHttpClient(config2) {
|
|
|
32753
32547
|
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/revisions${qs}`);
|
|
32754
32548
|
return result ?? [];
|
|
32755
32549
|
},
|
|
32756
|
-
listProjectRevisions: async (projectId, options) => {
|
|
32757
|
-
const params = new URLSearchParams();
|
|
32758
|
-
if (options?.status) params.set("status", options.status);
|
|
32759
|
-
if (options?.includeArchived) params.set("includeArchived", "true");
|
|
32760
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
32761
|
-
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/revisions${qs}`);
|
|
32762
|
-
return result ?? [];
|
|
32763
|
-
},
|
|
32764
32550
|
listBeatRevisions: async (projectId, beatId, options) => {
|
|
32765
32551
|
const params = new URLSearchParams();
|
|
32766
32552
|
params.set("beatId", beatId);
|
|
@@ -32990,14 +32776,6 @@ function createHttpClient(config2) {
|
|
|
32990
32776
|
const result = await request("GET", `/api/sessions?${params.toString()}`);
|
|
32991
32777
|
return result ?? [];
|
|
32992
32778
|
},
|
|
32993
|
-
listProjectSessions: async (projectId, options) => {
|
|
32994
|
-
const params = new URLSearchParams();
|
|
32995
|
-
params.set("projectId", projectId);
|
|
32996
|
-
if (options?.status) params.set("status", options.status);
|
|
32997
|
-
if (options?.includeTerminal) params.set("includeTerminal", "true");
|
|
32998
|
-
const result = await request("GET", `/api/sessions?${params.toString()}`);
|
|
32999
|
-
return result ?? [];
|
|
33000
|
-
},
|
|
33001
32779
|
listBeatSessions: async (beatId, options) => {
|
|
33002
32780
|
const params = new URLSearchParams();
|
|
33003
32781
|
params.set("beatId", beatId);
|
|
@@ -33185,14 +32963,6 @@ function createHttpClient(config2) {
|
|
|
33185
32963
|
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/tasks${qs}`);
|
|
33186
32964
|
return result?.tasks ?? [];
|
|
33187
32965
|
},
|
|
33188
|
-
listProjectTasks: async (projectId, options) => {
|
|
33189
|
-
const params = new URLSearchParams();
|
|
33190
|
-
if (options?.status) params.set("status", options.status);
|
|
33191
|
-
if (options?.limit) params.set("limit", String(options.limit));
|
|
33192
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
33193
|
-
const result = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/tasks${qs}`);
|
|
33194
|
-
return result?.tasks ?? [];
|
|
33195
|
-
},
|
|
33196
32966
|
listTaskEvents: async (taskId, options) => {
|
|
33197
32967
|
const params = new URLSearchParams();
|
|
33198
32968
|
if (options?.afterSeq !== void 0) params.set("after", String(options.afterSeq));
|
|
@@ -33225,15 +32995,6 @@ function createHttpClient(config2) {
|
|
|
33225
32995
|
const result = await request("GET", path);
|
|
33226
32996
|
return { entries: result.activities ?? [], hasMore: false };
|
|
33227
32997
|
},
|
|
33228
|
-
listProjectActivities: async (projectId, options) => {
|
|
33229
|
-
const params = new URLSearchParams();
|
|
33230
|
-
if (options?.limit) params.set("limit", String(options.limit));
|
|
33231
|
-
if (options?.minImportance) params.set("importance", options.minImportance);
|
|
33232
|
-
const qs = params.toString();
|
|
33233
|
-
const path = `/api/systems/${encodeURIComponent(projectId)}/activities${qs ? `?${qs}` : ""}`;
|
|
33234
|
-
const result = await request("GET", path);
|
|
33235
|
-
return { entries: result.activities ?? [], hasMore: false };
|
|
33236
|
-
},
|
|
33237
32998
|
createActivity: async (input) => {
|
|
33238
32999
|
const result = await request("POST", `/api/systems/${encodeURIComponent(input.projectId)}/activities`, {
|
|
33239
33000
|
action: input.action,
|
|
@@ -33308,20 +33069,6 @@ function createHttpClient(config2) {
|
|
|
33308
33069
|
);
|
|
33309
33070
|
return result.ranked ?? [];
|
|
33310
33071
|
},
|
|
33311
|
-
rankProjectBeatVersions: async (projectId, lens) => {
|
|
33312
|
-
const result = await request(
|
|
33313
|
-
"GET",
|
|
33314
|
-
`/api/systems/${encodeURIComponent(projectId)}/beat-versions/ranked?lens=${encodeURIComponent(lens)}`
|
|
33315
|
-
);
|
|
33316
|
-
return result.ranked ?? [];
|
|
33317
|
-
},
|
|
33318
|
-
rankProjectBeatVersionsWithLeverage: async (projectId, lens) => {
|
|
33319
|
-
const result = await request(
|
|
33320
|
-
"GET",
|
|
33321
|
-
`/api/systems/${encodeURIComponent(projectId)}/beat-versions/ranked?lens=${encodeURIComponent(lens)}&withLeverage=true`
|
|
33322
|
-
);
|
|
33323
|
-
return result.ranked ?? [];
|
|
33324
|
-
},
|
|
33325
33072
|
// All four use requestOrThrow, not request. These endpoints answer 404 for a
|
|
33326
33073
|
// missing edge/Beat with a real domain message, and `request()` turns a 404
|
|
33327
33074
|
// into `undefined` — so the old `result.edge` access threw
|
|
@@ -33620,18 +33367,6 @@ function createHttpClient(config2) {
|
|
|
33620
33367
|
);
|
|
33621
33368
|
return { checks: res?.checks ?? [], nextCursor: res?.nextCursor };
|
|
33622
33369
|
},
|
|
33623
|
-
listProjectChecks: async (projectId, checkType, options) => {
|
|
33624
|
-
const params = new URLSearchParams();
|
|
33625
|
-
if (checkType) params.set("type", checkType);
|
|
33626
|
-
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
33627
|
-
if (options?.cursor) params.set("cursor", options.cursor);
|
|
33628
|
-
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
33629
|
-
const res = await request(
|
|
33630
|
-
"GET",
|
|
33631
|
-
`/api/systems/${encodeURIComponent(projectId)}/checks${qs}`
|
|
33632
|
-
);
|
|
33633
|
-
return { checks: res?.checks ?? [], nextCursor: res?.nextCursor };
|
|
33634
|
-
},
|
|
33635
33370
|
listLatestSystemChecks: async (projectId) => {
|
|
33636
33371
|
const res = await request(
|
|
33637
33372
|
"GET",
|
|
@@ -33639,13 +33374,6 @@ function createHttpClient(config2) {
|
|
|
33639
33374
|
);
|
|
33640
33375
|
return res?.checks ?? [];
|
|
33641
33376
|
},
|
|
33642
|
-
listLatestProjectChecks: async (projectId) => {
|
|
33643
|
-
const res = await request(
|
|
33644
|
-
"GET",
|
|
33645
|
-
`/api/checks/latest?projectId=${encodeURIComponent(projectId)}`
|
|
33646
|
-
);
|
|
33647
|
-
return res?.checks ?? [];
|
|
33648
|
-
},
|
|
33649
33377
|
listBeatChecks: async (beatId, projectId, checkType) => {
|
|
33650
33378
|
const qs = checkType ? `?type=${encodeURIComponent(checkType)}` : "";
|
|
33651
33379
|
const res = await request(
|
|
@@ -33705,20 +33433,6 @@ function createHttpClient(config2) {
|
|
|
33705
33433
|
updateTeamspace: async (teamspaceId, updates) => {
|
|
33706
33434
|
return request("PATCH", `/api/teamspaces/${encodeURIComponent(teamspaceId)}`, updates);
|
|
33707
33435
|
},
|
|
33708
|
-
// Deliverables
|
|
33709
|
-
listTeamspaceDeliverables: async (teamspaceId) => {
|
|
33710
|
-
const res = await request("GET", `/api/teamspaces/${encodeURIComponent(teamspaceId)}/deliverables`);
|
|
33711
|
-
return res?.deliverables ?? [];
|
|
33712
|
-
},
|
|
33713
|
-
getDeliverable: async (deliverableId) => {
|
|
33714
|
-
return request("GET", `/api/deliverables/${encodeURIComponent(deliverableId)}`);
|
|
33715
|
-
},
|
|
33716
|
-
createDeliverable: async (input) => {
|
|
33717
|
-
return request("POST", `/api/teamspaces/${encodeURIComponent(input.teamspaceId)}/deliverables`, input);
|
|
33718
|
-
},
|
|
33719
|
-
updateDeliverable: async (deliverableId, updates) => {
|
|
33720
|
-
return request("PATCH", `/api/deliverables/${encodeURIComponent(deliverableId)}`, updates);
|
|
33721
|
-
},
|
|
33722
33436
|
// DeliverableGroups
|
|
33723
33437
|
listTeamspaceDeliverableGroups: async (teamspaceId) => {
|
|
33724
33438
|
const res = await request("GET", `/api/teamspaces/${encodeURIComponent(teamspaceId)}/deliverable-groups`);
|
|
@@ -33730,11 +33444,6 @@ function createHttpClient(config2) {
|
|
|
33730
33444
|
if (res === void 0) throw new Error(`Project ${projectId} not found`);
|
|
33731
33445
|
return res.deliverableGroups;
|
|
33732
33446
|
},
|
|
33733
|
-
listProjectDeliverableGroups: async (projectId) => {
|
|
33734
|
-
const res = await request("GET", `/api/systems/${encodeURIComponent(projectId)}/deliverable-groups`);
|
|
33735
|
-
if (res === void 0) throw new Error(`Project ${projectId} not found`);
|
|
33736
|
-
return res.deliverableGroups;
|
|
33737
|
-
},
|
|
33738
33447
|
listMovementDeliverableGroups: async (movementId) => {
|
|
33739
33448
|
const res = await request("GET", `/api/movements/${encodeURIComponent(movementId)}/deliverable-groups`);
|
|
33740
33449
|
if (res === void 0) throw new Error(`Movement ${movementId} not found`);
|
|
@@ -33771,10 +33480,6 @@ function createHttpClient(config2) {
|
|
|
33771
33480
|
...opts ?? {}
|
|
33772
33481
|
});
|
|
33773
33482
|
},
|
|
33774
|
-
listDeliverableGroupDeliverables: async (deliverableGroupId) => {
|
|
33775
|
-
const res = await request("GET", `/api/deliverable-groups/${encodeURIComponent(deliverableGroupId)}/deliverables`);
|
|
33776
|
-
return res?.deliverables ?? [];
|
|
33777
|
-
},
|
|
33778
33483
|
listDeliverableGroupDrops: async (deliverableGroupId) => {
|
|
33779
33484
|
const res = await request("GET", `/api/deliverable-groups/${encodeURIComponent(deliverableGroupId)}/drops`);
|
|
33780
33485
|
return res?.drops ?? [];
|
|
@@ -34354,28 +34059,54 @@ function createHttpClient(config2) {
|
|
|
34354
34059
|
);
|
|
34355
34060
|
return result?.usedBy;
|
|
34356
34061
|
},
|
|
34357
|
-
// Feature flags (B-135
|
|
34358
|
-
// npm package
|
|
34359
|
-
listFlags: async () => {
|
|
34360
|
-
|
|
34062
|
+
// Feature flags (B-135 v11) — routed through /api/mcp/feature-flags/* so the
|
|
34063
|
+
// published npm package (no DynamoDB credentials) can manage flags via HTTP.
|
|
34064
|
+
listFlags: async (options) => {
|
|
34065
|
+
const params = new URLSearchParams();
|
|
34066
|
+
if (options?.includeArchived) params.set("includeArchived", "true");
|
|
34067
|
+
if (options?.search) params.set("search", options.search);
|
|
34068
|
+
if (options?.cursor) params.set("cursor", options.cursor);
|
|
34069
|
+
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
34070
|
+
const qs = params.toString();
|
|
34071
|
+
return requestOrThrow(
|
|
34072
|
+
"GET",
|
|
34073
|
+
`/api/mcp/feature-flags${qs ? `?${qs}` : ""}`
|
|
34074
|
+
);
|
|
34361
34075
|
},
|
|
34362
|
-
getFlag: async () => {
|
|
34363
|
-
|
|
34076
|
+
getFlag: async (name, options) => {
|
|
34077
|
+
const qs = options?.includeHistory ? "?includeHistory=true" : "";
|
|
34078
|
+
return request("GET", `/api/mcp/feature-flags/${encodeURIComponent(name)}${qs}`);
|
|
34364
34079
|
},
|
|
34365
|
-
checkFlag: async () => {
|
|
34366
|
-
|
|
34080
|
+
checkFlag: async (name, stage) => {
|
|
34081
|
+
const flag = await request(
|
|
34082
|
+
"GET",
|
|
34083
|
+
`/api/mcp/feature-flags/${encodeURIComponent(name)}`
|
|
34084
|
+
);
|
|
34085
|
+
return flag ? flag.enabledIn.includes(stage) : false;
|
|
34367
34086
|
},
|
|
34368
|
-
createFlag: async () => {
|
|
34369
|
-
|
|
34087
|
+
createFlag: async (name, enabledIn, options) => {
|
|
34088
|
+
return requestOrThrow("POST", "/api/mcp/feature-flags", {
|
|
34089
|
+
name,
|
|
34090
|
+
enabledIn,
|
|
34091
|
+
description: options?.description,
|
|
34092
|
+
note: options?.note
|
|
34093
|
+
});
|
|
34370
34094
|
},
|
|
34371
|
-
setFlag: async () => {
|
|
34372
|
-
|
|
34095
|
+
setFlag: async (name, enabledIn, options) => {
|
|
34096
|
+
return requestOrThrow("PUT", `/api/mcp/feature-flags/${encodeURIComponent(name)}`, {
|
|
34097
|
+
enabledIn,
|
|
34098
|
+
note: options?.note
|
|
34099
|
+
});
|
|
34373
34100
|
},
|
|
34374
|
-
archiveFlag: async () => {
|
|
34375
|
-
|
|
34101
|
+
archiveFlag: async (name, options) => {
|
|
34102
|
+
return requestOrThrow("POST", `/api/mcp/feature-flags/${encodeURIComponent(name)}/archive`, {
|
|
34103
|
+
note: options?.note
|
|
34104
|
+
});
|
|
34376
34105
|
},
|
|
34377
|
-
unarchiveFlag: async () => {
|
|
34378
|
-
|
|
34106
|
+
unarchiveFlag: async (name, options) => {
|
|
34107
|
+
return requestOrThrow("POST", `/api/mcp/feature-flags/${encodeURIComponent(name)}/unarchive`, {
|
|
34108
|
+
note: options?.note
|
|
34109
|
+
});
|
|
34379
34110
|
}
|
|
34380
34111
|
};
|
|
34381
34112
|
return client;
|
|
@@ -34426,7 +34157,7 @@ function loadConfig() {
|
|
|
34426
34157
|
};
|
|
34427
34158
|
}
|
|
34428
34159
|
async function main() {
|
|
34429
|
-
console.error(`[harmonica-mcp] v${"3.
|
|
34160
|
+
console.error(`[harmonica-mcp] v${"3.6.0"} starting\u2026`);
|
|
34430
34161
|
const config2 = loadConfig();
|
|
34431
34162
|
const client = createHttpClient({
|
|
34432
34163
|
apiBaseUrl: config2.apiBaseUrl,
|