minecodex 0.1.12 → 0.1.14
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.
|
@@ -8,6 +8,20 @@ licensed under the MIT License. Product names and marks remain the property of t
|
|
|
8
8
|
|
|
9
9
|
The upstream license text is preserved in `vendor/cc-switch-LICENSE`.
|
|
10
10
|
|
|
11
|
+
## Zhipu official favicon
|
|
12
|
+
|
|
13
|
+
`assets/providers/zhipu.svg` wraps the official Z.ai (Zhipu) favicon
|
|
14
|
+
downloaded from <https://www.zhipuai.cn/favicon.png> in an SVG container.
|
|
15
|
+
The favicon and Z.ai marks remain the property of Zhipu AI; the wrapper is
|
|
16
|
+
distributed under MineCodex's MIT License.
|
|
17
|
+
|
|
18
|
+
## Simple Icons (Xiaomi)
|
|
19
|
+
|
|
20
|
+
`assets/providers/xiaomimimo.svg` uses the Xiaomi mark from
|
|
21
|
+
[`simple-icons/simple-icons`](https://github.com/simple-icons/simple-icons)
|
|
22
|
+
(`icons/xiaomi.svg`), licensed under CC0 1.0. The Xiaomi brand mark remains
|
|
23
|
+
the property of Xiaomi Corporation.
|
|
24
|
+
|
|
11
25
|
## Lucide
|
|
12
26
|
|
|
13
27
|
Lucide icons distributed by MineCodex include the Model Slider UI icons, Notes action and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg
|
|
1
|
+
<svg role="img" viewBox="0 0 24 24" fill="#FF6900" xmlns="http://www.w3.org/2000/svg"><title>Xiaomi</title><path d="M12 0C8.016 0 4.756.255 2.493 2.516.23 4.776 0 8.033 0 12.012c0 3.98.23 7.235 2.494 9.497C4.757 23.77 8.017 24 12 24c3.983 0 7.243-.23 9.506-2.491C23.77 19.247 24 15.99 24 12.012c0-3.984-.233-7.243-2.502-9.504C19.234.252 15.978 0 12 0zM4.906 7.405h5.624c1.47 0 3.007.068 3.764.827.746.746.827 2.233.83 3.676v4.54a.15.15 0 0 1-.152.147h-1.947a.15.15 0 0 1-.152-.148V11.83c-.002-.806-.048-1.634-.464-2.051-.358-.36-1.026-.441-1.72-.458H7.158a.15.15 0 0 0-.151.147v6.98a.15.15 0 0 1-.152.148H4.906a.15.15 0 0 1-.15-.148V7.554a.15.15 0 0 1 .15-.149zm12.131 0h1.949a.15.15 0 0 1 .15.15v8.892a.15.15 0 0 1-.15.148h-1.949a.15.15 0 0 1-.151-.148V7.554a.15.15 0 0 1 .151-.149zM8.92 10.948h2.046c.083 0 .15.066.15.147v5.352a.15.15 0 0 1-.15.148H8.92a.15.15 0 0 1-.152-.148v-5.352a.15.15 0 0 1 .152-.147Z" fill="#FF6900"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0
|
|
1
|
+
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 96 96" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>Zhipu</title><image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAOgSURBVHgB7Z3LcRpBEIYb2QcfCWGVARkIIhAZQAaQAUsE4AggAysDUAZkAI6Avfq0noaljGERjxn6MdNf1V/S6qLZ/ufRM10MDbhO06nr9ObUrp6bYFxi5bRx+nD6rH5/CAzyyGnrVJoe1swpgzvpgQU+pNZVTG9iBMDe4Fg1Agu+XBP6ghoZu3pwQgb7eUpD42MQrq+7TPJbZcAU9immQcMPpz9Oywb86/0GLYXT6wtYz+dit8FFA97B4OINDcjA4KKNa0AJBheFGcDMCxismAHMmAHMmAHMmAHMfAdPms3mTpwURbHTMZTt2mw24IPXyV6/3y+5abfbZ+1ar9clBbPZzPdkVLcBeZ6ftWk0GpUUoMlZlqVrAAbgtD0YECparZZv8EvVi3Cn0/nvGef8xWIBFIzHY1itVhAClSOgbuqZTCYlBXUjz0P6DHC9nK0d2+02xLyv14C6hQ+fqbKe4XAYMvi6DMCeX9f78O8UBEg5z+R9HM294XEpJ7j1ACj+Ny76vpuuOkqtokw5e73es95DXmBvFdW8P51On/kesoJ6qyh3u09+F1mBvUV49kNF4JRTvwGUKWfdZi95A+bzeUlB3WYveQMGg0FJQaBTzrgMwIDgMQAFT0w59RqgqMASnwHKCixxGaCtwBKVAe6MKbaUU5cBVCknwW5XnwGKCyz6DVBeYNFvgOYCi3oDIk85ZRsQSYFFrwGRFFh0GhBRgUWfAd1ut6RCyLwvx4AICyy6DIiwwKLHgEgLLDoMiLjAosOAiAss8g1IcLcrx4AECixyDUikwCLXgEQKLDINSKjAIs+AxAos8gxIrMAiywBLORkNSLTAIseARAssMgxIuMDCb0DiBZa75H1f0CkuIDCZTIACvK+h7mOjVB+drbun6BGCOspZYMHRQJXyIri5DBCzcMHnLLBQbvYOiDKAu8BCNfKOEWUAZ4GFauSdIsYAzt0u5cg7RYQB3AUW6nn/mBAGeF1Zxn1FGN6Ugmmvdh52j7PAgqOBmxAjwOu+IKre53Mx6zPu9wmJfX8AM3Z3NDNmADNmADNmADNmADNogP+BtvEwZgAvKzTgEwwufqMBSzC4+IU7YdzPr6ufBi2vhzXgJxjUzJ02hwfs/fg126WJRGuo+RbbvsCGxqoeXCAX1MhYlcMVcgGNTDb4B/qwn6e0vJh0bauY3kUG+5Va04tKDHwOX6T4DbhO5tR2eq9+b4FxiaLSEvYnDB9w5ajnLzy3z1aOtKIfAAAAAElFTkSuQmCC" x="0" y="0" width="96" height="96" preserveAspectRatio="xMidYMid meet"/></svg>
|
package/package.json
CHANGED
|
@@ -439,6 +439,20 @@ export function createInjectionSource(features, {
|
|
|
439
439
|
}) ?? null;
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
+
function nativeSidePanelButton() {
|
|
443
|
+
return Array.from(document.querySelectorAll("button")).find((button) => {
|
|
444
|
+
if (button.getAttribute("aria-label") !== "Toggle side panel") return false;
|
|
445
|
+
return isVisibleToolbarControl(button);
|
|
446
|
+
}) ?? null;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function nativeTemporaryChatButton() {
|
|
450
|
+
return Array.from(document.querySelectorAll("button")).find((button) => {
|
|
451
|
+
if (!/temporary chat/i.test(button.getAttribute("aria-label") ?? "")) return false;
|
|
452
|
+
return isVisibleToolbarControl(button);
|
|
453
|
+
}) ?? null;
|
|
454
|
+
}
|
|
455
|
+
|
|
442
456
|
function toolbarControlRoot(button) {
|
|
443
457
|
return button?.parentElement?.parentElement ?? button?.parentElement ?? button ?? null;
|
|
444
458
|
}
|
|
@@ -463,12 +477,28 @@ export function createInjectionSource(features, {
|
|
|
463
477
|
if (!group) {
|
|
464
478
|
group = document.createElement("div");
|
|
465
479
|
group.setAttribute("data-codex-personal-summary-toolbar-group", "fallback");
|
|
466
|
-
|
|
480
|
+
// The host toolbar strip is pointer-events:none; without this the
|
|
481
|
+
// fallback entries would be visible but unclickable.
|
|
482
|
+
group.className = "ms-auto flex shrink-0 items-center gap-1.5 pointer-events-auto";
|
|
483
|
+
// Same structure as the native tool group (e.g. the temporary-chat
|
|
484
|
+
// group in Chat mode): an in-flow ms-auto strip inside the flexible
|
|
485
|
+
// header area. It sits at the right edge while the side panel is
|
|
486
|
+
// closed and, when the side panel widens its host container, moves
|
|
487
|
+
// together with the native layout exactly like Chat mode does.
|
|
467
488
|
toolbarHost.append(group);
|
|
468
489
|
}
|
|
469
490
|
return group;
|
|
470
491
|
}
|
|
471
492
|
|
|
493
|
+
function toolbarEntryFitsHeader(entryRoot) {
|
|
494
|
+
const header = entryRoot.closest("header");
|
|
495
|
+
if (!header) return true;
|
|
496
|
+
const headerRect = header.getBoundingClientRect();
|
|
497
|
+
const entryRect = entryRoot.getBoundingClientRect();
|
|
498
|
+
if (entryRect.width <= 0 || entryRect.height <= 0) return false;
|
|
499
|
+
return entryRect.right <= headerRect.right + 1 && entryRect.left >= headerRect.left - 1;
|
|
500
|
+
}
|
|
501
|
+
|
|
472
502
|
function isNativeSummaryButton(element) {
|
|
473
503
|
if (!(element instanceof Element)) return false;
|
|
474
504
|
const button = element.closest("button");
|
|
@@ -719,10 +749,52 @@ export function createInjectionSource(features, {
|
|
|
719
749
|
for (let depth = 0; fiber && depth < 40; depth += 1, fiber = fiber.return) {
|
|
720
750
|
const props = fiber.memoizedProps;
|
|
721
751
|
if (Array.isArray(props?.models) && typeof props.onSelectReasoningEffort === "function") return props;
|
|
752
|
+
if (
|
|
753
|
+
props?.models
|
|
754
|
+
&& typeof props.models === "object"
|
|
755
|
+
&& !Array.isArray(props.models)
|
|
756
|
+
&& typeof props.onModelChange === "function"
|
|
757
|
+
&& props.selectedModel
|
|
758
|
+
) {
|
|
759
|
+
return chatComposerModelController(props);
|
|
760
|
+
}
|
|
722
761
|
}
|
|
723
762
|
return null;
|
|
724
763
|
}
|
|
725
764
|
|
|
765
|
+
function chatComposerModelController(props) {
|
|
766
|
+
const selected = props.selectedModel ?? {};
|
|
767
|
+
if (!Array.isArray(props.models?.versionOptions) || !selected.versionId) return null;
|
|
768
|
+
const version = props.models.versionOptions.find(
|
|
769
|
+
(candidate) => String(candidate.id ?? "") === String(selected.versionId ?? ""),
|
|
770
|
+
);
|
|
771
|
+
if (!version) return null;
|
|
772
|
+
const options = Array.isArray(version?.options) ? version.options : [];
|
|
773
|
+
const effortFor = (option) => String(option?.title ?? option?.lane ?? "").toLowerCase();
|
|
774
|
+
const efforts = options.map(effortFor).filter(Boolean);
|
|
775
|
+
const selectedOption = options.find(
|
|
776
|
+
(option) => String(option.thinkingEffort ?? "") === String(selected.thinkingEffort ?? ""),
|
|
777
|
+
);
|
|
778
|
+
const selectedEffort = selectedOption ? effortFor(selectedOption) : (efforts[0] ?? "instant");
|
|
779
|
+
const models = [{
|
|
780
|
+
model: String(selected.slug ?? ""),
|
|
781
|
+
displayName: String(version?.label ?? selected.slug ?? ""),
|
|
782
|
+
defaultReasoningEffort: selectedEffort,
|
|
783
|
+
supportedReasoningEfforts: efforts.map((effort) => ({ reasoningEffort: effort })),
|
|
784
|
+
}];
|
|
785
|
+
return {
|
|
786
|
+
models,
|
|
787
|
+
onSelectReasoningEffort(effort) {
|
|
788
|
+
const target = options.find((option) => effortFor(option) === String(effort).toLowerCase());
|
|
789
|
+
if (!target) return;
|
|
790
|
+
const next = { ...selected, slug: String(target.slug ?? selected.slug ?? "") };
|
|
791
|
+
if (target.thinkingEffort) next.thinkingEffort = target.thinkingEffort;
|
|
792
|
+
else delete next.thinkingEffort;
|
|
793
|
+
props.onModelChange(next);
|
|
794
|
+
},
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
|
|
726
798
|
function nativeCatalogModelFor(identity) {
|
|
727
799
|
const models = nativeComposerModelController()?.models ?? [];
|
|
728
800
|
const exact = models.find((model) => String(model.model ?? "").toLowerCase() === identity.raw.toLowerCase());
|
|
@@ -1138,11 +1210,11 @@ export function createInjectionSource(features, {
|
|
|
1138
1210
|
const observedIdentity = modelIdentity(observedRaw);
|
|
1139
1211
|
const nativeDescriptor = nativeModelDescriptorForItem(item, observedRaw);
|
|
1140
1212
|
const catalogModel = catalogModelFor(observedIdentity, selector);
|
|
1141
|
-
const raw =
|
|
1213
|
+
const raw = catalogModel?.slug ?? nativeDescriptor?.slug ?? observedRaw;
|
|
1142
1214
|
item.dataset.codexModelSliderRaw = raw;
|
|
1143
1215
|
item.dataset.codexModelSliderItem = "";
|
|
1144
1216
|
item.dataset.codexModelSliderOrder = String(index);
|
|
1145
|
-
item.dataset.codexModelSliderIdentitySource =
|
|
1217
|
+
item.dataset.codexModelSliderIdentitySource = catalogModel ? "catalog" : nativeDescriptor ? "native" : "visible";
|
|
1146
1218
|
if (item.querySelector("[data-codex-model-slider-row]")) return;
|
|
1147
1219
|
|
|
1148
1220
|
const identity = modelIdentity(raw);
|
|
@@ -2105,7 +2177,10 @@ export function createInjectionSource(features, {
|
|
|
2105
2177
|
}
|
|
2106
2178
|
|
|
2107
2179
|
function currentComposer() {
|
|
2108
|
-
|
|
2180
|
+
const marked = document.querySelector('[data-codex-composer="true"][contenteditable="true"]');
|
|
2181
|
+
if (marked) return marked;
|
|
2182
|
+
return Array.from(document.querySelectorAll('[contenteditable="true"][role="textbox"]'))
|
|
2183
|
+
.find((element) => isVisibleToolbarControl(element)) ?? null;
|
|
2109
2184
|
}
|
|
2110
2185
|
|
|
2111
2186
|
function rememberComposerSelection() {
|
|
@@ -2428,9 +2503,16 @@ export function createInjectionSource(features, {
|
|
|
2428
2503
|
const entryRect = entry.getBoundingClientRect();
|
|
2429
2504
|
const scrollRect = mainContentViewport()?.querySelector(".thread-scroll-container")
|
|
2430
2505
|
?.getBoundingClientRect();
|
|
2506
|
+
// The native conversation header is a fixed overlay that starts above the
|
|
2507
|
+
// thread scroll container (scroll top is often 0 while the header still
|
|
2508
|
+
// occupies the top toolbar strip). Anchor below the header so the pinned
|
|
2509
|
+
// surface never covers the toolbar entry used to close it again.
|
|
2510
|
+
const header = entry.closest("header");
|
|
2511
|
+
const headerBottom = header?.getBoundingClientRect().bottom ?? 0;
|
|
2512
|
+
const contentTop = Math.max(scrollRect?.top ?? 0, headerBottom);
|
|
2431
2513
|
const top = displayMode === "overlay"
|
|
2432
2514
|
? entryRect.bottom + layout.popoverOffset
|
|
2433
|
-
: (
|
|
2515
|
+
: (contentTop || 46) + layout.verticalInset;
|
|
2434
2516
|
const right = displayMode === "overlay"
|
|
2435
2517
|
? Math.max(layout.popoverOffset, innerWidth - entryRect.right)
|
|
2436
2518
|
: Math.max(layout.panelInset, innerWidth - target.right + layout.panelInset);
|
|
@@ -3218,15 +3300,24 @@ export function createInjectionSource(features, {
|
|
|
3218
3300
|
|
|
3219
3301
|
function ensureToolbarEntries() {
|
|
3220
3302
|
if (!toolbarFeatures.length) return;
|
|
3221
|
-
const
|
|
3222
|
-
if (!bottomPanelButton) return;
|
|
3303
|
+
const temporaryChatButton = nativeTemporaryChatButton();
|
|
3223
3304
|
const summaryButton = nativeSummaryButton();
|
|
3224
|
-
const
|
|
3225
|
-
const
|
|
3226
|
-
const
|
|
3227
|
-
|
|
3305
|
+
const bottomPanelButton = nativeBottomPanelButton();
|
|
3306
|
+
const sidePanelButton = nativeSidePanelButton();
|
|
3307
|
+
const anchorButton = temporaryChatButton ?? summaryButton ?? bottomPanelButton ?? sidePanelButton;
|
|
3308
|
+
if (!anchorButton) return;
|
|
3309
|
+
const anchorRoot = toolbarControlRoot(anchorButton);
|
|
3310
|
+
// The bottom/side-panel toggles sit in narrow fixed containers that
|
|
3311
|
+
// travel with the native panels. Entries anchored to them must live in
|
|
3312
|
+
// the fallback toolbar group, otherwise the Notes entry would be
|
|
3313
|
+
// dragged into the panel or push the native toggle out of the header.
|
|
3314
|
+
// The Notes entry is only grouped with the native summary button when
|
|
3315
|
+
// that button is the anchor.
|
|
3316
|
+
const useFallbackAnchor = anchorButton === sidePanelButton || anchorButton === bottomPanelButton;
|
|
3317
|
+
const summaryGroup = useFallbackAnchor ? null : nativeSummaryToolbarGroup(anchorButton);
|
|
3318
|
+
let targetGroup = summaryGroup ?? ensureFallbackSummaryToolbarGroup(anchorButton);
|
|
3228
3319
|
if (!targetGroup) return;
|
|
3229
|
-
let cursor =
|
|
3320
|
+
let cursor = useFallbackAnchor ? null : anchorRoot;
|
|
3230
3321
|
for (const feature of toolbarFeatures) {
|
|
3231
3322
|
const entries = Array.from(document.querySelectorAll(`[${entryMarker}="${feature.id}"]`));
|
|
3232
3323
|
for (const duplicate of entries.slice(1)) {
|
|
@@ -3234,7 +3325,7 @@ export function createInjectionSource(features, {
|
|
|
3234
3325
|
}
|
|
3235
3326
|
const entry = entries[0]?.isConnected
|
|
3236
3327
|
? entries[0]
|
|
3237
|
-
: createToolbarEntry(feature,
|
|
3328
|
+
: createToolbarEntry(feature, anchorButton);
|
|
3238
3329
|
const entryRoot = entry?.closest("[data-codex-personal-toolbar-entry]") ?? entry;
|
|
3239
3330
|
if (!entryRoot) continue;
|
|
3240
3331
|
if (cursor) {
|
|
@@ -3242,10 +3333,24 @@ export function createInjectionSource(features, {
|
|
|
3242
3333
|
} else if (targetGroup.lastElementChild !== entryRoot) {
|
|
3243
3334
|
targetGroup.append(entryRoot);
|
|
3244
3335
|
}
|
|
3336
|
+
// Narrow native anchor containers (e.g. the Work-mode side-panel
|
|
3337
|
+
// button) can push the entry outside the header so it becomes
|
|
3338
|
+
// unreachable. Move it into the fallback toolbar group instead.
|
|
3339
|
+
if (summaryGroup && !toolbarEntryFitsHeader(entryRoot)) {
|
|
3340
|
+
const fallback = ensureFallbackSummaryToolbarGroup(anchorButton);
|
|
3341
|
+
if (fallback && fallback !== summaryGroup) {
|
|
3342
|
+
fallback.append(entryRoot);
|
|
3343
|
+
targetGroup = fallback;
|
|
3344
|
+
cursor = null;
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3245
3347
|
cursor = entryRoot;
|
|
3246
3348
|
}
|
|
3247
3349
|
if (summaryGroup) {
|
|
3248
|
-
document.querySelectorAll("[data-codex-personal-summary-toolbar-group]").forEach((group) =>
|
|
3350
|
+
document.querySelectorAll("[data-codex-personal-summary-toolbar-group]").forEach((group) => {
|
|
3351
|
+
const used = [...group.querySelectorAll(`[${entryMarker}]`)].some((entry) => entry.isConnected);
|
|
3352
|
+
if (!used) group.remove();
|
|
3353
|
+
});
|
|
3249
3354
|
}
|
|
3250
3355
|
}
|
|
3251
3356
|
|