@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.
- package/README.md +5 -5
- package/README.zh.md +5 -5
- package/dist/packages/extension-sdk/src/workflow.d.ts +17 -2
- package/dist/packages/extension-sdk/src/workflow.js +36 -0
- package/dist/src/modules/browser/BrowserPool.d.ts +49 -0
- package/dist/src/modules/browser/BrowserPool.js +288 -0
- package/dist/src/modules/deobfuscator/AdvancedDeobfuscator.d.ts +5 -0
- package/dist/src/modules/deobfuscator/AdvancedDeobfuscator.js +43 -2
- package/dist/src/modules/deobfuscator/Deobfuscator.js +5 -0
- package/dist/src/modules/external/ExternalToolRunner.js +1 -1
- package/dist/src/server/MCPServer.context.d.ts +1 -0
- package/dist/src/server/domains/browser/handlers/stealth-injection.d.ts +1 -0
- package/dist/src/server/domains/browser/handlers/stealth-injection.js +3 -0
- package/dist/src/server/domains/shared-state-board/definitions.d.ts +2 -0
- package/dist/src/server/domains/shared-state-board/definitions.js +78 -0
- package/dist/src/server/domains/shared-state-board/handlers.impl.d.ts +58 -0
- package/dist/src/server/domains/shared-state-board/handlers.impl.js +419 -0
- package/dist/src/server/domains/shared-state-board/index.d.ts +2 -0
- package/dist/src/server/domains/shared-state-board/index.js +2 -0
- package/dist/src/server/domains/shared-state-board/manifest.d.ts +57 -0
- package/dist/src/server/domains/shared-state-board/manifest.js +74 -0
- package/dist/src/server/http/SseStream.d.ts +21 -0
- package/dist/src/server/http/SseStream.js +129 -0
- package/dist/src/server/teams/TeamManager.d.ts +43 -0
- package/dist/src/server/teams/TeamManager.js +238 -0
- package/dist/src/server/teams/index.d.ts +1 -0
- package/dist/src/server/teams/index.js +1 -0
- package/dist/src/server/workflows/WorkflowContract.d.ts +20 -4
- package/dist/src/server/workflows/WorkflowContract.js +40 -0
- package/dist/src/server/workflows/WorkflowEngine.js +190 -13
- package/dist/src/types/deobfuscator.d.ts +1 -0
- package/dist/src/utils/cache/CachedDecorator.d.ts +8 -0
- package/dist/src/utils/cache/CachedDecorator.js +55 -0
- package/dist/src/utils/cache/PersistentCache.d.ts +33 -0
- package/dist/src/utils/cache/PersistentCache.js +246 -0
- package/dist/src/utils/cache/index.d.ts +2 -0
- package/dist/src/utils/cache/index.js +2 -0
- package/package.json +11 -12
- package/scripts/postinstall.cjs +54 -27
- package/workflows/anti-bot-diagnoser/.jshook-install.json +14 -0
- package/workflows/anti-bot-diagnoser/LICENSE +21 -0
- package/workflows/anti-bot-diagnoser/README.md +105 -0
- package/workflows/anti-bot-diagnoser/docs/agent-recipes.md +44 -0
- package/workflows/anti-bot-diagnoser/meta.yaml +6 -0
- package/workflows/anti-bot-diagnoser/package.json +22 -0
- package/workflows/anti-bot-diagnoser/tsconfig.json +15 -0
- package/workflows/anti-bot-diagnoser/workflow.ts +224 -0
- package/workflows/api-openapi-probe/.jshook-install.json +14 -0
- package/workflows/api-openapi-probe/meta.yaml +6 -0
- package/workflows/api-openapi-probe/package.json +22 -0
- package/workflows/api-openapi-probe/pnpm-lock.yaml +819 -0
- package/workflows/api-openapi-probe/tsconfig.json +15 -0
- package/workflows/api-openapi-probe/workflow.ts +40 -0
- package/workflows/api-probe-batch/.jshook-install.json +14 -0
- package/workflows/api-probe-batch/LICENSE +21 -0
- package/workflows/api-probe-batch/README.md +45 -0
- package/workflows/api-probe-batch/meta.yaml +4 -0
- package/workflows/api-probe-batch/package.json +23 -0
- package/workflows/api-probe-batch/tsconfig.json +16 -0
- package/workflows/api-probe-batch/workflow.ts +111 -0
- package/workflows/auth-bootstrap/.jshook-install.json +14 -0
- package/workflows/auth-bootstrap/LICENSE +21 -0
- package/workflows/auth-bootstrap/README.md +74 -0
- package/workflows/auth-bootstrap/meta.yaml +4 -0
- package/workflows/auth-bootstrap/package.json +23 -0
- package/workflows/auth-bootstrap/tsconfig.json +16 -0
- package/workflows/auth-bootstrap/workflow.ts +141 -0
- package/workflows/auth-extract/.jshook-install.json +14 -0
- package/workflows/auth-extract/meta.yaml +6 -0
- package/workflows/auth-extract/package.json +22 -0
- package/workflows/auth-extract/pnpm-lock.yaml +819 -0
- package/workflows/auth-extract/tsconfig.json +15 -0
- package/workflows/auth-extract/workflow.ts +36 -0
- package/workflows/auth-surface-mapper/.jshook-install.json +14 -0
- package/workflows/auth-surface-mapper/meta.yaml +6 -0
- package/workflows/auth-surface-mapper/package.json +22 -0
- package/workflows/auth-surface-mapper/pnpm-lock.yaml +819 -0
- package/workflows/auth-surface-mapper/tsconfig.json +15 -0
- package/workflows/auth-surface-mapper/workflow.ts +104 -0
- package/workflows/batch-register/.jshook-install.json +14 -0
- package/workflows/batch-register/LICENSE +21 -0
- package/workflows/batch-register/README.md +39 -0
- package/workflows/batch-register/meta.yaml +4 -0
- package/workflows/batch-register/package.json +23 -0
- package/workflows/batch-register/tsconfig.json +16 -0
- package/workflows/batch-register/workflow.ts +67 -0
- package/workflows/bundle-recovery/.jshook-install.json +14 -0
- package/workflows/bundle-recovery/LICENSE +21 -0
- package/workflows/bundle-recovery/README.md +105 -0
- package/workflows/bundle-recovery/docs/agent-recipes.md +44 -0
- package/workflows/bundle-recovery/meta.yaml +6 -0
- package/workflows/bundle-recovery/package.json +22 -0
- package/workflows/bundle-recovery/tsconfig.json +15 -0
- package/workflows/bundle-recovery/workflow.ts +179 -0
- package/workflows/challenge-detector/.jshook-install.json +14 -0
- package/workflows/challenge-detector/meta.yaml +14 -0
- package/workflows/challenge-detector/package.json +22 -0
- package/workflows/challenge-detector/pnpm-lock.yaml +819 -0
- package/workflows/challenge-detector/tsconfig.json +15 -0
- package/workflows/challenge-detector/workflow.ts +298 -0
- package/workflows/deobfuscation-pipeline/.jshook-install.json +14 -0
- package/workflows/deobfuscation-pipeline/meta.yaml +6 -0
- package/workflows/deobfuscation-pipeline/package.json +22 -0
- package/workflows/deobfuscation-pipeline/pnpm-lock.yaml +819 -0
- package/workflows/deobfuscation-pipeline/tsconfig.json +15 -0
- package/workflows/deobfuscation-pipeline/workflow.ts +119 -0
- package/workflows/electron-bridge-mapper/.jshook-install.json +14 -0
- package/workflows/electron-bridge-mapper/meta.yaml +6 -0
- package/workflows/electron-bridge-mapper/package.json +22 -0
- package/workflows/electron-bridge-mapper/pnpm-lock.yaml +819 -0
- package/workflows/electron-bridge-mapper/tsconfig.json +15 -0
- package/workflows/electron-bridge-mapper/workflow.ts +125 -0
- package/workflows/evidence-pack/.jshook-install.json +14 -0
- package/workflows/evidence-pack/LICENSE +21 -0
- package/workflows/evidence-pack/README.md +105 -0
- package/workflows/evidence-pack/docs/agent-recipes.md +44 -0
- package/workflows/evidence-pack/meta.yaml +6 -0
- package/workflows/evidence-pack/package.json +22 -0
- package/workflows/evidence-pack/tsconfig.json +15 -0
- package/workflows/evidence-pack/workflow.ts +154 -0
- package/workflows/js-bundle-search/.jshook-install.json +14 -0
- package/workflows/js-bundle-search/LICENSE +21 -0
- package/workflows/js-bundle-search/README.md +46 -0
- package/workflows/js-bundle-search/meta.yaml +4 -0
- package/workflows/js-bundle-search/package.json +23 -0
- package/workflows/js-bundle-search/tsconfig.json +16 -0
- package/workflows/js-bundle-search/workflow.ts +118 -0
- package/workflows/protocol-registry/.jshook-install.json +14 -0
- package/workflows/protocol-registry/meta.yaml +6 -0
- package/workflows/protocol-registry/package.json +22 -0
- package/workflows/protocol-registry/pnpm-lock.yaml +819 -0
- package/workflows/protocol-registry/tsconfig.json +15 -0
- package/workflows/protocol-registry/workflow.ts +107 -0
- package/workflows/qwen-mail-open-latest/meta.yaml +7 -0
- package/workflows/qwen-mail-open-latest/package.json +22 -0
- package/workflows/qwen-mail-open-latest/pnpm-lock.yaml +819 -0
- package/workflows/qwen-mail-open-latest/tsconfig.json +15 -0
- package/workflows/qwen-mail-open-latest/workflow.ts +77 -0
- package/workflows/register-account-flow/.jshook-install.json +14 -0
- package/workflows/register-account-flow/LICENSE +21 -0
- package/workflows/register-account-flow/README.md +64 -0
- package/workflows/register-account-flow/meta.yaml +4 -0
- package/workflows/register-account-flow/package.json +23 -0
- package/workflows/register-account-flow/tsconfig.json +16 -0
- package/workflows/register-account-flow/workflow.ts +127 -0
- package/workflows/replay-lab/.jshook-install.json +14 -0
- package/workflows/replay-lab/meta.yaml +6 -0
- package/workflows/replay-lab/package.json +22 -0
- package/workflows/replay-lab/pnpm-lock.yaml +819 -0
- package/workflows/replay-lab/tsconfig.json +15 -0
- package/workflows/replay-lab/workflow.ts +106 -0
- package/workflows/script-evidence-scan/.jshook-install.json +14 -0
- package/workflows/script-evidence-scan/LICENSE +21 -0
- package/workflows/script-evidence-scan/README.md +61 -0
- package/workflows/script-evidence-scan/meta.yaml +4 -0
- package/workflows/script-evidence-scan/package.json +23 -0
- package/workflows/script-evidence-scan/tsconfig.json +16 -0
- package/workflows/script-evidence-scan/workflow.ts +89 -0
- package/workflows/signature-hunter/.jshook-install.json +14 -0
- package/workflows/signature-hunter/LICENSE +21 -0
- package/workflows/signature-hunter/README.md +105 -0
- package/workflows/signature-hunter/docs/agent-recipes.md +44 -0
- package/workflows/signature-hunter/meta.yaml +6 -0
- package/workflows/signature-hunter/package.json +22 -0
- package/workflows/signature-hunter/tsconfig.json +15 -0
- package/workflows/signature-hunter/workflow.ts +170 -0
- package/workflows/signing-lineage/.jshook-install.json +14 -0
- package/workflows/signing-lineage/meta.yaml +6 -0
- package/workflows/signing-lineage/package.json +22 -0
- package/workflows/signing-lineage/pnpm-lock.yaml +819 -0
- package/workflows/signing-lineage/tsconfig.json +15 -0
- package/workflows/signing-lineage/workflow.ts +120 -0
- package/workflows/temp-mail-extract-link/.jshook-install.json +14 -0
- package/workflows/temp-mail-extract-link/LICENSE +21 -0
- package/workflows/temp-mail-extract-link/README.md +71 -0
- package/workflows/temp-mail-extract-link/meta.yaml +4 -0
- package/workflows/temp-mail-extract-link/package.json +23 -0
- package/workflows/temp-mail-extract-link/tsconfig.json +16 -0
- package/workflows/temp-mail-extract-link/workflow.ts +221 -0
- package/workflows/temp-mail-open-latest/.jshook-install.json +14 -0
- package/workflows/temp-mail-open-latest/LICENSE +21 -0
- package/workflows/temp-mail-open-latest/README.md +61 -0
- package/workflows/temp-mail-open-latest/meta.yaml +4 -0
- package/workflows/temp-mail-open-latest/package.json +23 -0
- package/workflows/temp-mail-open-latest/tsconfig.json +16 -0
- package/workflows/temp-mail-open-latest/workflow.ts +136 -0
- package/workflows/template/.jshook-install.json +14 -0
- package/workflows/template/LICENSE +21 -0
- package/workflows/template/README.md +45 -0
- package/workflows/template/docs/SKILL.md +111 -0
- package/workflows/template/meta.yaml +6 -0
- package/workflows/template/package.json +22 -0
- package/workflows/template/pnpm-lock.yaml +819 -0
- package/workflows/template/tsconfig.json +15 -0
- package/workflows/template/workflow.ts +73 -0
- package/workflows/web-api-capture-session/.jshook-install.json +14 -0
- package/workflows/web-api-capture-session/LICENSE +21 -0
- package/workflows/web-api-capture-session/README.md +64 -0
- package/workflows/web-api-capture-session/meta.yaml +4 -0
- package/workflows/web-api-capture-session/package.json +23 -0
- package/workflows/web-api-capture-session/tsconfig.json +16 -0
- package/workflows/web-api-capture-session/workflow.ts +124 -0
- package/workflows/ws-protocol-lifter/.jshook-install.json +14 -0
- package/workflows/ws-protocol-lifter/LICENSE +21 -0
- package/workflows/ws-protocol-lifter/README.md +105 -0
- package/workflows/ws-protocol-lifter/docs/agent-recipes.md +44 -0
- package/workflows/ws-protocol-lifter/meta.yaml +6 -0
- package/workflows/ws-protocol-lifter/package.json +22 -0
- package/workflows/ws-protocol-lifter/tsconfig.json +15 -0
- 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,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,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,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
|
+
}
|