@matamt-dbg/dsh-studio 0.2.7 → 0.2.8
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/client.js +219 -46
- package/index.js +147 -4
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -115,8 +115,7 @@ function parsePreviewRequest(value) {
|
|
|
115
115
|
var import_react = __toESM(require("react"), 1);
|
|
116
116
|
|
|
117
117
|
// src/ui-styles.ts
|
|
118
|
-
var
|
|
119
|
-
.studio-ui {
|
|
118
|
+
var adapter = `.studio-ui {
|
|
120
119
|
--studio-bg: var(--dsw-alias-bg-base);
|
|
121
120
|
--studio-surface: var(--dsw-alias-bg-layer-1);
|
|
122
121
|
--studio-inset: var(--dsw-alias-bg-layer-2);
|
|
@@ -148,7 +147,9 @@ var studioStyles = `/* Only this adapter references host tokens. Studio never in
|
|
|
148
147
|
min-width: 0;
|
|
149
148
|
overflow-wrap: anywhere;
|
|
150
149
|
}
|
|
151
|
-
|
|
150
|
+
`;
|
|
151
|
+
var studioStyles = `/* Only this adapter references host tokens. Studio never installs a global theme. */
|
|
152
|
+
${adapter}.studio-ui *, .studio-ui *::before, .studio-ui *::after { box-sizing: border-box; }
|
|
152
153
|
.studio-ui .studio-tool-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 12px; }
|
|
153
154
|
.studio-ui .studio-tool-card { display: flex; flex-direction: column; gap: 8px; padding: 14px; border: 1px solid var(--studio-line); border-radius: var(--studio-radius); cursor: pointer; min-width: 0; }
|
|
154
155
|
.studio-ui .studio-tool-card[data-selected="true"] { background: var(--studio-hover); border-color: var(--studio-ink); }
|
|
@@ -217,6 +218,14 @@ var studioStyles = `/* Only this adapter references host tokens. Studio never in
|
|
|
217
218
|
.studio-ui .studio-service-panel[hidden] { display: none; }
|
|
218
219
|
.studio-ui .studio-service-panel > .studio-ui { max-width: 960px; margin: 0 auto; padding: 24px clamp(16px, 3vw, 40px) 48px; }
|
|
219
220
|
.studio-ui .studio-layout { display: grid; grid-template-columns: 208px minmax(0, 1fr); height: 100%; }
|
|
221
|
+
/* Version footer pinned to the bottom of the Studio navigation. */
|
|
222
|
+
.studio-ui .studio-nav-footer { display: flex; align-items: center; gap: 6px; margin-top: auto; padding: 12px 10px 0; color: var(--studio-subtle); font-size: 12px; }
|
|
223
|
+
.studio-ui .studio-icon-button { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: var(--studio-small-radius); background: none; color: var(--studio-info); cursor: pointer; }
|
|
224
|
+
.studio-ui .studio-icon-button:hover:not(:disabled) { background: var(--studio-hover); }
|
|
225
|
+
.studio-ui .studio-icon-button[data-tone=success] { color: var(--studio-success); }
|
|
226
|
+
.studio-ui .studio-icon-button[data-tone=error] { color: var(--studio-error); }
|
|
227
|
+
.studio-ui .studio-icon-button:disabled { cursor: default; opacity: 1; }
|
|
228
|
+
.studio-ui .studio-icon-button[aria-busy=true] { opacity: .5; }
|
|
220
229
|
.studio-ui nav.studio-nav { display: flex; flex-direction: column; flex-wrap: nowrap; gap: 2px; margin: 0; padding: 24px 12px; border-inline-end: .5px solid var(--studio-line); overflow-y: auto; }
|
|
221
230
|
.studio-ui .studio-nav-head { display: grid; gap: 2px; padding: 0 10px 8px; }
|
|
222
231
|
.studio-ui .studio-nav-title { font-size: 14px; }
|
|
@@ -607,6 +616,7 @@ var studioStyles = `/* Only this adapter references host tokens. Studio never in
|
|
|
607
616
|
.studio-ui nav.studio-nav { flex-direction: row; overflow-x: auto; padding: 8px 12px; border-inline-end: 0; border-bottom: .5px solid var(--studio-line); }
|
|
608
617
|
.studio-ui .studio-nav-title, .studio-ui .studio-nav-group { display: none; }
|
|
609
618
|
.studio-ui .studio-nav-item { flex: 0 0 auto; }
|
|
619
|
+
.studio-ui .studio-nav-footer { margin: 0 0 0 auto; padding: 0 0 0 8px; }
|
|
610
620
|
.studio-ui .studio-scroller { overflow: visible; }
|
|
611
621
|
}
|
|
612
622
|
@container studio-main (max-width: 560px) {
|
|
@@ -625,6 +635,13 @@ var studioStyles = `/* Only this adapter references host tokens. Studio never in
|
|
|
625
635
|
.studio-ui dd { margin-bottom: 8px; }
|
|
626
636
|
}
|
|
627
637
|
`;
|
|
638
|
+
var sidebarMarkStyles = `${adapter}
|
|
639
|
+
.studio-ui.studio-sidebar-glyph { display: inline-flex; color: inherit; line-height: 0; }
|
|
640
|
+
.studio-ui .studio-sidebar-dot { fill: var(--studio-info); }
|
|
641
|
+
/* order keeps the mark last even if the sidebar later appends its own label. */
|
|
642
|
+
.studio-ui.studio-sidebar-update { display: inline-flex; flex: none; align-items: center; order: 99; margin-left: auto; color: var(--studio-info); line-height: 0; }
|
|
643
|
+
.studio-ui.studio-sidebar-update[data-phase=failed] { color: var(--studio-error); }
|
|
644
|
+
`;
|
|
628
645
|
|
|
629
646
|
// src/ui.tsx
|
|
630
647
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -702,6 +719,9 @@ function SplitButton({ label, onClick, primary = false, disabled = false, action
|
|
|
702
719
|
}, children: action.label }, action.label)) })
|
|
703
720
|
] });
|
|
704
721
|
}
|
|
722
|
+
function IconButton({ label, tone = "info", disabled = false, busy = false, onClick, children }) {
|
|
723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "studio-icon-button", "data-tone": tone, title: label, "aria-label": label, "aria-busy": busy || void 0, disabled, onClick, children });
|
|
724
|
+
}
|
|
705
725
|
function DetailDialog({ open, title, subtitle, onClose, closeLabel, footer, wide = false, compact = false, children }) {
|
|
706
726
|
const ref = import_react.default.useRef(null);
|
|
707
727
|
const opener = import_react.default.useRef(null);
|
|
@@ -800,7 +820,7 @@ ${item.searchText ?? ""}`.toLowerCase().includes(text)));
|
|
|
800
820
|
// src/role-editor.tsx
|
|
801
821
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
802
822
|
function RoleEditor({ locale, roles, onChange, loadModels, defaultPersona = "", tools, hiddenTools = [], onHiddenToolsChange, delegates = true }) {
|
|
803
|
-
const t = (
|
|
823
|
+
const t = (ko3, en3, zh3) => locale.startsWith("ko") ? ko3 : locale.startsWith("zh") ? zh3 : en3;
|
|
804
824
|
const [selected, setSelected] = import_react3.default.useState();
|
|
805
825
|
const [catalog, setCatalog] = import_react3.default.useState();
|
|
806
826
|
const [error, setError] = import_react3.default.useState("");
|
|
@@ -984,7 +1004,7 @@ var import_react9 = __toESM(require("react"), 1);
|
|
|
984
1004
|
var import_react4 = __toESM(require("react"), 1);
|
|
985
1005
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
986
1006
|
function MasterExtensionsEditor({ locale, actions }) {
|
|
987
|
-
const t = (
|
|
1007
|
+
const t = (ko3, en3, zh3) => locale.startsWith("ko") ? ko3 : locale.startsWith("zh") ? zh3 : en3;
|
|
988
1008
|
const [text, setText] = import_react4.default.useState("[]");
|
|
989
1009
|
const [error, setError] = import_react4.default.useState("");
|
|
990
1010
|
const [busy, setBusy] = import_react4.default.useState(false);
|
|
@@ -1039,6 +1059,7 @@ var PACKAGE_NAME = "@matamt-dbg/dsh-studio";
|
|
|
1039
1059
|
var POLICY_PLUGIN = `${PACKAGE_NAME}/policy`;
|
|
1040
1060
|
var ROLE_PLUGIN = `${PACKAGE_NAME}/roles`;
|
|
1041
1061
|
var BATCH_PLUGIN = `${PACKAGE_NAME}/batch`;
|
|
1062
|
+
var STUDIO_VERSION = "0.2.8";
|
|
1042
1063
|
|
|
1043
1064
|
// src/delegation.ts
|
|
1044
1065
|
var ROLE_TOOL = "subagent_role";
|
|
@@ -1467,7 +1488,7 @@ var import_react6 = __toESM(require("react"), 1);
|
|
|
1467
1488
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1468
1489
|
var message = (error) => error instanceof Error ? error.message : String(error);
|
|
1469
1490
|
function PresetList({ locale, api, revision, onEdit, onCopy }) {
|
|
1470
|
-
const t = (
|
|
1491
|
+
const t = (ko3, en3, zh3) => locale.startsWith("ko") ? ko3 : locale.startsWith("zh") ? zh3 : en3;
|
|
1471
1492
|
const [load, setLoad] = import_react6.default.useState({ phase: "loading" });
|
|
1472
1493
|
const [action, setAction] = import_react6.default.useState();
|
|
1473
1494
|
const [deleting, setDeleting] = import_react6.default.useState();
|
|
@@ -1629,7 +1650,7 @@ var import_react7 = __toESM(require("react"), 1);
|
|
|
1629
1650
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1630
1651
|
var defaultProvidedTools = [];
|
|
1631
1652
|
function PromptToolsPrototype({ locale, prompt, onPromptChange, provided, onProvidedChange, catalog, catalogError, onPreview, onRequestChange, initialRequest }) {
|
|
1632
|
-
const t = (
|
|
1653
|
+
const t = (ko3, en3, zh3) => locale.startsWith("ko") ? ko3 : locale.startsWith("zh") ? zh3 : en3;
|
|
1633
1654
|
const base = initialRequest?.preset ?? "studio-master";
|
|
1634
1655
|
const [toolOverrides, setToolOverrides] = import_react7.default.useState(renameLegacyRoleKey(initialRequest?.toolOverrides) ?? {});
|
|
1635
1656
|
const [sections, setSections] = import_react7.default.useState(initialRequest?.sections ?? {});
|
|
@@ -1841,7 +1862,7 @@ function parameterFields(schema, prefix = "") {
|
|
|
1841
1862
|
// src/detail-layout.tsx
|
|
1842
1863
|
var import_react8 = __toESM(require("react"), 1);
|
|
1843
1864
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1844
|
-
function DetailLayout({ title, subtitle, navigation, pages, selected, onSelect }) {
|
|
1865
|
+
function DetailLayout({ title, subtitle, navigation, pages, selected, onSelect, footer }) {
|
|
1845
1866
|
const id = import_react8.default.useId();
|
|
1846
1867
|
const scroller = import_react8.default.useRef(null);
|
|
1847
1868
|
import_react8.default.useLayoutEffect(() => {
|
|
@@ -1866,7 +1887,8 @@ function DetailLayout({ title, subtitle, navigation, pages, selected, onSelect }
|
|
|
1866
1887
|
children: page.label
|
|
1867
1888
|
}
|
|
1868
1889
|
)
|
|
1869
|
-
] }, page.id))
|
|
1890
|
+
] }, page.id)),
|
|
1891
|
+
footer
|
|
1870
1892
|
] }),
|
|
1871
1893
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "studio-scroller", ref: scroller, "data-studio-scroller": "", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "studio-content", children: pages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1872
1894
|
"section",
|
|
@@ -1892,8 +1914,8 @@ var seeds = [
|
|
|
1892
1914
|
{ name: "Researcher", role: "research", model: "inherit", reasoning: "inherit", spawn: "fresh", persona: "Investigate primary sources and cite the evidence." },
|
|
1893
1915
|
{ name: "Reviewer", role: "review", model: "inherit", reasoning: "inherit", spawn: "fork", persona: "Review correctness and identify concrete risks." }
|
|
1894
1916
|
];
|
|
1895
|
-
function OptimizationPrototype({ locale, catalog, catalogError, onPreview, presetActions, extensionActions }) {
|
|
1896
|
-
const t = (
|
|
1917
|
+
function OptimizationPrototype({ locale, catalog, catalogError, onPreview, presetActions, extensionActions, navFooter }) {
|
|
1918
|
+
const t = (ko3, en3, zh3) => locale.startsWith("ko") ? ko3 : locale.startsWith("zh") ? zh3 : en3;
|
|
1897
1919
|
const [page, setPage] = import_react9.default.useState("list");
|
|
1898
1920
|
const [common, setCommon] = import_react9.default.useState({ ...initial });
|
|
1899
1921
|
const [agents, setAgents] = import_react9.default.useState(() => seeds.map((a) => ({ ...a })));
|
|
@@ -1936,9 +1958,9 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1936
1958
|
setSaving(false);
|
|
1937
1959
|
}
|
|
1938
1960
|
};
|
|
1939
|
-
const editPreset = (item,
|
|
1940
|
-
setEditing(
|
|
1941
|
-
setName(
|
|
1961
|
+
const editPreset = (item, copy3 = false) => {
|
|
1962
|
+
setEditing(copy3 ? { ...item, id: "" } : item);
|
|
1963
|
+
setName(copy3 ? `${item.name} Copy` : item.name);
|
|
1942
1964
|
setDescription(item.description);
|
|
1943
1965
|
setCommon({ ...initial, prompt: item.request.prompt, spill: item.conveniences?.spill ?? initial.spill });
|
|
1944
1966
|
setProvided([...item.request.tools]);
|
|
@@ -1965,7 +1987,7 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
1965
1987
|
{ id: "agents", label: t("\uC11C\uBE0C\uC5D0\uC774\uC804\uD2B8", "Subagent settings", "\u5B50\u4EE3\u7406\u8BBE\u7F6E"), content: agentPage }
|
|
1966
1988
|
];
|
|
1967
1989
|
const tabId = import_react9.default.useId();
|
|
1968
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DetailLayout, { title: "DSH Studio", subtitle: t("\uC5D0\uC774\uC804\uD2B8 \uD504\uB9AC\uC14B \uD3B8\uC9D1\uAE30", "Agent preset editor", "\u4EE3\u7406\u9884\u8BBE\u7F16\u8F91\u5668"), navigation: t("Studio \uBA54\uB274", "Studio menu", "\u9884\u8BBE\u5BFC\u822A"), selected: page, onSelect: (next) => {
|
|
1990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DetailLayout, { footer: navFooter, title: "DSH Studio", subtitle: t("\uC5D0\uC774\uC804\uD2B8 \uD504\uB9AC\uC14B \uD3B8\uC9D1\uAE30", "Agent preset editor", "\u4EE3\u7406\u9884\u8BBE\u7F16\u8F91\u5668"), navigation: t("Studio \uBA54\uB274", "Studio menu", "\u9884\u8BBE\u5BFC\u822A"), selected: page, onSelect: (next) => {
|
|
1969
1991
|
if (next === "create" && editing) {
|
|
1970
1992
|
setEditing(void 0);
|
|
1971
1993
|
setName("");
|
|
@@ -2006,7 +2028,7 @@ function OptimizationPrototype({ locale, catalog, catalogError, onPreview, prese
|
|
|
2006
2028
|
}
|
|
2007
2029
|
|
|
2008
2030
|
// src/shell.tsx
|
|
2009
|
-
var
|
|
2031
|
+
var import_react12 = __toESM(require("react"), 1);
|
|
2010
2032
|
var import_dsh_client_ui_slots = require("@deepseek-ai/dsh-client-ui-slots");
|
|
2011
2033
|
|
|
2012
2034
|
// src/service-layout.tsx
|
|
@@ -2050,8 +2072,145 @@ function ServiceLayout({ locale, services, renderSlot }) {
|
|
|
2050
2072
|
] });
|
|
2051
2073
|
}
|
|
2052
2074
|
|
|
2053
|
-
// src/
|
|
2075
|
+
// src/update-store.ts
|
|
2076
|
+
function createUpdateStore(actions, current) {
|
|
2077
|
+
let state = { phase: "idle", current };
|
|
2078
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2079
|
+
const set = (next) => {
|
|
2080
|
+
state = next;
|
|
2081
|
+
listeners.forEach((listener) => listener());
|
|
2082
|
+
};
|
|
2083
|
+
return {
|
|
2084
|
+
getSnapshot: () => state,
|
|
2085
|
+
subscribe(listener) {
|
|
2086
|
+
listeners.add(listener);
|
|
2087
|
+
return () => {
|
|
2088
|
+
listeners.delete(listener);
|
|
2089
|
+
};
|
|
2090
|
+
},
|
|
2091
|
+
async refresh(force = false) {
|
|
2092
|
+
if (state.phase === "updating" || state.phase === "installed") return;
|
|
2093
|
+
try {
|
|
2094
|
+
const status = await actions.status(force);
|
|
2095
|
+
const phase = () => state.phase;
|
|
2096
|
+
if (phase() === "updating" || phase() === "installed") return;
|
|
2097
|
+
if (status.installed) {
|
|
2098
|
+
set({ phase: "installed", current: status.current, version: status.installed });
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
2101
|
+
const version = status.available && !status.blocked ? status.available : void 0;
|
|
2102
|
+
set({ phase: "idle", current: status.current, ...version ? { version } : {} });
|
|
2103
|
+
} catch {
|
|
2104
|
+
}
|
|
2105
|
+
},
|
|
2106
|
+
async update() {
|
|
2107
|
+
if (state.phase !== "idle" && state.phase !== "failed") return;
|
|
2108
|
+
const version = state.version;
|
|
2109
|
+
if (!version) return;
|
|
2110
|
+
set({ phase: "updating", current: state.current, version });
|
|
2111
|
+
try {
|
|
2112
|
+
const result = await actions.update(version);
|
|
2113
|
+
if (result.status === "restart-required" || result.status === "applied") set({ phase: "installed", current: state.current, version: result.version });
|
|
2114
|
+
else set({ phase: "failed", current: state.current, version, message: result.message ?? result.status });
|
|
2115
|
+
} catch (error) {
|
|
2116
|
+
set({ phase: "failed", current: state.current, version, message: error instanceof Error ? error.message : String(error) });
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
};
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
// src/update-indicator.tsx
|
|
2123
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
2124
|
+
var import_react_dom = require("react-dom");
|
|
2054
2125
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2126
|
+
var ko2 = {
|
|
2127
|
+
available: (v) => `v${v}\uB85C \uC5C5\uB370\uC774\uD2B8`,
|
|
2128
|
+
updating: (v) => `v${v} \uC124\uCE58 \uC911`,
|
|
2129
|
+
installed: (v) => `v${v}\uB97C \uC124\uCE58\uD588\uC2B5\uB2C8\uB2E4. DSH\uB97C \uB2E4\uC2DC \uC2DC\uC791\uD558\uBA74 \uC801\uC6A9\uB429\uB2C8\uB2E4.`,
|
|
2130
|
+
failed: (v, message2) => `v${v}\uB85C \uC5C5\uB370\uC774\uD2B8\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uB824\uBA74 \uB204\uB974\uC138\uC694. (${message2})`
|
|
2131
|
+
};
|
|
2132
|
+
var en2 = {
|
|
2133
|
+
available: (v) => `Update to v${v}`,
|
|
2134
|
+
updating: (v) => `Installing v${v}`,
|
|
2135
|
+
installed: (v) => `Installed v${v}. Restart DSH to use it.`,
|
|
2136
|
+
failed: (v, message2) => `Could not update to v${v}. Select to try again. (${message2})`
|
|
2137
|
+
};
|
|
2138
|
+
var zh2 = {
|
|
2139
|
+
available: (v) => `\u66F4\u65B0\u5230 v${v}`,
|
|
2140
|
+
updating: (v) => `\u6B63\u5728\u5B89\u88C5 v${v}`,
|
|
2141
|
+
installed: (v) => `\u5DF2\u5B89\u88C5 v${v}\u3002\u91CD\u542F DSH \u540E\u751F\u6548`,
|
|
2142
|
+
failed: (v, message2) => `\u65E0\u6CD5\u66F4\u65B0\u5230 v${v}\u3002\u70B9\u51FB\u91CD\u8BD5\uFF08${message2}\uFF09`
|
|
2143
|
+
};
|
|
2144
|
+
var copy2 = (locale) => locale.startsWith("ko") ? ko2 : locale.startsWith("zh") ? zh2 : en2;
|
|
2145
|
+
function useUpdateState(store) {
|
|
2146
|
+
return import_react11.default.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
2147
|
+
}
|
|
2148
|
+
function updateLabel(state, locale) {
|
|
2149
|
+
const t = copy2(locale);
|
|
2150
|
+
if (state.phase === "updating") return t.updating(state.version);
|
|
2151
|
+
if (state.phase === "installed") return t.installed(state.version);
|
|
2152
|
+
if (state.phase === "failed") return t.failed(state.version, state.message);
|
|
2153
|
+
return state.version ? t.available(state.version) : void 0;
|
|
2154
|
+
}
|
|
2155
|
+
function UpdateGlyph({ phase, size = 14 }) {
|
|
2156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: size, height: size, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
2157
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "8", cy: "8", r: "6.5" }),
|
|
2158
|
+
phase === "installed" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M5.2 8.2l1.9 1.9 3.7-4" }) : phase === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M8 4.8v3.8M8 11.2v.01" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M8 11V5.2M5.4 7.6L8 5l2.6 2.6" })
|
|
2159
|
+
] });
|
|
2160
|
+
}
|
|
2161
|
+
function VersionFooter({ store, locale }) {
|
|
2162
|
+
const state = useUpdateState(store);
|
|
2163
|
+
const label = updateLabel(state, locale);
|
|
2164
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "studio-nav-footer", children: [
|
|
2165
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "studio-mono", children: [
|
|
2166
|
+
"v",
|
|
2167
|
+
state.current
|
|
2168
|
+
] }),
|
|
2169
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2170
|
+
IconButton,
|
|
2171
|
+
{
|
|
2172
|
+
label,
|
|
2173
|
+
tone: state.phase === "failed" ? "error" : state.phase === "installed" ? "success" : "info",
|
|
2174
|
+
disabled: state.phase === "updating" || state.phase === "installed",
|
|
2175
|
+
busy: state.phase === "updating",
|
|
2176
|
+
onClick: () => {
|
|
2177
|
+
void store.update();
|
|
2178
|
+
},
|
|
2179
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(UpdateGlyph, { phase: state.phase })
|
|
2180
|
+
}
|
|
2181
|
+
)
|
|
2182
|
+
] });
|
|
2183
|
+
}
|
|
2184
|
+
function SidebarIcon({ size = 20, store, locale }) {
|
|
2185
|
+
const state = useUpdateState(store);
|
|
2186
|
+
const label = updateLabel(state, locale);
|
|
2187
|
+
const glyph = import_react11.default.useRef(null);
|
|
2188
|
+
const [row, setRow] = import_react11.default.useState(null);
|
|
2189
|
+
import_react11.default.useLayoutEffect(() => {
|
|
2190
|
+
setRow(glyph.current?.closest("button") ?? null);
|
|
2191
|
+
}, [size]);
|
|
2192
|
+
const wide = size <= 16;
|
|
2193
|
+
const marked = label !== void 0 && state.phase !== "installed";
|
|
2194
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2195
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "studio-ui studio-sidebar-glyph", children: [
|
|
2196
|
+
marked && !wide && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: sidebarMarkStyles }),
|
|
2197
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { ref: glyph, width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.7", "aria-hidden": "true", children: [
|
|
2198
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "3", y: "3", width: "7", height: "7", rx: "2" }),
|
|
2199
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "14", y: "3", width: "7", height: "7", rx: "2" }),
|
|
2200
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "3", y: "14", width: "7", height: "7", rx: "2" }),
|
|
2201
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M17.5 14v7M14 17.5h7" }),
|
|
2202
|
+
marked && !wide && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { className: "studio-sidebar-dot", cx: "21", cy: "3", r: "3", stroke: "none" })
|
|
2203
|
+
] })
|
|
2204
|
+
] }),
|
|
2205
|
+
marked && wide && row && (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "studio-ui studio-sidebar-update", "data-phase": state.phase, title: label, role: "img", "aria-label": label, children: [
|
|
2206
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: sidebarMarkStyles }),
|
|
2207
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(UpdateGlyph, { phase: state.phase, size: 14 })
|
|
2208
|
+
] }), row)
|
|
2209
|
+
] });
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
// src/shell.tsx
|
|
2213
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2055
2214
|
var inject = ["slots", "locale", "remote"];
|
|
2056
2215
|
var panel = "local-dsh-studio";
|
|
2057
2216
|
async function apply(ctx) {
|
|
@@ -2072,7 +2231,18 @@ async function apply(ctx) {
|
|
|
2072
2231
|
invocation: { kind: "direct" },
|
|
2073
2232
|
parameters: [{ name: "request", wire: "request", source: "json", codec: { mode: "strict", typeSymbol: "PreviewRequest", create: () => ({ parse: parsePreviewRequest }) } }],
|
|
2074
2233
|
result: { mode: "src-json" }
|
|
2075
|
-
}, ...["
|
|
2234
|
+
}, ...["updateStatus", "updateStudio"].map((method) => ({
|
|
2235
|
+
id: `${PACKAGE_NAME}#studioCatalog/${method}`,
|
|
2236
|
+
service: "studioCatalog",
|
|
2237
|
+
namespace: "studioCatalog",
|
|
2238
|
+
method,
|
|
2239
|
+
invocation: { kind: "direct" },
|
|
2240
|
+
parameters: [{ name: method === "updateStatus" ? "force" : "version", wire: method === "updateStatus" ? "force" : "version", source: "json", codec: { mode: "strict", typeSymbol: "string", create: () => ({ parse: (value) => {
|
|
2241
|
+
if (typeof value !== "string") throw new TypeError("Expected a string");
|
|
2242
|
+
return value;
|
|
2243
|
+
} }) } }],
|
|
2244
|
+
result: { mode: "src-json" }
|
|
2245
|
+
})), ...["listPresets", "savePreset", "applyPreset", "unapplyPreset", "roleModels", "deletePreset", "readExtensions", "saveExtensions"].map((method) => ({
|
|
2076
2246
|
id: `${PACKAGE_NAME}#studioCatalog/${method}`,
|
|
2077
2247
|
service: "studioCatalog",
|
|
2078
2248
|
namespace: "studioCatalog",
|
|
@@ -2096,35 +2266,35 @@ async function apply(ctx) {
|
|
|
2096
2266
|
};
|
|
2097
2267
|
ctx.effect(() => ctx.slots.subscribe("local.dsh-studio.services", syncServices));
|
|
2098
2268
|
ctx.effect(() => ctx.locale.subscribe(syncServices));
|
|
2269
|
+
const updateActions = /* @__PURE__ */ (() => {
|
|
2270
|
+
const call = async (method, arg) => {
|
|
2271
|
+
const service = ctx.get("remote.studioCatalog");
|
|
2272
|
+
const fn = service?.[method];
|
|
2273
|
+
if (!fn) throw new Error("Studio update API unavailable");
|
|
2274
|
+
const result = await fn(arg);
|
|
2275
|
+
if (!result.ok) throw new Error(result.error?.message ?? "Update request failed");
|
|
2276
|
+
return result.value;
|
|
2277
|
+
};
|
|
2278
|
+
return {
|
|
2279
|
+
status: (force) => call("updateStatus", force ? "force" : ""),
|
|
2280
|
+
update: (version) => call("updateStudio", version)
|
|
2281
|
+
};
|
|
2282
|
+
})();
|
|
2283
|
+
const updates = createUpdateStore(updateActions, STUDIO_VERSION);
|
|
2284
|
+
void updates.refresh();
|
|
2099
2285
|
function StudioServices({ renderSlot }) {
|
|
2100
|
-
const items =
|
|
2286
|
+
const items = import_react12.default.useSyncExternalStore((listener) => {
|
|
2101
2287
|
serviceListeners.add(listener);
|
|
2102
2288
|
return () => {
|
|
2103
2289
|
serviceListeners.delete(listener);
|
|
2104
2290
|
};
|
|
2105
2291
|
}, () => services);
|
|
2106
|
-
const locale =
|
|
2107
|
-
return /* @__PURE__ */ (0,
|
|
2292
|
+
const locale = import_react12.default.useSyncExternalStore((listener) => ctx.locale.subscribe(listener), () => ctx.locale.getLocale().active);
|
|
2293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StudioSurface, { className: "studio-shell", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("main", { className: "studio-page", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ServiceLayout, { locale, services: items, renderSlot }) }) });
|
|
2108
2294
|
}
|
|
2109
2295
|
function Icon({ size = 20 }) {
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
{
|
|
2113
|
-
width: size,
|
|
2114
|
-
height: size,
|
|
2115
|
-
viewBox: "0 0 24 24",
|
|
2116
|
-
fill: "none",
|
|
2117
|
-
stroke: "currentColor",
|
|
2118
|
-
strokeWidth: "1.7",
|
|
2119
|
-
"aria-hidden": "true",
|
|
2120
|
-
children: [
|
|
2121
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "3", y: "3", width: "7", height: "7", rx: "2" }),
|
|
2122
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "14", y: "3", width: "7", height: "7", rx: "2" }),
|
|
2123
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "3", y: "14", width: "7", height: "7", rx: "2" }),
|
|
2124
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M17.5 14v7M14 17.5h7" })
|
|
2125
|
-
]
|
|
2126
|
-
}
|
|
2127
|
-
);
|
|
2296
|
+
const locale = import_react12.default.useSyncExternalStore((listener) => ctx.locale.subscribe(listener), () => ctx.locale.getLocale().active);
|
|
2297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SidebarIcon, { size, store: updates, locale });
|
|
2128
2298
|
}
|
|
2129
2299
|
ctx.slots.inject(
|
|
2130
2300
|
"main",
|
|
@@ -2140,10 +2310,10 @@ async function apply(ctx) {
|
|
|
2140
2310
|
)
|
|
2141
2311
|
);
|
|
2142
2312
|
function OptimizationPage() {
|
|
2143
|
-
const locale =
|
|
2144
|
-
const [catalog, setCatalog] =
|
|
2145
|
-
const [catalogError, setCatalogError] =
|
|
2146
|
-
|
|
2313
|
+
const locale = import_react12.default.useSyncExternalStore((listener) => ctx.locale.subscribe(listener), () => ctx.locale.getLocale().active);
|
|
2314
|
+
const [catalog, setCatalog] = import_react12.default.useState();
|
|
2315
|
+
const [catalogError, setCatalogError] = import_react12.default.useState("");
|
|
2316
|
+
import_react12.default.useEffect(() => {
|
|
2147
2317
|
let active = true;
|
|
2148
2318
|
const remote2 = ctx.get("remote.studioCatalog");
|
|
2149
2319
|
if (!remote2) {
|
|
@@ -2161,7 +2331,7 @@ async function apply(ctx) {
|
|
|
2161
2331
|
active = false;
|
|
2162
2332
|
};
|
|
2163
2333
|
}, []);
|
|
2164
|
-
const presetActions =
|
|
2334
|
+
const presetActions = import_react12.default.useMemo(() => {
|
|
2165
2335
|
const call = async (method, ...args) => {
|
|
2166
2336
|
const service = ctx.get("remote.studioCatalog");
|
|
2167
2337
|
const result = await service[method](...args);
|
|
@@ -2177,7 +2347,7 @@ async function apply(ctx) {
|
|
|
2177
2347
|
delete: (id) => call("deletePreset", id)
|
|
2178
2348
|
};
|
|
2179
2349
|
}, []);
|
|
2180
|
-
const extensionActions =
|
|
2350
|
+
const extensionActions = import_react12.default.useMemo(() => {
|
|
2181
2351
|
const call = async (method, ...args) => {
|
|
2182
2352
|
const service = ctx.get("remote.studioCatalog");
|
|
2183
2353
|
const result = await service[method](...args);
|
|
@@ -2188,7 +2358,10 @@ async function apply(ctx) {
|
|
|
2188
2358
|
setCatalog(await call("saveExtensions", payload));
|
|
2189
2359
|
} };
|
|
2190
2360
|
}, []);
|
|
2191
|
-
|
|
2361
|
+
import_react12.default.useEffect(() => {
|
|
2362
|
+
void updates.refresh();
|
|
2363
|
+
}, []);
|
|
2364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OptimizationPrototype, { navFooter: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(VersionFooter, { store: updates, locale }), extensionActions, presetActions, locale, catalog, catalogError, onPreview: async (request) => {
|
|
2192
2365
|
const service = ctx.get("remote.studioCatalog");
|
|
2193
2366
|
const response = await service.preview(request);
|
|
2194
2367
|
if (!response.ok) throw new Error(response.error?.message ?? "Preview failed");
|
package/index.js
CHANGED
|
@@ -56,6 +56,7 @@ var BATCH_PLUGIN = `${PACKAGE_NAME}/batch`;
|
|
|
56
56
|
function currentPluginName(name) {
|
|
57
57
|
return name === LEGACY_PACKAGE_NAME || name.startsWith(`${LEGACY_PACKAGE_NAME}/`) ? PACKAGE_NAME + name.slice(LEGACY_PACKAGE_NAME.length) : name;
|
|
58
58
|
}
|
|
59
|
+
var STUDIO_VERSION = "0.2.8";
|
|
59
60
|
|
|
60
61
|
// src/delegation.ts
|
|
61
62
|
var ROLE_TOOL = "subagent_role";
|
|
@@ -383,7 +384,7 @@ var MasterExtensions = class {
|
|
|
383
384
|
};
|
|
384
385
|
|
|
385
386
|
// src/host/shell.ts
|
|
386
|
-
import { dirname as dirname3, join as
|
|
387
|
+
import { dirname as dirname3, join as join3 } from "node:path";
|
|
387
388
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
388
389
|
import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
389
390
|
|
|
@@ -1170,9 +1171,142 @@ var PresetStore = class {
|
|
|
1170
1171
|
}
|
|
1171
1172
|
};
|
|
1172
1173
|
|
|
1174
|
+
// src/host/studio-update.ts
|
|
1175
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
1176
|
+
import { join as join2 } from "node:path";
|
|
1177
|
+
import { evaluatePluginCompatibility, getDshRuntimeVersion } from "@deepseek-ai/dsh-app-boot";
|
|
1178
|
+
|
|
1179
|
+
// src/update-check.ts
|
|
1180
|
+
var STABLE = /^(\d+)\.(\d+)\.(\d+)$/;
|
|
1181
|
+
function compareStable(a, b) {
|
|
1182
|
+
const x = STABLE.exec(a);
|
|
1183
|
+
const y = STABLE.exec(b);
|
|
1184
|
+
if (!x || !y) return Number(Boolean(x)) - Number(Boolean(y));
|
|
1185
|
+
for (let i = 1; i <= 3; i++) {
|
|
1186
|
+
const diff = Number(x[i]) - Number(y[i]);
|
|
1187
|
+
if (diff) return Math.sign(diff);
|
|
1188
|
+
}
|
|
1189
|
+
return 0;
|
|
1190
|
+
}
|
|
1191
|
+
function isNewer(candidate, current) {
|
|
1192
|
+
return STABLE.test(candidate) && compareStable(candidate, current.split("-")[0]) > 0;
|
|
1193
|
+
}
|
|
1194
|
+
function pickUpdate(document, current, compatible) {
|
|
1195
|
+
const latest = document["dist-tags"]?.latest;
|
|
1196
|
+
const candidates = Object.entries(document.versions ?? {}).filter(([version, manifest]) => isNewer(version, current) && !manifest.deprecated).sort(([a], [b]) => compareStable(b, a));
|
|
1197
|
+
const available = candidates.find(([, manifest]) => compatible(manifest))?.[0];
|
|
1198
|
+
const incompatibleLatest = latest !== void 0 && isNewer(latest, current) && latest !== available && candidates.some(([version]) => version === latest) ? latest : void 0;
|
|
1199
|
+
return { ...latest ? { latest } : {}, ...available ? { available } : {}, ...incompatibleLatest ? { incompatibleLatest } : {} };
|
|
1200
|
+
}
|
|
1201
|
+
function packumentUrl(registry, name) {
|
|
1202
|
+
return `${registry.replace(/\/+$/, "")}/${name.replace("/", "%2f")}`;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
// src/host/studio-update.ts
|
|
1206
|
+
var DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
1207
|
+
var CACHE_MS = 10 * 6e4;
|
|
1208
|
+
var StudioUpdater = class {
|
|
1209
|
+
constructor(ctx, fetcher = globalThis.fetch) {
|
|
1210
|
+
this.ctx = ctx;
|
|
1211
|
+
this.fetcher = fetcher;
|
|
1212
|
+
}
|
|
1213
|
+
cached;
|
|
1214
|
+
installing;
|
|
1215
|
+
manager() {
|
|
1216
|
+
return this.ctx.get("pluginManager");
|
|
1217
|
+
}
|
|
1218
|
+
/** Read the current status, reusing a recent registry answer unless `force`. */
|
|
1219
|
+
status(force = false) {
|
|
1220
|
+
if (!force && this.cached && Date.now() - this.cached.at < CACHE_MS) return this.cached.status;
|
|
1221
|
+
const status = this.check();
|
|
1222
|
+
this.cached = { at: Date.now(), status };
|
|
1223
|
+
void status.catch(() => {
|
|
1224
|
+
if (this.cached?.status === status) this.cached = void 0;
|
|
1225
|
+
});
|
|
1226
|
+
return status;
|
|
1227
|
+
}
|
|
1228
|
+
async check() {
|
|
1229
|
+
const result = { current: STUDIO_VERSION };
|
|
1230
|
+
let runtimeVersion;
|
|
1231
|
+
try {
|
|
1232
|
+
runtimeVersion = getDshRuntimeVersion();
|
|
1233
|
+
result.runtimeVersion = runtimeVersion;
|
|
1234
|
+
} catch {
|
|
1235
|
+
}
|
|
1236
|
+
const { source, installed } = await this.profilePackage();
|
|
1237
|
+
if (source) result.source = source;
|
|
1238
|
+
if (installed && installed !== STUDIO_VERSION) result.installed = installed;
|
|
1239
|
+
const baseline = installed && isNewer(installed, STUDIO_VERSION) ? installed : STUDIO_VERSION;
|
|
1240
|
+
const manager = this.manager();
|
|
1241
|
+
if (!manager) result.blocked = "no-plugin-manager";
|
|
1242
|
+
else if (!source) result.blocked = "not-profile-dependency";
|
|
1243
|
+
try {
|
|
1244
|
+
const registries = manager ? await manager.registries().catch(() => void 0) : void 0;
|
|
1245
|
+
const registry = registries?.registry ?? registries?.resolved ?? DEFAULT_REGISTRY;
|
|
1246
|
+
const response = await this.fetcher(packumentUrl(registry, PACKAGE_NAME), {
|
|
1247
|
+
headers: { accept: "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8" },
|
|
1248
|
+
signal: AbortSignal.timeout(15e3)
|
|
1249
|
+
});
|
|
1250
|
+
if (!response.ok) throw new Error(`Registry answered ${response.status}`);
|
|
1251
|
+
const document = await response.json();
|
|
1252
|
+
Object.assign(result, pickUpdate(document, baseline, (manifest) => {
|
|
1253
|
+
try {
|
|
1254
|
+
return evaluatePluginCompatibility({ name: PACKAGE_NAME, version: "0.0.0", ...manifest }, {}, runtimeVersion) === void 0;
|
|
1255
|
+
} catch {
|
|
1256
|
+
return false;
|
|
1257
|
+
}
|
|
1258
|
+
}));
|
|
1259
|
+
} catch (error) {
|
|
1260
|
+
result.error = error instanceof Error ? error.message : String(error);
|
|
1261
|
+
}
|
|
1262
|
+
return result;
|
|
1263
|
+
}
|
|
1264
|
+
/** How the profile declares Studio and which version its files hold now. */
|
|
1265
|
+
async profilePackage() {
|
|
1266
|
+
const dir = this.ctx.get("profileContext")?.dir ?? process.env.DSH_PROFILE_DIR;
|
|
1267
|
+
if (!dir) return {};
|
|
1268
|
+
const json2 = async (path) => {
|
|
1269
|
+
try {
|
|
1270
|
+
return JSON.parse(await readFile3(path, "utf8"));
|
|
1271
|
+
} catch {
|
|
1272
|
+
return void 0;
|
|
1273
|
+
}
|
|
1274
|
+
};
|
|
1275
|
+
const manifest = await json2(join2(dir, "package.json"));
|
|
1276
|
+
const source = manifest?.dependencies?.[PACKAGE_NAME];
|
|
1277
|
+
const installed = (await json2(join2(dir, "node_modules", ...PACKAGE_NAME.split("/"), "package.json")))?.version;
|
|
1278
|
+
return { ...source ? { source } : {}, ...typeof installed === "string" ? { installed } : {} };
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* Install one exact version offered by {@link status}. The running Studio keeps its code until DSH restarts.
|
|
1282
|
+
* @param version Exact version; must equal the current offer so arbitrary specs never reach pnpm.
|
|
1283
|
+
*/
|
|
1284
|
+
update(version) {
|
|
1285
|
+
if (this.installing) return this.installing;
|
|
1286
|
+
const run = (async () => {
|
|
1287
|
+
const status = await this.status();
|
|
1288
|
+
if (status.available !== version) throw new Error(`Version ${version} is not the offered update`);
|
|
1289
|
+
if (status.blocked) throw new Error(`Studio cannot update this install (${status.blocked})`);
|
|
1290
|
+
const manager = this.manager();
|
|
1291
|
+
const result = await manager.installBundle(`${PACKAGE_NAME}@${version}`, { enabled: true });
|
|
1292
|
+
const installed = result.version ?? version;
|
|
1293
|
+
if (result.application === "failed" || result.application === "cancelled") {
|
|
1294
|
+
const detail = result.error?.diagnostic ?? result.error?.code ?? result.packageResult?.output?.trim().split("\n").slice(-3).join("\n");
|
|
1295
|
+
return { status: result.application, version: installed, ...detail ? { message: detail } : {} };
|
|
1296
|
+
}
|
|
1297
|
+
this.cached = void 0;
|
|
1298
|
+
return { status: result.application === "applied" ? "applied" : "restart-required", version: installed };
|
|
1299
|
+
})();
|
|
1300
|
+
this.installing = run;
|
|
1301
|
+
return run.finally(() => {
|
|
1302
|
+
this.installing = void 0;
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
};
|
|
1306
|
+
|
|
1173
1307
|
// src/host/shell.ts
|
|
1174
|
-
var _preview_dec, _saveExtensions_dec, _readExtensions_dec, _read_dec, _deletePreset_dec, _roleModels_dec, _unapplyPreset_dec, _applyPreset_dec, _savePreset_dec, _listPresets_dec, _a, _init;
|
|
1175
|
-
var StudioCatalog = class extends (_a = TypertRemoteService, _listPresets_dec = [Remote], _savePreset_dec = [Remote], _applyPreset_dec = [Remote], _unapplyPreset_dec = [Remote], _roleModels_dec = [Remote], _deletePreset_dec = [Remote], _read_dec = [Remote], _readExtensions_dec = [Remote], _saveExtensions_dec = [Remote], _preview_dec = [Remote], _a) {
|
|
1308
|
+
var _preview_dec, _saveExtensions_dec, _readExtensions_dec, _read_dec, _deletePreset_dec, _updateStudio_dec, _updateStatus_dec, _roleModels_dec, _unapplyPreset_dec, _applyPreset_dec, _savePreset_dec, _listPresets_dec, _a, _init;
|
|
1309
|
+
var StudioCatalog = class extends (_a = TypertRemoteService, _listPresets_dec = [Remote], _savePreset_dec = [Remote], _applyPreset_dec = [Remote], _unapplyPreset_dec = [Remote], _roleModels_dec = [Remote], _updateStatus_dec = [Remote], _updateStudio_dec = [Remote], _deletePreset_dec = [Remote], _read_dec = [Remote], _readExtensions_dec = [Remote], _saveExtensions_dec = [Remote], _preview_dec = [Remote], _a) {
|
|
1176
1310
|
constructor(ctx) {
|
|
1177
1311
|
super(ctx, "studioCatalog");
|
|
1178
1312
|
__runInitializers(_init, 5, this);
|
|
@@ -1182,8 +1316,9 @@ var StudioCatalog = class extends (_a = TypertRemoteService, _listPresets_dec =
|
|
|
1182
1316
|
__publicField(this, "stopped", false);
|
|
1183
1317
|
__publicField(this, "extensions");
|
|
1184
1318
|
__publicField(this, "changes", Promise.resolve());
|
|
1319
|
+
__publicField(this, "updater", new StudioUpdater(this.ctx));
|
|
1185
1320
|
const storePath = studioStorePath(process.env, ctx.get("profileContext"));
|
|
1186
|
-
this.extensions = new MasterExtensions(
|
|
1321
|
+
this.extensions = new MasterExtensions(join3(dirname3(storePath), "master-extensions.json"));
|
|
1187
1322
|
this.store = new PresetStore(ctx, storePath);
|
|
1188
1323
|
this.snapshot = new Promise((resolve2) => {
|
|
1189
1324
|
setImmediate(resolve2);
|
|
@@ -1219,6 +1354,12 @@ var StudioCatalog = class extends (_a = TypertRemoteService, _listPresets_dec =
|
|
|
1219
1354
|
if (!service) throw new Error("Model catalog API unavailable");
|
|
1220
1355
|
return service.modelCatalog();
|
|
1221
1356
|
}
|
|
1357
|
+
async updateStatus(force) {
|
|
1358
|
+
return this.updater.status(force === "force");
|
|
1359
|
+
}
|
|
1360
|
+
async updateStudio(version) {
|
|
1361
|
+
return this.updater.update(version);
|
|
1362
|
+
}
|
|
1222
1363
|
async deletePreset(id) {
|
|
1223
1364
|
return this.store.delete(id);
|
|
1224
1365
|
}
|
|
@@ -1319,6 +1460,8 @@ __decorateElement(_init, 1, "savePreset", _savePreset_dec, StudioCatalog);
|
|
|
1319
1460
|
__decorateElement(_init, 1, "applyPreset", _applyPreset_dec, StudioCatalog);
|
|
1320
1461
|
__decorateElement(_init, 1, "unapplyPreset", _unapplyPreset_dec, StudioCatalog);
|
|
1321
1462
|
__decorateElement(_init, 1, "roleModels", _roleModels_dec, StudioCatalog);
|
|
1463
|
+
__decorateElement(_init, 1, "updateStatus", _updateStatus_dec, StudioCatalog);
|
|
1464
|
+
__decorateElement(_init, 1, "updateStudio", _updateStudio_dec, StudioCatalog);
|
|
1322
1465
|
__decorateElement(_init, 1, "deletePreset", _deletePreset_dec, StudioCatalog);
|
|
1323
1466
|
__decorateElement(_init, 1, "read", _read_dec, StudioCatalog);
|
|
1324
1467
|
__decorateElement(_init, 1, "readExtensions", _readExtensions_dec, StudioCatalog);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matamt-dbg/dsh-studio",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "DSH Studio: build, edit and apply DeepSeek Harness agent presets — tools, prompts, Configs and role-based subagents — from the web GUI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|