x-developer 2.6.7 → 2.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.
Files changed (160) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/.claude-plugin/plugin.json +2 -27
  3. package/.codex-plugin/plugin.json +4 -28
  4. package/README.de.md +505 -0
  5. package/README.es.md +504 -0
  6. package/README.fr.md +507 -0
  7. package/README.it.md +499 -0
  8. package/README.ja.md +493 -0
  9. package/README.ko.md +494 -0
  10. package/README.md +486 -123
  11. package/README.tr.md +502 -0
  12. package/README.zh-CN.md +484 -0
  13. package/assets/logo-400.png +0 -0
  14. package/commands/post.md +2 -2
  15. package/commands/search.md +1 -1
  16. package/commands/trending.md +1 -1
  17. package/commands/user.md +1 -1
  18. package/context7.json +5 -11
  19. package/docker-mcp-registry/xquik/readme.md +1 -0
  20. package/docker-mcp-registry/xquik/server.yaml +23 -0
  21. package/docker-mcp-registry/xquik/tools.json +1 -0
  22. package/glama.json +4 -0
  23. package/mcp.json +9 -0
  24. package/openclaw.plugin.json +2 -2
  25. package/package.json +24 -20
  26. package/plugin.json +22 -0
  27. package/registry.json +60 -0
  28. package/server.json +2 -2
  29. package/skills/x-twitter-scraper/LICENSE +21 -0
  30. package/skills/x-twitter-scraper/SKILL.md +175 -457
  31. package/skills/x-twitter-scraper/metadata.json +19 -9
  32. package/skills/x-twitter-scraper/references/compare-faq.md +101 -0
  33. package/skills/x-twitter-scraper/references/extractions.md +65 -290
  34. package/skills/x-twitter-scraper/references/mcp.md +24 -0
  35. package/skills/x-twitter-scraper/references/monitors-webhooks.md +167 -0
  36. package/skills/x-twitter-scraper/references/reads.md +415 -0
  37. package/skills/x-twitter-scraper/references/writes.md +109 -0
  38. package/skills/xquik-mcp/SKILL.md +75 -0
  39. package/skills/{x-twitter-scraper → xquik-mcp}/references/mcp-setup.md +32 -108
  40. package/skills/xquik-social-research/SKILL.md +61 -74
  41. package/skills.sh.json +6 -68
  42. package/start.sh +2 -2
  43. package/stub-server.mjs +37 -86
  44. package/task-guides/check-mutuals.md +1 -1
  45. package/task-guides/clean-followers.md +2 -2
  46. package/task-guides/export-tweets-csv.md +1 -1
  47. package/task-guides/extract-followers.md +6 -6
  48. package/task-guides/find-bangers.md +1 -1
  49. package/task-guides/find-influencers.md +3 -3
  50. package/task-guides/find-viral-tweets.md +2 -2
  51. package/task-guides/follow-unfollow.md +3 -3
  52. package/task-guides/for-you-feed.md +2 -2
  53. package/task-guides/going-viral.md +5 -5
  54. package/task-guides/grow-followers.md +1 -1
  55. package/task-guides/monitor-accounts.md +4 -4
  56. package/task-guides/optimize-tweets.md +1 -1
  57. package/task-guides/post-tweets.md +6 -6
  58. package/task-guides/run-giveaway.md +4 -4
  59. package/task-guides/search-tweets.md +2 -2
  60. package/task-guides/send-dms.md +9 -9
  61. package/task-guides/top-replies.md +4 -4
  62. package/task-guides/track-competitors.md +6 -6
  63. package/task-guides/track-hashtags.md +7 -7
  64. package/task-guides/track-mentions.md +3 -3
  65. package/task-guides/trending-news.md +3 -3
  66. package/task-guides/tweet-analytics.md +2 -2
  67. package/task-guides/tweet-ideas.md +1 -1
  68. package/task-guides/tweet-replies.md +5 -5
  69. package/task-guides/tweet-style.md +2 -2
  70. package/task-guides/tweet-webhooks.md +3 -3
  71. package/task-guides/update-x-profile.md +4 -4
  72. package/task-guides/user-tweets.md +3 -3
  73. package/task-guides/who-liked.md +2 -2
  74. package/task-guides/who-quoted.md +2 -2
  75. package/task-guides/who-retweeted.md +2 -2
  76. package/task-guides/write-threads.md +4 -4
  77. package/task-guides/write-tweets.md +4 -4
  78. package/task-guides/x-articles.md +1 -1
  79. package/task-guides/x-bookmarks.md +3 -3
  80. package/task-guides/x-communities.md +2 -2
  81. package/task-guides/x-lists.md +3 -3
  82. package/task-guides/x-spaces.md +2 -2
  83. package/task-guides/x-trends.md +2 -2
  84. package/x-twitter-scraper.json +10 -0
  85. package/CHANGELOG.md +0 -94
  86. package/scripts/check-reproducible.mjs +0 -48
  87. package/scripts/check-versions.mjs +0 -24
  88. package/scripts/release-guard/content-policy.mjs +0 -410
  89. package/scripts/release-guard/context.mjs +0 -61
  90. package/scripts/release-guard/frontmatter.mjs +0 -151
  91. package/scripts/release-guard/policy-checks.mjs +0 -134
  92. package/scripts/release-guard/policy.mjs +0 -226
  93. package/scripts/release-guard/repository-checks.mjs +0 -256
  94. package/skills/x-twitter-scraper/references/api-endpoints-api-keys.md +0 -14
  95. package/skills/x-twitter-scraper/references/api-endpoints-compose.md +0 -33
  96. package/skills/x-twitter-scraper/references/api-endpoints-credits.md +0 -11
  97. package/skills/x-twitter-scraper/references/api-endpoints-drafts.md +0 -105
  98. package/skills/x-twitter-scraper/references/api-endpoints-draws.md +0 -101
  99. package/skills/x-twitter-scraper/references/api-endpoints-error-codes.md +0 -67
  100. package/skills/x-twitter-scraper/references/api-endpoints-events.md +0 -50
  101. package/skills/x-twitter-scraper/references/api-endpoints-extractions.md +0 -113
  102. package/skills/x-twitter-scraper/references/api-endpoints-monitors.md +0 -111
  103. package/skills/x-twitter-scraper/references/api-endpoints-radar.md +0 -50
  104. package/skills/x-twitter-scraper/references/api-endpoints-support.md +0 -53
  105. package/skills/x-twitter-scraper/references/api-endpoints-trends.md +0 -48
  106. package/skills/x-twitter-scraper/references/api-endpoints-tweet-style-cache.md +0 -186
  107. package/skills/x-twitter-scraper/references/api-endpoints-webhooks.md +0 -120
  108. package/skills/x-twitter-scraper/references/api-endpoints-x-accounts.md +0 -54
  109. package/skills/x-twitter-scraper/references/api-endpoints-x-api.md +0 -267
  110. package/skills/x-twitter-scraper/references/api-endpoints-x-media.md +0 -50
  111. package/skills/x-twitter-scraper/references/api-endpoints-x-write.md +0 -270
  112. package/skills/x-twitter-scraper/references/api-endpoints.md +0 -30
  113. package/skills/x-twitter-scraper/references/automate-twitter-giveaways.md +0 -130
  114. package/skills/x-twitter-scraper/references/best-x-api-alternative.md +0 -198
  115. package/skills/x-twitter-scraper/references/compare-twitter-apis.md +0 -151
  116. package/skills/x-twitter-scraper/references/draws.md +0 -57
  117. package/skills/x-twitter-scraper/references/export-twitter-followers.md +0 -127
  118. package/skills/x-twitter-scraper/references/extract-x-community-data.md +0 -121
  119. package/skills/x-twitter-scraper/references/mcp-tools.md +0 -183
  120. package/skills/x-twitter-scraper/references/monitor-twitter-webhooks.md +0 -121
  121. package/skills/x-twitter-scraper/references/python-examples.md +0 -201
  122. package/skills/x-twitter-scraper/references/reliable-twitter-data-api-2026.md +0 -239
  123. package/skills/x-twitter-scraper/references/scrape-export-twitter-data.md +0 -173
  124. package/skills/x-twitter-scraper/references/security.md +0 -111
  125. package/skills/x-twitter-scraper/references/track-twitter-keywords-mentions.md +0 -148
  126. package/skills/x-twitter-scraper/references/twitter-api-alternative-faq.md +0 -128
  127. package/skills/x-twitter-scraper/references/twitter-api-without-x-account.md +0 -110
  128. package/skills/x-twitter-scraper/references/twitter-data-pipeline.md +0 -136
  129. package/skills/x-twitter-scraper/references/twitter-scraper-api-guide.md +0 -229
  130. package/skills/x-twitter-scraper/references/types-account-identity.md +0 -9
  131. package/skills/x-twitter-scraper/references/types-account.md +0 -26
  132. package/skills/x-twitter-scraper/references/types-api-keys.md +0 -22
  133. package/skills/x-twitter-scraper/references/types-bookmarks-and-timeline.md +0 -46
  134. package/skills/x-twitter-scraper/references/types-credits.md +0 -11
  135. package/skills/x-twitter-scraper/references/types-download-media.md +0 -22
  136. package/skills/x-twitter-scraper/references/types-draws.md +0 -60
  137. package/skills/x-twitter-scraper/references/types-error.md +0 -29
  138. package/skills/x-twitter-scraper/references/types-events.md +0 -23
  139. package/skills/x-twitter-scraper/references/types-extractions.md +0 -136
  140. package/skills/x-twitter-scraper/references/types-mcp-output-schemas.md +0 -13
  141. package/skills/x-twitter-scraper/references/types-monitors.md +0 -49
  142. package/skills/x-twitter-scraper/references/types-radar.md +0 -47
  143. package/skills/x-twitter-scraper/references/types-request-bodies.md +0 -30
  144. package/skills/x-twitter-scraper/references/types-rest-api-vs-mcp-field-naming.md +0 -11
  145. package/skills/x-twitter-scraper/references/types-support.md +0 -46
  146. package/skills/x-twitter-scraper/references/types-trends.md +0 -21
  147. package/skills/x-twitter-scraper/references/types-tweet-drafts.md +0 -20
  148. package/skills/x-twitter-scraper/references/types-tweet-style-cache.md +0 -50
  149. package/skills/x-twitter-scraper/references/types-user-activity.md +0 -35
  150. package/skills/x-twitter-scraper/references/types-webhooks.md +0 -46
  151. package/skills/x-twitter-scraper/references/types-x-accounts.md +0 -16
  152. package/skills/x-twitter-scraper/references/types-x-api.md +0 -144
  153. package/skills/x-twitter-scraper/references/types-x-articles.md +0 -36
  154. package/skills/x-twitter-scraper/references/types-x-write.md +0 -78
  155. package/skills/x-twitter-scraper/references/types.md +0 -31
  156. package/skills/x-twitter-scraper/references/usage.md +0 -50
  157. package/skills/x-twitter-scraper/references/webhooks.md +0 -321
  158. package/skills/x-twitter-scraper/references/workflows.md +0 -215
  159. package/skills/x-twitter-scraper/skill-card.md +0 -84
  160. package/skills/x-twitter-scraper/skillspector-report.md +0 -20
@@ -1,134 +0,0 @@
1
- // SPDX-FileCopyrightText: 2026 Xquik Contributors
2
- // SPDX-License-Identifier: MIT
3
-
4
- import { readdirSync } from "node:fs";
5
- import { join } from "node:path";
6
-
7
- import { contentChecks } from "./content-policy.mjs";
8
- import {
9
- expected,
10
- asArray,
11
- readJson,
12
- readText,
13
- root,
14
- taskGuideNames,
15
- taskGuidePaths,
16
- } from "./context.mjs";
17
- import { collectFrontmatterDrifts } from "./frontmatter.mjs";
18
- import {
19
- skillFrontmatterExpectations,
20
- taskGuideFrontmatterExpectations,
21
- versionSurfaces,
22
- } from "./policy.mjs";
23
-
24
- function collectVersionDrifts() {
25
- const drifts = [];
26
- for (const surface of versionSurfaces) {
27
- const raw = readText(surface.path);
28
- for (const version of asArray(surface.get(raw))) {
29
- if (version !== expected) {
30
- drifts.push(
31
- ` ${surface.path}: ${version ?? "<missing>"} (expected ${expected})`,
32
- );
33
- }
34
- }
35
- }
36
- return drifts;
37
- }
38
-
39
- function collectContentDrifts() {
40
- const drifts = [];
41
- for (const check of contentChecks) {
42
- const raw = readText(check.path);
43
- for (const required of check.required) {
44
- if (!raw.includes(required)) {
45
- drifts.push(` ${check.path}: missing "${required}"`);
46
- }
47
- }
48
- for (const forbidden of check.forbidden) {
49
- const matches =
50
- typeof forbidden === "string"
51
- ? raw.includes(forbidden)
52
- : forbidden.pattern.test(raw);
53
- if (matches) {
54
- const label =
55
- typeof forbidden === "string" ? `"${forbidden}"` : forbidden.label;
56
- drifts.push(` ${check.path}: stale ${label}`);
57
- }
58
- }
59
- }
60
- return drifts;
61
- }
62
-
63
- function collectFrontmatterPolicyDrifts(paths, expectations) {
64
- return paths.flatMap((path) =>
65
- collectFrontmatterDrifts(path, readText(path), expectations),
66
- );
67
- }
68
-
69
- function collectSkillMetadataDrifts() {
70
- const portableSkillPaths = readdirSync(join(root, "skills"))
71
- .filter((directory) => directory !== "x-twitter-scraper")
72
- .map((directory) => `skills/${directory}/SKILL.md`);
73
- return [
74
- ...collectFrontmatterPolicyDrifts(
75
- ["skills/x-twitter-scraper/SKILL.md"],
76
- skillFrontmatterExpectations,
77
- ),
78
- ...collectFrontmatterPolicyDrifts(portableSkillPaths, {}),
79
- ];
80
- }
81
-
82
- function collectTaskGuideMetadataDrifts() {
83
- return collectFrontmatterPolicyDrifts(taskGuidePaths, {
84
- ...taskGuideFrontmatterExpectations,
85
- scalars: {
86
- ...taskGuideFrontmatterExpectations.scalars,
87
- "metadata.version": expected,
88
- },
89
- });
90
- }
91
-
92
- function collectTaskGuideUsageLanguageDrifts() {
93
- const drifts = [];
94
- for (const path of taskGuidePaths) {
95
- const raw = readText(path);
96
- if (raw.includes("| Free") || raw.includes("free read-only")) {
97
- drifts.push(` ${path}: use "Included" instead of pricing-style "Free"`);
98
- }
99
- if (raw.includes("sibling skills") || raw.includes("` skill")) {
100
- drifts.push(` ${path}: task guides must not be labeled skills`);
101
- }
102
- }
103
- return drifts;
104
- }
105
-
106
- function collectSkillsShGroupingDrifts() {
107
- const drifts = [];
108
- const groupedSkills = new Set();
109
- for (const group of readJson("skills.sh.json").groupings ?? []) {
110
- for (const skill of group.skills ?? []) {
111
- groupedSkills.add(skill);
112
- if (skill !== "x-twitter-scraper" && !taskGuideNames.has(skill)) {
113
- drifts.push(` skills.sh.json: grouped skill "${skill}" has no guide`);
114
- }
115
- }
116
- }
117
- for (const skill of taskGuideNames) {
118
- if (!groupedSkills.has(skill)) {
119
- drifts.push(` skills.sh.json: missing task guide "${skill}"`);
120
- }
121
- }
122
- return drifts;
123
- }
124
-
125
- export function collectPolicyDrifts() {
126
- return [
127
- ...collectVersionDrifts(),
128
- ...collectContentDrifts(),
129
- ...collectSkillMetadataDrifts(),
130
- ...collectTaskGuideMetadataDrifts(),
131
- ...collectTaskGuideUsageLanguageDrifts(),
132
- ...collectSkillsShGroupingDrifts(),
133
- ];
134
- }
@@ -1,226 +0,0 @@
1
- // SPDX-FileCopyrightText: 2026 Xquik Contributors
2
- // SPDX-License-Identifier: MIT
3
-
4
- /** Each entry maps a repository path to a version extractor. */
5
- function parseJsonVersion(raw) {
6
- return JSON.parse(raw).version;
7
- }
8
-
9
- export const versionSurfaces = [
10
- { path: "openclaw.plugin.json", get: parseJsonVersion },
11
- { path: ".codex-plugin/plugin.json", get: parseJsonVersion },
12
- { path: ".claude-plugin/plugin.json", get: parseJsonVersion },
13
- {
14
- path: ".claude-plugin/marketplace.json",
15
- get: (j) => {
16
- const m = JSON.parse(j);
17
- return [m.metadata?.version, ...(m.plugins ?? []).map((p) => p.version)];
18
- },
19
- },
20
- {
21
- path: "skills/x-twitter-scraper/metadata.json",
22
- get: parseJsonVersion,
23
- },
24
- {
25
- path: "skills/x-twitter-scraper/SKILL.md",
26
- get: (t) => {
27
- const match = /^\s*version:\s*"([^"]+)"/m.exec(t);
28
- return match?.[1];
29
- },
30
- },
31
- {
32
- path: "stub-server.mjs",
33
- get: (t) => /version:\s*"([^"]+)"/.exec(t)?.[1],
34
- },
35
- ];
36
-
37
- export const skillFrontmatterExpectations = {
38
- scalars: {
39
- author: "Xquik <support@xquik.com>",
40
- compatibility:
41
- "Requires internet access to call the first-party Xquik REST API.",
42
- "metadata.author": "Xquik",
43
- "metadata.capabilities.network.allowed": true,
44
- "metadata.capabilities.shell.allowed": false,
45
- "metadata.capabilities.filesystem.read": false,
46
- "metadata.capabilities.filesystem.write": false,
47
- "metadata.capabilities.mcp.allowed": true,
48
- "metadata.capabilities.mcp.transport": "native-http-or-oauth-only",
49
- "metadata.capabilities.codeExecution.allowed": false,
50
- "metadata.capabilities.localNetwork.allowed": false,
51
- "metadata.openclaw.primaryEnv": "XQUIK_API_KEY",
52
- "metadata.openclaw.homepage": "https://docs.xquik.com",
53
- "metadata.security.credentialsHandledByAgent": "api-key-only",
54
- "metadata.security.credentialsTransmitted": "xquik-api-key-only",
55
- "metadata.security.xLoginSecretsHandled": false,
56
- "metadata.security.passwordsCollected": false,
57
- "metadata.security.totpCollected": false,
58
- "metadata.security.sessionCookiesCollected": false,
59
- "metadata.security.contentIsolation": "enforced",
60
- "metadata.security.inputValidation": "enforced",
61
- "metadata.security.outputSanitization": "enforced",
62
- "metadata.security.writeConfirmation": "required",
63
- "metadata.security.persistentResourceConfirmation": "required",
64
- "metadata.security.accountChangeExecution": false,
65
- "metadata.security.autonomousPlanChanges": false,
66
- "metadata.security.planChanges": "dashboard-only",
67
- "metadata.security.creditChanges": "dashboard-only",
68
- "metadata.security.mcpTransport": "native-http-or-oauth-only",
69
- "metadata.security.thirdPartyContentIsolation": "explicit-boundary-markers",
70
- "metadata.security.executionModel": "api-only",
71
- "metadata.security.codeExecution": "none",
72
- "metadata.security.localFileAccess": "none",
73
- "metadata.security.localNetworkAccess": "none",
74
- "metadata.security.auditLogging": "enabled",
75
- "metadata.security.rateLimiting": "per-method-tier",
76
- "metadata.security.usageConfirmation": "required",
77
- "metadata.security.securityReference": "references/security.md",
78
- },
79
- arrays: {
80
- "metadata.tags": ["twitter", "x", "social-media", "api-development", "scraping"],
81
- "metadata.capabilities.network.hosts": ["xquik.com", "docs.xquik.com"],
82
- "metadata.capabilities.environment.required": ["XQUIK_API_KEY"],
83
- "metadata.capabilities.environment.optional": ["XQUIK_WEBHOOK_SECRET"],
84
- "metadata.openclaw.requires.env": ["XQUIK_API_KEY"],
85
- "metadata.security.allowedHosts": ["xquik.com", "docs.xquik.com"],
86
- },
87
- enums: {
88
- "metadata.security.contentTrust": ["mixed"],
89
- },
90
- };
91
-
92
- export const taskGuideFrontmatterExpectations = {
93
- scalars: {
94
- "metadata.internal": true,
95
- "metadata.author": "Xquik",
96
- "metadata.openclaw.primaryEnv": "XQUIK_API_KEY",
97
- "metadata.openclaw.homepage": "https://docs.xquik.com",
98
- "metadata.security.contentIsolation": "enforced",
99
- "metadata.security.promptInjectionDefense": true,
100
- "metadata.security.writeConfirmation": "required",
101
- "metadata.security.usageConfirmation": "required",
102
- "metadata.security.planChanges": "dashboard-only",
103
- "metadata.security.creditChanges": "dashboard-only",
104
- "metadata.security.executionModel": "api-only",
105
- "metadata.security.codeExecution": "none",
106
- "metadata.security.credentialProxy": false,
107
- },
108
- arrays: {
109
- "metadata.openclaw.requires.env": ["XQUIK_API_KEY"],
110
- },
111
- enums: {
112
- "metadata.security.contentTrust": ["trusted", "mixed", "untrusted"],
113
- },
114
- };
115
-
116
- export const manifestReferences = [
117
- [".codex-plugin/plugin.json", "skills"],
118
- [".codex-plugin/plugin.json", "mcpServers"],
119
- [".codex-plugin/plugin.json", "interface.composerIcon"],
120
- [".claude-plugin/plugin.json", "skills"],
121
- [".claude-plugin/plugin.json", "mcpServers"],
122
- ["openclaw.plugin.json", "skills"],
123
- ];
124
-
125
- export const jsonFieldExpectations = [
126
- {
127
- path: "package.json",
128
- fields: {
129
- name: "x-developer",
130
- "author.name": "Xquik",
131
- "author.url": "https://docs.xquik.com",
132
- homepage: "https://docs.xquik.com",
133
- license: "MIT",
134
- "repository.url": "git+https://github.com/Xquik-dev/x-twitter-scraper.git",
135
- "bugs.url": "https://github.com/Xquik-dev/x-twitter-scraper/issues",
136
- },
137
- },
138
- {
139
- path: "openclaw.plugin.json",
140
- fields: {
141
- id: "x-developer",
142
- name: "X Developer API",
143
- "skills.0": "./skills",
144
- "providerAuthEnvVars.xquik.0": "XQUIK_API_KEY",
145
- "uiHints.apiKey.sensitive": true,
146
- "configSchema.additionalProperties": false,
147
- },
148
- },
149
- {
150
- path: ".codex-plugin/plugin.json",
151
- fields: {
152
- name: "x-twitter-scraper",
153
- "author.name": "Xquik",
154
- homepage: "https://docs.xquik.com",
155
- repository: "https://github.com/Xquik-dev/x-twitter-scraper",
156
- license: "MIT",
157
- skills: "./skills/",
158
- mcpServers: "./.mcp.json",
159
- "interface.developerName": "Xquik",
160
- "interface.websiteURL": "https://docs.xquik.com",
161
- "interface.privacyPolicyURL": "https://xquik.com/privacy",
162
- "interface.termsOfServiceURL": "https://xquik.com/terms",
163
- },
164
- },
165
- {
166
- path: ".claude-plugin/plugin.json",
167
- fields: {
168
- name: "x-twitter-scraper",
169
- "author.name": "Xquik",
170
- homepage: "https://docs.xquik.com",
171
- repository: "https://github.com/Xquik-dev/x-twitter-scraper",
172
- license: "MIT",
173
- skills: "./skills/",
174
- mcpServers: "./.mcp.json",
175
- "userConfig.api_key.sensitive": true,
176
- },
177
- },
178
- {
179
- path: ".claude-plugin/marketplace.json",
180
- fields: {
181
- name: "x-twitter-scraper",
182
- "owner.name": "Xquik",
183
- "owner.email": "support@xquik.com",
184
- "plugins.0.name": "x-twitter-scraper",
185
- "plugins.0.homepage": "https://docs.xquik.com",
186
- "plugins.0.repository": "https://github.com/Xquik-dev/x-twitter-scraper",
187
- "plugins.0.license": "MIT",
188
- },
189
- },
190
- {
191
- path: "server.json",
192
- fields: {
193
- name: "com.xquik/mcp",
194
- title: "Xquik MCP Server",
195
- "repository.url": "https://github.com/Xquik-dev/x-twitter-scraper",
196
- "repository.source": "github",
197
- websiteUrl: "https://docs.xquik.com/mcp/overview",
198
- "remotes.0.type": "streamable-http",
199
- "remotes.0.url": "https://xquik.com/mcp",
200
- version: "2.6.0",
201
- },
202
- },
203
- {
204
- path: "skills/x-twitter-scraper/metadata.json",
205
- fields: {
206
- organization: "Xquik",
207
- homepage: "https://docs.xquik.com",
208
- repository: "https://github.com/Xquik-dev/x-twitter-scraper",
209
- license: "MIT",
210
- "security.defaultMode": "read-only-public-data",
211
- "security.localExecution": false,
212
- "security.localFileAccess": false,
213
- "security.localNetworkAccess": false,
214
- "security.untrustedContentBoundaries": true,
215
- },
216
- },
217
- ];
218
-
219
- export const markdownRoots = [
220
- ".github",
221
- "commands",
222
- "docker-mcp-registry",
223
- "mcpize",
224
- "skills",
225
- "task-guides",
226
- ];
@@ -1,256 +0,0 @@
1
- // SPDX-FileCopyrightText: 2026 Xquik Contributors
2
- // SPDX-License-Identifier: MIT
3
-
4
- import { existsSync, readdirSync, statSync } from "node:fs";
5
- import { dirname, join } from "node:path";
6
-
7
- import {
8
- asArray,
9
- collectFilesBelow,
10
- formatValue,
11
- readJson,
12
- readSelector,
13
- readText,
14
- root,
15
- } from "./context.mjs";
16
- import {
17
- jsonFieldExpectations,
18
- manifestReferences,
19
- markdownRoots,
20
- } from "./policy.mjs";
21
-
22
- const publicContractRoots = [
23
- ".claude-plugin",
24
- ".codex-plugin",
25
- "docker-mcp-registry",
26
- "mcpize",
27
- "skills",
28
- "task-guides",
29
- ];
30
-
31
- const publicContractFiles = [
32
- "README.md",
33
- "openclaw.plugin.json",
34
- "package.json",
35
- "server.json",
36
- "stub-server.mjs",
37
- ];
38
-
39
- const stalePublicContractPatterns = [
40
- [
41
- "127-operation REST count",
42
- /\b127 (?:OpenAPI-documented )?REST(?: API)? operations\b/u,
43
- ],
44
- [
45
- "119-route MCP count",
46
- /\b(?:119 MCP (?:catalog )?routes|119 catalog routes through|119-route API catalog|catalogs 119 of \d+)\b/iu,
47
- ],
48
- ["118 JSON or text count", /\b118 (?:support |JSON\/text|JSON or text)/u],
49
- ["MCP v2.5.6", /\bMCP v2\.5\.6\b/u],
50
- ["126-operation REST count", /\b126 REST(?: API)? operations\b/u],
51
- ["ambiguous 118-operation MCP count", /\b118 (?:MCP )?operations\b/u],
52
- ["118-of-126 MCP count", /\b118 of 126\b/u],
53
- ["MCP v2.5.4", /\bMCP v2\.5\.4\b/u],
54
- ["60/1s read limit", /\bRead(?::| \() 60\/1s\b/u],
55
- ["60-per-1s read limit", /\b60 requests per (?:1s|second)\b/iu],
56
- ["30/60s write limit", /\bWrite(?::| \() 30\/60s\b/u],
57
- ["30-per-60s write limit", /\b30 requests per (?:60s|60 seconds)\b/iu],
58
- ["15/60s delete limit", /\bDelete(?::| \() 15\/60s\b/u],
59
- ["15-per-60s delete limit", /\b15 requests per (?:60s|60 seconds)\b/iu],
60
- ["volatile agent count", /\b40\+ (?:AI )?(?:coding )?agents\b/iu],
61
- ["stub in-memory catalog claim", /in-memory catalog of \d+ MCP operations/iu],
62
- ];
63
-
64
- function collectMarkdownPathsBelow(path) {
65
- const paths = [];
66
- for (const entry of readdirSync(join(root, path), { withFileTypes: true })) {
67
- const childPath = `${path}/${entry.name}`;
68
- if (entry.isDirectory()) {
69
- paths.push(...collectMarkdownPathsBelow(childPath));
70
- } else if (entry.isFile() && entry.name.endsWith(".md")) {
71
- paths.push(childPath);
72
- }
73
- }
74
- return paths;
75
- }
76
-
77
- function extractMarkdownLinks(raw) {
78
- return [...raw.matchAll(/\[[^\]]+\]\(([^)]+)\)/g)].map(
79
- (match) => match[1],
80
- );
81
- }
82
-
83
- function collectMarkdownLinkDrifts() {
84
- const paths = [
85
- "README.md",
86
- "CODE_OF_CONDUCT.md",
87
- ...markdownRoots.flatMap(collectMarkdownPathsBelow),
88
- ];
89
- const drifts = [];
90
- for (const path of paths) {
91
- for (const target of extractMarkdownLinks(readText(path))) {
92
- const cleanTarget = target.split("#", 1)[0];
93
- if (
94
- cleanTarget !== "" &&
95
- !/^[a-z][a-z0-9+.-]*:/i.test(cleanTarget) &&
96
- !existsSync(join(root, dirname(path), cleanTarget))
97
- ) {
98
- drifts.push(` ${path}: broken markdown link "${target}"`);
99
- }
100
- }
101
- }
102
- return drifts;
103
- }
104
-
105
- function collectManifestReferenceDrifts() {
106
- const drifts = [];
107
- for (const [path, selector] of manifestReferences) {
108
- for (const target of asArray(readSelector(readJson(path), selector))) {
109
- if (
110
- typeof target === "string" &&
111
- target.startsWith("./") &&
112
- !existsSync(join(root, target))
113
- ) {
114
- drifts.push(
115
- ` ${path}: missing manifest reference "${selector}" -> ${target}`,
116
- );
117
- }
118
- }
119
- }
120
- return drifts;
121
- }
122
-
123
- function collectJsonFieldDrifts() {
124
- const drifts = [];
125
- for (const expectation of jsonFieldExpectations) {
126
- const data = readJson(expectation.path);
127
- for (const [selector, expectedValue] of Object.entries(
128
- expectation.fields,
129
- )) {
130
- const actualValue = readSelector(data, selector);
131
- if (actualValue !== expectedValue) {
132
- drifts.push(
133
- ` ${expectation.path}: ${selector} = ${formatValue(actualValue)} (expected ${formatValue(expectedValue)})`,
134
- );
135
- }
136
- }
137
- }
138
- return drifts;
139
- }
140
-
141
- function collectPackageFiles(patterns) {
142
- const files = new Set(["package.json"]);
143
- for (const pattern of patterns) {
144
- if (!pattern.startsWith("!") && existsSync(join(root, pattern))) {
145
- for (const path of collectFilesBelow(pattern)) {
146
- files.add(path);
147
- }
148
- }
149
- }
150
- return files;
151
- }
152
-
153
- function collectPackageFileDrifts() {
154
- const packageJson = readJson("package.json");
155
- const drifts = [];
156
- for (const command of Object.values(packageJson.scripts ?? {})) {
157
- const scriptPath = command.match(/\bscripts\/[^\s]+/)?.[0];
158
- if (scriptPath && !existsSync(join(root, scriptPath))) {
159
- drifts.push(` package.json: script target missing "${scriptPath}"`);
160
- }
161
- }
162
- const requiredPackageFiles = [
163
- ".mcp.json",
164
- ".claude-plugin/plugin.json",
165
- ".codex-plugin/plugin.json",
166
- "CHANGELOG.md",
167
- "commands/post.md",
168
- "task-guides/search-tweets.md",
169
- "server.json",
170
- "scripts/check-versions.mjs",
171
- "scripts/release-guard/context.mjs",
172
- "scripts/release-guard/content-policy.mjs",
173
- "scripts/release-guard/frontmatter.mjs",
174
- "scripts/release-guard/policy-checks.mjs",
175
- "scripts/release-guard/policy.mjs",
176
- "scripts/release-guard/repository-checks.mjs",
177
- "skills.sh.json",
178
- "start.sh",
179
- "stub-server.mjs",
180
- ];
181
- const packageFiles = collectPackageFiles(packageJson.files ?? []);
182
- for (const path of requiredPackageFiles) {
183
- if (!packageFiles.has(path)) {
184
- drifts.push(` package.json files: missing "${path}"`);
185
- }
186
- }
187
- if ((statSync(join(root, "start.sh")).mode & 0o111) === 0) {
188
- drifts.push(" start.sh: must be executable");
189
- }
190
- return drifts;
191
- }
192
-
193
- function collectNestedReferenceDrifts() {
194
- const drifts = [];
195
- for (const skill of readdirSync(join(root, "skills"))) {
196
- const referencesPath = `skills/${skill}/references`;
197
- if (!existsSync(join(root, referencesPath))) {
198
- continue;
199
- }
200
- for (const entry of readdirSync(join(root, referencesPath), {
201
- withFileTypes: true,
202
- })) {
203
- if (entry.isDirectory()) {
204
- drifts.push(
205
- ` ${referencesPath}/${entry.name}: nested reference directories are not allowed`,
206
- );
207
- }
208
- }
209
- }
210
- return drifts;
211
- }
212
-
213
- function collectPublicContractDrifts() {
214
- const paths = new Set([
215
- ...publicContractFiles,
216
- ...publicContractRoots.flatMap(collectFilesBelow),
217
- ]);
218
- const drifts = [];
219
- for (const path of paths) {
220
- if (!/\.(?:json|md|mjs|ya?ml)$/u.test(path)) {
221
- continue;
222
- }
223
- const raw = readText(path);
224
- for (const [label, pattern] of stalePublicContractPatterns) {
225
- if (pattern.test(raw)) {
226
- drifts.push(` ${path}: stale ${label}`);
227
- }
228
- }
229
- }
230
- return drifts;
231
- }
232
-
233
- function collectRegistryMetadataDrifts() {
234
- const description = readJson("server.json").description;
235
- if (typeof description !== "string") {
236
- return [" server.json: description must be a string"];
237
- }
238
- if (description.length > 100) {
239
- return [
240
- ` server.json: description has ${description.length} characters (maximum 100)`,
241
- ];
242
- }
243
- return [];
244
- }
245
-
246
- export function collectRepositoryDrifts() {
247
- return [
248
- ...collectMarkdownLinkDrifts(),
249
- ...collectManifestReferenceDrifts(),
250
- ...collectJsonFieldDrifts(),
251
- ...collectPackageFileDrifts(),
252
- ...collectNestedReferenceDrifts(),
253
- ...collectPublicContractDrifts(),
254
- ...collectRegistryMetadataDrifts(),
255
- ];
256
- }
@@ -1,14 +0,0 @@
1
- # Xquik REST API endpoints: API keys
2
-
3
- These endpoints require session authentication. They do not accept API keys.
4
-
5
- ## Manage API keys in the dashboard
6
-
7
- API key lifecycle operations stay in the Xquik dashboard. Never request, copy,
8
- display, store, rotate, or revoke an API key through this Skill. Direct the
9
- user to the dashboard account page.
10
-
11
- This reference omits API key lifecycle requests and responses. Do not call
12
- those routes from this Skill. Use the dashboard account page.
13
-
14
- ---
@@ -1,33 +0,0 @@
1
- # Xquik REST API endpoints: compose
2
-
3
- ### Compose tweet
4
-
5
- ```
6
- POST /compose
7
- ```
8
-
9
- Compose, refine, and score tweets with Xquik style signals. Run each step separately.
10
-
11
- Send this body:
12
-
13
- | Field | Type | Required | Description |
14
- |-------|------|----------|-------------|
15
- | `step` | string | Yes | `compose`, `refine`, or `score` |
16
- | `topic` | string | No | Tweet topic for compose or refine |
17
- | `goal` | string | No | `engagement`, `followers`, `authority`, `conversation` |
18
- | `styleUsername` | string | No | Cached style username for compose |
19
- | `tone` | string | No | Desired tone for refine |
20
- | `additionalContext` | string | No | Extra context or URLs for refine |
21
- | `callToAction` | string | No | Desired call to action for refine |
22
- | `mediaType` | string | No | `photo`, `video`, or `none` for refine |
23
- | `draft` | string | No | Tweet text to evaluate for score |
24
- | `hasLink` | boolean | No | Whether score evaluates a link |
25
- | `hasMedia` | boolean | No | Whether score evaluates media |
26
-
27
- For `step=compose`, the API returns `contentRules`, `scorerWeights`, `followUpQuestions`, `algorithmInsights`, `engagementMultipliers`, and `topPenalties`.
28
-
29
- For `step=refine`, the API returns `compositionGuidance` and `examplePatterns`.
30
-
31
- For `step=score`, the API returns `totalChecks`, `passedCount`, `topSuggestion`, and `checklist[]`. Each checklist item contains `factor`, `passed`, and `suggestion`.
32
-
33
- ---
@@ -1,11 +0,0 @@
1
- # Xquik REST API endpoints: credits
2
-
3
- ### Get credit balance
4
-
5
- ```
6
- GET /credits
7
- ```
8
-
9
- Get the credit balance and lifetime usage fields. Plan and credit changes are dashboard-only. This installable Skill omits those routes.
10
-
11
- ---