rankcontrol 0.2.0 → 0.7.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/LICENSE +1 -1
- package/README.md +182 -10
- package/package.json +1 -1
- package/src/cli.mjs +648 -5
- package/src/client.mjs +135 -0
- package/src/login.mjs +11 -2
- package/src/mcp.mjs +734 -2
package/src/client.mjs
CHANGED
|
@@ -87,6 +87,14 @@ export const api = {
|
|
|
87
87
|
overviewFunnel: () => request("GET", "/api/v1/overview/funnel"),
|
|
88
88
|
visibilityTrend: (days = 30) =>
|
|
89
89
|
request("GET", `/api/v1/visibility/trend?days=${days}`),
|
|
90
|
+
shareOfVoice: (days = 30) =>
|
|
91
|
+
request("GET", `/api/v1/visibility/share-of-voice?days=${days}`),
|
|
92
|
+
citationSources: (days = 30) =>
|
|
93
|
+
request("GET", `/api/v1/visibility/sources?days=${days}`),
|
|
94
|
+
citationSentiment: (days = 30) =>
|
|
95
|
+
request("GET", `/api/v1/visibility/sentiment?days=${days}`),
|
|
96
|
+
optimizer: (limit = 25) =>
|
|
97
|
+
request("GET", `/api/v1/content/optimizer?limit=${limit}`),
|
|
90
98
|
citations: (params = {}) => {
|
|
91
99
|
const q = new URLSearchParams();
|
|
92
100
|
if (params.model) q.set("model", params.model);
|
|
@@ -103,4 +111,131 @@ export const api = {
|
|
|
103
111
|
request("POST", "/api/v1/content/plan/commit", opts),
|
|
104
112
|
publishContent: (contentId, confirm = false) =>
|
|
105
113
|
request("POST", "/api/v1/content/publish", { contentId, confirm }),
|
|
114
|
+
generateContent: (contentId, confirm = false) =>
|
|
115
|
+
request("POST", "/api/v1/content/generate", { contentId, confirm }),
|
|
116
|
+
shopifyInstallUrl: (shop) =>
|
|
117
|
+
request("POST", "/api/v1/integrations/shopify/install-url", { shop }),
|
|
118
|
+
internalLinks: (contentId) =>
|
|
119
|
+
request(
|
|
120
|
+
"GET",
|
|
121
|
+
`/api/v1/content/internal-links?contentId=${encodeURIComponent(contentId)}`
|
|
122
|
+
),
|
|
123
|
+
articleSettings: () => request("GET", "/api/v1/settings/articles"),
|
|
124
|
+
updateArticleSettings: (opts) =>
|
|
125
|
+
request("POST", "/api/v1/settings/articles", opts),
|
|
126
|
+
reschedule: (contentId, targetDayStartMs) =>
|
|
127
|
+
request("POST", "/api/v1/content/reschedule", { contentId, targetDayStartMs }),
|
|
128
|
+
sitePages: () => request("GET", "/api/v1/links/pages"),
|
|
129
|
+
detectSiteLinks: (source, url) =>
|
|
130
|
+
request("POST", "/api/v1/links/detect", { source, url }),
|
|
131
|
+
addSitePages: (urls) => request("POST", "/api/v1/links/pages", { urls }),
|
|
132
|
+
leads: (limit = 100) => request("GET", `/api/v1/leads?limit=${limit}`),
|
|
133
|
+
repurposeQueue: () => request("GET", "/api/v1/repurpose"),
|
|
134
|
+
repurposeDrafts: (contentId) =>
|
|
135
|
+
request(
|
|
136
|
+
"GET",
|
|
137
|
+
`/api/v1/repurpose?contentId=${encodeURIComponent(contentId)}`
|
|
138
|
+
),
|
|
139
|
+
repurposeChannels: () => request("GET", "/api/v1/repurpose/channels"),
|
|
140
|
+
repurposeGenerate: (opts) =>
|
|
141
|
+
request("POST", "/api/v1/repurpose/generate", opts),
|
|
142
|
+
repurposeEditDraft: (opts) => request("POST", "/api/v1/repurpose/draft", opts),
|
|
143
|
+
repurposeMarkPosted: (draftId) =>
|
|
144
|
+
request("POST", "/api/v1/repurpose/mark-posted", { draftId }),
|
|
145
|
+
repurposePush: (opts) => request("POST", "/api/v1/repurpose/push", opts),
|
|
146
|
+
trackedQueries: () => request("GET", "/api/v1/queries"),
|
|
147
|
+
addQuery: (queryText) => request("POST", "/api/v1/queries", { queryText }),
|
|
148
|
+
removeQuery: (queryId) =>
|
|
149
|
+
request("POST", "/api/v1/queries/remove", { queryId }),
|
|
150
|
+
setQueryTracking: (queryId, tracked) =>
|
|
151
|
+
request("POST", "/api/v1/queries/set-tracking", { queryId, tracked }),
|
|
152
|
+
updateQuery: (queryId, queryText) =>
|
|
153
|
+
request("POST", "/api/v1/queries/update", { queryId, queryText }),
|
|
154
|
+
competitors: () => request("GET", "/api/v1/competitors"),
|
|
155
|
+
addCompetitor: (name, websiteUrl) =>
|
|
156
|
+
request("POST", "/api/v1/competitors", { name, websiteUrl }),
|
|
157
|
+
removeCompetitor: (competitorId) =>
|
|
158
|
+
request("POST", "/api/v1/competitors/remove", { competitorId }),
|
|
159
|
+
topics: () => request("GET", "/api/v1/topics"),
|
|
160
|
+
setTopics: (topics) => request("POST", "/api/v1/topics", { topics }),
|
|
161
|
+
deletePlanned: (contentId) =>
|
|
162
|
+
request("POST", "/api/v1/content/delete-planned", { contentId }),
|
|
163
|
+
crawlerAccess: () => request("GET", "/api/v1/crawler-access"),
|
|
164
|
+
trafficOverview: (days = 30) =>
|
|
165
|
+
request("GET", `/api/v1/analytics/traffic?days=${days}`),
|
|
166
|
+
analyticsSources: () => request("GET", "/api/v1/analytics/sources"),
|
|
167
|
+
setAnalyticsSource: (dataType, source) =>
|
|
168
|
+
request("POST", "/api/v1/analytics/sources", { dataType, source }),
|
|
169
|
+
activateScreen: (screen) =>
|
|
170
|
+
request("POST", "/api/v1/analytics/activate", { screen }),
|
|
171
|
+
cloudflareConnectUrl: () =>
|
|
172
|
+
request("POST", "/api/v1/integrations/cloudflare/connect-url"),
|
|
173
|
+
cloudflareZones: () =>
|
|
174
|
+
request("GET", "/api/v1/integrations/cloudflare/zones"),
|
|
175
|
+
cloudflareSelectZone: (zoneId, zoneName) =>
|
|
176
|
+
request("POST", "/api/v1/integrations/cloudflare/zone", { zoneId, zoneName }),
|
|
177
|
+
framerInstallEmbed: (opts = {}) =>
|
|
178
|
+
request("POST", "/api/v1/integrations/framer/install-embed", opts),
|
|
179
|
+
webflowInstallCustomCode: (opts = {}) =>
|
|
180
|
+
request("POST", "/api/v1/integrations/webflow/custom-code", opts),
|
|
181
|
+
team: () => request("GET", "/api/v1/team"),
|
|
182
|
+
teamInvite: (opts) => request("POST", "/api/v1/team/invite", opts),
|
|
183
|
+
teamRevoke: (invitationId) =>
|
|
184
|
+
request("POST", "/api/v1/team/revoke", { invitationId }),
|
|
185
|
+
teamRemove: (opts) => request("POST", "/api/v1/team/remove", opts),
|
|
186
|
+
outreachProspects: () => request("GET", "/api/v1/outreach/prospects"),
|
|
187
|
+
outreachFindContact: (backlinkId) =>
|
|
188
|
+
request("POST", "/api/v1/outreach/find-contact", { backlinkId }),
|
|
189
|
+
outreachQueue: (opts) => request("POST", "/api/v1/outreach/queue", opts),
|
|
190
|
+
outreachDraftReply: (backlinkId) =>
|
|
191
|
+
request("POST", "/api/v1/outreach/draft-reply", { backlinkId }),
|
|
192
|
+
contentIdeas: () => request("GET", "/api/v1/content/ideas"),
|
|
193
|
+
planIdea: (opts) => request("POST", "/api/v1/content/ideas/plan", opts),
|
|
194
|
+
archiveContent: (contentId) =>
|
|
195
|
+
request("POST", "/api/v1/content/archive", { contentId }),
|
|
196
|
+
pageEngagement: () => request("GET", "/api/v1/analytics/engagement"),
|
|
197
|
+
reportSummary: () => request("GET", "/api/v1/reports/summary"),
|
|
198
|
+
reportWins: () => request("GET", "/api/v1/reports/wins"),
|
|
199
|
+
agentActivity: (params = {}) => {
|
|
200
|
+
const q = new URLSearchParams();
|
|
201
|
+
if (params.perAgent) q.set("perAgent", String(params.perAgent));
|
|
202
|
+
if (params.sinceDays) q.set("sinceDays", String(params.sinceDays));
|
|
203
|
+
const qs = q.toString();
|
|
204
|
+
return request("GET", `/api/v1/reports/agent-activity${qs ? `?${qs}` : ""}`);
|
|
205
|
+
},
|
|
206
|
+
backlinks: (status) =>
|
|
207
|
+
request(
|
|
208
|
+
"GET",
|
|
209
|
+
`/api/v1/backlinks${status ? `?status=${encodeURIComponent(status)}` : ""}`
|
|
210
|
+
),
|
|
211
|
+
backlinkStats: () => request("GET", "/api/v1/backlinks/stats"),
|
|
212
|
+
outreachStatus: (backlinkId, status) =>
|
|
213
|
+
request("POST", "/api/v1/outreach/status", { backlinkId, status }),
|
|
214
|
+
linkNetwork: () => request("GET", "/api/v1/link-network"),
|
|
215
|
+
linkNetworkOptIn: (optIn, confirm = false) =>
|
|
216
|
+
request("POST", "/api/v1/link-network/opt-in", { optIn, confirm }),
|
|
217
|
+
linkNetworkRemovePlacement: (placementId, confirm = false) =>
|
|
218
|
+
request("POST", "/api/v1/link-network/remove-placement", {
|
|
219
|
+
placementId,
|
|
220
|
+
confirm,
|
|
221
|
+
}),
|
|
222
|
+
socialThreads: (params = {}) => {
|
|
223
|
+
const q = new URLSearchParams();
|
|
224
|
+
if (params.platform) q.set("platform", params.platform);
|
|
225
|
+
if (params.status) q.set("status", params.status);
|
|
226
|
+
if (params.age) q.set("age", params.age);
|
|
227
|
+
const qs = q.toString();
|
|
228
|
+
return request("GET", `/api/v1/social${qs ? `?${qs}` : ""}`);
|
|
229
|
+
},
|
|
230
|
+
socialStats: () => request("GET", "/api/v1/social/stats"),
|
|
231
|
+
socialStatus: (threadId, status) =>
|
|
232
|
+
request("POST", "/api/v1/social/status", { threadId, status }),
|
|
233
|
+
socialDraftReply: (threadId, mentionMode) =>
|
|
234
|
+
request("POST", "/api/v1/social/draft-reply", { threadId, mentionMode }),
|
|
235
|
+
support: (opts) => request("POST", "/api/v1/support", opts),
|
|
236
|
+
brand: () => request("GET", "/api/v1/brand"),
|
|
237
|
+
brandIdentitySet: (opts) => request("POST", "/api/v1/brand", opts),
|
|
238
|
+
brandProfileSet: (opts) => request("POST", "/api/v1/brand/profile", opts),
|
|
239
|
+
brandProductWrite: (opts) => request("POST", "/api/v1/brand/product", opts),
|
|
240
|
+
brandIcpWrite: (opts) => request("POST", "/api/v1/brand/icp", opts),
|
|
106
241
|
};
|
package/src/login.mjs
CHANGED
|
@@ -6,13 +6,22 @@ import {
|
|
|
6
6
|
deleteStoredConfig,
|
|
7
7
|
} from "./client.mjs";
|
|
8
8
|
|
|
9
|
+
// Owner self-connection gets every grantable scope (server grants the full
|
|
10
|
+
// set on approval regardless; "admin" keys are minted in Settings only).
|
|
9
11
|
const DEFAULT_SCOPES = [
|
|
10
12
|
"read:citations",
|
|
11
13
|
"read:content",
|
|
12
14
|
"read:leads",
|
|
13
15
|
"read:analytics",
|
|
14
16
|
"write:content",
|
|
17
|
+
"write:queries",
|
|
18
|
+
"write:leads",
|
|
19
|
+
"write:backlinks",
|
|
20
|
+
"write:social",
|
|
15
21
|
"write:publish",
|
|
22
|
+
"manage:integrations",
|
|
23
|
+
"manage:org",
|
|
24
|
+
"trigger:agents",
|
|
16
25
|
];
|
|
17
26
|
|
|
18
27
|
function openBrowser(url) {
|
|
@@ -31,9 +40,9 @@ function openBrowser(url) {
|
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
|
|
34
|
-
export async function login(
|
|
43
|
+
export async function login() {
|
|
35
44
|
const { baseUrl, appUrl } = getBaseUrls();
|
|
36
|
-
const requested =
|
|
45
|
+
const requested = DEFAULT_SCOPES;
|
|
37
46
|
|
|
38
47
|
const startRes = await fetch(`${baseUrl}/api/v1/auth/device/start`, {
|
|
39
48
|
method: "POST",
|