@leadpoet/client 0.0.0-stage → 0.1.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/README.md +160 -2
- package/cli.js +436 -0
- package/cli.js.map +7 -0
- package/client.js +309 -0
- package/client.js.map +7 -0
- package/mcp.js +415 -0
- package/mcp.js.map +7 -0
- package/package.json +33 -4
- package/skill/SKILL.md +64 -0
- package/types/scripts/leadpoet-mcp.d.ts +5 -0
- package/types/scripts/leadpoet.d.ts +7 -0
- package/types/shared/leadpoet-client.d.ts +896 -0
- package/types/shared/workspace-operations.d.ts +2220 -0
package/cli.js
ADDED
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// scripts/leadpoet.ts
|
|
4
|
+
import { createReadStream, realpathSync } from "node:fs";
|
|
5
|
+
import { parseArgs } from "node:util";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
// shared/workspace-operations.ts
|
|
9
|
+
var WORKSPACE_OPERATIONS = [
|
|
10
|
+
{ "method": "post", "nativePath": "/api/requests", "path": "/requests", "id": "createRequest", "scope": "lead_engine:write", "bodyScopes": { "recurrence": ["outreach:send"] }, "group": "workspace", "retry": "header" },
|
|
11
|
+
{ "method": "get", "nativePath": "/api/requests/contact-settings", "path": "/requests/contact-settings", "id": "getContactAllowance", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
12
|
+
{ "method": "get", "nativePath": "/api/queries", "path": "/requests", "id": "listRequests", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
13
|
+
{ "method": "get", "nativePath": "/api/queries/:id", "path": "/requests/:id", "id": "getRequest", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
14
|
+
{ "method": "get", "nativePath": "/api/company-pipeline", "path": "/pipeline", "id": "getPipeline", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
15
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/cards/:id", "path": "/pipeline/companies/:id", "id": "updateCompany", "scope": "pipeline:write", "group": "workspace", "retry": "state" },
|
|
16
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/contact-enrichment/readiness", "path": "/pipeline/contact-enrichment/readiness", "id": "getContactReadiness", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
17
|
+
{ "method": "post", "nativePath": "/api/company-pipeline/cards/:id/contact-requests", "path": "/pipeline/companies/:id/contact-requests", "id": "requestContacts", "scope": "pipeline:write", "group": "workspace", "retry": "header" },
|
|
18
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/cards/:cardId/contact-requests/:requestId", "path": "/pipeline/companies/:cardId/contact-requests/:requestId", "id": "getContactRequest", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
19
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/cards/:cardId/contact-requests/latest", "path": "/pipeline/companies/:cardId/contact-requests/latest", "id": "getLatestContactRequest", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
20
|
+
{ "method": "get", "nativePath": "/api/icp-profiles", "path": "/icps", "id": "listIcps", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
21
|
+
{ "method": "post", "nativePath": "/api/icp-profiles/audiences", "path": "/icps/audiences", "id": "createIcp", "scope": "lead_engine:write", "group": "workspace", "retry": "header" },
|
|
22
|
+
{ "method": "get", "nativePath": "/api/icp-profiles/:icpId", "path": "/icps/:icpId", "id": "getIcp", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
23
|
+
{ "method": "get", "nativePath": "/api/icp-profiles/:icpId/versions", "path": "/icps/:icpId/versions", "id": "listIcpVersions", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
24
|
+
{ "method": "post", "nativePath": "/api/icp-profiles/:icpId/draft", "path": "/icps/:icpId/draft", "id": "createIcpDraft", "scope": "lead_engine:write", "group": "workspace", "retry": "none" },
|
|
25
|
+
{ "method": "patch", "nativePath": "/api/icp-profiles/:icpId/drafts/:draftId", "path": "/icps/:icpId/drafts/:draftId", "id": "updateIcpDraft", "scope": "lead_engine:write", "group": "workspace", "retry": "state" },
|
|
26
|
+
{ "method": "post", "nativePath": "/api/icp-profiles/:icpId/drafts/:draftId/publish", "path": "/icps/:icpId/drafts/:draftId/publish", "id": "publishIcp", "scope": "lead_engine:write", "group": "workspace", "retry": "header" },
|
|
27
|
+
{ "method": "post", "nativePath": "/api/icp-profiles/:icpId/archive", "path": "/icps/:icpId/archive", "id": "archiveIcp", "scope": "lead_engine:write", "group": "workspace", "retry": "header" },
|
|
28
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/contact-engagements", "path": "/pipeline/contacts", "id": "listPipelineContacts", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
29
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/contact-engagements/:engagementId/stage", "path": "/pipeline/contacts/:engagementId/stage", "id": "moveContact", "scope": "pipeline:write", "group": "workspace", "retry": "body" },
|
|
30
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/contact-engagements/:engagementId/pin", "path": "/pipeline/contacts/:engagementId/pin", "id": "pinContact", "scope": "pipeline:write", "group": "workspace", "retry": "state" },
|
|
31
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/deals", "path": "/pipeline/deals", "id": "listDeals", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
32
|
+
{ "method": "post", "nativePath": "/api/company-pipeline/cards/:cardId/deals", "path": "/pipeline/companies/:cardId/deals", "id": "createDeal", "scope": "pipeline:write", "group": "workspace", "retry": "header" },
|
|
33
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/deals/:dealId", "path": "/pipeline/deals/:dealId", "id": "updateDeal", "scope": "pipeline:write", "group": "workspace", "retry": "state" },
|
|
34
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/deals/:dealId/stage", "path": "/pipeline/deals/:dealId/stage", "id": "moveDeal", "scope": "pipeline:write", "group": "workspace", "retry": "body" },
|
|
35
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/pipeline-config", "path": "/pipeline/configuration", "id": "getPipelineConfiguration", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
36
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/cards/:cardId/notes", "path": "/pipeline/companies/:cardId/notes", "id": "listCompanyNotes", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
37
|
+
{ "method": "post", "nativePath": "/api/company-pipeline/cards/:cardId/notes", "path": "/pipeline/companies/:cardId/notes", "id": "createCompanyNote", "scope": "pipeline:write", "group": "workspace", "retry": "header_uuid" },
|
|
38
|
+
{ "method": "get", "nativePath": "/accounts", "path": "/outreach/accounts", "id": "listSendingAccounts", "scope": "outreach:read", "group": "outreach", "retry": "none" },
|
|
39
|
+
{ "method": "get", "nativePath": "/conversations", "path": "/outreach/conversations", "id": "listConversations", "scope": "outreach:read", "group": "outreach", "retry": "none" },
|
|
40
|
+
{ "method": "get", "nativePath": "/workspace-profile", "path": "/outreach/profile", "id": "getOutreachProfile", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
41
|
+
{ "method": "put", "nativePath": "/workspace-profile", "path": "/outreach/profile", "id": "updateOutreachProfile", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
42
|
+
{ "method": "get", "nativePath": "/audience-sources", "path": "/outreach/audience-sources", "id": "listAudienceSources", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
43
|
+
{ "method": "get", "nativePath": "/audience-contacts", "path": "/outreach/audience-contacts", "id": "listAudienceContacts", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
44
|
+
{ "method": "post", "nativePath": "/audience-snapshots/preview-selection", "path": "/outreach/audiences/preview", "id": "previewAudience", "scope": "outreach:write", "group": "campaigns", "retry": "operation_id" },
|
|
45
|
+
{ "method": "post", "nativePath": "/audience-snapshots/from-selection", "path": "/outreach/audiences", "id": "createAudience", "scope": "outreach:write", "group": "campaigns", "retry": "operation_id" },
|
|
46
|
+
{ "method": "get", "nativePath": "/strategies", "path": "/outreach/campaigns", "id": "listCampaigns", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
47
|
+
{ "method": "get", "nativePath": "/campaign-product-descriptions", "path": "/outreach/campaign-product-descriptions", "id": "listCampaignProductDescriptions", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
48
|
+
{ "method": "post", "nativePath": "/strategies", "path": "/outreach/campaigns", "id": "createCampaign", "scope": "outreach:write", "group": "campaigns", "retry": "operation_id" },
|
|
49
|
+
{ "method": "get", "nativePath": "/strategies/:id", "path": "/outreach/campaigns/:id", "id": "getCampaign", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
50
|
+
{ "method": "put", "nativePath": "/strategies/:id", "path": "/outreach/campaigns/:id", "id": "updateCampaign", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
51
|
+
{ "method": "post", "nativePath": "/strategies/:id/preview", "path": "/outreach/campaigns/:id/preview", "id": "previewCampaign", "scope": "outreach:read", "group": "campaigns", "retry": "safe" },
|
|
52
|
+
{ "method": "post", "nativePath": "/strategies/:id/contract-proposal", "path": "/outreach/campaigns/:id/contract-proposal", "id": "proposeCampaignContract", "scope": "outreach:read", "group": "campaigns", "retry": "safe" },
|
|
53
|
+
{ "method": "post", "nativePath": "/strategies/:id/launch", "path": "/outreach/campaigns/:id/launch", "id": "launchCampaign", "scope": "outreach:send", "group": "campaigns", "retry": "bound" },
|
|
54
|
+
{ "method": "post", "nativePath": "/strategies/:id/pause", "path": "/outreach/campaigns/:id/pause", "id": "pauseCampaign", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
55
|
+
{ "method": "post", "nativePath": "/strategies/:id/resume", "path": "/outreach/campaigns/:id/resume", "id": "resumeCampaign", "scope": "outreach:send", "group": "campaigns", "retry": "state" },
|
|
56
|
+
{ "method": "get", "nativePath": "/review", "path": "/outreach/review", "id": "listReview", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
57
|
+
{ "method": "post", "nativePath": "/review/:messageId/deny", "path": "/outreach/review/:messageId/deny", "id": "denyMessage", "scope": "outreach:write", "group": "campaigns", "retry": "bound" },
|
|
58
|
+
{ "method": "post", "nativePath": "/review/:messageId/skip", "path": "/outreach/review/:messageId/skip", "id": "skipMessage", "scope": "outreach:write", "group": "campaigns", "retry": "bound" },
|
|
59
|
+
{ "method": "get", "nativePath": "/replies", "path": "/outreach/replies", "id": "listReplies", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
60
|
+
{ "method": "get", "nativePath": "/performance/summary", "path": "/outreach/analytics", "id": "getOutreachAnalytics", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
61
|
+
{ "method": "post", "nativePath": "/review/prepare-approval", "path": "/outreach/review/approve", "id": "approveMessages", "scope": "outreach:send", "group": "campaigns", "retry": "bound" },
|
|
62
|
+
{ "method": "post", "nativePath": "/conversations/:id/reply", "path": "/outreach/conversations/:id/reply", "id": "replyToConversation", "scope": "outreach:send", "group": "outreach", "retry": "request_id" },
|
|
63
|
+
{ "method": "post", "nativePath": "/strategies/:id/archive", "path": "/outreach/campaigns/:id/archive", "id": "archiveCampaign", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
64
|
+
{ "method": "get", "nativePath": "/", "path": "/outreach/sequence-templates", "id": "listSequenceTemplates", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
65
|
+
{ "method": "get", "nativePath": "/:id", "path": "/outreach/sequence-templates/:id", "id": "getSequenceTemplate", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
66
|
+
{ "method": "get", "nativePath": "/from-campaign/:id", "path": "/outreach/campaigns/:id/sequence", "id": "getCampaignSequence", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
67
|
+
{ "method": "post", "nativePath": "/", "path": "/outreach/sequence-templates", "id": "createSequenceTemplate", "scope": "outreach:write", "group": "campaigns", "retry": "operation_id" },
|
|
68
|
+
{ "method": "post", "nativePath": "/:id/duplicate", "path": "/outreach/sequence-templates/:id/duplicate", "id": "duplicateSequenceTemplate", "scope": "outreach:write", "group": "campaigns", "retry": "operation_id" },
|
|
69
|
+
{ "method": "post", "nativePath": "/:id/archive", "path": "/outreach/sequence-templates/:id/archive", "id": "archiveSequenceTemplate", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
70
|
+
{ "method": "get", "nativePath": "/strategies/:id/messaging", "path": "/outreach/campaigns/:id/messaging", "id": "getCampaignMessaging", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
71
|
+
{ "method": "put", "nativePath": "/strategies/:id/messaging", "path": "/outreach/campaigns/:id/messaging", "id": "updateCampaignMessaging", "scope": "outreach:send", "group": "campaigns", "retry": "operation_id" },
|
|
72
|
+
{ "method": "get", "nativePath": "/api/recurring-requests", "path": "/recurring-requests", "id": "listRecurringRequests", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
73
|
+
{ "method": "get", "nativePath": "/api/recurring-requests/options", "path": "/recurring-requests/options", "id": "getRecurringRequestOptions", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
74
|
+
{ "method": "post", "nativePath": "/api/recurring-requests", "path": "/recurring-requests", "id": "createRecurringRequest", "scope": "lead_engine:write", "group": "workspace", "retry": "operation_id", "additionalScopes": ["outreach:send"] },
|
|
75
|
+
{ "method": "patch", "nativePath": "/api/recurring-requests/setups/:id", "path": "/recurring-requests/setups/:id", "id": "updateRecurringSetup", "scope": "lead_engine:write", "group": "workspace", "retry": "bound", "additionalScopes": ["outreach:send"] },
|
|
76
|
+
{ "method": "patch", "nativePath": "/api/recurring-requests/:id", "path": "/recurring-requests/:id", "id": "updateRecurringRequest", "scope": "lead_engine:write", "group": "workspace", "retry": "bound", "additionalScopes": ["outreach:send"] },
|
|
77
|
+
{ "method": "get", "nativePath": "/queued", "path": "/outreach/queued", "id": "listQueuedMessages", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
78
|
+
{ "method": "get", "nativePath": "/queued/:messageId", "path": "/outreach/queued/:messageId", "id": "getQueuedMessage", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
79
|
+
{ "method": "get", "nativePath": "/queued/:messageId/outcome", "path": "/outreach/queued/:messageId/outcome", "id": "getMessageOutcome", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
80
|
+
{ "method": "post", "nativePath": "/queued/priority", "path": "/outreach/queued/priority", "id": "prioritizeMessages", "scope": "outreach:send", "group": "campaigns", "retry": "request_id" },
|
|
81
|
+
{ "method": "post", "nativePath": "/queued/:messageId/cancel", "path": "/outreach/queued/:messageId/cancel", "id": "cancelQueuedMessage", "scope": "outreach:write", "group": "campaigns", "retry": "bound" },
|
|
82
|
+
{ "method": "post", "nativePath": "/queued/:messageId/return-to-review", "path": "/outreach/queued/:messageId/return-to-review", "id": "returnQueuedMessageToReview", "scope": "outreach:write", "group": "campaigns", "retry": "bound" },
|
|
83
|
+
{ "method": "get", "nativePath": "/queued/:messageId/edit-session", "path": "/outreach/queued/:messageId/edit-session", "id": "getQueuedMessageEditSession", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
84
|
+
{ "method": "post", "nativePath": "/queued/:messageId/resume-unchanged", "path": "/outreach/queued/:messageId/resume-unchanged", "id": "resumeQueuedMessageUnchanged", "scope": "outreach:send", "group": "campaigns", "retry": "bound" },
|
|
85
|
+
{ "method": "post", "nativePath": "/queued/:messageId/send-now", "path": "/outreach/queued/:messageId/send-now", "id": "sendQueuedMessageNow", "scope": "outreach:send", "group": "campaigns", "retry": "bound" },
|
|
86
|
+
{ "method": "post", "nativePath": "/queued/:messageId/send-sooner", "path": "/outreach/queued/:messageId/send-sooner", "id": "sendQueuedMessageSooner", "scope": "outreach:send", "group": "campaigns", "retry": "bound" },
|
|
87
|
+
{ "method": "patch", "nativePath": "/strategies/:id/name", "path": "/outreach/campaigns/:id/name", "id": "renameCampaign", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
88
|
+
{ "method": "post", "nativePath": "/strategies/:id/restore", "path": "/outreach/campaigns/:id/restore", "id": "restoreCampaign", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
89
|
+
{ "method": "post", "nativePath": "/sender-allocations/preview", "path": "/outreach/sender-allocations/preview", "id": "previewSenderAllocations", "scope": "outreach:read", "group": "campaigns", "retry": "safe" },
|
|
90
|
+
{ "method": "put", "nativePath": "/strategies/:id/sending-schedule", "path": "/outreach/campaigns/:id/sending-schedule", "id": "updateCampaignSchedule", "scope": "outreach:send", "group": "campaigns", "retry": "state" },
|
|
91
|
+
{ "method": "get", "nativePath": "/strategies/:id/activity", "path": "/outreach/campaigns/:id/activity", "id": "getCampaignActivity", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
92
|
+
{ "method": "get", "nativePath": "/strategies/:id/decisions", "path": "/outreach/campaigns/:id/decisions", "id": "getCampaignDecisions", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
93
|
+
{ "method": "get", "nativePath": "/strategies/:id/reviews", "path": "/outreach/campaigns/:id/reviews", "id": "getCampaignReviews", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
94
|
+
{ "method": "get", "nativePath": "/audience-snapshots", "path": "/outreach/audiences", "id": "listAudiences", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
95
|
+
{ "method": "get", "nativePath": "/audience-snapshots/:id/funnel", "path": "/outreach/audiences/:id/funnel", "id": "getAudienceFunnel", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
96
|
+
{ "method": "get", "nativePath": "/audience-snapshots/:snapshotId/preflight", "path": "/outreach/audiences/:snapshotId/preflight", "id": "getAudiencePreflight", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
97
|
+
{ "method": "post", "nativePath": "/strategies/:id/message-preview", "path": "/outreach/campaigns/:id/message-preview", "id": "previewCampaignMessage", "scope": "outreach:read", "group": "campaigns", "retry": "safe" },
|
|
98
|
+
{ "method": "post", "nativePath": "/safety-attention/delivery-unknown/:messageId/check", "path": "/outreach/safety-attention/delivery-unknown/:messageId/check", "id": "checkMessageDelivery", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
99
|
+
{ "method": "post", "nativePath": "/api/icp-profiles", "path": "/icps", "id": "createManualIcp", "scope": "lead_engine:write", "group": "workspace", "retry": "header" },
|
|
100
|
+
{ "method": "get", "nativePath": "/api/icp-profiles/:icpId/usage", "path": "/icps/:icpId/usage", "id": "getIcpUsage", "scope": "lead_engine:read", "group": "workspace", "retry": "none" },
|
|
101
|
+
{ "method": "get", "nativePath": "/strategies/:id/description", "path": "/outreach/campaigns/:id/description", "id": "getCampaignDescription", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
102
|
+
{ "method": "put", "nativePath": "/strategies/:id/description", "path": "/outreach/campaigns/:id/description", "id": "updateCampaignDescription", "scope": "outreach:send", "group": "campaigns", "retry": "operation_id" },
|
|
103
|
+
{ "method": "get", "nativePath": "/performance/filters", "path": "/outreach/analytics/filters", "id": "getAnalyticsFilters", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
104
|
+
{ "method": "get", "nativePath": "/performance/analytics", "path": "/outreach/analytics/report", "id": "getAnalyticsReport", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
105
|
+
{ "method": "post", "nativePath": "/api/icp-profiles/lead-engine-audience", "path": "/icps/lead-engine-audience", "id": "saveLeadEngineAudience", "scope": "lead_engine:write", "group": "workspace", "retry": "header" },
|
|
106
|
+
{ "method": "post", "nativePath": "/api/icp-profiles/from-scan", "path": "/icps/from-scan", "id": "createIcpFromScan", "scope": "lead_engine:write", "group": "workspace", "retry": "header" },
|
|
107
|
+
{ "method": "post", "nativePath": "/api/icp-profiles/:icpId/apply-preview", "path": "/icps/:icpId/apply-preview", "id": "previewIcpApplication", "scope": "lead_engine:read", "group": "workspace", "retry": "safe" },
|
|
108
|
+
{ "method": "post", "nativePath": "/api/icp-profiles/:icpId/promote-overrides", "path": "/icps/:icpId/promote-overrides", "id": "promoteIcpOverrides", "scope": "lead_engine:write", "group": "workspace", "retry": "header" },
|
|
109
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/deal-summaries", "path": "/pipeline/deal-summaries", "id": "getDealSummaries", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
110
|
+
{ "method": "get", "nativePath": "/api/revenue-insights", "path": "/pipeline/revenue-insights", "id": "getRevenueInsights", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
111
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/cards/:cardId/deals", "path": "/pipeline/companies/:cardId/deals", "id": "listCompanyDeals", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
112
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/deals/:dealId/pin", "path": "/pipeline/deals/:dealId/pin", "id": "pinDeal", "scope": "pipeline:write", "group": "workspace", "retry": "state" },
|
|
113
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/deals/:dealId/attribution", "path": "/pipeline/deals/:dealId/attribution", "id": "updateDealAttribution", "scope": "pipeline:write", "group": "workspace", "retry": "state" },
|
|
114
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/deals/actions/bulk-stage", "path": "/pipeline/deals/actions/bulk-stage", "id": "moveDeals", "scope": "pipeline:write", "group": "workspace", "retry": "body" },
|
|
115
|
+
{ "method": "patch", "nativePath": "/api/company-pipeline/contact-engagements/actions/bulk-stage", "path": "/pipeline/contacts/actions/bulk-stage", "id": "moveContacts", "scope": "pipeline:write", "group": "workspace", "retry": "body" },
|
|
116
|
+
{ "method": "post", "nativePath": "/api/company-pipeline/contact-engagements/:engagementId/qualification-deal/undo", "path": "/pipeline/contacts/:engagementId/qualification-deal/undo", "id": "undoContactQualification", "scope": "pipeline:write", "group": "workspace", "retry": "body" },
|
|
117
|
+
{ "method": "get", "nativePath": "/api/company-pipeline/cards/:cardId/note-counts", "path": "/pipeline/companies/:cardId/note-counts", "id": "getCompanyNoteCounts", "scope": "pipeline:read", "group": "workspace", "retry": "none" },
|
|
118
|
+
{ "method": "post", "nativePath": "/api/company-pipeline/cards/:cardId/notes/clear", "path": "/pipeline/companies/:cardId/notes/archive", "id": "archiveCompanyNotes", "scope": "pipeline:write", "group": "workspace", "retry": "state" },
|
|
119
|
+
{ "method": "post", "nativePath": "/strategies/:id/audience/preview", "path": "/outreach/campaigns/:id/audience/preview", "id": "previewCampaignAudience", "scope": "outreach:write", "group": "campaigns", "retry": "operation_id", "retryIdentity": "campaignAudience" },
|
|
120
|
+
{ "method": "post", "nativePath": "/strategies/:id/audience/add", "path": "/outreach/campaigns/:id/audience/add", "id": "addCampaignAudience", "scope": "outreach:send", "group": "campaigns", "retry": "operation_id", "retryIdentity": "campaignAudience" },
|
|
121
|
+
{ "method": "get", "nativePath": "/strategies/:id/audience/contacts", "path": "/outreach/campaigns/:id/audience/contacts", "id": "listCampaignContacts", "scope": "outreach:read", "group": "campaigns", "retry": "none" },
|
|
122
|
+
{ "method": "post", "nativePath": "/strategies/:id/audience/contacts/:enrollmentId/remove", "path": "/outreach/campaigns/:id/audience/contacts/:enrollmentId/remove", "id": "removePendingCampaignContact", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
123
|
+
{ "method": "post", "nativePath": "/conversations/:id/sequence", "path": "/outreach/conversations/:id/sequence", "id": "updateConversationSequence", "scope": "outreach:send", "group": "campaigns", "retry": "state" },
|
|
124
|
+
{ "method": "put", "nativePath": "/strategies/:id/contact-cap", "path": "/outreach/campaigns/:id/contact-cap", "id": "updateCampaignContactCap", "scope": "outreach:send", "group": "campaigns", "retry": "operation_id" },
|
|
125
|
+
{ "method": "put", "nativePath": "/strategies/:id/sender-allocations", "path": "/outreach/campaigns/:id/sender-allocations", "id": "updateSenderAllocations", "scope": "outreach:send", "group": "campaigns", "retry": "state" },
|
|
126
|
+
{ "method": "put", "nativePath": "/strategies/:id/sending-days", "path": "/outreach/campaigns/:id/sending-days", "id": "updateSendingDays", "scope": "outreach:send", "group": "campaigns", "retry": "state" },
|
|
127
|
+
{ "method": "post", "nativePath": "/strategies/:id/change-mode", "path": "/outreach/campaigns/:id/change-mode", "id": "changeCampaignMode", "scope": "outreach:send", "group": "campaigns", "retry": "bound" },
|
|
128
|
+
{ "method": "post", "nativePath": "/strategies/:id/discard", "path": "/outreach/campaigns/:id/discard", "id": "discardCampaign", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
129
|
+
{ "method": "post", "nativePath": "/strategies/:id/drafts/restore", "path": "/outreach/campaigns/:id/drafts/restore", "id": "restoreCampaignDrafts", "scope": "outreach:write", "group": "campaigns", "retry": "state" },
|
|
130
|
+
{ "method": "post", "nativePath": "/safety-attention/delivery-unknown/:messageId/resolve", "path": "/outreach/safety-attention/delivery-unknown/:messageId/resolve", "id": "resolveUnknownDelivery", "scope": "outreach:send", "group": "campaigns", "retry": "bound" },
|
|
131
|
+
{ "method": "post", "nativePath": "/review/bulk-approve", "path": "/outreach/review/bulk-approve", "id": "bulkApproveMessages", "scope": "outreach:send", "group": "campaigns", "retry": "bound" },
|
|
132
|
+
{ "method": "post", "nativePath": "/review/bulk-deny", "path": "/outreach/review/bulk-deny", "id": "bulkDenyMessages", "scope": "outreach:write", "group": "campaigns", "retry": "bound" },
|
|
133
|
+
{ "method": "post", "nativePath": "/review/bulk-skip", "path": "/outreach/review/bulk-skip", "id": "bulkSkipMessages", "scope": "outreach:write", "group": "campaigns", "retry": "bound" },
|
|
134
|
+
{ "method": "post", "nativePath": "/review/:messageId/recheck-autopilot", "path": "/outreach/review/:messageId/recheck-autopilot", "id": "recheckMessageAutopilot", "scope": "outreach:send", "group": "campaigns", "retry": "bound" }
|
|
135
|
+
];
|
|
136
|
+
var bodyScopeRules = (operation) => Object.entries(operation.bodyScopes ?? {});
|
|
137
|
+
var requiredScopes = (operation, body) => [
|
|
138
|
+
operation.scope,
|
|
139
|
+
...operation.additionalScopes ?? [],
|
|
140
|
+
...bodyScopeRules(operation).flatMap(([field, scopes]) => body && typeof body === "object" && Object.prototype.hasOwnProperty.call(body, field) ? scopes : [])
|
|
141
|
+
].filter(Boolean);
|
|
142
|
+
var LEGACY_API_OPERATIONS = [
|
|
143
|
+
{ method: "get", path: "/pricing", id: "getPricing", scope: "", retry: "none" },
|
|
144
|
+
{ method: "get", path: "/me", id: "getApiIdentity", scope: "", retry: "none" },
|
|
145
|
+
{ method: "get", path: "/credits", id: "getCredits", scope: "credits:read", retry: "none" },
|
|
146
|
+
{ method: "get", path: "/reference/countries", id: "listCountries", scope: "", retry: "none" },
|
|
147
|
+
{ method: "get", path: "/reference/states", id: "listStates", scope: "", retry: "none" },
|
|
148
|
+
{ method: "get", path: "/reference/cities", id: "listCities", scope: "", retry: "none" },
|
|
149
|
+
{ method: "get", path: "/reference/company-sizes", id: "listCompanySizes", scope: "", retry: "none" },
|
|
150
|
+
{ method: "get", path: "/reference/lead-types", id: "listLeadTypes", scope: "", retry: "none" },
|
|
151
|
+
{ method: "get", path: "/lead-requests", id: "listLeadRequests", scope: "lead_requests:read", retry: "none" },
|
|
152
|
+
{ method: "post", path: "/lead-requests", id: "createLeadRequest", scope: "lead_requests:write", additionalScopes: ["leads:read"], retry: "header" },
|
|
153
|
+
{ method: "get", path: "/lead-requests/:id", id: "getLeadRequest", scope: "lead_requests:read", retry: "none" },
|
|
154
|
+
{ method: "post", path: "/company-requests", id: "createCompanyRequest", scope: "company_requests:write", additionalScopes: ["company_requests:read"], retry: "header" },
|
|
155
|
+
{ method: "get", path: "/company-requests/:id", id: "getCompanyRequest", scope: "company_requests:read", retry: "none" }
|
|
156
|
+
];
|
|
157
|
+
var CLIENT_OPERATIONS = [...WORKSPACE_OPERATIONS, ...LEGACY_API_OPERATIONS.map((operation) => ({ ...operation, group: "legacy", nativePath: operation.path }))];
|
|
158
|
+
|
|
159
|
+
// shared/leadpoet-client.ts
|
|
160
|
+
var LeadpoetError = class extends Error {
|
|
161
|
+
constructor(message, status, code, requestId, details, retryAfterSeconds) {
|
|
162
|
+
super(message);
|
|
163
|
+
this.status = status;
|
|
164
|
+
this.code = code;
|
|
165
|
+
this.requestId = requestId;
|
|
166
|
+
this.details = details;
|
|
167
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
168
|
+
this.name = "LeadpoetError";
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
var object = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
172
|
+
var keyRequired = (retry) => ["header", "header_uuid", "operation_id", "request_id", "body"].includes(retry);
|
|
173
|
+
var operations = CLIENT_OPERATIONS.map(({ nativePath: _native, group: _group, ...operation }) => operation);
|
|
174
|
+
var LeadpoetClient = class {
|
|
175
|
+
#apiKey;
|
|
176
|
+
constructor(options) {
|
|
177
|
+
const url = new URL(options.baseUrl);
|
|
178
|
+
if (url.username || url.password || url.search || url.hash || !(url.protocol === "https:" || url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))) {
|
|
179
|
+
throw new Error("Use an HTTPS API base URL, or HTTP on localhost; credentials, query strings and fragments are forbidden");
|
|
180
|
+
}
|
|
181
|
+
if (url.pathname.replace(/\/$/, "") !== "/api/v1") throw new Error("The API base URL must end in /api/v1");
|
|
182
|
+
if (!options.apiKey || /\s/.test(options.apiKey)) throw new LeadpoetError("Set LEADPOET_API_KEY to a valid API key", 401, "authentication_required");
|
|
183
|
+
this.baseUrl = url.href.replace(/\/$/, "");
|
|
184
|
+
this.#apiKey = options.apiKey;
|
|
185
|
+
this.fetcher = options.fetch ?? fetch;
|
|
186
|
+
this.timeoutMs = options.timeoutMs ?? 3e4;
|
|
187
|
+
if (!Number.isSafeInteger(this.timeoutMs) || this.timeoutMs < 1 || this.timeoutMs > 3e5) throw new Error("timeoutMs must be an integer between 1 and 300000");
|
|
188
|
+
}
|
|
189
|
+
async openapi(signal) {
|
|
190
|
+
const { value: result, requestId } = await this.request("/openapi.json", "GET", void 0, void 0, signal);
|
|
191
|
+
if (!object(result) || !object(result.paths)) throw new LeadpoetError("Invalid OpenAPI response", 502, "invalid_response", requestId);
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
async call(operationId, input = {}) {
|
|
195
|
+
const operation = CLIENT_OPERATIONS.find((item) => item.id === operationId);
|
|
196
|
+
if (!operation) throw new Error("Unknown operation; use operations to discover supported calls");
|
|
197
|
+
if (requiredScopes(operation, input.body).includes("outreach:send") && input.allowSend !== true) throw new Error("This operation authorizes delivery; explicit allowSend is required");
|
|
198
|
+
const expected = [...operation.path.matchAll(/:([A-Za-z]+)/g)].map((match) => match[1]);
|
|
199
|
+
if (Object.keys(input.params ?? {}).some((name) => !expected.includes(name))) throw new Error("Unexpected path parameter");
|
|
200
|
+
let path = operation.path;
|
|
201
|
+
for (const name of expected) {
|
|
202
|
+
const value = input.params?.[name];
|
|
203
|
+
if (!value || !/^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i.test(value)) throw new Error(`Expected UUID parameter: ${name}`);
|
|
204
|
+
path = path.replace(`:${name}`, encodeURIComponent(value));
|
|
205
|
+
}
|
|
206
|
+
if (keyRequired(operation.retry) && !input.idempotencyKey) throw new Error("This operation requires a persisted idempotencyKey");
|
|
207
|
+
if (input.idempotencyKey && !/^[A-Za-z0-9._:-]{8,160}$/.test(input.idempotencyKey)) throw new Error("Invalid idempotencyKey");
|
|
208
|
+
if (operation.method === "get" && input.body !== void 0) throw new Error("Read operations do not accept a body");
|
|
209
|
+
const query = new URLSearchParams();
|
|
210
|
+
for (const [name, value] of Object.entries(input.query ?? {})) {
|
|
211
|
+
if (Array.isArray(value)) for (const item of value) query.append(name, item);
|
|
212
|
+
else query.set(name, String(value));
|
|
213
|
+
}
|
|
214
|
+
if (query.size) path += `?${query}`;
|
|
215
|
+
const { value: result, requestId } = await this.request(path, operation.method.toUpperCase(), input.body, input.idempotencyKey, input.signal, operation.group === "legacy");
|
|
216
|
+
if (!object(result) || !("data" in result) || typeof result.request_id !== "string") throw new LeadpoetError("Invalid API response", 502, "invalid_response", requestId);
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
/** Bounded paging for the request history contract. Other cursors are operation-specific. */
|
|
220
|
+
async *requestPages(options = {}) {
|
|
221
|
+
const max = options.maxPages ?? 100;
|
|
222
|
+
if (!Number.isInteger(max) || max < 1 || max > 1e3) throw new Error("maxPages must be between 1 and 1000");
|
|
223
|
+
const start = options.page ?? 1, limit = options.limit ?? 25;
|
|
224
|
+
if (!Number.isInteger(start) || start < 1 || start > 1e5 || !Number.isInteger(limit) || limit < 1 || limit > 100) throw new Error("Invalid request pagination bounds");
|
|
225
|
+
for (let page = start, count = 0; count < max; page++, count++) {
|
|
226
|
+
const result = await this.call("listRequests", { query: { page, limit }, signal: options.signal });
|
|
227
|
+
if (!object(result.data) || typeof result.data.total !== "number" || !Number.isSafeInteger(result.data.total) || result.data.total < 0 || !Array.isArray(result.data.queries)) {
|
|
228
|
+
throw new LeadpoetError("Invalid request pagination metadata", 502, "invalid_response", result.request_id);
|
|
229
|
+
}
|
|
230
|
+
yield result;
|
|
231
|
+
if (page * limit >= result.data.total) return;
|
|
232
|
+
}
|
|
233
|
+
throw new LeadpoetError("Pagination limit reached; resume from the last page", 0, "pagination_limit");
|
|
234
|
+
}
|
|
235
|
+
async waitForRequest(id, options = {}) {
|
|
236
|
+
const timeout = options.timeoutMs ?? 3e5, interval = options.intervalMs ?? 2e3;
|
|
237
|
+
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 36e5 || !Number.isSafeInteger(interval) || interval < 1 || interval > 36e5) throw new Error("Invalid polling bounds");
|
|
238
|
+
const signal = AbortSignal.any([AbortSignal.timeout(timeout), ...options.signal ? [options.signal] : []]);
|
|
239
|
+
while (true) {
|
|
240
|
+
const result = await this.call("getRequest", { params: { id }, signal });
|
|
241
|
+
if (!object(result.data) || typeof result.data.status !== "string" || !result.data.status.trim()) {
|
|
242
|
+
throw new LeadpoetError("Invalid request status response", 502, "invalid_response", result.request_id);
|
|
243
|
+
}
|
|
244
|
+
if (["ready", "error", "completed", "failed", "cancelled", "canceled"].includes(String(result.data.status))) return result;
|
|
245
|
+
if (!["pending", "processing"].includes(result.data.status)) {
|
|
246
|
+
throw new LeadpoetError("Invalid request status response", 502, "invalid_response", result.request_id);
|
|
247
|
+
}
|
|
248
|
+
await new Promise((resolve, reject) => {
|
|
249
|
+
const onAbort = () => {
|
|
250
|
+
clearTimeout(timer);
|
|
251
|
+
reject(signal.reason);
|
|
252
|
+
};
|
|
253
|
+
const timer = setTimeout(() => {
|
|
254
|
+
signal.removeEventListener("abort", onAbort);
|
|
255
|
+
resolve();
|
|
256
|
+
}, interval);
|
|
257
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
258
|
+
if (signal.aborted) onAbort();
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async request(path, method, body, idempotencyKey, signal, wrapLegacy = false) {
|
|
263
|
+
const deadline = AbortSignal.any([AbortSignal.timeout(this.timeoutMs), ...signal ? [signal] : []]);
|
|
264
|
+
const response = await this.fetcher(this.baseUrl + path, {
|
|
265
|
+
method,
|
|
266
|
+
redirect: "error",
|
|
267
|
+
credentials: "omit",
|
|
268
|
+
headers: { Authorization: `Bearer ${this.#apiKey}`, Accept: "application/json", ...body ? { "Content-Type": "application/json" } : {}, ...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {} },
|
|
269
|
+
...body ? { body: JSON.stringify(body) } : {},
|
|
270
|
+
signal: deadline
|
|
271
|
+
});
|
|
272
|
+
const retry = response.headers.get("retry-after");
|
|
273
|
+
const seconds = retry ? /^\d+$/.test(retry) ? Number(retry) : Math.max(0, Math.ceil((Date.parse(retry) - Date.now()) / 1e3)) : void 0;
|
|
274
|
+
const retryAfterSeconds = Number.isFinite(seconds) ? seconds : void 0;
|
|
275
|
+
let value;
|
|
276
|
+
let cancelBody = () => {
|
|
277
|
+
};
|
|
278
|
+
try {
|
|
279
|
+
value = await new Promise((resolve, reject) => {
|
|
280
|
+
cancelBody = () => reject(deadline.reason);
|
|
281
|
+
deadline.addEventListener("abort", cancelBody, { once: true });
|
|
282
|
+
if (deadline.aborted) {
|
|
283
|
+
cancelBody();
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
response.json().then(resolve, reject);
|
|
287
|
+
});
|
|
288
|
+
} catch {
|
|
289
|
+
deadline.throwIfAborted();
|
|
290
|
+
throw new LeadpoetError("The API returned a non-JSON response", response.ok ? 502 : response.status, "invalid_response", response.headers.get("x-request-id") ?? void 0, void 0, retryAfterSeconds);
|
|
291
|
+
} finally {
|
|
292
|
+
deadline.removeEventListener("abort", cancelBody);
|
|
293
|
+
}
|
|
294
|
+
if (!response.ok) {
|
|
295
|
+
const error = object(value) && object(value.error) ? value.error : {};
|
|
296
|
+
throw new LeadpoetError(
|
|
297
|
+
typeof error.message === "string" ? error.message : "API request failed",
|
|
298
|
+
response.status,
|
|
299
|
+
typeof error.code === "string" ? error.code : "request_failed",
|
|
300
|
+
typeof error.request_id === "string" ? error.request_id : response.headers.get("x-request-id") ?? void 0,
|
|
301
|
+
error.details,
|
|
302
|
+
retryAfterSeconds
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
const requestId = response.headers.get("x-request-id") ?? void 0;
|
|
306
|
+
return { value: wrapLegacy ? { data: value, request_id: requestId ?? "" } : value, requestId };
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// scripts/leadpoet.ts
|
|
311
|
+
var help = `Leadpoet \u2014 Lead engine, Pipeline and Outreach
|
|
312
|
+
|
|
313
|
+
leadpoet operations
|
|
314
|
+
leadpoet describe <operation>
|
|
315
|
+
leadpoet call <operation> [--params '{"id":"..."}'] [--query '{"limit":25}']
|
|
316
|
+
[--input body.json | --input -] [--idempotency-key persisted-key] [--allow-send]
|
|
317
|
+
leadpoet wait <request-uuid> [--timeout 300]
|
|
318
|
+
|
|
319
|
+
Set LEADPOET_API_KEY and LEADPOET_API_BASE (HTTPS URL ending in /api/v1).
|
|
320
|
+
Output is JSON. Exit codes: 0 success, 1 transport/server, 2 invalid input,
|
|
321
|
+
3 credentials/permission, 4 conflict, 5 rate limit, 6 pending/failed request, 130 interrupted.
|
|
322
|
+
Writes are never automatically retried. Keep the same key and body on retry.
|
|
323
|
+
`;
|
|
324
|
+
var parseObject = (text) => {
|
|
325
|
+
let value;
|
|
326
|
+
try {
|
|
327
|
+
value = JSON.parse(text);
|
|
328
|
+
} catch {
|
|
329
|
+
throw new Error("Invalid JSON input; provide a JSON object");
|
|
330
|
+
}
|
|
331
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Expected a JSON object");
|
|
332
|
+
return value;
|
|
333
|
+
};
|
|
334
|
+
async function readCliBody(input, signal) {
|
|
335
|
+
signal.throwIfAborted();
|
|
336
|
+
const abort = () => input.destroy(signal.reason);
|
|
337
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
338
|
+
try {
|
|
339
|
+
const chunks = [];
|
|
340
|
+
let size = 0;
|
|
341
|
+
for await (const chunk of input) {
|
|
342
|
+
const bytes = Buffer.from(chunk);
|
|
343
|
+
size += bytes.length;
|
|
344
|
+
if (size > 256 * 1024) throw new Error("Request body exceeds 256 KiB");
|
|
345
|
+
chunks.push(bytes);
|
|
346
|
+
}
|
|
347
|
+
signal.throwIfAborted();
|
|
348
|
+
return parseObject(Buffer.concat(chunks).toString("utf8"));
|
|
349
|
+
} finally {
|
|
350
|
+
signal.removeEventListener("abort", abort);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
async function runCli(args, io, env = process.env) {
|
|
354
|
+
try {
|
|
355
|
+
const { values, positionals } = parseArgs({ args, allowPositionals: true, strict: true, options: {
|
|
356
|
+
help: { type: "boolean", short: "h" },
|
|
357
|
+
params: { type: "string" },
|
|
358
|
+
query: { type: "string" },
|
|
359
|
+
input: { type: "string" },
|
|
360
|
+
"idempotency-key": { type: "string" },
|
|
361
|
+
"allow-send": { type: "boolean" },
|
|
362
|
+
timeout: { type: "string" }
|
|
363
|
+
} });
|
|
364
|
+
if (values.help || !positionals.length) {
|
|
365
|
+
io.out(help);
|
|
366
|
+
return 0;
|
|
367
|
+
}
|
|
368
|
+
const [command, id] = positionals;
|
|
369
|
+
if (positionals.length > (command === "operations" ? 1 : 2)) throw new Error("Extra arguments are not supported; use --help");
|
|
370
|
+
const allowedOptions = command === "call" ? ["params", "query", "input", "idempotency-key", "allow-send"] : command === "wait" ? ["timeout"] : [];
|
|
371
|
+
if (Object.keys(values).some((option) => option !== "help" && !allowedOptions.includes(option))) {
|
|
372
|
+
throw new Error("These options are not supported by this command; use --help");
|
|
373
|
+
}
|
|
374
|
+
if (command === "operations") {
|
|
375
|
+
io.out(JSON.stringify(operations, null, 2));
|
|
376
|
+
return 0;
|
|
377
|
+
}
|
|
378
|
+
if (!["describe", "call", "wait"].includes(command) || !id) throw new Error("Choose describe, call, or wait and an operation or request ID");
|
|
379
|
+
const operation = operations.find((item) => item.id === id);
|
|
380
|
+
if (command !== "wait" && !operation) throw new Error("Unknown operation; run leadpoet operations");
|
|
381
|
+
const client = new LeadpoetClient({ baseUrl: env.LEADPOET_API_BASE ?? "https://leadpoet.com/api/v1", apiKey: env.LEADPOET_API_KEY ?? "" });
|
|
382
|
+
const controller = new AbortController();
|
|
383
|
+
const abort = () => controller.abort(new DOMException("Interrupted; writes may have committed. Keep the original retry key.", "AbortError"));
|
|
384
|
+
process.once("SIGINT", abort);
|
|
385
|
+
try {
|
|
386
|
+
if (command === "describe") {
|
|
387
|
+
const spec = await client.openapi(controller.signal);
|
|
388
|
+
const paths = spec.paths;
|
|
389
|
+
const path = operation.path.replace(/:([A-Za-z]+)/g, "{$1}");
|
|
390
|
+
const contract = paths[path]?.[operation.method];
|
|
391
|
+
if (!contract) throw new Error("This deployment does not expose this operation");
|
|
392
|
+
io.out(JSON.stringify({ operation: contract, components: spec.components ?? {} }, null, 2));
|
|
393
|
+
return 0;
|
|
394
|
+
}
|
|
395
|
+
if (command === "wait") {
|
|
396
|
+
const result2 = await client.waitForRequest(id, { timeoutMs: Number(values.timeout ?? 300) * 1e3, signal: controller.signal });
|
|
397
|
+
io.out(JSON.stringify(result2, null, 2));
|
|
398
|
+
return ["ready", "completed"].includes(String(result2.data.status)) ? 0 : 6;
|
|
399
|
+
}
|
|
400
|
+
const params = values.params ? parseObject(values.params) : void 0;
|
|
401
|
+
if (params && Object.values(params).some((value) => typeof value !== "string")) throw new Error("Path parameter values must be strings");
|
|
402
|
+
const query = values.query ? parseObject(values.query) : void 0;
|
|
403
|
+
if (query && Object.values(query).some((value) => value === null || typeof value === "object" && !(Array.isArray(value) && value.every((item) => typeof item === "string")))) throw new Error("Query values must be scalars or string arrays");
|
|
404
|
+
let body;
|
|
405
|
+
if (values.input) {
|
|
406
|
+
body = await readCliBody(values.input === "-" ? process.stdin : createReadStream(values.input), controller.signal);
|
|
407
|
+
}
|
|
408
|
+
const result = await client.call(id, {
|
|
409
|
+
params,
|
|
410
|
+
query,
|
|
411
|
+
body,
|
|
412
|
+
idempotencyKey: values["idempotency-key"],
|
|
413
|
+
allowSend: values["allow-send"],
|
|
414
|
+
signal: controller.signal
|
|
415
|
+
});
|
|
416
|
+
io.out(JSON.stringify(result, null, 2));
|
|
417
|
+
return 0;
|
|
418
|
+
} finally {
|
|
419
|
+
process.removeListener("SIGINT", abort);
|
|
420
|
+
}
|
|
421
|
+
} catch (error) {
|
|
422
|
+
const known = error instanceof LeadpoetError;
|
|
423
|
+
const code = known ? error.code : error instanceof Error && error.name === "TimeoutError" ? "timeout" : error instanceof Error && error.name === "AbortError" ? "interrupted" : "client_error";
|
|
424
|
+
io.err(JSON.stringify({ error: { code, message: known ? error.message : error instanceof Error ? error.message : "Request failed", ...known ? { status: error.status, request_id: error.requestId, details: error.details, retry_after_seconds: error.retryAfterSeconds } : {} } }));
|
|
425
|
+
if (known) return [401, 403].includes(error.status) ? 3 : error.status === 409 ? 4 : error.status === 429 ? 5 : error.status >= 500 ? 1 : 2;
|
|
426
|
+
return code === "interrupted" ? 130 : code === "timeout" ? 6 : error instanceof TypeError ? 1 : 2;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (process.argv[1] && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
430
|
+
process.exitCode = await runCli(process.argv.slice(2), { out: (text) => process.stdout.write(text + "\n"), err: (text) => process.stderr.write(text + "\n") });
|
|
431
|
+
}
|
|
432
|
+
export {
|
|
433
|
+
readCliBody,
|
|
434
|
+
runCli
|
|
435
|
+
};
|
|
436
|
+
//# sourceMappingURL=cli.js.map
|