@gethmy/mcp 2.15.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +36 -15
- package/dist/index.js +36 -15
- package/dist/lib/api-client.js +4 -0
- package/package.json +1 -1
- package/src/api-client.ts +19 -0
- package/src/server.ts +51 -23
package/dist/cli.js
CHANGED
|
@@ -1826,6 +1826,10 @@ class HarmonyApiClient {
|
|
|
1826
1826
|
async updateCard(cardId, updates) {
|
|
1827
1827
|
return this.request("PATCH", `/cards/${cardId}`, updates);
|
|
1828
1828
|
}
|
|
1829
|
+
async claimCard(cardId, agentId) {
|
|
1830
|
+
const res = await this.request("PATCH", `/cards/${cardId}`, { assignedAgentId: agentId, ifAssignedAgentNull: true });
|
|
1831
|
+
return { claimed: res.claimed !== false };
|
|
1832
|
+
}
|
|
1829
1833
|
async moveCard(cardId, columnId, position) {
|
|
1830
1834
|
return this.request("POST", `/cards/${cardId}/move`, {
|
|
1831
1835
|
columnId,
|
|
@@ -6335,11 +6339,11 @@ async function handleToolCall(name, args, deps) {
|
|
|
6335
6339
|
}
|
|
6336
6340
|
case "harmony_generate_prompt": {
|
|
6337
6341
|
let cardId;
|
|
6342
|
+
const projectId = args.projectId || deps.getActiveProjectId() || undefined;
|
|
6338
6343
|
if (args.cardId) {
|
|
6339
6344
|
cardId = z.string().uuid().parse(args.cardId);
|
|
6340
6345
|
} else if (args.shortId !== undefined) {
|
|
6341
6346
|
const shortId = z.number().int().positive().parse(args.shortId);
|
|
6342
|
-
const projectId = args.projectId || deps.getActiveProjectId();
|
|
6343
6347
|
if (!projectId) {
|
|
6344
6348
|
throw new Error("Project ID required when using shortId. Use harmony_set_project_context or provide projectId.");
|
|
6345
6349
|
}
|
|
@@ -6348,23 +6352,40 @@ async function handleToolCall(name, args, deps) {
|
|
|
6348
6352
|
} else {
|
|
6349
6353
|
throw new Error("Either cardId or shortId must be provided");
|
|
6350
6354
|
}
|
|
6351
|
-
|
|
6352
|
-
|
|
6355
|
+
const variant = args.variant || undefined;
|
|
6356
|
+
const customConstraints = typeof args.customConstraints === "string" ? args.customConstraints : undefined;
|
|
6357
|
+
const contextOptions = {
|
|
6358
|
+
includeSubtasks: args.includeSubtasks !== false,
|
|
6359
|
+
includeLinks: args.includeLinks !== false,
|
|
6360
|
+
includeDescription: args.includeDescription !== false
|
|
6361
|
+
};
|
|
6353
6362
|
try {
|
|
6354
|
-
const
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6363
|
+
const result = await client3.generateCardPrompt({
|
|
6364
|
+
cardId,
|
|
6365
|
+
workspaceId: deps.getActiveWorkspaceId() || "",
|
|
6366
|
+
projectId,
|
|
6367
|
+
variant,
|
|
6368
|
+
customConstraints,
|
|
6369
|
+
contextOptions
|
|
6370
|
+
});
|
|
6371
|
+
return { success: true, ...result };
|
|
6372
|
+
} catch (err) {
|
|
6373
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6374
|
+
console.debug(`[harmony_generate_prompt] falling back: ${msg}`);
|
|
6375
|
+
let cardTitle = "";
|
|
6376
|
+
let cardDescription = "";
|
|
6377
|
+
try {
|
|
6378
|
+
const { card } = await client3.getCard(cardId);
|
|
6379
|
+
const typedCard = card;
|
|
6380
|
+
cardTitle = typedCard.title || "";
|
|
6381
|
+
cardDescription = typedCard.description || "";
|
|
6382
|
+
} catch {}
|
|
6383
|
+
const taskBlock = [cardTitle, cardDescription].filter(Boolean).join(`
|
|
6360
6384
|
|
|
6361
6385
|
`);
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
prompt,
|
|
6366
|
-
cardId
|
|
6367
|
-
};
|
|
6386
|
+
const prompt = `Here is the task: ${taskBlock || "(no description available)"}`;
|
|
6387
|
+
return { success: true, prompt, cardId };
|
|
6388
|
+
}
|
|
6368
6389
|
}
|
|
6369
6390
|
case "harmony_remember": {
|
|
6370
6391
|
const title = z.string().min(1).max(300).parse(args.title);
|
package/dist/index.js
CHANGED
|
@@ -1821,6 +1821,10 @@ class HarmonyApiClient {
|
|
|
1821
1821
|
async updateCard(cardId, updates) {
|
|
1822
1822
|
return this.request("PATCH", `/cards/${cardId}`, updates);
|
|
1823
1823
|
}
|
|
1824
|
+
async claimCard(cardId, agentId) {
|
|
1825
|
+
const res = await this.request("PATCH", `/cards/${cardId}`, { assignedAgentId: agentId, ifAssignedAgentNull: true });
|
|
1826
|
+
return { claimed: res.claimed !== false };
|
|
1827
|
+
}
|
|
1824
1828
|
async moveCard(cardId, columnId, position) {
|
|
1825
1829
|
return this.request("POST", `/cards/${cardId}/move`, {
|
|
1826
1830
|
columnId,
|
|
@@ -6330,11 +6334,11 @@ async function handleToolCall(name, args, deps) {
|
|
|
6330
6334
|
}
|
|
6331
6335
|
case "harmony_generate_prompt": {
|
|
6332
6336
|
let cardId;
|
|
6337
|
+
const projectId = args.projectId || deps.getActiveProjectId() || undefined;
|
|
6333
6338
|
if (args.cardId) {
|
|
6334
6339
|
cardId = z.string().uuid().parse(args.cardId);
|
|
6335
6340
|
} else if (args.shortId !== undefined) {
|
|
6336
6341
|
const shortId = z.number().int().positive().parse(args.shortId);
|
|
6337
|
-
const projectId = args.projectId || deps.getActiveProjectId();
|
|
6338
6342
|
if (!projectId) {
|
|
6339
6343
|
throw new Error("Project ID required when using shortId. Use harmony_set_project_context or provide projectId.");
|
|
6340
6344
|
}
|
|
@@ -6343,23 +6347,40 @@ async function handleToolCall(name, args, deps) {
|
|
|
6343
6347
|
} else {
|
|
6344
6348
|
throw new Error("Either cardId or shortId must be provided");
|
|
6345
6349
|
}
|
|
6346
|
-
|
|
6347
|
-
|
|
6350
|
+
const variant = args.variant || undefined;
|
|
6351
|
+
const customConstraints = typeof args.customConstraints === "string" ? args.customConstraints : undefined;
|
|
6352
|
+
const contextOptions = {
|
|
6353
|
+
includeSubtasks: args.includeSubtasks !== false,
|
|
6354
|
+
includeLinks: args.includeLinks !== false,
|
|
6355
|
+
includeDescription: args.includeDescription !== false
|
|
6356
|
+
};
|
|
6348
6357
|
try {
|
|
6349
|
-
const
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6358
|
+
const result = await client3.generateCardPrompt({
|
|
6359
|
+
cardId,
|
|
6360
|
+
workspaceId: deps.getActiveWorkspaceId() || "",
|
|
6361
|
+
projectId,
|
|
6362
|
+
variant,
|
|
6363
|
+
customConstraints,
|
|
6364
|
+
contextOptions
|
|
6365
|
+
});
|
|
6366
|
+
return { success: true, ...result };
|
|
6367
|
+
} catch (err) {
|
|
6368
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6369
|
+
console.debug(`[harmony_generate_prompt] falling back: ${msg}`);
|
|
6370
|
+
let cardTitle = "";
|
|
6371
|
+
let cardDescription = "";
|
|
6372
|
+
try {
|
|
6373
|
+
const { card } = await client3.getCard(cardId);
|
|
6374
|
+
const typedCard = card;
|
|
6375
|
+
cardTitle = typedCard.title || "";
|
|
6376
|
+
cardDescription = typedCard.description || "";
|
|
6377
|
+
} catch {}
|
|
6378
|
+
const taskBlock = [cardTitle, cardDescription].filter(Boolean).join(`
|
|
6355
6379
|
|
|
6356
6380
|
`);
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
prompt,
|
|
6361
|
-
cardId
|
|
6362
|
-
};
|
|
6381
|
+
const prompt = `Here is the task: ${taskBlock || "(no description available)"}`;
|
|
6382
|
+
return { success: true, prompt, cardId };
|
|
6383
|
+
}
|
|
6363
6384
|
}
|
|
6364
6385
|
case "harmony_remember": {
|
|
6365
6386
|
const title = z.string().min(1).max(300).parse(args.title);
|
package/dist/lib/api-client.js
CHANGED
|
@@ -1273,6 +1273,10 @@ class HarmonyApiClient {
|
|
|
1273
1273
|
async updateCard(cardId, updates) {
|
|
1274
1274
|
return this.request("PATCH", `/cards/${cardId}`, updates);
|
|
1275
1275
|
}
|
|
1276
|
+
async claimCard(cardId, agentId) {
|
|
1277
|
+
const res = await this.request("PATCH", `/cards/${cardId}`, { assignedAgentId: agentId, ifAssignedAgentNull: true });
|
|
1278
|
+
return { claimed: res.claimed !== false };
|
|
1279
|
+
}
|
|
1276
1280
|
async moveCard(cardId, columnId, position) {
|
|
1277
1281
|
return this.request("POST", `/cards/${cardId}/move`, {
|
|
1278
1282
|
columnId,
|
package/package.json
CHANGED
package/src/api-client.ts
CHANGED
|
@@ -625,6 +625,25 @@ export class HarmonyApiClient {
|
|
|
625
625
|
return this.request("PATCH", `/cards/${cardId}`, updates);
|
|
626
626
|
}
|
|
627
627
|
|
|
628
|
+
/**
|
|
629
|
+
* Compare-and-set claim of a card for a virtual agent: sets assigned_agent_id
|
|
630
|
+
* only if it is currently NULL (server-side guard). Returns `{ claimed: false }`
|
|
631
|
+
* when another daemon already owns it. Used by the agent-agnostic review pickup.
|
|
632
|
+
*/
|
|
633
|
+
async claimCard(
|
|
634
|
+
cardId: string,
|
|
635
|
+
agentId: string,
|
|
636
|
+
): Promise<{ claimed: boolean }> {
|
|
637
|
+
const res = await this.request<{ card?: unknown; claimed?: boolean }>(
|
|
638
|
+
"PATCH",
|
|
639
|
+
`/cards/${cardId}`,
|
|
640
|
+
{ assignedAgentId: agentId, ifAssignedAgentNull: true },
|
|
641
|
+
);
|
|
642
|
+
// Success body is `{ card }` (no `claimed` key) → won. Lost-race body is
|
|
643
|
+
// `{ claimed: false }`.
|
|
644
|
+
return { claimed: res.claimed !== false };
|
|
645
|
+
}
|
|
646
|
+
|
|
628
647
|
async moveCard(
|
|
629
648
|
cardId: string,
|
|
630
649
|
columnId: string,
|
package/src/server.ts
CHANGED
|
@@ -3824,17 +3824,16 @@ async function handleToolCall(
|
|
|
3824
3824
|
}
|
|
3825
3825
|
|
|
3826
3826
|
// Prompt generation
|
|
3827
|
-
// TODO Phase 1: rebuild full context assembly per docs/superpowers/plans/2026-05-07-memory-architecture-v2.md §10
|
|
3828
3827
|
case "harmony_generate_prompt": {
|
|
3829
3828
|
// Resolve card ID — either directly or via short ID
|
|
3830
3829
|
let cardId: string;
|
|
3830
|
+
const projectId =
|
|
3831
|
+
(args.projectId as string) || deps.getActiveProjectId() || undefined;
|
|
3831
3832
|
|
|
3832
3833
|
if (args.cardId) {
|
|
3833
3834
|
cardId = z.string().uuid().parse(args.cardId);
|
|
3834
3835
|
} else if (args.shortId !== undefined) {
|
|
3835
3836
|
const shortId = z.number().int().positive().parse(args.shortId);
|
|
3836
|
-
const projectId =
|
|
3837
|
-
(args.projectId as string) || deps.getActiveProjectId();
|
|
3838
3837
|
if (!projectId) {
|
|
3839
3838
|
throw new Error(
|
|
3840
3839
|
"Project ID required when using shortId. Use harmony_set_project_context or provide projectId.",
|
|
@@ -3846,29 +3845,58 @@ async function handleToolCall(
|
|
|
3846
3845
|
throw new Error("Either cardId or shortId must be provided");
|
|
3847
3846
|
}
|
|
3848
3847
|
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3848
|
+
const variant =
|
|
3849
|
+
(args.variant as "analysis" | "draft" | "execute") || undefined;
|
|
3850
|
+
const customConstraints =
|
|
3851
|
+
typeof args.customConstraints === "string"
|
|
3852
|
+
? args.customConstraints
|
|
3853
|
+
: undefined;
|
|
3854
|
+
|
|
3855
|
+
// Context toggles default ON — a card's reference fields (linked cards,
|
|
3856
|
+
// external URLs, attachments) are hydrated inside generateCardPrompt so
|
|
3857
|
+
// the prompt carries the links the agent needs to fetch related content.
|
|
3858
|
+
const contextOptions = {
|
|
3859
|
+
includeSubtasks: args.includeSubtasks !== false,
|
|
3860
|
+
includeLinks: args.includeLinks !== false,
|
|
3861
|
+
includeDescription: args.includeDescription !== false,
|
|
3862
|
+
};
|
|
3863
|
+
|
|
3853
3864
|
try {
|
|
3854
|
-
const
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3865
|
+
const result = await client.generateCardPrompt({
|
|
3866
|
+
cardId,
|
|
3867
|
+
workspaceId: deps.getActiveWorkspaceId() || "",
|
|
3868
|
+
projectId,
|
|
3869
|
+
variant,
|
|
3870
|
+
customConstraints,
|
|
3871
|
+
contextOptions,
|
|
3872
|
+
});
|
|
3873
|
+
return { success: true, ...result };
|
|
3874
|
+
} catch (err) {
|
|
3875
|
+
// Graceful fallback: if full context assembly fails (e.g. an offline
|
|
3876
|
+
// sub-fetch), still return a usable title/description prompt so the
|
|
3877
|
+
// Harmony command never dead-ends. The reference-link hydration is
|
|
3878
|
+
// best-effort inside generateCardPrompt and won't reach here.
|
|
3879
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3880
|
+
console.debug(`[harmony_generate_prompt] falling back: ${msg}`);
|
|
3881
|
+
|
|
3882
|
+
let cardTitle = "";
|
|
3883
|
+
let cardDescription = "";
|
|
3884
|
+
try {
|
|
3885
|
+
const { card } = await client.getCard(cardId);
|
|
3886
|
+
const typedCard = card as { title?: string; description?: string };
|
|
3887
|
+
cardTitle = typedCard.title || "";
|
|
3888
|
+
cardDescription = typedCard.description || "";
|
|
3889
|
+
} catch {
|
|
3890
|
+
// Card fetch failed; return an empty task description.
|
|
3891
|
+
}
|
|
3861
3892
|
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3893
|
+
const taskBlock = [cardTitle, cardDescription]
|
|
3894
|
+
.filter(Boolean)
|
|
3895
|
+
.join("\n\n");
|
|
3896
|
+
const prompt = `Here is the task: ${taskBlock || "(no description available)"}`;
|
|
3866
3897
|
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
prompt,
|
|
3870
|
-
cardId,
|
|
3871
|
-
};
|
|
3898
|
+
return { success: true, prompt, cardId };
|
|
3899
|
+
}
|
|
3872
3900
|
}
|
|
3873
3901
|
|
|
3874
3902
|
// Memory / Knowledge Graph operations
|