@yusufffararatt/dombridge-mcp 2.7.5
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 +559 -0
- package/bin/cli.js +88 -0
- package/package.json +54 -0
- package/src/bridge/http-server.js +290 -0
- package/src/bridge/middleware.js +56 -0
- package/src/bridge/routes.js +1003 -0
- package/src/bridge-daemon.js +172 -0
- package/src/cli/auto-config.js +120 -0
- package/src/constants.js +13 -0
- package/src/index.js +279 -0
- package/src/mcp-bridge.js +136 -0
- package/src/metrics/error-codes.js +44 -0
- package/src/metrics/index.js +3 -0
- package/src/metrics/metrics-db.js +269 -0
- package/src/metrics/metrics-recorder.js +240 -0
- package/src/metrics/metrics-report.js +146 -0
- package/src/profiles/profile-db.js +159 -0
- package/src/profiles/profile-enricher.js +333 -0
- package/src/profiles/profile-manager.js +563 -0
- package/src/profiles/profile-repo.js +183 -0
- package/src/state/bridge-client.js +272 -0
- package/src/state/bridge-persistence.js +205 -0
- package/src/state/cache.js +38 -0
- package/src/state/extension-state.js +321 -0
- package/src/tools/action_tools.js +218 -0
- package/src/tools/analyze-page.js +247 -0
- package/src/tools/debug-mcp-state.js +172 -0
- package/src/tools/discover-apis.js +186 -0
- package/src/tools/execute-js.js +284 -0
- package/src/tools/export-session.js +171 -0
- package/src/tools/extract-data.js +395 -0
- package/src/tools/get-element.js +281 -0
- package/src/tools/get-network-trace.js +471 -0
- package/src/tools/index.js +110 -0
- package/src/tools/manage-site-profile.js +153 -0
- package/src/tools/paginate.js +444 -0
- package/src/tools/quick-scan.js +418 -0
- package/src/tools/screenshot_tools.js +117 -0
- package/src/utils/circuit-breaker.js +112 -0
- package/src/utils/extract-density.js +21 -0
- package/src/utils/logger.js +31 -0
- package/src/utils/paginate-detector.js +24 -0
- package/src/utils/rate-limiter.js +244 -0
- package/src/utils/run-script.js +37 -0
- package/src/utils/selector-validator.js +95 -0
- package/src/utils/state-validator.js +354 -0
- package/src/utils/tab-resolver.js +70 -0
- package/src/utils/workflow-helper.js +292 -0
- package/src/utils/workflow-state.js +177 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow State
|
|
3
|
+
* Tracks per-tab history and per-domain profile usage.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { loadProfile, getProfileFieldTimestamp } from '../profiles/profile-manager.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {object} TabState
|
|
10
|
+
* @property {string} url
|
|
11
|
+
* @property {string} domain
|
|
12
|
+
* @property {number|null} lastQuickScanAt
|
|
13
|
+
* @property {number|null} lastAnalyzeAt
|
|
14
|
+
* @property {number|null} lastDiscoverApisAt
|
|
15
|
+
* @property {number|null} lastProfileLoadAt
|
|
16
|
+
* @property {number|null} lastProfileCheckAt
|
|
17
|
+
* @property {number|null} lastSelectedElementAt
|
|
18
|
+
* @property {number|null} lastNavigationAt
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {object} ProfileState
|
|
23
|
+
* @property {boolean} exists
|
|
24
|
+
* @property {number|null} lastLoadedAt
|
|
25
|
+
* @property {number|null} lastSavedAt
|
|
26
|
+
* @property {number|null} lastCheckedAt
|
|
27
|
+
* @property {number|null} freshUntil
|
|
28
|
+
* @property {Record<string, string|number>} fieldFreshness
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
const PROFILE_FRESHNESS_MS = 15 * 60 * 1000;
|
|
32
|
+
|
|
33
|
+
const STALENESS_THRESHOLDS = {
|
|
34
|
+
framework: 7 * 24 * 60 * 60 * 1000,
|
|
35
|
+
apiEndpoints: 24 * 60 * 60 * 1000,
|
|
36
|
+
dataSchema: 3 * 24 * 60 * 60 * 1000,
|
|
37
|
+
authInfo: 7 * 24 * 60 * 60 * 1000,
|
|
38
|
+
pageCharacteristics: 3 * 24 * 60 * 60 * 1000,
|
|
39
|
+
knownPaths: 3 * 24 * 60 * 60 * 1000,
|
|
40
|
+
default: 24 * 60 * 60 * 1000
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const workflowState = {
|
|
44
|
+
tabs: {},
|
|
45
|
+
profiles: {}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
function extractDomain(url) {
|
|
49
|
+
if (!url) return '';
|
|
50
|
+
try {
|
|
51
|
+
return new URL(url).hostname;
|
|
52
|
+
} catch {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function createEmptyTabState(url) {
|
|
58
|
+
return {
|
|
59
|
+
url,
|
|
60
|
+
domain: extractDomain(url),
|
|
61
|
+
lastQuickScanAt: null,
|
|
62
|
+
lastAnalyzeAt: null,
|
|
63
|
+
lastDiscoverApisAt: null,
|
|
64
|
+
lastProfileLoadAt: null,
|
|
65
|
+
lastProfileCheckAt: null,
|
|
66
|
+
lastSelectedElementAt: null,
|
|
67
|
+
lastNavigationAt: null
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getTabState(tabId, url) {
|
|
72
|
+
if (!workflowState.tabs[tabId]) {
|
|
73
|
+
workflowState.tabs[tabId] = createEmptyTabState(url || '');
|
|
74
|
+
}
|
|
75
|
+
return workflowState.tabs[tabId];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function invalidateTabState(tabId, newUrl) {
|
|
79
|
+
workflowState.tabs[tabId] = createEmptyTabState(newUrl);
|
|
80
|
+
workflowState.tabs[tabId].lastNavigationAt = Date.now();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function touchTabField(tabId, field, url) {
|
|
84
|
+
const state = getTabState(tabId, url);
|
|
85
|
+
|
|
86
|
+
if (url && url !== state.url) {
|
|
87
|
+
invalidateTabState(tabId, url);
|
|
88
|
+
workflowState.tabs[tabId][field] = Date.now();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
state[field] = Date.now();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function removeTabState(tabId) {
|
|
96
|
+
delete workflowState.tabs[tabId];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function createEmptyProfileState() {
|
|
100
|
+
return {
|
|
101
|
+
exists: false,
|
|
102
|
+
lastLoadedAt: null,
|
|
103
|
+
lastSavedAt: null,
|
|
104
|
+
lastCheckedAt: null,
|
|
105
|
+
freshUntil: null,
|
|
106
|
+
fieldFreshness: {}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function getProfileState(domain) {
|
|
111
|
+
if (!workflowState.profiles[domain]) {
|
|
112
|
+
workflowState.profiles[domain] = createEmptyProfileState();
|
|
113
|
+
}
|
|
114
|
+
return workflowState.profiles[domain];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function markProfileLoaded(domain, freshnessMs = PROFILE_FRESHNESS_MS) {
|
|
118
|
+
const state = getProfileState(domain);
|
|
119
|
+
const now = Date.now();
|
|
120
|
+
state.exists = true;
|
|
121
|
+
state.lastLoadedAt = now;
|
|
122
|
+
state.freshUntil = now + freshnessMs;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function markProfileSaved(domain) {
|
|
126
|
+
const state = getProfileState(domain);
|
|
127
|
+
state.exists = true;
|
|
128
|
+
state.lastSavedAt = Date.now();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function markProfileChecked(domain) {
|
|
132
|
+
const state = getProfileState(domain);
|
|
133
|
+
state.lastCheckedAt = Date.now();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function isProfileFresh(domain) {
|
|
137
|
+
const state = workflowState.profiles[domain];
|
|
138
|
+
if (!state?.freshUntil) return false;
|
|
139
|
+
return Date.now() < state.freshUntil;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function markFieldFresh(domain, field, timestamp = Date.now()) {
|
|
143
|
+
const state = getProfileState(domain);
|
|
144
|
+
state.fieldFreshness[field] = timestamp;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function isFieldFresh(domain, field, maxAgeMs) {
|
|
148
|
+
const threshold = maxAgeMs ?? STALENESS_THRESHOLDS[field] ?? STALENESS_THRESHOLDS.default;
|
|
149
|
+
const runtimeTimestamp = workflowState.profiles[domain]?.fieldFreshness?.[field] || null;
|
|
150
|
+
const persistedTimestamp = getProfileFieldTimestamp(loadProfile(domain), field);
|
|
151
|
+
const timestamp = runtimeTimestamp || persistedTimestamp;
|
|
152
|
+
if (!timestamp) return false;
|
|
153
|
+
return Date.now() - new Date(timestamp).getTime() < threshold;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function snapshot() {
|
|
157
|
+
return JSON.parse(JSON.stringify(workflowState));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export {
|
|
161
|
+
workflowState,
|
|
162
|
+
getTabState,
|
|
163
|
+
touchTabField,
|
|
164
|
+
invalidateTabState,
|
|
165
|
+
removeTabState,
|
|
166
|
+
getProfileState,
|
|
167
|
+
markProfileLoaded,
|
|
168
|
+
markProfileSaved,
|
|
169
|
+
markProfileChecked,
|
|
170
|
+
isProfileFresh,
|
|
171
|
+
markFieldFresh,
|
|
172
|
+
isFieldFresh,
|
|
173
|
+
extractDomain,
|
|
174
|
+
snapshot,
|
|
175
|
+
PROFILE_FRESHNESS_MS,
|
|
176
|
+
STALENESS_THRESHOLDS
|
|
177
|
+
};
|