@oh-my-pi/pi-coding-agent 16.1.7 → 16.1.9
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/CHANGELOG.md +71 -0
- package/dist/cli.js +4266 -3446
- package/dist/types/cli/flag-tables.d.ts +17 -0
- package/dist/types/cli/session-picker.d.ts +0 -1
- package/dist/types/cli/tiny-models-cli.d.ts +2 -0
- package/dist/types/cli-commands.d.ts +4 -2
- package/dist/types/collab/protocol.d.ts +20 -1
- package/dist/types/config/settings-schema.d.ts +57 -6
- package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +5 -1
- package/dist/types/internal-urls/filesystem-resource.d.ts +9 -0
- package/dist/types/mcp/loader.d.ts +3 -2
- package/dist/types/mcp/manager.d.ts +4 -3
- package/dist/types/mcp/startup-events.d.ts +21 -4
- package/dist/types/mnemopi/config.d.ts +1 -0
- package/dist/types/modes/components/agent-hub.d.ts +1 -0
- package/dist/types/modes/components/agent-transcript-viewer.d.ts +1 -0
- package/dist/types/modes/components/assistant-message.d.ts +5 -1
- package/dist/types/modes/components/btw-panel.d.ts +2 -0
- package/dist/types/modes/components/chat-transcript-builder.d.ts +1 -0
- package/dist/types/modes/components/session-selector.d.ts +0 -2
- package/dist/types/modes/controllers/btw-controller.d.ts +2 -0
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/controllers/streaming-reveal.d.ts +3 -2
- package/dist/types/modes/interactive-mode.d.ts +4 -1
- package/dist/types/modes/types.d.ts +4 -1
- package/dist/types/session/agent-session.d.ts +18 -3
- package/dist/types/session/session-history-format.d.ts +25 -0
- package/dist/types/session/snapcompact-inline.d.ts +1 -1
- package/dist/types/slash-commands/builtin-registry.d.ts +7 -4
- package/dist/types/slash-commands/types.d.ts +2 -0
- package/dist/types/system-prompt.d.ts +1 -0
- package/dist/types/tiny/models.d.ts +11 -7
- package/dist/types/tools/browser/launch.d.ts +5 -0
- package/dist/types/tools/todo.d.ts +1 -0
- package/dist/types/utils/thinking-display.d.ts +2 -0
- package/package.json +12 -12
- package/src/advisor/__tests__/advisor.test.ts +104 -0
- package/src/advisor/runtime.ts +38 -2
- package/src/cli/args.ts +0 -1
- package/src/cli/flag-tables.ts +42 -0
- package/src/cli/profile-bootstrap.ts +1 -11
- package/src/cli/session-picker.ts +1 -2
- package/src/cli/tiny-models-cli.ts +7 -2
- package/src/cli-commands.ts +48 -3
- package/src/collab/guest.ts +172 -20
- package/src/collab/host.ts +47 -5
- package/src/collab/protocol.ts +16 -1
- package/src/config/model-registry.ts +6 -7
- package/src/config/settings-schema.ts +59 -5
- package/src/edit/renderer.ts +8 -12
- package/src/extensibility/legacy-pi-ai-shim.ts +16 -4
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/internal-urls/filesystem-resource.ts +34 -0
- package/src/internal-urls/local-protocol.ts +7 -1
- package/src/internal-urls/memory-protocol.ts +5 -1
- package/src/internal-urls/skill-protocol.ts +20 -4
- package/src/internal-urls/vault-protocol.ts +5 -2
- package/src/lsp/client.ts +39 -25
- package/src/main.ts +8 -8
- package/src/mcp/loader.ts +4 -3
- package/src/mcp/manager.ts +35 -15
- package/src/mcp/startup-events.ts +106 -11
- package/src/mnemopi/config.ts +2 -0
- package/src/mnemopi/state.ts +3 -1
- package/src/modes/components/agent-hub.ts +4 -0
- package/src/modes/components/agent-transcript-viewer.ts +2 -0
- package/src/modes/components/assistant-message.ts +217 -18
- package/src/modes/components/btw-panel.ts +15 -3
- package/src/modes/components/chat-transcript-builder.ts +8 -2
- package/src/modes/components/model-selector.ts +72 -9
- package/src/modes/components/omfg-panel.ts +1 -1
- package/src/modes/components/session-selector.ts +4 -9
- package/src/modes/components/snapcompact-shape-preview.ts +1 -1
- package/src/modes/components/tool-execution.ts +10 -2
- package/src/modes/controllers/btw-controller.ts +32 -7
- package/src/modes/controllers/command-controller.ts +18 -3
- package/src/modes/controllers/event-controller.ts +24 -4
- package/src/modes/controllers/input-controller.ts +43 -21
- package/src/modes/controllers/mcp-command-controller.ts +40 -12
- package/src/modes/controllers/selector-controller.ts +23 -13
- package/src/modes/controllers/streaming-reveal.ts +78 -20
- package/src/modes/controllers/todo-command-controller.ts +9 -10
- package/src/modes/interactive-mode.ts +84 -9
- package/src/modes/types.ts +4 -1
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/prompts/advisor/system.md +1 -1
- package/src/prompts/system/side-channel-no-tools.md +3 -0
- package/src/sdk.ts +12 -8
- package/src/session/agent-session.ts +385 -85
- package/src/session/history-storage.ts +15 -16
- package/src/session/session-history-format.ts +41 -1
- package/src/session/snapcompact-inline.ts +9 -6
- package/src/slash-commands/builtin-registry.ts +171 -87
- package/src/slash-commands/helpers/todo.ts +12 -6
- package/src/slash-commands/types.ts +2 -0
- package/src/system-prompt.ts +6 -11
- package/src/tiny/models.ts +7 -3
- package/src/tiny/title-client.ts +8 -2
- package/src/tiny/worker.ts +1 -0
- package/src/tools/browser/launch.ts +107 -31
- package/src/tools/puppeteer/00_stealth_tampering.txt +16 -35
- package/src/tools/puppeteer/01_stealth_activity.txt +79 -19
- package/src/tools/puppeteer/02_stealth_hairline.txt +57 -11
- package/src/tools/puppeteer/03_stealth_botd.txt +10 -14
- package/src/tools/puppeteer/04_stealth_iframe.txt +156 -63
- package/src/tools/puppeteer/05_stealth_webgl.txt +222 -64
- package/src/tools/puppeteer/06_stealth_screen.txt +255 -67
- package/src/tools/puppeteer/07_stealth_fonts.txt +17 -15
- package/src/tools/puppeteer/08_stealth_audio.txt +32 -20
- package/src/tools/puppeteer/09_stealth_locale.txt +45 -40
- package/src/tools/puppeteer/10_stealth_plugins.txt +12 -8
- package/src/tools/puppeteer/11_stealth_hardware.txt +57 -6
- package/src/tools/puppeteer/12_stealth_codecs.txt +20 -18
- package/src/tools/puppeteer/13_stealth_worker.txt +206 -45
- package/src/tools/search.ts +10 -1
- package/src/tools/sqlite-reader.ts +59 -3
- package/src/tools/todo.ts +6 -0
- package/src/tools/write.ts +4 -6
- package/src/utils/thinking-display.ts +78 -0
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
const makeNativeString = (name) => "function " + (name || "") + "() { [native code] }";
|
|
2
|
-
const patchToString = (fn, name) => {
|
|
3
|
-
if (typeof fn !== "function") return;
|
|
4
|
-
Object_defineProperty(fn, "toString", {
|
|
5
|
-
value: function toString() {
|
|
6
|
-
return makeNativeString(name);
|
|
7
|
-
},
|
|
8
|
-
writable: false,
|
|
9
|
-
configurable: true,
|
|
10
|
-
enumerable: false,
|
|
11
|
-
});
|
|
12
|
-
};
|
|
13
1
|
|
|
14
2
|
// Ensure navigator.webdriver behaves like real Chrome
|
|
15
3
|
if (navigator.webdriver !== false && navigator.webdriver !== undefined) {
|
|
@@ -356,13 +344,19 @@ if (window.chrome && !("runtime" in window.chrome) && isSecureOrigin) {
|
|
|
356
344
|
// Suppress Permission.query for automation-controlled
|
|
357
345
|
if (navigator.permissions?.query) {
|
|
358
346
|
if (isSecureOrigin && "Notification" in window) {
|
|
347
|
+
const notificationPermissionGetter = Object_getOwnPropertyDescriptor({
|
|
348
|
+
get permission() {
|
|
349
|
+
return "default";
|
|
350
|
+
},
|
|
351
|
+
}, "permission").get;
|
|
352
|
+
patchToString(notificationPermissionGetter, "get permission");
|
|
359
353
|
Object_defineProperty(Notification, "permission", {
|
|
360
|
-
get:
|
|
354
|
+
get: notificationPermissionGetter,
|
|
361
355
|
configurable: true,
|
|
362
356
|
});
|
|
363
357
|
} else if (!isSecureOrigin) {
|
|
364
358
|
const originalQuery = navigator.permissions.query;
|
|
365
|
-
|
|
359
|
+
const patchedPermissionsQuery = function query(parameters) {
|
|
366
360
|
if (parameters?.name === "notifications") {
|
|
367
361
|
const status = { state: "denied", onchange: null };
|
|
368
362
|
if (typeof PermissionStatus !== "undefined") {
|
|
@@ -372,6 +366,8 @@ if (navigator.permissions?.query) {
|
|
|
372
366
|
}
|
|
373
367
|
return originalQuery.call(this, parameters);
|
|
374
368
|
};
|
|
369
|
+
patchToString(patchedPermissionsQuery, "query");
|
|
370
|
+
navigator.permissions.query = patchedPermissionsQuery;
|
|
375
371
|
}
|
|
376
372
|
}
|
|
377
373
|
|
|
@@ -1,81 +1,174 @@
|
|
|
1
|
+
const iframeWindowProxies = new WeakMap();
|
|
2
|
+
|
|
3
|
+
const isFrameIndexKey = (key) => {
|
|
4
|
+
if (typeof key !== "string" || key === "") return false;
|
|
5
|
+
const number = +key;
|
|
6
|
+
return number >= 0 && number < 4294967295 && Math_floor(number) === number && `${number}` === key;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const getPropertyDescriptor = (object, key) => {
|
|
10
|
+
let current = object;
|
|
11
|
+
while (current) {
|
|
12
|
+
const descriptor = Object_getOwnPropertyDescriptor(current, key);
|
|
13
|
+
if (descriptor) return descriptor;
|
|
14
|
+
current = Object_getPrototypeOf(current);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const descriptorWithValue = (target, key, value, writable) => {
|
|
19
|
+
const descriptor = Reflect_getOwnPropertyDescriptor(target, key);
|
|
20
|
+
if (descriptor && descriptor.configurable === false) return descriptor;
|
|
21
|
+
const next = descriptor ? Object_assign({}, descriptor) : { configurable: true, enumerable: true };
|
|
22
|
+
Reflect_deleteProperty(next, "get");
|
|
23
|
+
Reflect_deleteProperty(next, "set");
|
|
24
|
+
next.value = value;
|
|
25
|
+
if (!Reflect_has(next, "writable")) next.writable = writable;
|
|
26
|
+
return next;
|
|
27
|
+
};
|
|
28
|
+
const iframeContentWindowDescriptor =
|
|
29
|
+
typeof HTMLIFrameElement === "undefined"
|
|
30
|
+
? undefined
|
|
31
|
+
: getPropertyDescriptor(HTMLIFrameElement.prototype, "contentWindow");
|
|
32
|
+
const iframeSrcdocDescriptor =
|
|
33
|
+
typeof HTMLIFrameElement === "undefined"
|
|
34
|
+
? undefined
|
|
35
|
+
: getPropertyDescriptor(HTMLIFrameElement.prototype, "srcdoc");
|
|
36
|
+
|
|
37
|
+
const getNativeContentWindow = (iframe) => {
|
|
38
|
+
if (iframeContentWindowDescriptor && iframeContentWindowDescriptor.get) {
|
|
39
|
+
return Reflect_apply(iframeContentWindowDescriptor.get, iframe, []);
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
};
|
|
43
|
+
|
|
1
44
|
const addContentWindowProxy = (iframe) => {
|
|
45
|
+
let state = Reflect_apply(Page_WeakMap_get, iframeWindowProxies, [iframe]);
|
|
46
|
+
if (state) return state.proxy;
|
|
47
|
+
|
|
48
|
+
state = { proxy: undefined, target: undefined, wasConnected: false, setProxyTarget: undefined };
|
|
49
|
+
|
|
50
|
+
const isDiscarded = () => {
|
|
51
|
+
if (iframe.isConnected) state.wasConnected = true;
|
|
52
|
+
return state.wasConnected && !iframe.isConnected;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const currentFrameElement = () => {
|
|
56
|
+
if (iframe.isConnected) {
|
|
57
|
+
state.wasConnected = true;
|
|
58
|
+
return iframe;
|
|
59
|
+
}
|
|
60
|
+
return state.wasConnected ? null : iframe;
|
|
61
|
+
};
|
|
62
|
+
|
|
2
63
|
const contentWindowProxy = {
|
|
3
64
|
get(target, key) {
|
|
4
|
-
if (key === "self") return
|
|
5
|
-
if (key === "frameElement") return
|
|
6
|
-
if (key === "
|
|
65
|
+
if (key === "self" || key === "window" || key === "frames" || key === "globalThis") return state.proxy;
|
|
66
|
+
if (key === "frameElement") return currentFrameElement();
|
|
67
|
+
if (key === "closed" && isDiscarded()) return true;
|
|
68
|
+
if (isFrameIndexKey(key)) return undefined;
|
|
69
|
+
if (key === "length") return 0;
|
|
7
70
|
return Reflect_get(target, key);
|
|
8
71
|
},
|
|
72
|
+
getOwnPropertyDescriptor(target, key) {
|
|
73
|
+
if (key === "self" || key === "window" || key === "frames" || key === "globalThis") {
|
|
74
|
+
return descriptorWithValue(target, key, state.proxy, true);
|
|
75
|
+
}
|
|
76
|
+
if (key === "frameElement") {
|
|
77
|
+
return descriptorWithValue(target, key, currentFrameElement(), false);
|
|
78
|
+
}
|
|
79
|
+
if (key === "closed" && isDiscarded()) {
|
|
80
|
+
return descriptorWithValue(target, key, true, false);
|
|
81
|
+
}
|
|
82
|
+
if (isFrameIndexKey(key)) return undefined;
|
|
83
|
+
if (key === "length") return descriptorWithValue(target, key, 0, false);
|
|
84
|
+
return Reflect_getOwnPropertyDescriptor(target, key);
|
|
85
|
+
},
|
|
86
|
+
has(target, key) {
|
|
87
|
+
if (key === "self" || key === "window" || key === "frames" || key === "globalThis" || key === "frameElement") return true;
|
|
88
|
+
if (isFrameIndexKey(key)) return false;
|
|
89
|
+
return Reflect_has(target, key);
|
|
90
|
+
},
|
|
91
|
+
ownKeys(target) {
|
|
92
|
+
const keys = Reflect_ownKeys(target);
|
|
93
|
+
const filtered = [];
|
|
94
|
+
for (let index = 0; index < keys.length; index++) {
|
|
95
|
+
if (!isFrameIndexKey(keys[index])) filtered.push(keys[index]);
|
|
96
|
+
}
|
|
97
|
+
return filtered;
|
|
98
|
+
},
|
|
9
99
|
};
|
|
10
100
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
};
|
|
101
|
+
const setProxyTarget = (target) => {
|
|
102
|
+
if (state.target === target && state.proxy) return state.proxy;
|
|
103
|
+
state.target = target;
|
|
104
|
+
state.proxy = new Window_Proxy(target, contentWindowProxy);
|
|
105
|
+
return state.proxy;
|
|
106
|
+
};
|
|
107
|
+
state.setProxyTarget = setProxyTarget;
|
|
108
|
+
const initialContentWindow = getNativeContentWindow(iframe);
|
|
109
|
+
if (initialContentWindow) setProxyTarget(initialContentWindow);
|
|
110
|
+
if (iframe.isConnected) state.wasConnected = true;
|
|
111
|
+
Reflect_apply(Page_WeakMap_set, iframeWindowProxies, [iframe, state]);
|
|
25
112
|
|
|
26
|
-
const handleIframeCreation = (target, thisArg, args) => {
|
|
27
|
-
const iframe = Reflect_apply(target, thisArg, args);
|
|
28
|
-
const originalIframe = iframe;
|
|
29
|
-
const originalSrcdoc = originalIframe.srcdoc;
|
|
30
113
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
114
|
+
return state.proxy;
|
|
115
|
+
};
|
|
116
|
+
if (
|
|
117
|
+
iframeContentWindowDescriptor &&
|
|
118
|
+
iframeContentWindowDescriptor.get &&
|
|
119
|
+
iframeContentWindowDescriptor.configurable !== false
|
|
120
|
+
) {
|
|
121
|
+
const contentWindowAccessors = {
|
|
122
|
+
get contentWindow() {
|
|
123
|
+
const state = Reflect_apply(Page_WeakMap_get, iframeWindowProxies, [this]);
|
|
124
|
+
if (!state) return getNativeContentWindow(this);
|
|
125
|
+
if (this.isConnected) state.wasConnected = true;
|
|
126
|
+
if (state.wasConnected && !this.isConnected) return null;
|
|
127
|
+
const nativeContentWindow = getNativeContentWindow(this);
|
|
128
|
+
if (!nativeContentWindow) return nativeContentWindow;
|
|
129
|
+
return state.setProxyTarget(nativeContentWindow);
|
|
44
130
|
},
|
|
131
|
+
};
|
|
132
|
+
const contentWindowGetter = Object_getOwnPropertyDescriptor(contentWindowAccessors, "contentWindow").get;
|
|
133
|
+
patchToString(contentWindowGetter, "get contentWindow");
|
|
134
|
+
Object_defineProperty(HTMLIFrameElement.prototype, "contentWindow", {
|
|
135
|
+
get: contentWindowGetter,
|
|
136
|
+
set: iframeContentWindowDescriptor.set,
|
|
137
|
+
enumerable: iframeContentWindowDescriptor.enumerable,
|
|
138
|
+
configurable: iframeContentWindowDescriptor.configurable,
|
|
45
139
|
});
|
|
140
|
+
}
|
|
46
141
|
|
|
47
|
-
return iframe;
|
|
48
|
-
};
|
|
49
142
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
143
|
+
if (
|
|
144
|
+
iframeSrcdocDescriptor &&
|
|
145
|
+
iframeSrcdocDescriptor.configurable !== false
|
|
146
|
+
) {
|
|
147
|
+
const srcdocAccessors = {
|
|
148
|
+
get srcdoc() {
|
|
149
|
+
if (iframeSrcdocDescriptor.get) {
|
|
150
|
+
return Reflect_apply(iframeSrcdocDescriptor.get, this, []);
|
|
57
151
|
}
|
|
58
|
-
|
|
152
|
+
const value = this.getAttribute("srcdoc");
|
|
153
|
+
return value === null ? "" : value;
|
|
59
154
|
},
|
|
60
|
-
|
|
61
|
-
|
|
155
|
+
set srcdoc(newValue) {
|
|
156
|
+
addContentWindowProxy(this);
|
|
157
|
+
if (iframeSrcdocDescriptor.set) {
|
|
158
|
+
return Reflect_apply(iframeSrcdocDescriptor.set, this, [newValue]);
|
|
159
|
+
}
|
|
160
|
+
return this.setAttribute("srcdoc", newValue);
|
|
62
161
|
},
|
|
63
162
|
};
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
configurable: true,
|
|
75
|
-
enumerable: false,
|
|
163
|
+
const srcdocDescriptor = Object_getOwnPropertyDescriptor(srcdocAccessors, "srcdoc");
|
|
164
|
+
const srcdocGetter = srcdocDescriptor.get;
|
|
165
|
+
const srcdocSetter = srcdocDescriptor.set;
|
|
166
|
+
patchToString(srcdocGetter, "get srcdoc");
|
|
167
|
+
patchToString(srcdocSetter, "set srcdoc");
|
|
168
|
+
Object_defineProperty(HTMLIFrameElement.prototype, "srcdoc", {
|
|
169
|
+
get: srcdocGetter,
|
|
170
|
+
set: srcdocSetter,
|
|
171
|
+
enumerable: iframeSrcdocDescriptor.enumerable,
|
|
172
|
+
configurable: iframeSrcdocDescriptor.configurable,
|
|
76
173
|
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
addIframeCreationSniffer();
|
|
81
|
-
} catch {}
|
|
174
|
+
}
|
|
@@ -1,75 +1,233 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
const webglPlatformSource =
|
|
2
|
+
String(navigator.userAgentData?.platform || navigator.platform || "") +
|
|
3
|
+
" " +
|
|
4
|
+
String(navigator.userAgent || "");
|
|
5
|
+
const webglPlatformText = webglPlatformSource.toLowerCase();
|
|
6
|
+
const webglPlatformKind = webglPlatformText.includes("android")
|
|
7
|
+
? "android"
|
|
8
|
+
: webglPlatformText.includes("iphone") ||
|
|
9
|
+
webglPlatformText.includes("ipad") ||
|
|
10
|
+
webglPlatformText.includes("ipod")
|
|
11
|
+
? "ios"
|
|
12
|
+
: webglPlatformText.includes("mac")
|
|
13
|
+
? "mac"
|
|
14
|
+
: webglPlatformText.includes("win")
|
|
15
|
+
? "windows"
|
|
16
|
+
: webglPlatformText.includes("cros")
|
|
17
|
+
? "cros"
|
|
18
|
+
: "linux";
|
|
19
|
+
|
|
20
|
+
const webglFallbackProfiles = {
|
|
21
|
+
android: {
|
|
22
|
+
vendor: "Qualcomm",
|
|
23
|
+
renderer: "Adreno (TM) 640",
|
|
24
|
+
},
|
|
25
|
+
ios: {
|
|
26
|
+
vendor: "Apple Inc.",
|
|
27
|
+
renderer: "Apple GPU",
|
|
28
|
+
},
|
|
29
|
+
mac: {
|
|
30
|
+
vendor: "Google Inc. (Intel Inc.)",
|
|
31
|
+
renderer: "ANGLE (Intel Inc., Intel(R) Iris(TM) Plus Graphics 640 OpenGL Engine, OpenGL 4.1)",
|
|
32
|
+
},
|
|
33
|
+
windows: {
|
|
34
|
+
vendor: "Google Inc. (Intel)",
|
|
35
|
+
renderer: "ANGLE (Intel, Intel(R) UHD Graphics 620 Direct3D11 vs_5_0 ps_5_0, D3D11)",
|
|
36
|
+
},
|
|
37
|
+
cros: {
|
|
38
|
+
vendor: "Google Inc. (Intel)",
|
|
39
|
+
renderer: "ANGLE (Intel, Mesa Intel(R) UHD Graphics 620 (KBL GT2), OpenGL 4.6)",
|
|
40
|
+
},
|
|
41
|
+
linux: {
|
|
42
|
+
vendor: "Google Inc. (Intel)",
|
|
43
|
+
renderer: "ANGLE (Intel, Mesa Intel(R) UHD Graphics 620 (KBL GT2), OpenGL 4.6)",
|
|
44
|
+
},
|
|
27
45
|
};
|
|
46
|
+
const webglFallbackProfile = webglFallbackProfiles[webglPlatformKind] || webglFallbackProfiles.linux;
|
|
47
|
+
const webglContextProfiles = new WeakMap();
|
|
48
|
+
const webglIsObjectKey = (value) =>
|
|
49
|
+
(typeof value === "object" && value !== null) || typeof value === "function";
|
|
28
50
|
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
const webglLooksSoftware = (value) => {
|
|
52
|
+
const text = String(value || "").toLowerCase();
|
|
53
|
+
return (
|
|
54
|
+
text.includes("swiftshader") ||
|
|
55
|
+
text.includes("llvmpipe") ||
|
|
56
|
+
text.includes("lavapipe") ||
|
|
57
|
+
text.includes("software") ||
|
|
58
|
+
text.includes("mesa offscreen") ||
|
|
59
|
+
text.includes("google inc. (google)")
|
|
60
|
+
);
|
|
38
61
|
};
|
|
39
62
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
63
|
+
const webglMatchesPlatform = (renderer) => {
|
|
64
|
+
const text = String(renderer || "").toLowerCase();
|
|
65
|
+
if (webglPlatformKind === "windows") {
|
|
66
|
+
return !text.includes("apple") && !text.includes("mesa") && !text.includes("opengl engine");
|
|
67
|
+
}
|
|
68
|
+
if (webglPlatformKind === "mac") {
|
|
69
|
+
return !text.includes("direct3d") && !text.includes("d3d") && !text.includes("mesa");
|
|
70
|
+
}
|
|
71
|
+
if (webglPlatformKind === "android") {
|
|
72
|
+
return (
|
|
73
|
+
text.includes("adreno") ||
|
|
74
|
+
text.includes("mali") ||
|
|
75
|
+
text.includes("powervr") ||
|
|
76
|
+
text.includes("qualcomm")
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
if (webglPlatformKind === "ios") {
|
|
80
|
+
return text.includes("apple");
|
|
81
|
+
}
|
|
82
|
+
return !text.includes("direct3d") && !text.includes("d3d") && !text.includes("apple");
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const webglGetContextProfile = (target, thisArg) => {
|
|
86
|
+
if (!webglIsObjectKey(thisArg)) return webglFallbackProfile;
|
|
87
|
+
const cached = Reflect_apply(Page_WeakMap_get, webglContextProfiles, [thisArg]);
|
|
88
|
+
if (cached) return cached;
|
|
89
|
+
|
|
90
|
+
let nativeVendor;
|
|
91
|
+
let nativeRenderer;
|
|
92
|
+
try {
|
|
93
|
+
nativeVendor = Reflect_apply(target, thisArg, [0x9245]);
|
|
94
|
+
nativeRenderer = Reflect_apply(target, thisArg, [0x9246]);
|
|
95
|
+
} catch {}
|
|
96
|
+
|
|
97
|
+
const nativeProfile =
|
|
98
|
+
typeof nativeVendor === "string" &&
|
|
99
|
+
typeof nativeRenderer === "string" &&
|
|
100
|
+
nativeVendor &&
|
|
101
|
+
nativeRenderer &&
|
|
102
|
+
!webglLooksSoftware(nativeVendor) &&
|
|
103
|
+
!webglLooksSoftware(nativeRenderer) &&
|
|
104
|
+
webglMatchesPlatform(nativeRenderer)
|
|
105
|
+
? { vendor: nativeVendor, renderer: nativeRenderer }
|
|
106
|
+
: webglFallbackProfile;
|
|
107
|
+
|
|
108
|
+
Reflect_apply(Page_WeakMap_set, webglContextProfiles, [thisArg, nativeProfile]);
|
|
109
|
+
return nativeProfile;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const webglGetParameterHandler = {
|
|
113
|
+
apply(target, thisArg, args) {
|
|
114
|
+
const nativeValue = Reflect_apply(target, thisArg, args);
|
|
115
|
+
const param = args[0];
|
|
116
|
+
if (param === 0x1f00 && typeof nativeValue === "string") return "WebKit";
|
|
117
|
+
if (param === 0x1f01 && typeof nativeValue === "string") return "WebKit WebGL";
|
|
118
|
+
if ((param === 0x9245 || param === 0x9246) && typeof nativeValue === "string") {
|
|
119
|
+
const profile = webglGetContextProfile(target, thisArg);
|
|
120
|
+
return param === 0x9245 ? profile.vendor : profile.renderer;
|
|
121
|
+
}
|
|
122
|
+
return nativeValue;
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const webglFloatPrecisionTypes = {
|
|
127
|
+
0x8df0: true,
|
|
128
|
+
0x8df1: true,
|
|
129
|
+
0x8df2: true,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const webglClonePrecisionFormat = (result, values) => {
|
|
133
|
+
const ownKeys = Reflect_ownKeys(result);
|
|
134
|
+
let hasRangeMin = false;
|
|
135
|
+
let hasRangeMax = false;
|
|
136
|
+
let hasPrecision = false;
|
|
137
|
+
for (let index = 0; index < ownKeys.length; index += 1) {
|
|
138
|
+
if (ownKeys[index] === "rangeMin") hasRangeMin = true;
|
|
139
|
+
if (ownKeys[index] === "rangeMax") hasRangeMax = true;
|
|
140
|
+
if (ownKeys[index] === "precision") hasPrecision = true;
|
|
141
|
+
}
|
|
142
|
+
if (!hasRangeMin || !hasRangeMax || !hasPrecision) return result;
|
|
143
|
+
|
|
144
|
+
const clone = Object_create(Object_getPrototypeOf(result));
|
|
145
|
+
for (let index = 0; index < ownKeys.length; index += 1) {
|
|
146
|
+
const key = ownKeys[index];
|
|
147
|
+
const descriptor = Object_getOwnPropertyDescriptor(result, key);
|
|
148
|
+
if (!descriptor) return result;
|
|
149
|
+
if (key === "rangeMin" || key === "rangeMax" || key === "precision") {
|
|
150
|
+
if (!("value" in descriptor)) return result;
|
|
151
|
+
descriptor.value = values[key];
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
Object_defineProperty(clone, key, descriptor);
|
|
155
|
+
} catch {
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return clone;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const webglGetShaderPrecisionFormatHandler = {
|
|
163
|
+
apply(target, thisArg, args) {
|
|
164
|
+
const result = Reflect_apply(target, thisArg, args);
|
|
165
|
+
const precisionType = args[1];
|
|
166
|
+
if (
|
|
167
|
+
!result ||
|
|
168
|
+
webglPlatformKind === "android" ||
|
|
169
|
+
webglPlatformKind === "ios" ||
|
|
170
|
+
!webglFloatPrecisionTypes[precisionType]
|
|
171
|
+
) {
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const rangeMin = result.rangeMin;
|
|
176
|
+
const rangeMax = result.rangeMax;
|
|
177
|
+
const precision = result.precision;
|
|
178
|
+
if (
|
|
179
|
+
typeof rangeMin !== "number" ||
|
|
180
|
+
typeof rangeMax !== "number" ||
|
|
181
|
+
typeof precision !== "number"
|
|
182
|
+
) {
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const values = {
|
|
187
|
+
rangeMin: Math_max(rangeMin, 127),
|
|
188
|
+
rangeMax: Math_max(rangeMax, 127),
|
|
189
|
+
precision: Math_max(precision, 23),
|
|
190
|
+
};
|
|
191
|
+
if (
|
|
192
|
+
values.rangeMin === rangeMin &&
|
|
193
|
+
values.rangeMax === rangeMax &&
|
|
194
|
+
values.precision === precision
|
|
195
|
+
) {
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
return webglClonePrecisionFormat(result, values);
|
|
199
|
+
},
|
|
200
|
+
};
|
|
46
201
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
return result;
|
|
63
|
-
},
|
|
64
|
-
writable: true,
|
|
65
|
-
configurable: true,
|
|
66
|
-
enumerable: true,
|
|
67
|
-
});
|
|
202
|
+
const webglInstallMethodProxy = (proto, name, handler) => {
|
|
203
|
+
if (!proto) return;
|
|
204
|
+
const descriptor = Object_getOwnPropertyDescriptor(proto, name);
|
|
205
|
+
if (!descriptor || typeof descriptor.value !== "function") return;
|
|
206
|
+
const proxy = new Window_Proxy(descriptor.value, handler);
|
|
207
|
+
patchToString(proxy, name);
|
|
208
|
+
try {
|
|
209
|
+
Object_defineProperty(proto, name, {
|
|
210
|
+
value: proxy,
|
|
211
|
+
writable: descriptor.writable,
|
|
212
|
+
configurable: descriptor.configurable,
|
|
213
|
+
enumerable: descriptor.enumerable,
|
|
214
|
+
});
|
|
215
|
+
} catch {}
|
|
68
216
|
};
|
|
69
217
|
|
|
70
218
|
if (window.WebGLRenderingContext) {
|
|
71
|
-
|
|
219
|
+
webglInstallMethodProxy(WebGLRenderingContext.prototype, "getParameter", webglGetParameterHandler);
|
|
220
|
+
webglInstallMethodProxy(
|
|
221
|
+
WebGLRenderingContext.prototype,
|
|
222
|
+
"getShaderPrecisionFormat",
|
|
223
|
+
webglGetShaderPrecisionFormatHandler,
|
|
224
|
+
);
|
|
72
225
|
}
|
|
73
226
|
if (window.WebGL2RenderingContext) {
|
|
74
|
-
|
|
227
|
+
webglInstallMethodProxy(WebGL2RenderingContext.prototype, "getParameter", webglGetParameterHandler);
|
|
228
|
+
webglInstallMethodProxy(
|
|
229
|
+
WebGL2RenderingContext.prototype,
|
|
230
|
+
"getShaderPrecisionFormat",
|
|
231
|
+
webglGetShaderPrecisionFormatHandler,
|
|
232
|
+
);
|
|
75
233
|
}
|