@gethmy/mcp 2.11.2 → 2.13.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 +546 -18
- package/dist/index.js +544 -16
- package/dist/lib/api-client.js +47 -0
- package/package.json +1 -1
- package/src/api-client.ts +173 -0
- package/src/server.ts +666 -17
package/dist/lib/api-client.js
CHANGED
|
@@ -944,6 +944,9 @@ var TIMINGS = {
|
|
|
944
944
|
QUERY_STALE_TIME: 1000 * 60 * 5,
|
|
945
945
|
QUERY_GC_TIME: 1000 * 60 * 60 * 24
|
|
946
946
|
};
|
|
947
|
+
// ../harmony-shared/dist/stageHandoff.js
|
|
948
|
+
var HANDOFF_MARKER = "harmony:stage-handoff";
|
|
949
|
+
var HANDOFF_BLOCK_RE = new RegExp("```json\\s*\\n//\\s*" + HANDOFF_MARKER + "\\s*\\n([\\s\\S]*?)\\n```", "m");
|
|
947
950
|
// src/api-client.ts
|
|
948
951
|
init_config();
|
|
949
952
|
var RETRY_CONFIG = {
|
|
@@ -1303,9 +1306,29 @@ class HarmonyApiClient {
|
|
|
1303
1306
|
async uploadCardAttachment(cardId, data) {
|
|
1304
1307
|
return this.request("POST", `/cards/${cardId}/attachments`, data);
|
|
1305
1308
|
}
|
|
1309
|
+
async requestCardAttachmentUploadUrl(cardId, data) {
|
|
1310
|
+
return this.request("POST", `/cards/${cardId}/attachment-upload-url`, data);
|
|
1311
|
+
}
|
|
1312
|
+
async finalizeCardAttachment(cardId, data) {
|
|
1313
|
+
return this.request("POST", `/cards/${cardId}/attachments/finalize`, data);
|
|
1314
|
+
}
|
|
1306
1315
|
async getCardExternalLinks(cardId) {
|
|
1307
1316
|
return this.request("GET", `/cards/${cardId}/external-links`);
|
|
1308
1317
|
}
|
|
1318
|
+
async uploadArtifact(data) {
|
|
1319
|
+
return this.request("POST", "/artifacts", data);
|
|
1320
|
+
}
|
|
1321
|
+
async requestArtifactUploadUrl(data) {
|
|
1322
|
+
return this.request("POST", "/artifacts/upload-url", data);
|
|
1323
|
+
}
|
|
1324
|
+
async finalizeArtifact(data) {
|
|
1325
|
+
return this.request("POST", "/artifacts/finalize", data);
|
|
1326
|
+
}
|
|
1327
|
+
async createArtifactShareLink(artifactId, expiresAt) {
|
|
1328
|
+
return this.request("POST", `/artifacts/${artifactId}/share`, {
|
|
1329
|
+
expires_at: expiresAt
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1309
1332
|
async classifyCard(cardId) {
|
|
1310
1333
|
return this.request("POST", `/cards/${cardId}/classify`);
|
|
1311
1334
|
}
|
|
@@ -1772,6 +1795,30 @@ ${planContent.trim()}`;
|
|
|
1772
1795
|
title: cardData.title
|
|
1773
1796
|
};
|
|
1774
1797
|
}
|
|
1798
|
+
async listPlaybooks(workspaceId) {
|
|
1799
|
+
return this.request("GET", `/playbooks?workspaceId=${encodeURIComponent(workspaceId)}`);
|
|
1800
|
+
}
|
|
1801
|
+
async getPlaybook(playbookId) {
|
|
1802
|
+
return this.request("GET", `/playbooks/${playbookId}`);
|
|
1803
|
+
}
|
|
1804
|
+
async getPlaybookVersion(playbookId, version) {
|
|
1805
|
+
return this.request("GET", `/playbooks/${encodeURIComponent(playbookId)}/versions/${version}`);
|
|
1806
|
+
}
|
|
1807
|
+
async recordStageGateEvidence(insert) {
|
|
1808
|
+
return this.request("POST", `/cards/${encodeURIComponent(insert.card_id)}/stage-gate-evidence`, insert);
|
|
1809
|
+
}
|
|
1810
|
+
async createPlaybook(data) {
|
|
1811
|
+
return this.request("POST", "/playbooks", data);
|
|
1812
|
+
}
|
|
1813
|
+
async updatePlaybook(playbookId, updates) {
|
|
1814
|
+
return this.request("PATCH", `/playbooks/${playbookId}`, updates);
|
|
1815
|
+
}
|
|
1816
|
+
async runPlaybook(playbookId) {
|
|
1817
|
+
return this.request("POST", `/playbooks/${playbookId}/run`);
|
|
1818
|
+
}
|
|
1819
|
+
async savePlaybookFromCard(data) {
|
|
1820
|
+
return this.request("POST", "/playbooks/from-card", data);
|
|
1821
|
+
}
|
|
1775
1822
|
}
|
|
1776
1823
|
var _promptModules = null;
|
|
1777
1824
|
async function loadPromptModules() {
|
package/package.json
CHANGED
package/src/api-client.ts
CHANGED
|
@@ -2,6 +2,9 @@ import {
|
|
|
2
2
|
type AgentRunEventDraft,
|
|
3
3
|
type Comment,
|
|
4
4
|
getDisplayLinkType,
|
|
5
|
+
type PlaybookVersionDef,
|
|
6
|
+
type StageGateEvidenceInsert,
|
|
7
|
+
type StageGateEvidenceRow,
|
|
5
8
|
serializeCommentThread,
|
|
6
9
|
type WorkspaceAgent,
|
|
7
10
|
} from "@harmony/shared";
|
|
@@ -143,6 +146,15 @@ export interface CardAttachment {
|
|
|
143
146
|
signed_url_expires_in: number;
|
|
144
147
|
}
|
|
145
148
|
|
|
149
|
+
/** Response of a `*-upload-url` endpoint: a one-shot signed Supabase Storage
|
|
150
|
+
* URL the caller PUTs raw bytes to, plus the service-chosen path that the
|
|
151
|
+
* matching `finalize` call validates and registers. */
|
|
152
|
+
export interface SignedUpload {
|
|
153
|
+
uploadUrl: string;
|
|
154
|
+
token: string;
|
|
155
|
+
storagePath: string;
|
|
156
|
+
}
|
|
157
|
+
|
|
146
158
|
export interface CardExternalLinkRow {
|
|
147
159
|
id: string;
|
|
148
160
|
card_id: string;
|
|
@@ -675,12 +687,89 @@ export class HarmonyApiClient {
|
|
|
675
687
|
return this.request("POST", `/cards/${cardId}/attachments`, data);
|
|
676
688
|
}
|
|
677
689
|
|
|
690
|
+
// Step 1 of the direct-to-storage attachment handshake: mint a signed upload
|
|
691
|
+
// URL for a server-chosen path under the card. The caller PUTs raw bytes to
|
|
692
|
+
// `uploadUrl`, then calls finalizeCardAttachment with the returned storagePath.
|
|
693
|
+
async requestCardAttachmentUploadUrl(
|
|
694
|
+
cardId: string,
|
|
695
|
+
data: { fileName: string; fileType?: string; size: number },
|
|
696
|
+
): Promise<SignedUpload & { fileType: string }> {
|
|
697
|
+
return this.request("POST", `/cards/${cardId}/attachment-upload-url`, data);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// Step 2: validate the uploaded object (size + magic-byte content-type +
|
|
701
|
+
// optional sha256) and insert the attachment row. The server deletes the
|
|
702
|
+
// object and rejects on any mismatch.
|
|
703
|
+
async finalizeCardAttachment(
|
|
704
|
+
cardId: string,
|
|
705
|
+
data: {
|
|
706
|
+
storagePath: string;
|
|
707
|
+
fileName: string;
|
|
708
|
+
fileType?: string;
|
|
709
|
+
sha256?: string;
|
|
710
|
+
size?: number;
|
|
711
|
+
},
|
|
712
|
+
): Promise<{ attachment: CardAttachment }> {
|
|
713
|
+
return this.request("POST", `/cards/${cardId}/attachments/finalize`, data);
|
|
714
|
+
}
|
|
715
|
+
|
|
678
716
|
async getCardExternalLinks(
|
|
679
717
|
cardId: string,
|
|
680
718
|
): Promise<{ external_links: CardExternalLinkRow[] }> {
|
|
681
719
|
return this.request("GET", `/cards/${cardId}/external-links`);
|
|
682
720
|
}
|
|
683
721
|
|
|
722
|
+
// ============ ARTIFACTS (hosted HTML documents) ============
|
|
723
|
+
|
|
724
|
+
async uploadArtifact(data: {
|
|
725
|
+
title?: string;
|
|
726
|
+
cardId?: string;
|
|
727
|
+
planId?: string;
|
|
728
|
+
workspaceId?: string;
|
|
729
|
+
contentType?: string;
|
|
730
|
+
data: string;
|
|
731
|
+
}): Promise<{ artifact: Record<string, unknown> }> {
|
|
732
|
+
return this.request("POST", "/artifacts", data);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// Step 1 of the direct-to-storage artifact handshake: mint a signed upload
|
|
736
|
+
// URL for a server-chosen path. The caller PUTs raw HTML bytes to `uploadUrl`,
|
|
737
|
+
// then calls finalizeArtifact with the returned storagePath.
|
|
738
|
+
async requestArtifactUploadUrl(data: {
|
|
739
|
+
title?: string;
|
|
740
|
+
cardId?: string;
|
|
741
|
+
planId?: string;
|
|
742
|
+
workspaceId?: string;
|
|
743
|
+
contentType?: string;
|
|
744
|
+
size?: number;
|
|
745
|
+
}): Promise<SignedUpload> {
|
|
746
|
+
return this.request("POST", "/artifacts/upload-url", data);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// Step 2: validate the uploaded object (size + HTML magic-byte sniff +
|
|
750
|
+
// optional sha256) and insert the artifact row. The server deletes the
|
|
751
|
+
// object and rejects on any mismatch.
|
|
752
|
+
async finalizeArtifact(data: {
|
|
753
|
+
storagePath: string;
|
|
754
|
+
sha256?: string;
|
|
755
|
+
size?: number;
|
|
756
|
+
title?: string;
|
|
757
|
+
cardId?: string;
|
|
758
|
+
planId?: string;
|
|
759
|
+
workspaceId?: string;
|
|
760
|
+
}): Promise<{ artifact: Record<string, unknown> }> {
|
|
761
|
+
return this.request("POST", "/artifacts/finalize", data);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
async createArtifactShareLink(
|
|
765
|
+
artifactId: string,
|
|
766
|
+
expiresAt?: string,
|
|
767
|
+
): Promise<{ link: Record<string, unknown> }> {
|
|
768
|
+
return this.request("POST", `/artifacts/${artifactId}/share`, {
|
|
769
|
+
expires_at: expiresAt,
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
|
|
684
773
|
async classifyCard(
|
|
685
774
|
cardId: string,
|
|
686
775
|
): Promise<{ classification: CardClassificationResult }> {
|
|
@@ -1709,6 +1798,90 @@ export class HarmonyApiClient {
|
|
|
1709
1798
|
title: cardData.title,
|
|
1710
1799
|
};
|
|
1711
1800
|
}
|
|
1801
|
+
|
|
1802
|
+
// ============ PLAYBOOKS (Method/Loop layer) ============
|
|
1803
|
+
|
|
1804
|
+
async listPlaybooks(workspaceId: string): Promise<{ playbooks: unknown[] }> {
|
|
1805
|
+
return this.request(
|
|
1806
|
+
"GET",
|
|
1807
|
+
`/playbooks?workspaceId=${encodeURIComponent(workspaceId)}`,
|
|
1808
|
+
);
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
async getPlaybook(
|
|
1812
|
+
playbookId: string,
|
|
1813
|
+
): Promise<{ playbook: unknown; runs: unknown[] }> {
|
|
1814
|
+
return this.request("GET", `/playbooks/${playbookId}`);
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
/**
|
|
1818
|
+
* Fetch the pinned, immutable stage-def snapshot for `(playbookId, version)`.
|
|
1819
|
+
* The agent daemon's stage executor (#514) resolves a card's `current_stage`
|
|
1820
|
+
* against this frozen def — never live `playbooks.steps` — so editing a
|
|
1821
|
+
* Playbook never rewrites an in-flight card.
|
|
1822
|
+
*/
|
|
1823
|
+
async getPlaybookVersion(
|
|
1824
|
+
playbookId: string,
|
|
1825
|
+
version: number,
|
|
1826
|
+
): Promise<{
|
|
1827
|
+
version: PlaybookVersionDef & { playbook_id: string; version: number };
|
|
1828
|
+
}> {
|
|
1829
|
+
return this.request(
|
|
1830
|
+
"GET",
|
|
1831
|
+
`/playbooks/${encodeURIComponent(playbookId)}/versions/${version}`,
|
|
1832
|
+
);
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
/**
|
|
1836
|
+
* Persist a stage gate evidence row (Playbooks P1 #3, card #516). The daemon
|
|
1837
|
+
* collects + evaluates a gate then POSTs the resulting evidence here; the edge
|
|
1838
|
+
* writes it with the service-role client (the table has no INSERT RLS policy,
|
|
1839
|
+
* so this is the only write path). Returns the inserted row.
|
|
1840
|
+
*/
|
|
1841
|
+
async recordStageGateEvidence(
|
|
1842
|
+
insert: StageGateEvidenceInsert,
|
|
1843
|
+
): Promise<{ evidence: StageGateEvidenceRow }> {
|
|
1844
|
+
return this.request(
|
|
1845
|
+
"POST",
|
|
1846
|
+
`/cards/${encodeURIComponent(insert.card_id)}/stage-gate-evidence`,
|
|
1847
|
+
insert,
|
|
1848
|
+
);
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
async createPlaybook(data: {
|
|
1852
|
+
workspaceId: string;
|
|
1853
|
+
name: string;
|
|
1854
|
+
description?: string;
|
|
1855
|
+
steps?: unknown;
|
|
1856
|
+
stepsVersion?: number;
|
|
1857
|
+
triggerType?: string;
|
|
1858
|
+
}): Promise<{ playbook: unknown }> {
|
|
1859
|
+
return this.request("POST", "/playbooks", data);
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
async updatePlaybook(
|
|
1863
|
+
playbookId: string,
|
|
1864
|
+
updates: {
|
|
1865
|
+
name?: string;
|
|
1866
|
+
description?: string;
|
|
1867
|
+
steps?: unknown;
|
|
1868
|
+
enabled?: boolean;
|
|
1869
|
+
state?: string;
|
|
1870
|
+
},
|
|
1871
|
+
): Promise<{ playbook: unknown }> {
|
|
1872
|
+
return this.request("PATCH", `/playbooks/${playbookId}`, updates);
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
async runPlaybook(playbookId: string): Promise<{ run: unknown }> {
|
|
1876
|
+
return this.request("POST", `/playbooks/${playbookId}/run`);
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
async savePlaybookFromCard(data: {
|
|
1880
|
+
cardId: string;
|
|
1881
|
+
name?: string;
|
|
1882
|
+
}): Promise<{ playbook: unknown }> {
|
|
1883
|
+
return this.request("POST", "/playbooks/from-card", data);
|
|
1884
|
+
}
|
|
1712
1885
|
}
|
|
1713
1886
|
|
|
1714
1887
|
// Shared types for generateCardPrompt to avoid inline assertions
|