minecodex 2.0.14 → 2.0.16
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 +9 -0
- package/apps/dashboard/app.js +8 -5
- package/apps/dashboard/assets/data-transfer.js +2 -1
- package/apps/dashboard/transport.js +18 -0
- package/assets/brand/minecodex-icon-selected.svg +4 -0
- package/features/markdown-reading/src/adapters/codex/rich-text.mjs +12 -5
- package/features/markdown-reading/src/adapters/codex/table-actions.mjs +13 -2
- package/features/markdown-reading/src/domain/footnotes.mjs +4 -2
- package/features/markdown-reading/src/injection-source.mjs +2 -0
- package/features/markdown-reading/src/reading.css +3 -3
- package/features/notes/assets/icons/prompt-entry-selected.svg +1 -0
- package/features/notes/assets/icons/prompt-entry.svg +16 -0
- package/features/notes/codex-feature.json +3 -2
- package/features/notes/src/adapters/codex/insertion.mjs +92 -0
- package/features/notes/src/adapters/codex/requests.mjs +7 -0
- package/features/notes/src/frontend/entry.mjs +39 -137
- package/features/notes/src/frontend/icons.json +0 -2
- package/features/notes/src/injection-source.mjs +5 -0
- package/package.json +18 -5
- package/packages/cli/src/commands.mjs +10 -0
- package/packages/codex-adapter/src/renderer/environment.mjs +30 -1
- package/packages/plugin/assets/app.js +116 -0
- package/packages/plugin/assets/prompts.js +437 -0
- package/packages/plugin/plugin.json +16 -0
- package/packages/plugin/src/app.mjs +17 -0
- package/packages/plugin/src/control-client.mjs +41 -0
- package/packages/plugin/src/install.mjs +26 -0
- package/packages/plugin/src/navigation-icons.mjs +8 -0
- package/packages/plugin/src/prompts-app.mjs +45 -0
- package/packages/plugin/src/prompts-client.mjs +16 -0
- package/packages/plugin/src/server.mjs +74 -0
- package/packages/plugin/src/ui-resource.mjs +22 -0
- package/packages/runtime-host/src/codex-injection.mjs +5 -12
- package/packages/runtime-host/src/codex-runtime.mjs +3 -16
- package/packages/ui/src/install.mjs +4 -3
- package/packages/ui/src/native/mcp-app.mjs +32 -0
- package/packages/ui/src/native/mcp-navigation.mjs +52 -0
- package/packages/ui/src/native/mcp-theme.css +4 -0
- package/packages/ui/src/native/mcp-theme.mjs +20 -0
- package/packages/ui/assets/arrow-up-right.svg +0 -13
- package/packages/ui/assets/minecodex-menu-16.svg +0 -7
- package/packages/ui/assets/minecodex-menu-20.svg +0 -7
- package/packages/ui/src/components/account-menu.mjs +0 -88
- package/packages/ui/src/native/account-menu.mjs +0 -21
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
export function installAccountMenuEntry(signal, ui, native) {
|
|
2
|
-
function accountMenuEntry({ label, icon, externalIcon, onOpen }) {
|
|
3
|
-
const marker = "data-mcx-account-menu-entry";
|
|
4
|
-
let node, anchor, entryBindings, opening = false;
|
|
5
|
-
const bindings = new AbortController();
|
|
6
|
-
function svg(source, template = null) {
|
|
7
|
-
if (typeof source !== "string") source = source[Number(template.getAttribute("width"))];
|
|
8
|
-
const result = new DOMParser().parseFromString(source, "image/svg+xml").documentElement;
|
|
9
|
-
result.setAttribute("aria-hidden", "true");
|
|
10
|
-
result.removeAttribute("role");
|
|
11
|
-
result.removeAttribute("aria-labelledby");
|
|
12
|
-
result.querySelectorAll("title, desc").forEach(n => n.remove());
|
|
13
|
-
result.setAttribute("class", template?.getAttribute("class") ?? "icon-xs shrink-0");
|
|
14
|
-
if (template) {
|
|
15
|
-
// 原生 16/20px 图标由外层切换,品牌资源的 24px 不能覆盖它。
|
|
16
|
-
for (const name of ["width", "height", "style"]) {
|
|
17
|
-
const value = template.getAttribute(name);
|
|
18
|
-
if (value == null) result.removeAttribute(name);
|
|
19
|
-
else result.setAttribute(name, value);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return result;
|
|
23
|
-
}
|
|
24
|
-
async function activate(event) {
|
|
25
|
-
event?.preventDefault();
|
|
26
|
-
event?.stopPropagation();
|
|
27
|
-
if (opening) return;
|
|
28
|
-
opening = true;
|
|
29
|
-
const close = anchor.close;
|
|
30
|
-
try { await onOpen(); close(); }
|
|
31
|
-
catch (error) { console.warn("[MineCodex] Control panel could not open", error); window.alert(error.message); }
|
|
32
|
-
finally { opening = false; }
|
|
33
|
-
}
|
|
34
|
-
function sync() {
|
|
35
|
-
if (signal.aborted) return;
|
|
36
|
-
const found = native.settings();
|
|
37
|
-
if (!found) { entryBindings?.abort(); node?.remove(); node = null; anchor = null; return; }
|
|
38
|
-
if (node?.isConnected && anchor.item === found.item) return;
|
|
39
|
-
entryBindings?.abort();
|
|
40
|
-
entryBindings = new AbortController();
|
|
41
|
-
node?.remove();
|
|
42
|
-
anchor = found;
|
|
43
|
-
// 只修改脱离 React 的副本,保留原生 Settings 节点及事件。
|
|
44
|
-
node = found.item.cloneNode(true);
|
|
45
|
-
for (const element of [node, ...node.querySelectorAll("*")]) {
|
|
46
|
-
for (const attr of [...element.attributes]) {
|
|
47
|
-
if (attr.name === "id" || attr.name === "title" || attr.name.startsWith("aria-")
|
|
48
|
-
|| attr.name.startsWith("data-")) element.removeAttribute(attr.name);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
node.setAttribute(marker, "");
|
|
52
|
-
node.setAttribute("role", "menuitem");
|
|
53
|
-
node.tabIndex = -1;
|
|
54
|
-
const [leading, title, trailing] = node.querySelector("div").children;
|
|
55
|
-
// 保留紧凑/普通图标的原生容器及颜色、透明度和状态规则。
|
|
56
|
-
for (const template of leading.querySelectorAll("svg")) template.replaceWith(svg(icon, template));
|
|
57
|
-
title.textContent = label;
|
|
58
|
-
// 右侧提示沿用原生 Help 箭头的 tertiary 色,不套左侧图标的透明度。
|
|
59
|
-
trailing.style.color = "inherit";
|
|
60
|
-
const external = svg(externalIcon);
|
|
61
|
-
external.setAttribute("class", "icon-xs shrink-0 text-tertiary");
|
|
62
|
-
trailing.replaceChildren(external);
|
|
63
|
-
node.addEventListener("click", activate, { signal:entryBindings.signal });
|
|
64
|
-
node.addEventListener("pointermove", () => node.focus({ preventScroll:true }), { signal:entryBindings.signal });
|
|
65
|
-
found.item.after(node);
|
|
66
|
-
}
|
|
67
|
-
function keyboard(event) {
|
|
68
|
-
if (!anchor || !node?.isConnected || !anchor.menu.contains(event.target)) return;
|
|
69
|
-
const current = event.target.closest('[role="menuitem"]');
|
|
70
|
-
let next;
|
|
71
|
-
if (current === anchor.item && event.key === "ArrowDown") next = node;
|
|
72
|
-
else if (current === node && event.key === "ArrowUp") next = anchor.item;
|
|
73
|
-
else if (current === node && event.key === "ArrowDown") {
|
|
74
|
-
const items = [...anchor.menu.querySelectorAll('[role="menuitem"]')];
|
|
75
|
-
next = items[items.indexOf(node) + 1] ?? items[0];
|
|
76
|
-
} else if (current === node && ["Enter", " "].includes(event.key)) { void activate(event); return; }
|
|
77
|
-
if (next) { event.preventDefault(); event.stopImmediatePropagation(); next.focus({ preventScroll:true }); }
|
|
78
|
-
}
|
|
79
|
-
document.addEventListener("keydown", keyboard, { capture:true, signal:bindings.signal });
|
|
80
|
-
const observer = new MutationObserver(sync);
|
|
81
|
-
observer.observe(document.documentElement, { childList:true, subtree:true });
|
|
82
|
-
const dispose = () => { observer.disconnect(); bindings.abort(); entryBindings?.abort(); node?.remove(); node = null; anchor = null; };
|
|
83
|
-
signal.addEventListener("abort", dispose, { once:true });
|
|
84
|
-
sync();
|
|
85
|
-
return { sync, dispose };
|
|
86
|
-
}
|
|
87
|
-
return { accountMenuEntry };
|
|
88
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export function createNativeAccountMenuAdapter(codex) {
|
|
2
|
-
function settings() {
|
|
3
|
-
for (const menu of document.querySelectorAll('[role="menu"]')) {
|
|
4
|
-
if (!menu.checkVisibility({ visibilityProperty:true })) continue;
|
|
5
|
-
for (const item of menu.querySelectorAll('[role="menuitem"]')) {
|
|
6
|
-
const profile = codex.props(item, p => typeof p.onOpenSettings === "function" && "settingsShortcut" in p);
|
|
7
|
-
if (!profile || !codex.props(item, p => p.onClick === profile.onOpenSettings)) continue;
|
|
8
|
-
const content = item.querySelector('[data-menu-row-content]');
|
|
9
|
-
const [leading, label, shortcut] = content?.children ?? [];
|
|
10
|
-
if (!leading?.querySelector('svg') || !label || !shortcut) continue;
|
|
11
|
-
const owner = codex.props(item, p => typeof p.onClose === "function" && "open" in p);
|
|
12
|
-
if (!owner) continue;
|
|
13
|
-
codex.report("account-menu", true);
|
|
14
|
-
return { menu, item, close:owner.onClose };
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
codex.report("account-menu", false, "profile-menu-unavailable");
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
return { settings };
|
|
21
|
-
}
|