@leeoohoo/ui-apps-devkit 0.1.4 → 0.1.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/package.json +1 -1
- package/src/sandbox/server.js +68 -4
package/package.json
CHANGED
package/src/sandbox/server.js
CHANGED
|
@@ -628,6 +628,16 @@ function htmlPage() {
|
|
|
628
628
|
}
|
|
629
629
|
#container { flex: 1 1 auto; min-height:0; overflow:hidden; }
|
|
630
630
|
#containerInner { height:100%; overflow:auto; }
|
|
631
|
+
body[data-surface='compact'] #headerSlot {
|
|
632
|
+
width: 50vw;
|
|
633
|
+
align-self: flex-end;
|
|
634
|
+
border-left: 1px solid var(--ds-panel-border);
|
|
635
|
+
}
|
|
636
|
+
body[data-surface='compact'] #container {
|
|
637
|
+
width: 50vw;
|
|
638
|
+
align-self: flex-end;
|
|
639
|
+
border-left: 1px solid var(--ds-panel-border);
|
|
640
|
+
}
|
|
631
641
|
.muted { opacity: 0.7; font-size: 12px; }
|
|
632
642
|
.bar { display:flex; gap:10px; align-items:center; justify-content:space-between; }
|
|
633
643
|
.btn {
|
|
@@ -795,6 +805,7 @@ function htmlPage() {
|
|
|
795
805
|
<div id="sandboxContext" class="muted"></div>
|
|
796
806
|
<button id="btnLlmConfig" class="btn" type="button">AI Config</button>
|
|
797
807
|
<button id="btnMcpTest" class="btn" type="button">MCP Test</button>
|
|
808
|
+
<button id="btnHalfApp" class="btn" type="button">半屏</button>
|
|
798
809
|
<button id="btnInspectorToggle" class="btn" type="button">Inspect</button>
|
|
799
810
|
<button id="btnReload" class="btn" type="button">Reload</button>
|
|
800
811
|
</div>
|
|
@@ -950,6 +961,7 @@ const llmModelId = $('#llmModelId');
|
|
|
950
961
|
const llmStatus = $('#llmStatus');
|
|
951
962
|
const llmKeyStatus = $('#llmKeyStatus');
|
|
952
963
|
const btnMcpTest = $('#btnMcpTest');
|
|
964
|
+
const btnHalfApp = $('#btnHalfApp');
|
|
953
965
|
const mcpPanel = $('#mcpPanel');
|
|
954
966
|
const btnMcpClose = $('#btnMcpClose');
|
|
955
967
|
const btnMcpClear = $('#btnMcpClear');
|
|
@@ -1021,6 +1033,34 @@ const updateContextStatus = () => {
|
|
|
1021
1033
|
sandboxContext.textContent = __SANDBOX__.pluginId + ':' + __SANDBOX__.appId;
|
|
1022
1034
|
};
|
|
1023
1035
|
|
|
1036
|
+
const entryCompactUrl = __SANDBOX__.entryCompactUrl || '';
|
|
1037
|
+
const hasCompactEntry = Boolean(entryCompactUrl);
|
|
1038
|
+
let currentSurface = 'full';
|
|
1039
|
+
|
|
1040
|
+
const updateSurfaceState = (surface) => {
|
|
1041
|
+
currentSurface = surface === 'compact' ? 'compact' : 'full';
|
|
1042
|
+
document.body.dataset.surface = currentSurface;
|
|
1043
|
+
if (btnHalfApp) {
|
|
1044
|
+
if (!hasCompactEntry) {
|
|
1045
|
+
btnHalfApp.disabled = true;
|
|
1046
|
+
btnHalfApp.title = 'plugin.json 未配置 entry.compact.path';
|
|
1047
|
+
delete btnHalfApp.dataset.active;
|
|
1048
|
+
} else {
|
|
1049
|
+
btnHalfApp.disabled = false;
|
|
1050
|
+
btnHalfApp.title = '';
|
|
1051
|
+
btnHalfApp.dataset.active = currentSurface === 'compact' ? '1' : '0';
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
if (host?.ui) host.ui.surface = currentSurface;
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
const toggleCompactSurface = () => {
|
|
1058
|
+
if (!hasCompactEntry) return;
|
|
1059
|
+
updateSurfaceState(currentSurface === 'compact' ? 'full' : 'compact');
|
|
1060
|
+
loadAndMount().catch(renderError);
|
|
1061
|
+
updateInspectorIfOpen();
|
|
1062
|
+
};
|
|
1063
|
+
|
|
1024
1064
|
const isInspectorOpen = () => sandboxInspector && sandboxInspector.style.display === 'flex';
|
|
1025
1065
|
const isLlmPanelOpen = () => llmPanel && llmPanel.style.display === 'flex';
|
|
1026
1066
|
const isMcpPanelOpen = () => mcpPanel && mcpPanel.style.display === 'flex';
|
|
@@ -1199,7 +1239,13 @@ const collectTokens = () => {
|
|
|
1199
1239
|
const readHostContext = () => {
|
|
1200
1240
|
if (!inspectorEnabled) return null;
|
|
1201
1241
|
if (typeof host?.context?.get === 'function') return host.context.get();
|
|
1202
|
-
return {
|
|
1242
|
+
return {
|
|
1243
|
+
pluginId: __SANDBOX__.pluginId,
|
|
1244
|
+
appId: __SANDBOX__.appId,
|
|
1245
|
+
theme: currentTheme,
|
|
1246
|
+
surface: currentSurface,
|
|
1247
|
+
bridge: { enabled: true },
|
|
1248
|
+
};
|
|
1203
1249
|
};
|
|
1204
1250
|
|
|
1205
1251
|
const readThemeInfo = () => ({
|
|
@@ -1279,6 +1325,7 @@ if (btnLlmRefresh) btnLlmRefresh.addEventListener('click', () => refreshLlmConfi
|
|
|
1279
1325
|
if (btnLlmSave) btnLlmSave.addEventListener('click', () => saveLlmConfig());
|
|
1280
1326
|
if (btnLlmClear) btnLlmClear.addEventListener('click', () => saveLlmConfig({ clearKey: true }));
|
|
1281
1327
|
if (btnMcpTest) btnMcpTest.addEventListener('click', () => setMcpPanelOpen(!isMcpPanelOpen()));
|
|
1328
|
+
if (btnHalfApp) btnHalfApp.addEventListener('click', () => toggleCompactSurface());
|
|
1282
1329
|
if (btnMcpClose) btnMcpClose.addEventListener('click', () => setMcpPanelOpen(false));
|
|
1283
1330
|
if (btnMcpClear)
|
|
1284
1331
|
btnMcpClear.addEventListener('click', () => {
|
|
@@ -1471,7 +1518,15 @@ const getTheme = () => currentTheme || resolveTheme();
|
|
|
1471
1518
|
|
|
1472
1519
|
const host = {
|
|
1473
1520
|
bridge: { enabled: true },
|
|
1474
|
-
context: {
|
|
1521
|
+
context: {
|
|
1522
|
+
get: () => ({
|
|
1523
|
+
pluginId: __SANDBOX__.pluginId,
|
|
1524
|
+
appId: __SANDBOX__.appId,
|
|
1525
|
+
theme: getTheme(),
|
|
1526
|
+
surface: currentSurface,
|
|
1527
|
+
bridge: { enabled: true },
|
|
1528
|
+
}),
|
|
1529
|
+
},
|
|
1475
1530
|
theme: {
|
|
1476
1531
|
get: getTheme,
|
|
1477
1532
|
onChange: (listener) => {
|
|
@@ -1524,7 +1579,7 @@ const host = {
|
|
|
1524
1579
|
close: () => (setPanelOpen(false), { ok: true }),
|
|
1525
1580
|
toggle: () => (setPanelOpen(panel.style.display !== 'flex'), { ok: true }),
|
|
1526
1581
|
},
|
|
1527
|
-
ui: { navigate: (menu) => ({ ok: true, menu }) },
|
|
1582
|
+
ui: { navigate: (menu) => ({ ok: true, menu }), surface: 'full' },
|
|
1528
1583
|
chat: (() => {
|
|
1529
1584
|
const clone = (v) => JSON.parse(JSON.stringify(v));
|
|
1530
1585
|
|
|
@@ -1779,6 +1834,8 @@ const host = {
|
|
|
1779
1834
|
})(),
|
|
1780
1835
|
};
|
|
1781
1836
|
|
|
1837
|
+
updateSurfaceState('full');
|
|
1838
|
+
|
|
1782
1839
|
inspectorEnabled = true;
|
|
1783
1840
|
updateInspector();
|
|
1784
1841
|
|
|
@@ -1788,7 +1845,7 @@ async function loadAndMount() {
|
|
|
1788
1845
|
if (typeof dispose === 'function') { try { await dispose(); } catch {} dispose = null; }
|
|
1789
1846
|
container.textContent = '';
|
|
1790
1847
|
|
|
1791
|
-
const entryUrl = __SANDBOX__.entryUrl;
|
|
1848
|
+
const entryUrl = currentSurface === 'compact' && entryCompactUrl ? entryCompactUrl : __SANDBOX__.entryUrl;
|
|
1792
1849
|
const mod = await import(entryUrl + (entryUrl.includes('?') ? '&' : '?') + 't=' + Date.now());
|
|
1793
1850
|
const mount = mod?.mount || mod?.default?.mount || (typeof mod?.default === 'function' ? mod.default : null);
|
|
1794
1851
|
if (typeof mount !== 'function') throw new Error('module entry must export mount()');
|
|
@@ -1851,7 +1908,13 @@ export async function startSandboxServer({ pluginDir, port = 4399, appId = '' })
|
|
|
1851
1908
|
const entryAbs = resolveInsideDir(pluginDir, entryRel);
|
|
1852
1909
|
if (!isFile(entryAbs)) throw new Error(`module entry not found: ${entryRel}`);
|
|
1853
1910
|
|
|
1911
|
+
const entryCompactRel = String(app?.entry?.compact?.path || '').trim();
|
|
1854
1912
|
const entryUrl = `/plugin/${encodeURIComponent(entryRel).replaceAll('%2F', '/')}`;
|
|
1913
|
+
const entryCompactAbs = entryCompactRel ? resolveInsideDir(pluginDir, entryCompactRel) : '';
|
|
1914
|
+
const entryCompactUrl =
|
|
1915
|
+
entryCompactAbs && isFile(entryCompactAbs)
|
|
1916
|
+
? `/plugin/${encodeURIComponent(entryCompactRel).replaceAll('%2F', '/')}`
|
|
1917
|
+
: '';
|
|
1855
1918
|
|
|
1856
1919
|
let backendInstance = null;
|
|
1857
1920
|
let backendFactory = null;
|
|
@@ -2165,6 +2228,7 @@ export async function startSandboxServer({ pluginDir, port = 4399, appId = '' })
|
|
|
2165
2228
|
.replaceAll('__SANDBOX__.pluginId', JSON.stringify(ctxBase.pluginId))
|
|
2166
2229
|
.replaceAll('__SANDBOX__.appId', JSON.stringify(effectiveAppId))
|
|
2167
2230
|
.replaceAll('__SANDBOX__.entryUrl', JSON.stringify(entryUrl))
|
|
2231
|
+
.replaceAll('__SANDBOX__.entryCompactUrl', JSON.stringify(entryCompactUrl))
|
|
2168
2232
|
.replaceAll('__SANDBOX__.registryApp', JSON.stringify({ plugin: { id: ctxBase.pluginId }, id: effectiveAppId, entry: { type: 'module', url: entryUrl } }))
|
|
2169
2233
|
.replaceAll('__SANDBOX__.tokenNames', JSON.stringify(tokenNames))
|
|
2170
2234
|
.replaceAll('__SANDBOX__.paths', JSON.stringify(sandboxPaths));
|