@agentrhq/webcmd 0.3.0 → 0.3.1
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 +13 -2
- package/cli-manifest.json +217 -13
- package/clis/chatgpt/ask.js +1 -1
- package/clis/chatgpt/ask.test.js +11 -0
- package/clis/chatgpt/commands.test.js +102 -1
- package/clis/chatgpt/deep-research-result.js +45 -3
- package/clis/chatgpt/image.js +22 -2
- package/clis/chatgpt/project-file-add.js +24 -1
- package/clis/chatgpt/utils.js +258 -52
- package/clis/chatgpt/utils.test.js +259 -1
- package/clis/claude/ask.js +21 -1
- package/clis/facebook/feed.js +110 -24
- package/clis/facebook/feed.test.js +62 -0
- package/clis/facebook/search.js +185 -38
- package/clis/facebook/search.test.js +95 -50
- package/clis/instagram/explore.js +30 -12
- package/clis/instagram/explore.test.js +77 -0
- package/clis/instagram/post.js +14 -1
- package/clis/instagram/reel.js +13 -1
- package/clis/linkedin/company.js +153 -0
- package/clis/linkedin/company.test.js +111 -0
- package/clis/linkedin/connections.js +135 -0
- package/clis/linkedin/connections.test.js +141 -0
- package/clis/mercury/reimbursement-draft.js +12 -1
- package/clis/twitter/article-evaluate.test.js +27 -0
- package/clis/twitter/article.js +73 -16
- package/clis/twitter/article.test.js +209 -0
- package/clis/twitter/download.js +6 -1
- package/clis/twitter/post.js +14 -1
- package/clis/twitter/profile.js +1 -1
- package/clis/twitter/profile.test.js +8 -0
- package/clis/twitter/quote.js +11 -1
- package/clis/twitter/reply.js +11 -1
- package/dist/src/browser/base-page.d.ts +26 -0
- package/dist/src/browser/base-page.js +23 -8
- package/dist/src/browser/base-page.test.js +45 -12
- package/dist/src/browser/command-catalog.d.ts +6 -0
- package/dist/src/browser/command-catalog.js +259 -0
- package/dist/src/browser/command-catalog.test.d.ts +1 -0
- package/dist/src/browser/command-catalog.test.js +79 -0
- package/dist/src/browser/runtime/local-cloak/darwin-background-launch.d.ts +17 -0
- package/dist/src/browser/runtime/local-cloak/darwin-background-launch.js +106 -0
- package/dist/src/browser/runtime/local-cloak/darwin-background-launch.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/darwin-background-launch.test.js +65 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.d.ts +7 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.js +23 -9
- package/dist/src/browser/runtime/local-cloak/session-manager.test.js +36 -0
- package/dist/src/browser/target-resolver.d.ts +1 -0
- package/dist/src/browser/target-resolver.js +99 -4
- package/dist/src/browser/target-resolver.test.js +141 -1
- package/dist/src/build-manifest.d.ts +6 -0
- package/dist/src/build-manifest.js +18 -1
- package/dist/src/build-manifest.test.js +57 -1
- package/dist/src/builtin-command-surface.d.ts +9 -0
- package/dist/src/builtin-command-surface.js +16 -0
- package/dist/src/check-hosted-contract.test.d.ts +1 -0
- package/dist/src/check-hosted-contract.test.js +56 -0
- package/dist/src/cli.js +58 -106
- package/dist/src/cli.test.js +71 -1
- package/dist/src/command-presentation.d.ts +95 -0
- package/dist/src/command-presentation.js +486 -0
- package/dist/src/command-presentation.test.d.ts +1 -0
- package/dist/src/command-presentation.test.js +97 -0
- package/dist/src/command-surface.d.ts +43 -0
- package/dist/src/command-surface.js +205 -0
- package/dist/src/command-surface.test.d.ts +1 -0
- package/dist/src/command-surface.test.js +406 -0
- package/dist/src/commanderAdapter.d.ts +5 -1
- package/dist/src/commanderAdapter.js +12 -55
- package/dist/src/commanderAdapter.test.js +15 -3
- package/dist/src/community-plugin-sync.d.ts +11 -0
- package/dist/src/community-plugin-sync.js +138 -0
- package/dist/src/community-plugin-sync.test.d.ts +1 -0
- package/dist/src/community-plugin-sync.test.js +123 -0
- package/dist/src/completion-fast.d.ts +4 -4
- package/dist/src/completion-fast.js +15 -34
- package/dist/src/completion-shared.d.ts +4 -0
- package/dist/src/completion-shared.js +38 -0
- package/dist/src/completion.js +3 -27
- package/dist/src/completion.test.js +31 -2
- package/dist/src/docs-sync-review-cli.test.d.ts +1 -0
- package/dist/src/docs-sync-review-cli.test.js +322 -0
- package/dist/src/docs-sync-review.d.ts +117 -0
- package/dist/src/docs-sync-review.js +475 -0
- package/dist/src/docs-sync-review.test.d.ts +1 -0
- package/dist/src/docs-sync-review.test.js +324 -0
- package/dist/src/errors.d.ts +12 -3
- package/dist/src/errors.js +11 -7
- package/dist/src/errors.test.js +14 -1
- package/dist/src/execution.d.ts +1 -2
- package/dist/src/execution.js +4 -45
- package/dist/src/generate-release-notes-cli.test.js +7 -2
- package/dist/src/help.d.ts +4 -0
- package/dist/src/help.js +50 -255
- package/dist/src/help.test.js +27 -1
- package/dist/src/hosted/args.d.ts +2 -7
- package/dist/src/hosted/args.js +2 -99
- package/dist/src/hosted/args.test.js +15 -1
- package/dist/src/hosted/availability.d.ts +13 -0
- package/dist/src/hosted/availability.js +16 -0
- package/dist/src/hosted/availability.test.d.ts +1 -0
- package/dist/src/hosted/availability.test.js +180 -0
- package/dist/src/hosted/browser-args.d.ts +18 -0
- package/dist/src/hosted/browser-args.js +152 -0
- package/dist/src/hosted/browser-args.test.d.ts +1 -0
- package/dist/src/hosted/browser-args.test.js +182 -0
- package/dist/src/hosted/client.d.ts +31 -2
- package/dist/src/hosted/client.js +441 -53
- package/dist/src/hosted/client.test.js +651 -32
- package/dist/src/hosted/config.d.ts +7 -2
- package/dist/src/hosted/config.js +26 -4
- package/dist/src/hosted/config.test.js +34 -1
- package/dist/src/hosted/contract.d.ts +94 -0
- package/dist/src/hosted/contract.js +208 -0
- package/dist/src/hosted/contract.test.d.ts +1 -0
- package/dist/src/hosted/contract.test.js +361 -0
- package/dist/src/hosted/credentials.d.ts +38 -0
- package/dist/src/hosted/credentials.js +248 -0
- package/dist/src/hosted/credentials.test.d.ts +1 -0
- package/dist/src/hosted/credentials.test.js +93 -0
- package/dist/src/hosted/file-contract.test.d.ts +1 -0
- package/dist/src/hosted/file-contract.test.js +174 -0
- package/dist/src/hosted/files.d.ts +29 -0
- package/dist/src/hosted/files.js +296 -0
- package/dist/src/hosted/files.test.d.ts +1 -0
- package/dist/src/hosted/files.test.js +231 -0
- package/dist/src/hosted/main-lifecycle.test.d.ts +1 -0
- package/dist/src/hosted/main-lifecycle.test.js +213 -0
- package/dist/src/hosted/manifest.d.ts +5 -0
- package/dist/src/hosted/manifest.js +21 -66
- package/dist/src/hosted/manifest.test.js +120 -2
- package/dist/src/hosted/output-parity.test.d.ts +1 -0
- package/dist/src/hosted/output-parity.test.js +108 -0
- package/dist/src/hosted/root-command-surface.test.d.ts +1 -0
- package/dist/src/hosted/root-command-surface.test.js +646 -0
- package/dist/src/hosted/runner.d.ts +7 -0
- package/dist/src/hosted/runner.js +554 -253
- package/dist/src/hosted/runner.test.js +1471 -53
- package/dist/src/hosted/setup.d.ts +3 -2
- package/dist/src/hosted/setup.js +45 -15
- package/dist/src/hosted/setup.test.js +133 -6
- package/dist/src/hosted/types.d.ts +101 -23
- package/dist/src/main.js +120 -108
- package/dist/src/manifest-types.d.ts +2 -0
- package/dist/src/output.d.ts +17 -2
- package/dist/src/output.js +88 -81
- package/dist/src/output.test.js +141 -51
- package/dist/src/pipeline/executor.test.js +1 -0
- package/dist/src/pipeline/steps/download.test.js +1 -0
- package/dist/src/plugin-create-cli.test.d.ts +1 -0
- package/dist/src/plugin-create-cli.test.js +37 -0
- package/dist/src/plugin-manifest.d.ts +12 -0
- package/dist/src/plugin-manifest.js +16 -0
- package/dist/src/plugin-manifest.test.js +19 -1
- package/dist/src/plugin-scaffold.d.ts +4 -1
- package/dist/src/plugin-scaffold.js +4 -1
- package/dist/src/plugin-scaffold.test.js +23 -8
- package/dist/src/plugin.js +4 -1
- package/dist/src/plugin.test.js +13 -0
- package/dist/src/registry.d.ts +2 -0
- package/dist/src/release-notes.js +12 -4
- package/dist/src/release-notes.test.js +27 -15
- package/dist/src/root-command-surface.d.ts +31 -0
- package/dist/src/root-command-surface.js +106 -0
- package/dist/src/serialization.d.ts +1 -16
- package/dist/src/serialization.js +5 -55
- package/dist/src/stream-write.d.ts +12 -0
- package/dist/src/stream-write.js +91 -0
- package/dist/src/stream-write.test.d.ts +1 -0
- package/dist/src/stream-write.test.js +186 -0
- package/dist/src/types.d.ts +5 -0
- package/dist/src/utils.d.ts +1 -1
- package/dist/src/utils.js +2 -8
- package/dist/src/utils.test.js +50 -0
- package/hosted-contract.json +36748 -0
- package/package.json +6 -1
- package/scripts/check-hosted-contract.mjs +108 -0
- package/scripts/docs-sync-review.ts +332 -0
- package/scripts/sync-community-plugins.ts +14 -0
- package/skills/webcmd-autofix/SKILL.md +26 -37
- package/skills/webcmd-usage/SKILL.md +7 -0
package/dist/src/utils.d.ts
CHANGED
|
@@ -54,4 +54,4 @@ export declare function parseJsonOrThrowLoginWall(response: Response, opts?: {
|
|
|
54
54
|
* return res;
|
|
55
55
|
*
|
|
56
56
|
* The Node side then calls `throwIfLoginWall(res, { url })` on the result. */
|
|
57
|
-
export declare const BROWSER_JSON_SNIFF_FN = "\nasync function fetchJsonOrLoginWall(input, init) {\n const r = await fetch(input, init);\n const contentType = r.headers.get('content-type') || '';\n const text = await r.text();\n const trimmed = text.replace(/^\\s+/, '');\n const looksLikeHtml =\n contentType.toLowerCase().includes('text/html')\n ||
|
|
57
|
+
export declare const BROWSER_JSON_SNIFF_FN = "\nasync function fetchJsonOrLoginWall(input, init) {\n const r = await fetch(input, init);\n const contentType = r.headers.get('content-type') || '';\n const text = await r.text();\n const trimmed = text.replace(/^\\s+/, '');\n const looksLikeHtml =\n contentType.toLowerCase().includes('text/html')\n || /^<(?:!doctype|html|head|body|title)(?:[\\s>/]|$)/i.test(trimmed);\n if (looksLikeHtml) {\n return {\n __loginWall: true,\n status: r.status,\n url: r.url || (typeof input === 'string' ? input : ''),\n contentType,\n bodyPreview: trimmed.slice(0, 100),\n };\n }\n if (!r.ok) {\n return { error: r.status };\n }\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new Error(\n 'JSON parse failed (status=' + r.status + ', body[0..50]=' + JSON.stringify(trimmed.slice(0, 50)) + '): '\n + (err && err.message ? err.message : String(err))\n );\n }\n}\n";
|
package/dist/src/utils.js
CHANGED
|
@@ -85,10 +85,7 @@ export async function parseJsonOrThrowLoginWall(response, opts = {}) {
|
|
|
85
85
|
const text = await response.text();
|
|
86
86
|
const trimmed = text.trimStart();
|
|
87
87
|
const looksLikeHtml = contentType.toLowerCase().includes('text/html')
|
|
88
|
-
||
|
|
89
|
-
|| trimmed.startsWith('<!doctype')
|
|
90
|
-
|| trimmed.startsWith('<html')
|
|
91
|
-
|| trimmed.startsWith('<HTML');
|
|
88
|
+
|| /^<(?:!doctype|html|head|body|title)(?:[\s>/]|$)/i.test(trimmed);
|
|
92
89
|
if (looksLikeHtml) {
|
|
93
90
|
throw new LoginWallError(`Server returned HTML instead of JSON (status=${response.status}). `
|
|
94
91
|
+ `Likely a login wall, rate limit, or WAF challenge.`, response.status, opts.url || response.url || '', trimmed.slice(0, 100));
|
|
@@ -124,10 +121,7 @@ async function fetchJsonOrLoginWall(input, init) {
|
|
|
124
121
|
const trimmed = text.replace(/^\\s+/, '');
|
|
125
122
|
const looksLikeHtml =
|
|
126
123
|
contentType.toLowerCase().includes('text/html')
|
|
127
|
-
||
|
|
128
|
-
|| trimmed.startsWith('<!doctype')
|
|
129
|
-
|| trimmed.startsWith('<html')
|
|
130
|
-
|| trimmed.startsWith('<HTML');
|
|
124
|
+
|| /^<(?:!doctype|html|head|body|title)(?:[\\s>/]|$)/i.test(trimmed);
|
|
131
125
|
if (looksLikeHtml) {
|
|
132
126
|
return {
|
|
133
127
|
__loginWall: true,
|
package/dist/src/utils.test.js
CHANGED
|
@@ -51,6 +51,29 @@ describe('parseJsonOrThrowLoginWall', () => {
|
|
|
51
51
|
});
|
|
52
52
|
await expect(parseJsonOrThrowLoginWall(res)).rejects.toBeInstanceOf(LoginWallError);
|
|
53
53
|
});
|
|
54
|
+
it('detects mixed-case HTML tags when content-type claims JSON', async () => {
|
|
55
|
+
const res = new Response('<HtMl lang="en"><body>nope</body></HtMl>', {
|
|
56
|
+
status: 403,
|
|
57
|
+
headers: { 'content-type': 'application/json' },
|
|
58
|
+
});
|
|
59
|
+
await expect(parseJsonOrThrowLoginWall(res)).rejects.toBeInstanceOf(LoginWallError);
|
|
60
|
+
});
|
|
61
|
+
it('detects mixed-case HTML fragments without a top-level html tag', async () => {
|
|
62
|
+
for (const html of ['<BoDy>blocked</BoDy>', '<TiTlE>login</TiTlE>']) {
|
|
63
|
+
const res = new Response(html, {
|
|
64
|
+
status: 403,
|
|
65
|
+
headers: { 'content-type': 'application/json' },
|
|
66
|
+
});
|
|
67
|
+
await expect(parseJsonOrThrowLoginWall(res)).rejects.toBeInstanceOf(LoginWallError);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
it('does not treat arbitrary angle-prefixed non-HTML text as a login wall', async () => {
|
|
71
|
+
const res = new Response('<htmlish', {
|
|
72
|
+
status: 200,
|
|
73
|
+
headers: { 'content-type': 'application/json' },
|
|
74
|
+
});
|
|
75
|
+
await expect(parseJsonOrThrowLoginWall(res)).rejects.not.toBeInstanceOf(LoginWallError);
|
|
76
|
+
});
|
|
54
77
|
it('throws LoginWallError when body has leading whitespace before <!DOCTYPE', async () => {
|
|
55
78
|
const res = new Response(' \n\n<!DOCTYPE html><html></html>', {
|
|
56
79
|
status: 200,
|
|
@@ -152,4 +175,31 @@ describe('BROWSER_JSON_SNIFF_FN', () => {
|
|
|
152
175
|
// we CAN confirm the fragment parses cleanly when embedded inside an async IIFE.
|
|
153
176
|
expect(() => new Function(`(async () => { ${BROWSER_JSON_SNIFF_FN} })`)).not.toThrow();
|
|
154
177
|
});
|
|
178
|
+
it('detects mixed-case HTML tags in browser-side responses', async () => {
|
|
179
|
+
const fetchJsonOrLoginWall = new Function('fetch', `${BROWSER_JSON_SNIFF_FN}; return fetchJsonOrLoginWall;`)(async () => new Response('<HtMl><body>login</body></HtMl>', {
|
|
180
|
+
status: 403,
|
|
181
|
+
headers: { 'content-type': 'application/json' },
|
|
182
|
+
}));
|
|
183
|
+
await expect(fetchJsonOrLoginWall('/api')).resolves.toMatchObject({
|
|
184
|
+
__loginWall: true,
|
|
185
|
+
status: 403,
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
it('detects mixed-case HTML fragments in browser-side responses', async () => {
|
|
189
|
+
const fetchJsonOrLoginWall = new Function('fetch', `${BROWSER_JSON_SNIFF_FN}; return fetchJsonOrLoginWall;`)(async () => new Response('<BoDy>login</BoDy>', {
|
|
190
|
+
status: 403,
|
|
191
|
+
headers: { 'content-type': 'application/json' },
|
|
192
|
+
}));
|
|
193
|
+
await expect(fetchJsonOrLoginWall('/api')).resolves.toMatchObject({
|
|
194
|
+
__loginWall: true,
|
|
195
|
+
status: 403,
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
it('does not flag browser-side non-HTML angle-prefixed text', async () => {
|
|
199
|
+
const fetchJsonOrLoginWall = new Function('fetch', `${BROWSER_JSON_SNIFF_FN}; return fetchJsonOrLoginWall;`)(async () => new Response('<htmlish', {
|
|
200
|
+
status: 200,
|
|
201
|
+
headers: { 'content-type': 'application/json' },
|
|
202
|
+
}));
|
|
203
|
+
await expect(fetchJsonOrLoginWall('/api')).rejects.toThrow('JSON parse failed');
|
|
204
|
+
});
|
|
155
205
|
});
|