@jshookmcp/jshook 0.2.5 → 0.2.6

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 (210) hide show
  1. package/README.md +5 -5
  2. package/README.zh.md +5 -5
  3. package/dist/packages/extension-sdk/src/workflow.d.ts +17 -2
  4. package/dist/packages/extension-sdk/src/workflow.js +36 -0
  5. package/dist/src/modules/browser/BrowserPool.d.ts +49 -0
  6. package/dist/src/modules/browser/BrowserPool.js +288 -0
  7. package/dist/src/modules/deobfuscator/AdvancedDeobfuscator.d.ts +5 -0
  8. package/dist/src/modules/deobfuscator/AdvancedDeobfuscator.js +43 -2
  9. package/dist/src/modules/deobfuscator/Deobfuscator.js +5 -0
  10. package/dist/src/modules/external/ExternalToolRunner.js +1 -1
  11. package/dist/src/server/MCPServer.context.d.ts +1 -0
  12. package/dist/src/server/domains/browser/handlers/stealth-injection.d.ts +1 -0
  13. package/dist/src/server/domains/browser/handlers/stealth-injection.js +3 -0
  14. package/dist/src/server/domains/shared-state-board/definitions.d.ts +2 -0
  15. package/dist/src/server/domains/shared-state-board/definitions.js +78 -0
  16. package/dist/src/server/domains/shared-state-board/handlers.impl.d.ts +58 -0
  17. package/dist/src/server/domains/shared-state-board/handlers.impl.js +419 -0
  18. package/dist/src/server/domains/shared-state-board/index.d.ts +2 -0
  19. package/dist/src/server/domains/shared-state-board/index.js +2 -0
  20. package/dist/src/server/domains/shared-state-board/manifest.d.ts +57 -0
  21. package/dist/src/server/domains/shared-state-board/manifest.js +74 -0
  22. package/dist/src/server/http/SseStream.d.ts +21 -0
  23. package/dist/src/server/http/SseStream.js +129 -0
  24. package/dist/src/server/teams/TeamManager.d.ts +43 -0
  25. package/dist/src/server/teams/TeamManager.js +238 -0
  26. package/dist/src/server/teams/index.d.ts +1 -0
  27. package/dist/src/server/teams/index.js +1 -0
  28. package/dist/src/server/workflows/WorkflowContract.d.ts +20 -4
  29. package/dist/src/server/workflows/WorkflowContract.js +40 -0
  30. package/dist/src/server/workflows/WorkflowEngine.js +190 -13
  31. package/dist/src/types/deobfuscator.d.ts +1 -0
  32. package/dist/src/utils/cache/CachedDecorator.d.ts +8 -0
  33. package/dist/src/utils/cache/CachedDecorator.js +55 -0
  34. package/dist/src/utils/cache/PersistentCache.d.ts +33 -0
  35. package/dist/src/utils/cache/PersistentCache.js +246 -0
  36. package/dist/src/utils/cache/index.d.ts +2 -0
  37. package/dist/src/utils/cache/index.js +2 -0
  38. package/package.json +11 -12
  39. package/scripts/postinstall.cjs +54 -27
  40. package/workflows/anti-bot-diagnoser/.jshook-install.json +14 -0
  41. package/workflows/anti-bot-diagnoser/LICENSE +21 -0
  42. package/workflows/anti-bot-diagnoser/README.md +105 -0
  43. package/workflows/anti-bot-diagnoser/docs/agent-recipes.md +44 -0
  44. package/workflows/anti-bot-diagnoser/meta.yaml +6 -0
  45. package/workflows/anti-bot-diagnoser/package.json +22 -0
  46. package/workflows/anti-bot-diagnoser/tsconfig.json +15 -0
  47. package/workflows/anti-bot-diagnoser/workflow.ts +224 -0
  48. package/workflows/api-openapi-probe/.jshook-install.json +14 -0
  49. package/workflows/api-openapi-probe/meta.yaml +6 -0
  50. package/workflows/api-openapi-probe/package.json +22 -0
  51. package/workflows/api-openapi-probe/pnpm-lock.yaml +819 -0
  52. package/workflows/api-openapi-probe/tsconfig.json +15 -0
  53. package/workflows/api-openapi-probe/workflow.ts +40 -0
  54. package/workflows/api-probe-batch/.jshook-install.json +14 -0
  55. package/workflows/api-probe-batch/LICENSE +21 -0
  56. package/workflows/api-probe-batch/README.md +45 -0
  57. package/workflows/api-probe-batch/meta.yaml +4 -0
  58. package/workflows/api-probe-batch/package.json +23 -0
  59. package/workflows/api-probe-batch/tsconfig.json +16 -0
  60. package/workflows/api-probe-batch/workflow.ts +111 -0
  61. package/workflows/auth-bootstrap/.jshook-install.json +14 -0
  62. package/workflows/auth-bootstrap/LICENSE +21 -0
  63. package/workflows/auth-bootstrap/README.md +74 -0
  64. package/workflows/auth-bootstrap/meta.yaml +4 -0
  65. package/workflows/auth-bootstrap/package.json +23 -0
  66. package/workflows/auth-bootstrap/tsconfig.json +16 -0
  67. package/workflows/auth-bootstrap/workflow.ts +141 -0
  68. package/workflows/auth-extract/.jshook-install.json +14 -0
  69. package/workflows/auth-extract/meta.yaml +6 -0
  70. package/workflows/auth-extract/package.json +22 -0
  71. package/workflows/auth-extract/pnpm-lock.yaml +819 -0
  72. package/workflows/auth-extract/tsconfig.json +15 -0
  73. package/workflows/auth-extract/workflow.ts +36 -0
  74. package/workflows/auth-surface-mapper/.jshook-install.json +14 -0
  75. package/workflows/auth-surface-mapper/meta.yaml +6 -0
  76. package/workflows/auth-surface-mapper/package.json +22 -0
  77. package/workflows/auth-surface-mapper/pnpm-lock.yaml +819 -0
  78. package/workflows/auth-surface-mapper/tsconfig.json +15 -0
  79. package/workflows/auth-surface-mapper/workflow.ts +104 -0
  80. package/workflows/batch-register/.jshook-install.json +14 -0
  81. package/workflows/batch-register/LICENSE +21 -0
  82. package/workflows/batch-register/README.md +39 -0
  83. package/workflows/batch-register/meta.yaml +4 -0
  84. package/workflows/batch-register/package.json +23 -0
  85. package/workflows/batch-register/tsconfig.json +16 -0
  86. package/workflows/batch-register/workflow.ts +67 -0
  87. package/workflows/bundle-recovery/.jshook-install.json +14 -0
  88. package/workflows/bundle-recovery/LICENSE +21 -0
  89. package/workflows/bundle-recovery/README.md +105 -0
  90. package/workflows/bundle-recovery/docs/agent-recipes.md +44 -0
  91. package/workflows/bundle-recovery/meta.yaml +6 -0
  92. package/workflows/bundle-recovery/package.json +22 -0
  93. package/workflows/bundle-recovery/tsconfig.json +15 -0
  94. package/workflows/bundle-recovery/workflow.ts +179 -0
  95. package/workflows/challenge-detector/.jshook-install.json +14 -0
  96. package/workflows/challenge-detector/meta.yaml +14 -0
  97. package/workflows/challenge-detector/package.json +22 -0
  98. package/workflows/challenge-detector/pnpm-lock.yaml +819 -0
  99. package/workflows/challenge-detector/tsconfig.json +15 -0
  100. package/workflows/challenge-detector/workflow.ts +298 -0
  101. package/workflows/deobfuscation-pipeline/.jshook-install.json +14 -0
  102. package/workflows/deobfuscation-pipeline/meta.yaml +6 -0
  103. package/workflows/deobfuscation-pipeline/package.json +22 -0
  104. package/workflows/deobfuscation-pipeline/pnpm-lock.yaml +819 -0
  105. package/workflows/deobfuscation-pipeline/tsconfig.json +15 -0
  106. package/workflows/deobfuscation-pipeline/workflow.ts +119 -0
  107. package/workflows/electron-bridge-mapper/.jshook-install.json +14 -0
  108. package/workflows/electron-bridge-mapper/meta.yaml +6 -0
  109. package/workflows/electron-bridge-mapper/package.json +22 -0
  110. package/workflows/electron-bridge-mapper/pnpm-lock.yaml +819 -0
  111. package/workflows/electron-bridge-mapper/tsconfig.json +15 -0
  112. package/workflows/electron-bridge-mapper/workflow.ts +125 -0
  113. package/workflows/evidence-pack/.jshook-install.json +14 -0
  114. package/workflows/evidence-pack/LICENSE +21 -0
  115. package/workflows/evidence-pack/README.md +105 -0
  116. package/workflows/evidence-pack/docs/agent-recipes.md +44 -0
  117. package/workflows/evidence-pack/meta.yaml +6 -0
  118. package/workflows/evidence-pack/package.json +22 -0
  119. package/workflows/evidence-pack/tsconfig.json +15 -0
  120. package/workflows/evidence-pack/workflow.ts +154 -0
  121. package/workflows/js-bundle-search/.jshook-install.json +14 -0
  122. package/workflows/js-bundle-search/LICENSE +21 -0
  123. package/workflows/js-bundle-search/README.md +46 -0
  124. package/workflows/js-bundle-search/meta.yaml +4 -0
  125. package/workflows/js-bundle-search/package.json +23 -0
  126. package/workflows/js-bundle-search/tsconfig.json +16 -0
  127. package/workflows/js-bundle-search/workflow.ts +118 -0
  128. package/workflows/protocol-registry/.jshook-install.json +14 -0
  129. package/workflows/protocol-registry/meta.yaml +6 -0
  130. package/workflows/protocol-registry/package.json +22 -0
  131. package/workflows/protocol-registry/pnpm-lock.yaml +819 -0
  132. package/workflows/protocol-registry/tsconfig.json +15 -0
  133. package/workflows/protocol-registry/workflow.ts +107 -0
  134. package/workflows/qwen-mail-open-latest/meta.yaml +7 -0
  135. package/workflows/qwen-mail-open-latest/package.json +22 -0
  136. package/workflows/qwen-mail-open-latest/pnpm-lock.yaml +819 -0
  137. package/workflows/qwen-mail-open-latest/tsconfig.json +15 -0
  138. package/workflows/qwen-mail-open-latest/workflow.ts +77 -0
  139. package/workflows/register-account-flow/.jshook-install.json +14 -0
  140. package/workflows/register-account-flow/LICENSE +21 -0
  141. package/workflows/register-account-flow/README.md +64 -0
  142. package/workflows/register-account-flow/meta.yaml +4 -0
  143. package/workflows/register-account-flow/package.json +23 -0
  144. package/workflows/register-account-flow/tsconfig.json +16 -0
  145. package/workflows/register-account-flow/workflow.ts +127 -0
  146. package/workflows/replay-lab/.jshook-install.json +14 -0
  147. package/workflows/replay-lab/meta.yaml +6 -0
  148. package/workflows/replay-lab/package.json +22 -0
  149. package/workflows/replay-lab/pnpm-lock.yaml +819 -0
  150. package/workflows/replay-lab/tsconfig.json +15 -0
  151. package/workflows/replay-lab/workflow.ts +106 -0
  152. package/workflows/script-evidence-scan/.jshook-install.json +14 -0
  153. package/workflows/script-evidence-scan/LICENSE +21 -0
  154. package/workflows/script-evidence-scan/README.md +61 -0
  155. package/workflows/script-evidence-scan/meta.yaml +4 -0
  156. package/workflows/script-evidence-scan/package.json +23 -0
  157. package/workflows/script-evidence-scan/tsconfig.json +16 -0
  158. package/workflows/script-evidence-scan/workflow.ts +89 -0
  159. package/workflows/signature-hunter/.jshook-install.json +14 -0
  160. package/workflows/signature-hunter/LICENSE +21 -0
  161. package/workflows/signature-hunter/README.md +105 -0
  162. package/workflows/signature-hunter/docs/agent-recipes.md +44 -0
  163. package/workflows/signature-hunter/meta.yaml +6 -0
  164. package/workflows/signature-hunter/package.json +22 -0
  165. package/workflows/signature-hunter/tsconfig.json +15 -0
  166. package/workflows/signature-hunter/workflow.ts +170 -0
  167. package/workflows/signing-lineage/.jshook-install.json +14 -0
  168. package/workflows/signing-lineage/meta.yaml +6 -0
  169. package/workflows/signing-lineage/package.json +22 -0
  170. package/workflows/signing-lineage/pnpm-lock.yaml +819 -0
  171. package/workflows/signing-lineage/tsconfig.json +15 -0
  172. package/workflows/signing-lineage/workflow.ts +120 -0
  173. package/workflows/temp-mail-extract-link/.jshook-install.json +14 -0
  174. package/workflows/temp-mail-extract-link/LICENSE +21 -0
  175. package/workflows/temp-mail-extract-link/README.md +71 -0
  176. package/workflows/temp-mail-extract-link/meta.yaml +4 -0
  177. package/workflows/temp-mail-extract-link/package.json +23 -0
  178. package/workflows/temp-mail-extract-link/tsconfig.json +16 -0
  179. package/workflows/temp-mail-extract-link/workflow.ts +221 -0
  180. package/workflows/temp-mail-open-latest/.jshook-install.json +14 -0
  181. package/workflows/temp-mail-open-latest/LICENSE +21 -0
  182. package/workflows/temp-mail-open-latest/README.md +61 -0
  183. package/workflows/temp-mail-open-latest/meta.yaml +4 -0
  184. package/workflows/temp-mail-open-latest/package.json +23 -0
  185. package/workflows/temp-mail-open-latest/tsconfig.json +16 -0
  186. package/workflows/temp-mail-open-latest/workflow.ts +136 -0
  187. package/workflows/template/.jshook-install.json +14 -0
  188. package/workflows/template/LICENSE +21 -0
  189. package/workflows/template/README.md +45 -0
  190. package/workflows/template/docs/SKILL.md +111 -0
  191. package/workflows/template/meta.yaml +6 -0
  192. package/workflows/template/package.json +22 -0
  193. package/workflows/template/pnpm-lock.yaml +819 -0
  194. package/workflows/template/tsconfig.json +15 -0
  195. package/workflows/template/workflow.ts +73 -0
  196. package/workflows/web-api-capture-session/.jshook-install.json +14 -0
  197. package/workflows/web-api-capture-session/LICENSE +21 -0
  198. package/workflows/web-api-capture-session/README.md +64 -0
  199. package/workflows/web-api-capture-session/meta.yaml +4 -0
  200. package/workflows/web-api-capture-session/package.json +23 -0
  201. package/workflows/web-api-capture-session/tsconfig.json +16 -0
  202. package/workflows/web-api-capture-session/workflow.ts +124 -0
  203. package/workflows/ws-protocol-lifter/.jshook-install.json +14 -0
  204. package/workflows/ws-protocol-lifter/LICENSE +21 -0
  205. package/workflows/ws-protocol-lifter/README.md +105 -0
  206. package/workflows/ws-protocol-lifter/docs/agent-recipes.md +44 -0
  207. package/workflows/ws-protocol-lifter/meta.yaml +6 -0
  208. package/workflows/ws-protocol-lifter/package.json +22 -0
  209. package/workflows/ws-protocol-lifter/tsconfig.json +15 -0
  210. package/workflows/ws-protocol-lifter/workflow.ts +163 -0
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "noEmit": false,
7
+ "outDir": "dist",
8
+ "rootDir": ".",
9
+ "strict": true,
10
+ "skipLibCheck": true,
11
+ "types": ["node"]
12
+ },
13
+ "include": ["workflow.ts"],
14
+ "exclude": ["dist", "node_modules"]
15
+ }
@@ -0,0 +1,40 @@
1
+ import {
2
+ createWorkflow,
3
+ type WorkflowExecutionContext,
4
+ SequenceNodeBuilder,
5
+ } from '@jshookmcp/extension-sdk/workflow';
6
+
7
+ const workflowId = 'workflow.api-openapi-probe.v1';
8
+
9
+ export default createWorkflow(workflowId, 'OpenAPI Probe Batch')
10
+ .description('Probe standard API docs/openapi paths in one burst.')
11
+ .tags(['workflow', 'api', 'openapi', 'probe'])
12
+ .timeoutMs(2 * 60_000)
13
+ .defaultMaxConcurrency(1)
14
+ .buildGraph((ctx: WorkflowExecutionContext) => {
15
+ const baseUrl = ctx.getConfig('workflows.apiProbe.baseUrl', '');
16
+ if (!baseUrl) throw new Error('[workflow.api-openapi-probe] Missing required config: workflows.apiProbe.baseUrl');
17
+
18
+ const root = new SequenceNodeBuilder('api-openapi-probe-root');
19
+
20
+ root.tool('probe-openapi-paths', 'api_probe_batch', {
21
+ input: {
22
+ baseUrl,
23
+ method: 'GET',
24
+ paths: [
25
+ '/docs',
26
+ '/openapi.json',
27
+ '/api/docs',
28
+ '/swagger.json',
29
+ '/api/v1/openapi.json',
30
+ '/api/openapi.json',
31
+ ],
32
+ includeBodyStatuses: [200, 201, 204],
33
+ maxBodySnippetLength: 800,
34
+ autoInjectAuth: true,
35
+ },
36
+ });
37
+
38
+ return root;
39
+ })
40
+ .build();
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": 1,
3
+ "kind": "workflow",
4
+ "slug": "api-probe-batch",
5
+ "id": "workflow.api-probe-batch.v1",
6
+ "source": {
7
+ "type": "git",
8
+ "repo": "https://github.com/vmoranv/jshook_workflow_api_probe_batch",
9
+ "ref": "main",
10
+ "commit": "6cfdefb",
11
+ "subpath": ".",
12
+ "entry": "workflow.ts"
13
+ }
14
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 vmoranv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,45 @@
1
+ # api-probe-batch workflow
2
+
3
+ Declarative workflow for OpenAPI-first endpoint probing. It codifies a safe probing order: establish same-origin browser context first, probe documentation/discovery paths next, and only then probe business endpoints.
4
+
5
+ ## Entry File
6
+
7
+ - `workflow.ts`
8
+
9
+ ## Workflow ID
10
+
11
+ - `workflow.api-probe-batch.v1`
12
+
13
+ ## Structure
14
+
15
+ This workflow wraps the built-in `api_probe_batch` tool with a repeatable operator flow:
16
+
17
+ - `page_navigate` to a same-origin app page so localStorage auth can be reused
18
+ - First `api_probe_batch` call for standard OpenAPI / Swagger discovery paths
19
+ - Second `api_probe_batch` call for configured business endpoints
20
+ - `console_execute` summary step to mark completion for downstream runners
21
+
22
+ ## Tools Used
23
+
24
+ - `page_navigate`
25
+ - `api_probe_batch`
26
+ - `console_execute`
27
+
28
+ ## Config
29
+
30
+ - `workflows.apiProbe.appUrl`
31
+ - `workflows.apiProbe.baseUrl`
32
+ - `workflows.apiProbe.method`
33
+ - `workflows.apiProbe.autoInjectAuth`
34
+ - `workflows.apiProbe.maxBodySnippetLength`
35
+ - `workflows.apiProbe.discoveryIncludeBodies`
36
+ - `workflows.apiProbe.targetPaths`
37
+
38
+ ## Local Validation
39
+
40
+ 1. Run `pnpm install`.
41
+ 2. Run `pnpm typecheck`.
42
+ 3. Put this repo under a configured `workflows/` extension root.
43
+ 4. Run `extensions_reload` in `jshookmcp`.
44
+ 5. Confirm the workflow appears in `extensions_list`.
45
+ 6. Execute the workflow and verify the order is `navigate -> discovery probe -> target probe -> summary`.
@@ -0,0 +1,4 @@
1
+ name: api-probe-batch
2
+ description: Declarative workflow for OpenAPI-first probing of authenticated API endpoints.
3
+ author: vmoranv
4
+ source_repo: https://github.com/vmoranv/jshook_workflow_api_probe_batch
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@jshookmcpextension/workflow-api-probe-batch",
3
+ "scripts": {
4
+ "build": "tsc -p tsconfig.json",
5
+ "typecheck": "tsc --noEmit -p tsconfig.json"
6
+ },
7
+ "type": "module",
8
+ "dependencies": {
9
+ "@jshookmcp/extension-sdk": "^0.3.0",
10
+ "@modelcontextprotocol/sdk": "^1.27.1",
11
+ "dotenv": "^17.3.1"
12
+ },
13
+ "version": "0.1.0",
14
+ "engines": {
15
+ "node": ">=20.0.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^25.3.0",
19
+ "typescript": "^5.9.3"
20
+ },
21
+ "private": true,
22
+ "packageManager": "pnpm@10.28.2"
23
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2022"],
7
+ "strict": true,
8
+ "skipLibCheck": true,
9
+ "esModuleInterop": true,
10
+ "resolveJsonModule": true,
11
+ "rootDir": ".",
12
+ "outDir": "dist"
13
+ },
14
+ "include": ["workflow.ts"],
15
+ "exclude": ["dist", "node_modules"]
16
+ }
@@ -0,0 +1,111 @@
1
+ import type { WorkflowContract, WorkflowExecutionContext } from '@jshookmcp/extension-sdk/workflow';
2
+ import { toolNode, sequenceNode, branchNode } from '@jshookmcp/extension-sdk/workflow';
3
+
4
+ const DISCOVERY_PATHS = [
5
+ '/docs',
6
+ '/openapi.json',
7
+ '/api/docs',
8
+ '/swagger.json',
9
+ '/api/v1/openapi.json',
10
+ '/api/openapi.json',
11
+ ] as const;
12
+
13
+ const DEFAULT_TARGET_PATHS = ['/api/v1/auths/', '/api/v2/chats/', '/api/models'] as const;
14
+
15
+ function getOrigin(url: string): string {
16
+ const match = url.match(/^(https?:\/\/[^/]+)/i);
17
+ return match ? match[1] : url;
18
+ }
19
+
20
+ const apiProbeBatchWorkflow: WorkflowContract = {
21
+ kind: 'workflow-contract',
22
+ version: 1,
23
+ id: 'workflow.api-probe-batch.v1',
24
+ displayName: 'API Probe Batch',
25
+ description:
26
+ 'Navigate to an application origin, optionally extract auth context, probe OpenAPI discovery paths first, and then probe configured business endpoints.',
27
+ tags: ['workflow', 'api', 'probe', 'openapi', 'auth'],
28
+ timeoutMs: 5 * 60_000,
29
+ defaultMaxConcurrency: 1,
30
+
31
+ build(ctx) {
32
+ const appUrl = ctx.getConfig<string>('workflows.apiProbe.appUrl', '');
33
+ if (!appUrl) throw new Error('[workflow.api-probe-batch] Missing required config: workflows.apiProbe.appUrl');
34
+ const derivedBaseUrl = getOrigin(appUrl);
35
+ const baseUrl = ctx.getConfig<string>('workflows.apiProbe.baseUrl', derivedBaseUrl);
36
+ const method = ctx.getConfig<string>('workflows.apiProbe.method', 'GET');
37
+ const autoInjectAuth = ctx.getConfig<boolean>('workflows.apiProbe.autoInjectAuth', true);
38
+ const maxBodySnippetLength = ctx.getConfig<number>('workflows.apiProbe.maxBodySnippetLength', 800);
39
+ const includeBodyStatuses = ctx.getConfig<number[]>(
40
+ 'workflows.apiProbe.includeBodyStatuses',
41
+ [200, 201, 204, 400, 401, 403, 404],
42
+ );
43
+ const targetPaths = ctx.getConfig<string[]>(
44
+ 'workflows.apiProbe.targetPaths',
45
+ [...DEFAULT_TARGET_PATHS],
46
+ );
47
+ const runAuthExtract = ctx.getConfig<boolean>('workflows.apiProbe.runAuthExtract', true);
48
+
49
+ return sequenceNode('api-probe-batch-root')
50
+ .step(toolNode('navigate-app-origin', 'page_navigate').input({
51
+ url: appUrl,
52
+ waitUntil: 'domcontentloaded',
53
+ enableNetworkMonitoring: true,
54
+ }))
55
+ .step(branchNode('maybe-auth-extract', 'api_probe_run_auth_extract')
56
+ .predicateFn(() => runAuthExtract)
57
+ .whenTrue(toolNode('auth-extract', 'page_script_run').input({ name: 'auth_extract' }))
58
+ .whenFalse(toolNode('skip-auth-extract', 'console_execute').input({
59
+ expression: '({ skipped: true, step: "auth_extract", reason: "config_disabled" })',
60
+ })))
61
+ .step(toolNode('probe-openapi-discovery', 'api_probe_batch').input({
62
+ baseUrl,
63
+ method,
64
+ autoInjectAuth,
65
+ maxBodySnippetLength,
66
+ includeBodyStatuses,
67
+ paths: [...DISCOVERY_PATHS],
68
+ }))
69
+ .step(toolNode('probe-business-endpoints', 'api_probe_batch').input({
70
+ baseUrl,
71
+ method,
72
+ autoInjectAuth,
73
+ maxBodySnippetLength,
74
+ includeBodyStatuses,
75
+ paths: targetPaths,
76
+ }))
77
+ .step(toolNode('emit-summary', 'console_execute').input({
78
+ expression: `(${JSON.stringify({
79
+ status: 'api_probe_complete',
80
+ order: ['navigate', 'auth_extract', 'discovery', 'target'],
81
+ appUrl,
82
+ baseUrl,
83
+ targetPaths,
84
+ })})`,
85
+ }))
86
+ .build();
87
+ },
88
+
89
+ onStart(ctx) {
90
+ ctx.emitMetric('workflow_runs_total', 1, 'counter', {
91
+ workflowId: 'workflow.api-probe-batch.v1',
92
+ stage: 'start',
93
+ });
94
+ },
95
+
96
+ onFinish(ctx) {
97
+ ctx.emitMetric('workflow_runs_total', 1, 'counter', {
98
+ workflowId: 'workflow.api-probe-batch.v1',
99
+ stage: 'finish',
100
+ });
101
+ },
102
+
103
+ onError(ctx, error) {
104
+ ctx.emitMetric('workflow_errors_total', 1, 'counter', {
105
+ workflowId: 'workflow.api-probe-batch.v1',
106
+ error: error.name,
107
+ });
108
+ },
109
+ };
110
+
111
+ export default apiProbeBatchWorkflow;
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": 1,
3
+ "kind": "workflow",
4
+ "slug": "auth-bootstrap",
5
+ "id": "workflow.auth-bootstrap.v1",
6
+ "source": {
7
+ "type": "git",
8
+ "repo": "https://github.com/vmoranv/jshook_workflow_auth_bootstrap",
9
+ "ref": "main",
10
+ "commit": "162b033",
11
+ "subpath": ".",
12
+ "entry": "workflow.ts"
13
+ }
14
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 vmoranv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,74 @@
1
+ # auth-bootstrap workflow
2
+
3
+ Declarative workflow for bootstrapping web authentication using a form-driven flow plus optional temp-mail verification and auth extraction.
4
+
5
+ ## Workflow ID
6
+
7
+ - `workflow.auth-bootstrap.v1`
8
+
9
+ ## Capabilities
10
+
11
+ - Navigate to an auth/register page
12
+ - Wait for the first form field
13
+ - Fill a configurable fields map
14
+ - Click configurable checkbox selectors
15
+ - Submit the form and wait for completion
16
+ - Optionally chain:
17
+ - `workflow.temp-mail-open-latest.v1`
18
+ - `workflow.temp-mail-extract-link.v1`
19
+ - Optionally run:
20
+ - `page_script_run(auth_extract)`
21
+ - `network_extract_auth`
22
+ - Emit a concise summary for downstream orchestration
23
+
24
+ ## Config
25
+
26
+ Prefix: `workflows.authBootstrap.*`
27
+
28
+ - `authUrl`
29
+ - `waitUntil`
30
+ - `clearCookiesFirst`
31
+ - `clearStorageFirst`
32
+ - `preAuthClearUrl`
33
+ - `fields`
34
+ - `firstFieldSelector`
35
+ - `submitSelector`
36
+ - `checkboxSelectors`
37
+ - `typingDelay`
38
+ - `afterSubmitWaitMs`
39
+ - `runMailboxVerification`
40
+ - `mailboxUrl`
41
+ - `mailboxReadySelector`
42
+ - `mailboxRefreshSelector`
43
+ - `mailboxItemSelector`
44
+ - `mailboxHrefIncludes`
45
+ - `mailboxHrefRegex`
46
+ - `mailboxTextIncludes`
47
+ - `mailboxTextRegex`
48
+ - `mailboxOpenOrder`
49
+ - `verificationWaitUntil`
50
+ - `verificationInitialWaitMs`
51
+ - `verificationRetryWaitMs`
52
+ - `verificationMaxWaitAttempts`
53
+ - `verificationReadySelector`
54
+ - `verificationReadyText`
55
+ - `verificationTitleBlocklist`
56
+ - `verificationBodyBlocklist`
57
+ - `verificationExpectedContextHints`
58
+ - `verificationLinkSelector`
59
+ - `verificationHrefIncludes`
60
+ - `verificationTextIncludes`
61
+ - `verificationRegexPattern`
62
+ - `verificationRegexFlags`
63
+ - `verificationMaxLinks`
64
+ - `verificationIncludeFallbackLinks`
65
+ - `verificationFallbackMaxLinks`
66
+ - `openVerificationLink`
67
+ - `verificationWaitAfterOpenMs`
68
+ - `runAuthExtract`
69
+ - `runNetworkAuthScan`
70
+ - `authMinConfidence`
71
+
72
+ ## Notes
73
+
74
+ This workflow is generic and does not hardcode Qwen-specific selectors or mail providers. It expects the caller to provide the correct field names, submit selector, and mailbox matching patterns for the target site.
@@ -0,0 +1,4 @@
1
+ name: auth-bootstrap
2
+ description: Declarative workflow for bootstrapping web authentication via form submission, optional temp-mail verification, and auth artifact extraction.
3
+ author: vmoranv
4
+ source_repo: https://github.com/vmoranv/jshook_workflow_auth_bootstrap
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@jshookmcpextension/workflow-auth-bootstrap",
3
+ "scripts": {
4
+ "build": "tsc -p tsconfig.json",
5
+ "typecheck": "tsc --noEmit -p tsconfig.json"
6
+ },
7
+ "type": "module",
8
+ "dependencies": {
9
+ "@jshookmcp/extension-sdk": "^0.3.0",
10
+ "@modelcontextprotocol/sdk": "^1.27.1",
11
+ "dotenv": "^17.3.1"
12
+ },
13
+ "version": "0.1.0",
14
+ "engines": {
15
+ "node": ">=20.0.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^25.3.0",
19
+ "typescript": "^5.9.3"
20
+ },
21
+ "private": true,
22
+ "packageManager": "pnpm@10.28.2"
23
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2022"],
7
+ "strict": true,
8
+ "skipLibCheck": true,
9
+ "esModuleInterop": true,
10
+ "resolveJsonModule": true,
11
+ "rootDir": ".",
12
+ "outDir": "dist"
13
+ },
14
+ "include": ["workflow.ts"],
15
+ "exclude": ["dist", "node_modules"]
16
+ }
@@ -0,0 +1,141 @@
1
+ import type { WorkflowContract } from '@jshookmcp/extension-sdk/workflow';
2
+ import { toolNode, sequenceNode, branchNode } from '@jshookmcp/extension-sdk/workflow';
3
+
4
+ const workflowId = 'workflow.auth-bootstrap.v1';
5
+
6
+ const workflow: WorkflowContract = {
7
+ kind: 'workflow-contract',
8
+ version: 1,
9
+ id: workflowId,
10
+ displayName: 'Auth Bootstrap',
11
+ description:
12
+ 'Bootstrap web authentication by delegating to register/temp-mail workflows, then extract auth artifacts.',
13
+ tags: ['workflow', 'auth', 'bootstrap', 'registration', 'verification'],
14
+ timeoutMs: 10 * 60_000,
15
+ defaultMaxConcurrency: 1,
16
+
17
+ build(ctx) {
18
+ const prefix = 'workflows.authBootstrap';
19
+ const registerWorkflowId = ctx.getConfig<string>(`${prefix}.registerWorkflowId`, 'workflow.register-account-flow.v1');
20
+ const registerUrl = ctx.getConfig<string>(`${prefix}.registerUrl`, '');
21
+ if (!registerUrl) throw new Error('[workflow.auth-bootstrap] Missing required config: workflows.authBootstrap.registerUrl');
22
+ const clearCookiesFirst = ctx.getConfig<boolean>(`${prefix}.clearCookiesFirst`, false);
23
+ const clearStorageFirst = ctx.getConfig<boolean>(`${prefix}.clearStorageFirst`, false);
24
+ const preAuthClearUrl = ctx.getConfig<string>(`${prefix}.preAuthClearUrl`, registerUrl.replace(/(https?:\/\/[^/]+).*/, '$1/'));
25
+ const username = ctx.getConfig<string>(`${prefix}.username`, '');
26
+ const email = ctx.getConfig<string>(`${prefix}.email`, '');
27
+ const password = ctx.getConfig<string>(`${prefix}.password`, '');
28
+ if (!username || !email || !password) {
29
+ throw new Error(`[workflow.auth-bootstrap] Missing required config: ${[!username && 'username', !email && 'email', !password && 'password'].filter(Boolean).join(', ')} (prefix: workflows.authBootstrap.*)`);
30
+ }
31
+ const includeConfirmPassword = ctx.getConfig<boolean>(`${prefix}.includeConfirmPassword`, true);
32
+ const confirmPasswordFieldName = ctx.getConfig<string>(`${prefix}.confirmPasswordFieldName`, 'checkPassword');
33
+ const extraFields = ctx.getConfig<Record<string, unknown>>(`${prefix}.extraFields`, {});
34
+ const checkboxSelectors = ctx.getConfig<string[]>(`${prefix}.checkboxSelectors`, []);
35
+ const submitSelector = ctx.getConfig<string>(`${prefix}.submitSelector`, "button[type='submit']");
36
+ const registerTimeoutMs = ctx.getConfig<number>(`${prefix}.registerTimeoutMs`, 90_000);
37
+
38
+ const enableEmailVerification = ctx.getConfig<boolean>(`${prefix}.enableEmailVerification`, false);
39
+ const emailProviderUrl = ctx.getConfig<string>(`${prefix}.emailProviderUrl`, '');
40
+ const mailOpenWorkflowId = ctx.getConfig<string>(`${prefix}.mailOpenWorkflowId`, 'workflow.temp-mail-open-latest.v1');
41
+ const mailOpenConfig = ctx.getConfig<Record<string, unknown>>(`${prefix}.mailOpenConfig`, {});
42
+ const mailExtractWorkflowId = ctx.getConfig<string>(`${prefix}.mailExtractWorkflowId`, 'workflow.temp-mail-extract-link.v1');
43
+ const mailExtractConfig = ctx.getConfig<Record<string, unknown>>(`${prefix}.mailExtractConfig`, {});
44
+ const postVerifyNavigateUrl = ctx.getConfig<string>(`${prefix}.postVerifyNavigateUrl`, '');
45
+
46
+ const authExtractPageUrl = ctx.getConfig<string>(`${prefix}.authExtractPageUrl`, '');
47
+ const runAuthExtract = ctx.getConfig<boolean>(`${prefix}.runAuthExtract`, true);
48
+ const runNetworkAuthExtract = ctx.getConfig<boolean>(`${prefix}.runNetworkAuthExtract`, true);
49
+ const authMinConfidence = ctx.getConfig<number>(`${prefix}.authMinConfidence`, 0.3);
50
+
51
+ const fields: Record<string, unknown> = { username, email, password, ...extraFields };
52
+ if (includeConfirmPassword) fields[confirmPasswordFieldName] = password;
53
+
54
+ const registerConfig = {
55
+ workflows: {
56
+ registerAccount: {
57
+ registerUrl, username, email, password,
58
+ includeConfirmPassword, confirmPasswordFieldName,
59
+ extraFields, checkboxSelectors, submitSelector,
60
+ timeoutMs: registerTimeoutMs,
61
+ },
62
+ },
63
+ };
64
+
65
+ const mailboxBranch = branchNode('maybe-email-verification', 'auth_bootstrap_enable_email_verification')
66
+ .predicateFn(() => enableEmailVerification && Boolean(emailProviderUrl))
67
+ .whenTrue(sequenceNode('email-verification-sequence')
68
+ .step(toolNode('open-latest-mail', 'run_extension_workflow')
69
+ .input({ workflowId: mailOpenWorkflowId, config: { workflows: { tempMailOpenLatest: { mailboxUrl: emailProviderUrl, ...mailOpenConfig } } } })
70
+ .timeout(180_000))
71
+ .step(toolNode('extract-verification-link', 'run_extension_workflow')
72
+ .input({ workflowId: mailExtractWorkflowId, config: { workflows: { tempMailExtractLink: { detailUrl: '', ...mailExtractConfig } } } })
73
+ .timeout(180_000))
74
+ .step(branchNode('maybe-post-verify-navigate', 'auth_bootstrap_post_verify_navigate')
75
+ .predicateFn(() => Boolean(postVerifyNavigateUrl))
76
+ .whenTrue(toolNode('navigate-post-verify-page', 'page_navigate').input({ url: postVerifyNavigateUrl, waitUntil: 'networkidle', enableNetworkMonitoring: true }))
77
+ .whenFalse(toolNode('skip-post-verify-navigate', 'console_execute').input({ expression: '({ skipped: true, step: "post_verify_navigate", reason: "postVerifyNavigateUrl not configured" })' }))))
78
+ .whenFalse(toolNode('skip-email-verification', 'console_execute').input({ expression: '({ skipped: true, step: "email_verification", reason: "config_disabled" })' }));
79
+
80
+ const authExtractBranch = branchNode('maybe-auth-extract', 'auth_bootstrap_run_auth_extract')
81
+ .predicateFn(() => runAuthExtract)
82
+ .whenTrue(sequenceNode('auth-extract-sequence')
83
+ .step(branchNode('maybe-navigate-auth-extract-page', 'auth_bootstrap_auth_extract_page_url')
84
+ .predicateFn(() => Boolean(authExtractPageUrl))
85
+ .whenTrue(toolNode('navigate-auth-extract-page', 'page_navigate').input({ url: authExtractPageUrl, waitUntil: 'networkidle', enableNetworkMonitoring: true }))
86
+ .whenFalse(toolNode('skip-auth-extract-page-nav', 'console_execute').input({ expression: '({ skipped: true, step: "auth_extract_page_nav", reason: "authExtractPageUrl not configured" })' })))
87
+ .step(toolNode('auth-extract', 'page_script_run').input({ name: 'auth_extract' })))
88
+ .whenFalse(toolNode('skip-auth-extract', 'console_execute').input({ expression: '({ skipped: true, step: "auth_extract", reason: "config_disabled" })' }));
89
+
90
+ const networkAuthBranch = branchNode('maybe-network-auth-extract', 'auth_bootstrap_run_network_auth_extract')
91
+ .predicateFn(() => runNetworkAuthExtract)
92
+ .whenTrue(toolNode('network-auth-extract', 'network_extract_auth').input({ minConfidence: authMinConfidence }))
93
+ .whenFalse(toolNode('skip-network-auth-extract', 'console_execute').input({ expression: '({ skipped: true, step: "network_auth_extract", reason: "config_disabled" })' }));
94
+
95
+ return sequenceNode('auth-bootstrap-root')
96
+ .step(branchNode('maybe-preclear-auth-state', 'auth_bootstrap_preclear_auth_state')
97
+ .predicateFn(() => clearCookiesFirst || clearStorageFirst)
98
+ .whenTrue(sequenceNode('preclear-auth-state-sequence')
99
+ .step(toolNode('navigate-preclear-page', 'page_navigate').input({ url: preAuthClearUrl, waitUntil: 'domcontentloaded', enableNetworkMonitoring: true }))
100
+ .step(branchNode('maybe-clear-cookies', 'auth_bootstrap_clear_cookies_first')
101
+ .predicateFn(() => clearCookiesFirst)
102
+ .whenTrue(toolNode('clear-cookies', 'page_clear_cookies').input({}))
103
+ .whenFalse(toolNode('skip-clear-cookies', 'console_execute').input({ expression: '({ skipped: true, step: "clear_cookies", reason: "config_disabled" })' })))
104
+ .step(branchNode('maybe-clear-storage', 'auth_bootstrap_clear_storage_first')
105
+ .predicateFn(() => clearStorageFirst)
106
+ .whenTrue(toolNode('clear-web-storage', 'page_evaluate').input({ code: '(() => { try { localStorage.clear(); sessionStorage.clear(); } catch {} return { ok: true, href: location.href }; })()' }))
107
+ .whenFalse(toolNode('skip-clear-storage', 'console_execute').input({ expression: '({ skipped: true, step: "clear_storage", reason: "config_disabled" })' }))))
108
+ .whenFalse(toolNode('skip-preclear-auth-state', 'console_execute').input({ expression: '({ skipped: true, step: "preclear_auth_state", reason: "all clear flags disabled" })' })))
109
+ .step(toolNode('run-register-workflow', 'run_extension_workflow')
110
+ .input({ workflowId: registerWorkflowId, config: registerConfig })
111
+ .timeout(Math.max(180_000, registerTimeoutMs + 60_000)))
112
+ .step(mailboxBranch)
113
+ .step(authExtractBranch)
114
+ .step(networkAuthBranch)
115
+ .step(toolNode('emit-summary', 'console_execute').input({
116
+ expression: `(${JSON.stringify({
117
+ workflowId, registerWorkflowId, registerUrl, email,
118
+ enableEmailVerification, emailProviderUrl,
119
+ mailOpenWorkflowId, mailExtractWorkflowId,
120
+ postVerifyNavigateUrl, authExtractPageUrl,
121
+ runAuthExtract, runNetworkAuthExtract, authMinConfidence,
122
+ note: 'Inspect nested workflow outputs for form submit, mail opening, link extraction, and final auth artifacts.',
123
+ })})`,
124
+ }))
125
+ .build();
126
+ },
127
+
128
+ onStart(ctx) {
129
+ ctx.emitMetric('workflow_runs_total', 1, 'counter', { workflowId, stage: 'start' });
130
+ },
131
+
132
+ onFinish(ctx) {
133
+ ctx.emitMetric('workflow_runs_total', 1, 'counter', { workflowId, stage: 'finish' });
134
+ },
135
+
136
+ onError(ctx, error) {
137
+ ctx.emitMetric('workflow_errors_total', 1, 'counter', { workflowId, error: error.name });
138
+ },
139
+ };
140
+
141
+ export default workflow;
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": 1,
3
+ "kind": "workflow",
4
+ "slug": "auth-extract",
5
+ "id": "workflow.auth-extract.v1",
6
+ "source": {
7
+ "type": "git",
8
+ "repo": "https://github.com/vmoranv/jshook_workflow_auth_extract",
9
+ "ref": "main",
10
+ "commit": "abcb3e8ef8e54a9742f1f6d51edbb2e551e72b40",
11
+ "subpath": ".",
12
+ "entry": "workflow.ts"
13
+ }
14
+ }
@@ -0,0 +1,6 @@
1
+ name: auth-extract
2
+ description: JSHook workflow for auth-extract
3
+ author: vmoranv
4
+ tags:
5
+ - workflow
6
+ - auth-extract
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "jshook-workflow-auth-extract",
3
+ "private": true,
4
+ "version": "0.1.0",
5
+ "description": "jshookmcp workflow: auth-extract",
6
+ "type": "module",
7
+ "packageManager": "pnpm@10.28.2",
8
+ "scripts": {
9
+ "build": "tsc -p tsconfig.json",
10
+ "check": "tsc -p tsconfig.json --noEmit"
11
+ },
12
+ "dependencies": {
13
+ "@jshookmcp/extension-sdk": "^0.3.0"
14
+ },
15
+ "devDependencies": {
16
+ "@types/node": "^25.3.0",
17
+ "typescript": "^5.9.3"
18
+ },
19
+ "engines": {
20
+ "node": ">=20.0.0"
21
+ }
22
+ }