@liyuera/dsh-dev-dock 0.0.0-stage → 1.0.3
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/LICENSE +24 -0
- package/README.md +42 -2
- package/cordis.patch.yml +4 -0
- package/lib/client.js +1131 -0
- package/lib/index.js +5770 -0
- package/lib/invariant.js +24 -0
- package/lib/types/actions.d.ts +124 -0
- package/lib/types/client/ComposerActions.d.ts +25 -0
- package/lib/types/client/DevDockDrawer.d.ts +29 -0
- package/lib/types/client/DevDockEntry.d.ts +28 -0
- package/lib/types/client/DevDockSettingsPage.d.ts +24 -0
- package/lib/types/client/StartTile.d.ts +25 -0
- package/lib/types/client/StartWorkButton.d.ts +28 -0
- package/lib/types/client/StartWorkModal.d.ts +25 -0
- package/lib/types/client/api.d.ts +56 -0
- package/lib/types/client/data.d.ts +75 -0
- package/lib/types/client/icons.d.ts +40 -0
- package/lib/types/client/index.d.ts +27 -0
- package/lib/types/client/locales.d.ts +65 -0
- package/lib/types/client/pages/ImportPage.d.ts +26 -0
- package/lib/types/client/pages/ProjectListPage.d.ts +34 -0
- package/lib/types/client/pages/QuickStartPage.d.ts +26 -0
- package/lib/types/client/probe.d.ts +3 -0
- package/lib/types/client/stores.d.ts +22 -0
- package/lib/types/domain.d.ts +17 -0
- package/lib/types/editors.d.ts +27 -0
- package/lib/types/index.d.ts +31 -0
- package/lib/types/invariant.d.ts +16 -0
- package/lib/types/platform/editors-darwin.d.ts +25 -0
- package/lib/types/platform/editors-win32.d.ts +25 -0
- package/lib/types/platform/open-ide.d.ts +23 -0
- package/lib/types/platform/open-terminal.d.ts +25 -0
- package/lib/types/platform/runner.d.ts +22 -0
- package/lib/types/schema.d.ts +52 -0
- package/lib/types/tools/actions.d.ts +35 -0
- package/lib/types/tools/editors.d.ts +27 -0
- package/lib/types/tools/project.d.ts +50 -0
- package/lib/types/tools/scan.d.ts +44 -0
- package/package.json +85 -4
package/lib/client.js
ADDED
|
@@ -0,0 +1,1131 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@liyuera/dsh-dev-dock",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
8
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
+
let react = require("react");
|
|
10
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
11
|
+
//#region lib/types/client/data.js
|
|
12
|
+
/**
|
|
13
|
+
* devDock browser data layer v2: mirrors the plugin's document from the host
|
|
14
|
+
* through the same-origin `/dev-dock/state` route and exposes the
|
|
15
|
+
* desktop-action bridge. Both are plain HTTP because static client bundles
|
|
16
|
+
* have no package-private RPC channel (host.call is a dynamic-plugin
|
|
17
|
+
* builtin); the host half owns the storage domain behind that route and runs
|
|
18
|
+
* the deterministic desktop actions.
|
|
19
|
+
* @module @liyuera/dsh-dev-dock/client/data
|
|
20
|
+
*/
|
|
21
|
+
/** Canonical editor names across platforms (union for stable UI display). */
|
|
22
|
+
const EDITOR_NAMES = [
|
|
23
|
+
"WebStorm",
|
|
24
|
+
"VS Code",
|
|
25
|
+
"IntelliJ IDEA",
|
|
26
|
+
"Cursor",
|
|
27
|
+
"Sublime Text",
|
|
28
|
+
"HBuilderX"
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Create the devDock data layer for one client plugin fiber.
|
|
32
|
+
* @param ctx - client root context, used to own the mirror's effects.
|
|
33
|
+
* @returns the document mirror and the action facade.
|
|
34
|
+
*/
|
|
35
|
+
function createDevDockData(ctx) {
|
|
36
|
+
const store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
|
|
37
|
+
ready: false,
|
|
38
|
+
settings: void 0
|
|
39
|
+
});
|
|
40
|
+
const adopt = (raw) => {
|
|
41
|
+
const settings = decodeSettings(raw);
|
|
42
|
+
if (settings === void 0) return;
|
|
43
|
+
store.set({
|
|
44
|
+
ready: true,
|
|
45
|
+
settings
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
const refresh = async () => {
|
|
49
|
+
try {
|
|
50
|
+
const answer = await (await fetch("/dev-dock/state", { method: "GET" })).json();
|
|
51
|
+
if (answer.ok === true) adopt(answer.settings);
|
|
52
|
+
} catch {}
|
|
53
|
+
};
|
|
54
|
+
refresh();
|
|
55
|
+
ctx.effect(() => {
|
|
56
|
+
const onFocus = () => {
|
|
57
|
+
refresh();
|
|
58
|
+
};
|
|
59
|
+
window.addEventListener("focus", onFocus);
|
|
60
|
+
return () => {
|
|
61
|
+
window.removeEventListener("focus", onFocus);
|
|
62
|
+
};
|
|
63
|
+
}, "dev-dock: focus refresh");
|
|
64
|
+
const write = async (field, value) => {
|
|
65
|
+
const snapshot = store.getSnapshot().settings;
|
|
66
|
+
if (snapshot !== void 0) store.set({
|
|
67
|
+
ready: true,
|
|
68
|
+
settings: {
|
|
69
|
+
...snapshot,
|
|
70
|
+
[field]: value
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
try {
|
|
74
|
+
const answer = await (await fetch("/dev-dock/state", {
|
|
75
|
+
method: "POST",
|
|
76
|
+
headers: { "content-type": "application/json" },
|
|
77
|
+
body: JSON.stringify({
|
|
78
|
+
field,
|
|
79
|
+
value
|
|
80
|
+
})
|
|
81
|
+
})).json();
|
|
82
|
+
if (answer.ok === true) adopt(answer.settings);
|
|
83
|
+
} catch {}
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
store,
|
|
87
|
+
actions: {
|
|
88
|
+
async setWorkspacePref(workspaceId, editor) {
|
|
89
|
+
const current = store.getSnapshot().settings;
|
|
90
|
+
if (current === void 0) return;
|
|
91
|
+
const rest = current.workspacePrefs.filter((p) => p.workspaceId !== workspaceId);
|
|
92
|
+
await write("workspacePrefs", editor === "" ? rest : [...rest, {
|
|
93
|
+
workspaceId,
|
|
94
|
+
editor
|
|
95
|
+
}]);
|
|
96
|
+
},
|
|
97
|
+
async setEditorManualPath(name, manualPath) {
|
|
98
|
+
const current = store.getSnapshot().settings;
|
|
99
|
+
if (current === void 0) return;
|
|
100
|
+
await write("editors", current.editors.find((e) => e.name === name) === void 0 ? [...current.editors, {
|
|
101
|
+
name,
|
|
102
|
+
manualPath
|
|
103
|
+
}] : current.editors.map((e) => e.name === name ? {
|
|
104
|
+
...e,
|
|
105
|
+
manualPath
|
|
106
|
+
} : e));
|
|
107
|
+
},
|
|
108
|
+
async setTerminalApp(app) {
|
|
109
|
+
await write("terminalApp", app);
|
|
110
|
+
},
|
|
111
|
+
async setStartWork(workspaceIds) {
|
|
112
|
+
await write("startWork", workspaceIds);
|
|
113
|
+
},
|
|
114
|
+
listEditors: () => rpcAction("list-editors"),
|
|
115
|
+
openIde: (workspaceId) => rpcAction("open-ide", { workspaceId }),
|
|
116
|
+
openTerminal: (workspaceId) => rpcAction("open-terminal", { workspaceId }),
|
|
117
|
+
start: (workspaceId) => rpcAction("start", { workspaceId }),
|
|
118
|
+
startWork: (workspaceIds) => rpcAction("start-work", { workspaceIds })
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/** Decode the wire section into the settings document (lenient cast). */
|
|
123
|
+
function decodeSettings(section) {
|
|
124
|
+
if (section === null || typeof section !== "object") return void 0;
|
|
125
|
+
const doc = section;
|
|
126
|
+
if (!Array.isArray(doc.workspacePrefs) || !Array.isArray(doc.editors) || !Array.isArray(doc.startWork)) return;
|
|
127
|
+
return {
|
|
128
|
+
workspacePrefs: doc.workspacePrefs,
|
|
129
|
+
editors: doc.editors,
|
|
130
|
+
terminalApp: doc.terminalApp === "iterm" ? "iterm" : "default",
|
|
131
|
+
startWork: doc.startWork
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* POST one action to the plugin's host route.
|
|
136
|
+
* @param action - action name.
|
|
137
|
+
* @param extra - additional JSON fields.
|
|
138
|
+
* @returns the host answer, or a fetch-failure answer when the wire failed.
|
|
139
|
+
*/
|
|
140
|
+
async function rpcAction(action, extra = {}) {
|
|
141
|
+
try {
|
|
142
|
+
return await (await fetch("/dev-dock/action", {
|
|
143
|
+
method: "POST",
|
|
144
|
+
headers: { "content-type": "application/json" },
|
|
145
|
+
body: JSON.stringify({
|
|
146
|
+
action,
|
|
147
|
+
...extra
|
|
148
|
+
})
|
|
149
|
+
})).json();
|
|
150
|
+
} catch (error) {
|
|
151
|
+
return {
|
|
152
|
+
ok: false,
|
|
153
|
+
error: `devDock action route unreachable: ${error instanceof Error ? error.message : String(error)}`
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region lib/types/client/stores.js
|
|
159
|
+
/**
|
|
160
|
+
* devDock panel viewing store: the start-work dialog open state. Shared by
|
|
161
|
+
* the sidebar footer button and entry row so the dialog opens from either
|
|
162
|
+
* and survives entry/overlay remounts.
|
|
163
|
+
* @module @liyuera/dsh-dev-dock/client/stores
|
|
164
|
+
*/
|
|
165
|
+
/**
|
|
166
|
+
* Create the devDock viewing store.
|
|
167
|
+
* @returns the store handle (spec + type + identity + factory in one).
|
|
168
|
+
*/
|
|
169
|
+
function createDevDockStore() {
|
|
170
|
+
return (0, _deepseek_ai_dsh_client_store.defineStore)({
|
|
171
|
+
init: () => ({ open: false }),
|
|
172
|
+
actions: { setOpen: (draft, open) => {
|
|
173
|
+
draft.open = open;
|
|
174
|
+
} }
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region lib/types/client/icons.js
|
|
179
|
+
/** Terminal glyph: `>_` command prompt. */
|
|
180
|
+
const TERMINAL_STROKE = {
|
|
181
|
+
stroke: "currentColor",
|
|
182
|
+
strokeWidth: 1.4,
|
|
183
|
+
strokeLinecap: "round",
|
|
184
|
+
strokeLinejoin: "round"
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* IDE glyph: `</>` code brackets.
|
|
188
|
+
* @param props - icon size and optional class.
|
|
189
|
+
* @returns the 16px editor svg.
|
|
190
|
+
*/
|
|
191
|
+
function DevIdeIcon({ size = 16, className }) {
|
|
192
|
+
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
193
|
+
width: size,
|
|
194
|
+
height: size,
|
|
195
|
+
viewBox: "0 0 16 16",
|
|
196
|
+
fill: "none",
|
|
197
|
+
stroke: "currentColor",
|
|
198
|
+
strokeWidth: "1.4",
|
|
199
|
+
strokeLinecap: "round",
|
|
200
|
+
strokeLinejoin: "round",
|
|
201
|
+
className,
|
|
202
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
203
|
+
children: [
|
|
204
|
+
(0, react_jsx_runtime.jsx)("path", { d: "M5.0 4.8 2.6 8 5.0 11.2" }),
|
|
205
|
+
(0, react_jsx_runtime.jsx)("path", { d: "M11.0 4.8 13.4 8 11.0 11.2" }),
|
|
206
|
+
(0, react_jsx_runtime.jsx)("path", { d: "M8.7 4.6 7.3 11.4" })
|
|
207
|
+
]
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Terminal glyph: `>_` prompt.
|
|
212
|
+
* @param props - icon size and optional class.
|
|
213
|
+
* @returns the 16px terminal svg.
|
|
214
|
+
*/
|
|
215
|
+
function DevTerminalIcon({ size = 16, className }) {
|
|
216
|
+
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
217
|
+
...TERMINAL_STROKE,
|
|
218
|
+
width: size,
|
|
219
|
+
height: size,
|
|
220
|
+
viewBox: "0 0 16 16",
|
|
221
|
+
fill: "none",
|
|
222
|
+
className,
|
|
223
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
224
|
+
children: [(0, react_jsx_runtime.jsx)("path", { d: "M4.4 4.8 7.6 8 4.4 11.2" }), (0, react_jsx_runtime.jsx)("path", { d: "M8.6 11.2H11.8" })]
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* App-icon-style terminal fallback: a dark rounded square with a light `>_`
|
|
229
|
+
* prompt, used where the real app icon is unavailable (Assets.car-only
|
|
230
|
+
* bundles, other platforms).
|
|
231
|
+
* @param props - icon size and optional class.
|
|
232
|
+
* @returns the 16px filled terminal svg.
|
|
233
|
+
*/
|
|
234
|
+
function DevTerminalAppIcon({ size = 16, className }) {
|
|
235
|
+
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
236
|
+
width: size,
|
|
237
|
+
height: size,
|
|
238
|
+
viewBox: "0 0 16 16",
|
|
239
|
+
fill: "none",
|
|
240
|
+
className,
|
|
241
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
242
|
+
children: [
|
|
243
|
+
(0, react_jsx_runtime.jsx)("rect", {
|
|
244
|
+
x: "1.6",
|
|
245
|
+
y: "1.6",
|
|
246
|
+
width: "12.8",
|
|
247
|
+
height: "12.8",
|
|
248
|
+
rx: "3.4",
|
|
249
|
+
fill: "#23272E"
|
|
250
|
+
}),
|
|
251
|
+
(0, react_jsx_runtime.jsx)("path", {
|
|
252
|
+
d: "M4.7 5.2 7.4 8 4.7 10.8",
|
|
253
|
+
stroke: "#E8EAED",
|
|
254
|
+
strokeWidth: "1.4",
|
|
255
|
+
strokeLinecap: "round",
|
|
256
|
+
strokeLinejoin: "round"
|
|
257
|
+
}),
|
|
258
|
+
(0, react_jsx_runtime.jsx)("path", {
|
|
259
|
+
d: "M8.1 10.9H11.5",
|
|
260
|
+
stroke: "#E8EAED",
|
|
261
|
+
strokeWidth: "1.4",
|
|
262
|
+
strokeLinecap: "round"
|
|
263
|
+
})
|
|
264
|
+
]
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* App-icon-style editor fallback: a blue rounded square with a white `</>`
|
|
269
|
+
* mark, used where the real app icon is unavailable.
|
|
270
|
+
* @param props - icon size and optional class.
|
|
271
|
+
* @returns the 16px filled editor svg.
|
|
272
|
+
*/
|
|
273
|
+
function DevIdeAppIcon({ size = 16, className }) {
|
|
274
|
+
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
275
|
+
width: size,
|
|
276
|
+
height: size,
|
|
277
|
+
viewBox: "0 0 16 16",
|
|
278
|
+
fill: "none",
|
|
279
|
+
className,
|
|
280
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
281
|
+
children: [
|
|
282
|
+
(0, react_jsx_runtime.jsx)("rect", {
|
|
283
|
+
x: "1.6",
|
|
284
|
+
y: "1.6",
|
|
285
|
+
width: "12.8",
|
|
286
|
+
height: "12.8",
|
|
287
|
+
rx: "3.4",
|
|
288
|
+
fill: "#3D8BFF"
|
|
289
|
+
}),
|
|
290
|
+
(0, react_jsx_runtime.jsx)("path", {
|
|
291
|
+
d: "M5.6 5.4 3.3 8 5.6 10.6",
|
|
292
|
+
stroke: "#FFFFFF",
|
|
293
|
+
strokeWidth: "1.4",
|
|
294
|
+
strokeLinecap: "round",
|
|
295
|
+
strokeLinejoin: "round"
|
|
296
|
+
}),
|
|
297
|
+
(0, react_jsx_runtime.jsx)("path", {
|
|
298
|
+
d: "M10.4 5.4 12.7 8 10.4 10.6",
|
|
299
|
+
stroke: "#FFFFFF",
|
|
300
|
+
strokeWidth: "1.4",
|
|
301
|
+
strokeLinecap: "round",
|
|
302
|
+
strokeLinejoin: "round"
|
|
303
|
+
}),
|
|
304
|
+
(0, react_jsx_runtime.jsx)("path", {
|
|
305
|
+
d: "M9.1 5.1 7.5 10.9",
|
|
306
|
+
stroke: "#FFFFFF",
|
|
307
|
+
strokeWidth: "1.4",
|
|
308
|
+
strokeLinecap: "round"
|
|
309
|
+
})
|
|
310
|
+
]
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region \0dsh-css:/Users/liyu/Documents/www/DeepSeek/deepseek-harness/deepseek-harness-plugin/dev-dock/src/client/StartTile.module.css.mjs
|
|
315
|
+
const css$4 = ".Im9i9a_tile{border-radius:4px;width:16px;height:16px;display:block;position:relative;overflow:hidden}.Im9i9a_halfTerminal{clip-path:polygon(0 0,100% 0,0 100%);justify-content:flex-start;align-items:flex-start;display:flex;position:absolute;inset:0}.Im9i9a_halfIde{clip-path:polygon(100% 0,100% 100%,0 100%);justify-content:flex-end;align-items:flex-end;display:flex;position:absolute;inset:0}.Im9i9a_img{object-fit:cover;width:100%;height:100%;display:block}.Im9i9a_tile:after{content:\"\";pointer-events:none;background:linear-gradient(to bottom right, transparent 40%, color-mix(in srgb, var(--dsw-alias-bg-layer-1) 55%, transparent) 50%, transparent 60%);position:absolute;inset:0}";
|
|
316
|
+
const tagId$4 = "@liyuera/dsh-dev-dock/StartTile.module.css";
|
|
317
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
318
|
+
const tag = document.createElement("style");
|
|
319
|
+
tag.dataset.plugin = "@liyuera/dsh-dev-dock";
|
|
320
|
+
tag.dataset.pluginCss = tagId$4;
|
|
321
|
+
tag.textContent = css$4;
|
|
322
|
+
document.head.appendChild(tag);
|
|
323
|
+
}
|
|
324
|
+
var StartTile_module_css_default = {
|
|
325
|
+
"halfIde": "Im9i9a_halfIde",
|
|
326
|
+
"halfTerminal": "Im9i9a_halfTerminal",
|
|
327
|
+
"img": "Im9i9a_img",
|
|
328
|
+
"tile": "Im9i9a_tile"
|
|
329
|
+
};
|
|
330
|
+
//#endregion
|
|
331
|
+
//#region lib/types/client/StartTile.js
|
|
332
|
+
/**
|
|
333
|
+
* Start-work tile: a 16px rounded square split from top-right to
|
|
334
|
+
* bottom-left — the terminal icon in the upper-left half, the editor icon in
|
|
335
|
+
* the lower-right half, no border or padding, with a soft diagonal seam
|
|
336
|
+
* blending the two halves. Used by the session-header start button and the
|
|
337
|
+
* sidebar start-work button, with app icons when resolvable and
|
|
338
|
+
* app-icon-style fallbacks otherwise.
|
|
339
|
+
* @module @liyuera/dsh-dev-dock/client/StartTile
|
|
340
|
+
*/
|
|
341
|
+
/**
|
|
342
|
+
* Render the combined start-work tile.
|
|
343
|
+
* @param props - optional app-icon URLs per half and the tile edge.
|
|
344
|
+
* @returns the split tile.
|
|
345
|
+
*/
|
|
346
|
+
function StartTile({ ideSrc, termSrc, size = 16 }) {
|
|
347
|
+
const [failed, setFailed] = (0, react.useState)({
|
|
348
|
+
ide: false,
|
|
349
|
+
term: false
|
|
350
|
+
});
|
|
351
|
+
(0, react.useEffect)(() => {
|
|
352
|
+
setFailed({
|
|
353
|
+
ide: false,
|
|
354
|
+
term: false
|
|
355
|
+
});
|
|
356
|
+
}, [ideSrc, termSrc]);
|
|
357
|
+
return (0, react_jsx_runtime.jsxs)("span", {
|
|
358
|
+
className: StartTile_module_css_default.tile,
|
|
359
|
+
style: {
|
|
360
|
+
width: size,
|
|
361
|
+
height: size
|
|
362
|
+
},
|
|
363
|
+
"aria-hidden": "true",
|
|
364
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
365
|
+
className: StartTile_module_css_default.halfTerminal,
|
|
366
|
+
children: failed.term || termSrc === void 0 ? (0, react_jsx_runtime.jsx)(DevTerminalAppIcon, {
|
|
367
|
+
size,
|
|
368
|
+
className: StartTile_module_css_default.img
|
|
369
|
+
}) : (0, react_jsx_runtime.jsx)("img", {
|
|
370
|
+
className: StartTile_module_css_default.img,
|
|
371
|
+
src: termSrc,
|
|
372
|
+
alt: "",
|
|
373
|
+
onError: () => {
|
|
374
|
+
setFailed((current) => ({
|
|
375
|
+
...current,
|
|
376
|
+
term: true
|
|
377
|
+
}));
|
|
378
|
+
}
|
|
379
|
+
})
|
|
380
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
381
|
+
className: StartTile_module_css_default.halfIde,
|
|
382
|
+
children: failed.ide || ideSrc === void 0 ? (0, react_jsx_runtime.jsx)(DevIdeAppIcon, {
|
|
383
|
+
size,
|
|
384
|
+
className: StartTile_module_css_default.img
|
|
385
|
+
}) : (0, react_jsx_runtime.jsx)("img", {
|
|
386
|
+
className: StartTile_module_css_default.img,
|
|
387
|
+
src: ideSrc,
|
|
388
|
+
alt: "",
|
|
389
|
+
onError: () => {
|
|
390
|
+
setFailed((current) => ({
|
|
391
|
+
...current,
|
|
392
|
+
ide: true
|
|
393
|
+
}));
|
|
394
|
+
}
|
|
395
|
+
})
|
|
396
|
+
})]
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
//#endregion
|
|
400
|
+
//#region \0dsh-css:/Users/liyu/Documents/www/DeepSeek/deepseek-harness/deepseek-harness-plugin/dev-dock/src/client/StartWorkButton.module.css.mjs
|
|
401
|
+
const css$3 = "._6acG6G_row{box-sizing:border-box;width:calc(100% + 4px);height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;transition:background var(--ds-transition-duration-fast) var(--ds-ease-in-out);background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;margin:4px -2px;padding:0 10px 0 8px;display:flex;overflow:hidden}._6acG6G_row:hover{background:var(--dsw-alias-interactive-bg-hover)}._6acG6G_row:active{background:var(--dsw-alias-interactive-bg-active)}._6acG6G_label{white-space:nowrap;font-size:14px;line-height:22px;overflow:hidden}._6acG6G_railButton{width:36px;height:36px;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:background var(--ds-transition-duration-fast) var(--ds-ease-in-out);background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;margin:8px 0 10px;padding:0;display:flex}._6acG6G_railButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}";
|
|
402
|
+
const tagId$3 = "@liyuera/dsh-dev-dock/StartWorkButton.module.css";
|
|
403
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
404
|
+
const tag = document.createElement("style");
|
|
405
|
+
tag.dataset.plugin = "@liyuera/dsh-dev-dock";
|
|
406
|
+
tag.dataset.pluginCss = tagId$3;
|
|
407
|
+
tag.textContent = css$3;
|
|
408
|
+
document.head.appendChild(tag);
|
|
409
|
+
}
|
|
410
|
+
var StartWorkButton_module_css_default = {
|
|
411
|
+
"label": "_6acG6G_label",
|
|
412
|
+
"railButton": "_6acG6G_railButton",
|
|
413
|
+
"row": "_6acG6G_row"
|
|
414
|
+
};
|
|
415
|
+
//#endregion
|
|
416
|
+
//#region lib/types/client/StartWorkButton.js
|
|
417
|
+
/**
|
|
418
|
+
* The sidebar footer start-work button.
|
|
419
|
+
* @param props - footer owner state, view store, settings mirror, translator.
|
|
420
|
+
* @returns the button row.
|
|
421
|
+
*/
|
|
422
|
+
function StartWorkButton({ wide, useWorkspaces, useDevDockData, actions, t }) {
|
|
423
|
+
const label = t("start.button");
|
|
424
|
+
const settings = useDevDockData((data) => data.settings);
|
|
425
|
+
const firstWorkspaceId = useWorkspaces((state) => state.items[0]?.workspaceId);
|
|
426
|
+
const editorPref = settings?.workspacePrefs.find((p) => p.workspaceId === firstWorkspaceId)?.editor ?? "";
|
|
427
|
+
const ideSrc = firstWorkspaceId === void 0 ? void 0 : `/dev-dock/workspace-editor-icon?workspaceId=${encodeURIComponent(firstWorkspaceId)}&v=${encodeURIComponent(editorPref)}`;
|
|
428
|
+
const termSrc = `/dev-dock/terminal-icon?app=${encodeURIComponent(settings?.terminalApp ?? "default")}`;
|
|
429
|
+
if (!wide) return (0, react_jsx_runtime.jsx)("button", {
|
|
430
|
+
type: "button",
|
|
431
|
+
className: StartWorkButton_module_css_default.railButton,
|
|
432
|
+
title: label,
|
|
433
|
+
"aria-label": label,
|
|
434
|
+
onClick: () => {
|
|
435
|
+
actions.setOpen(true);
|
|
436
|
+
},
|
|
437
|
+
children: (0, react_jsx_runtime.jsx)(StartTile, {
|
|
438
|
+
ideSrc,
|
|
439
|
+
termSrc,
|
|
440
|
+
size: 18
|
|
441
|
+
})
|
|
442
|
+
});
|
|
443
|
+
return (0, react_jsx_runtime.jsxs)("button", {
|
|
444
|
+
type: "button",
|
|
445
|
+
className: StartWorkButton_module_css_default.row,
|
|
446
|
+
title: label,
|
|
447
|
+
onClick: () => {
|
|
448
|
+
actions.setOpen(true);
|
|
449
|
+
},
|
|
450
|
+
children: [(0, react_jsx_runtime.jsx)(StartTile, {
|
|
451
|
+
ideSrc,
|
|
452
|
+
termSrc
|
|
453
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
454
|
+
className: StartWorkButton_module_css_default.label,
|
|
455
|
+
children: label
|
|
456
|
+
})]
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region \0dsh-css:/Users/liyu/Documents/www/DeepSeek/deepseek-harness/deepseek-harness-plugin/dev-dock/src/client/StartWork.module.css.mjs
|
|
461
|
+
const css$2 = ".G6Ne1q_dialog{width:min(570px,100%)}.G6Ne1q_actionBtn{min-width:96px;padding:0 20px}.G6Ne1q_list{flex-direction:column;gap:4px;max-height:426px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.G6Ne1q_row{cursor:pointer;border-radius:8px;align-items:center;gap:8px;padding:8px 10px;display:flex}.G6Ne1q_row:hover{background:var(--dsw-alias-interactive-bg-hover)}.G6Ne1q_row input{flex:none}.G6Ne1q_rowIcon{flex:none;display:block}.G6Ne1q_name{min-width:0;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;flex:auto;font-size:13px;font-weight:600}.G6Ne1q_empty{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px}.G6Ne1q_error{color:var(--dsw-alias-state-error,var(--dsw-alias-label-error));margin:10px 0 0;font-size:12.5px}";
|
|
462
|
+
const tagId$2 = "@liyuera/dsh-dev-dock/StartWork.module.css";
|
|
463
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
464
|
+
const tag = document.createElement("style");
|
|
465
|
+
tag.dataset.plugin = "@liyuera/dsh-dev-dock";
|
|
466
|
+
tag.dataset.pluginCss = tagId$2;
|
|
467
|
+
tag.textContent = css$2;
|
|
468
|
+
document.head.appendChild(tag);
|
|
469
|
+
}
|
|
470
|
+
var StartWork_module_css_default = {
|
|
471
|
+
"actionBtn": "G6Ne1q_actionBtn",
|
|
472
|
+
"dialog": "G6Ne1q_dialog",
|
|
473
|
+
"empty": "G6Ne1q_empty",
|
|
474
|
+
"error": "G6Ne1q_error",
|
|
475
|
+
"list": "G6Ne1q_list",
|
|
476
|
+
"name": "G6Ne1q_name",
|
|
477
|
+
"row": "G6Ne1q_row",
|
|
478
|
+
"rowIcon": "G6Ne1q_rowIcon"
|
|
479
|
+
};
|
|
480
|
+
//#endregion
|
|
481
|
+
//#region lib/types/client/StartWorkModal.js
|
|
482
|
+
/**
|
|
483
|
+
* Start-work dialog: check the workspace projects to launch, confirming
|
|
484
|
+
* starts each selected project's editor + system terminal. The selection is
|
|
485
|
+
* remembered in settings and prefilled next time.
|
|
486
|
+
*/
|
|
487
|
+
/**
|
|
488
|
+
* The start-work dialog.
|
|
489
|
+
* @param props - overlay runtime, view store, data hook, actions, translator.
|
|
490
|
+
* @returns the modal, or null when closed.
|
|
491
|
+
*/
|
|
492
|
+
function StartWorkModal({ useStore, actions, useWorkspaces, useDevDockData, dataActions, t }) {
|
|
493
|
+
const { open } = useStore((state) => state);
|
|
494
|
+
const workspaces = useWorkspaces((state) => state.items);
|
|
495
|
+
const settings = useDevDockData((data) => data.settings);
|
|
496
|
+
const [selection, setSelection] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
497
|
+
const [phase, setPhase] = (0, react.useState)("idle");
|
|
498
|
+
const [error, setError] = (0, react.useState)("");
|
|
499
|
+
(0, react.useEffect)(() => {
|
|
500
|
+
if (!open) return;
|
|
501
|
+
const remembered = settings?.startWork ?? [];
|
|
502
|
+
const available = new Set(workspaces.map((w) => w.workspaceId));
|
|
503
|
+
setSelection(new Set(remembered.filter((id) => available.has(id))));
|
|
504
|
+
setPhase("idle");
|
|
505
|
+
setError("");
|
|
506
|
+
}, [
|
|
507
|
+
open,
|
|
508
|
+
settings,
|
|
509
|
+
workspaces
|
|
510
|
+
]);
|
|
511
|
+
if (!open) return null;
|
|
512
|
+
const toggle = (workspaceId) => {
|
|
513
|
+
setSelection((current) => {
|
|
514
|
+
const next = new Set(current);
|
|
515
|
+
if (next.has(workspaceId)) next.delete(workspaceId);
|
|
516
|
+
else next.add(workspaceId);
|
|
517
|
+
return next;
|
|
518
|
+
});
|
|
519
|
+
};
|
|
520
|
+
const confirm = async () => {
|
|
521
|
+
const ids = workspaces.map((w) => w.workspaceId).filter((id) => selection.has(id));
|
|
522
|
+
if (ids.length === 0) return;
|
|
523
|
+
setPhase("running");
|
|
524
|
+
const answer = await dataActions.startWork(ids);
|
|
525
|
+
await dataActions.setStartWork(ids);
|
|
526
|
+
if (answer.ok) {
|
|
527
|
+
actions.setOpen(false);
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
setError("fetchError" in answer ? answer.error ?? String(answer.fetchError) : answer.error ?? "start failed");
|
|
531
|
+
setPhase("error");
|
|
532
|
+
};
|
|
533
|
+
const close = () => {
|
|
534
|
+
actions.setOpen(false);
|
|
535
|
+
};
|
|
536
|
+
return (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
537
|
+
open: true,
|
|
538
|
+
onClose: close,
|
|
539
|
+
title: t("start.button"),
|
|
540
|
+
closeLabel: t("start.cancel"),
|
|
541
|
+
description: t("start.notice"),
|
|
542
|
+
className: StartWork_module_css_default.dialog,
|
|
543
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
544
|
+
size: "md",
|
|
545
|
+
variant: "outline",
|
|
546
|
+
className: StartWork_module_css_default.actionBtn,
|
|
547
|
+
onClick: close,
|
|
548
|
+
disabled: phase === "running",
|
|
549
|
+
children: t("start.cancel")
|
|
550
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
551
|
+
size: "md",
|
|
552
|
+
variant: "primary",
|
|
553
|
+
className: StartWork_module_css_default.actionBtn,
|
|
554
|
+
onClick: () => {
|
|
555
|
+
confirm();
|
|
556
|
+
},
|
|
557
|
+
disabled: selection.size === 0 || phase === "running",
|
|
558
|
+
children: phase === "running" ? t("start.running") : t("start.confirm")
|
|
559
|
+
})] }),
|
|
560
|
+
children: [workspaces.length === 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
561
|
+
className: StartWork_module_css_default.empty,
|
|
562
|
+
children: t("start.empty")
|
|
563
|
+
}) : (0, react_jsx_runtime.jsx)("ul", {
|
|
564
|
+
className: StartWork_module_css_default.list,
|
|
565
|
+
"aria-label": t("start.button"),
|
|
566
|
+
children: workspaces.map((workspace) => {
|
|
567
|
+
const pref = settings?.workspacePrefs.find((p) => p.workspaceId === workspace.workspaceId)?.editor ?? "";
|
|
568
|
+
const ideSrc = `/dev-dock/workspace-editor-icon?workspaceId=${encodeURIComponent(workspace.workspaceId)}&v=${encodeURIComponent(pref)}`;
|
|
569
|
+
const termSrc = `/dev-dock/terminal-icon?app=${encodeURIComponent(settings?.terminalApp ?? "default")}`;
|
|
570
|
+
return (0, react_jsx_runtime.jsx)("li", { children: (0, react_jsx_runtime.jsxs)("label", {
|
|
571
|
+
className: StartWork_module_css_default.row,
|
|
572
|
+
children: [
|
|
573
|
+
(0, react_jsx_runtime.jsx)("input", {
|
|
574
|
+
type: "checkbox",
|
|
575
|
+
checked: selection.has(workspace.workspaceId),
|
|
576
|
+
onChange: () => {
|
|
577
|
+
toggle(workspace.workspaceId);
|
|
578
|
+
},
|
|
579
|
+
disabled: phase === "running"
|
|
580
|
+
}),
|
|
581
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
582
|
+
className: StartWork_module_css_default.rowIcon,
|
|
583
|
+
children: (0, react_jsx_runtime.jsx)(StartTile, {
|
|
584
|
+
ideSrc,
|
|
585
|
+
termSrc
|
|
586
|
+
})
|
|
587
|
+
}),
|
|
588
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
589
|
+
className: StartWork_module_css_default.name,
|
|
590
|
+
children: workspace.title || workspace.path
|
|
591
|
+
})
|
|
592
|
+
]
|
|
593
|
+
}) }, workspace.workspaceId);
|
|
594
|
+
})
|
|
595
|
+
}), phase === "error" && (0, react_jsx_runtime.jsx)("p", {
|
|
596
|
+
className: StartWork_module_css_default.error,
|
|
597
|
+
role: "alert",
|
|
598
|
+
children: error
|
|
599
|
+
})]
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
//#endregion
|
|
603
|
+
//#region \0dsh-css:/Users/liyu/Documents/www/DeepSeek/deepseek-harness/deepseek-harness-plugin/dev-dock/src/client/SessionActions.module.css.mjs
|
|
604
|
+
const css$1 = ".DLfkuW_button{min-width:28px;min-height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:background var(--ds-transition-duration-fast) var(--ds-ease-in-out);background:0 0;border:0;border-radius:6px;justify-content:center;align-items:center;padding:4px;display:inline-flex}.DLfkuW_appIcon{border-radius:4px;width:16px;height:16px}.DLfkuW_group{align-items:center;gap:2px;display:inline-flex}.DLfkuW_group .DLfkuW_button{min-width:24px;min-height:24px;padding:3px}.DLfkuW_button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.DLfkuW_button:disabled,.DLfkuW_button[aria-disabled=true]{opacity:.5;cursor:default}.DLfkuW_error{color:var(--dsw-alias-state-error,var(--dsw-alias-label-error))}";
|
|
605
|
+
const tagId$1 = "@liyuera/dsh-dev-dock/SessionActions.module.css";
|
|
606
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
607
|
+
const tag = document.createElement("style");
|
|
608
|
+
tag.dataset.plugin = "@liyuera/dsh-dev-dock";
|
|
609
|
+
tag.dataset.pluginCss = tagId$1;
|
|
610
|
+
tag.textContent = css$1;
|
|
611
|
+
document.head.appendChild(tag);
|
|
612
|
+
}
|
|
613
|
+
var SessionActions_module_css_default = {
|
|
614
|
+
"appIcon": "DLfkuW_appIcon",
|
|
615
|
+
"button": "DLfkuW_button",
|
|
616
|
+
"error": "DLfkuW_error",
|
|
617
|
+
"group": "DLfkuW_group"
|
|
618
|
+
};
|
|
619
|
+
//#endregion
|
|
620
|
+
//#region lib/types/client/ComposerActions.js
|
|
621
|
+
/**
|
|
622
|
+
* Composer actions: the three devDock buttons (IDE / terminal / start) in
|
|
623
|
+
* the input tool row's left seat, bound to the current session's workspace.
|
|
624
|
+
* Same resolution and feedback as the session-header actions, in a compact
|
|
625
|
+
* group beside the resident chrome.
|
|
626
|
+
*/
|
|
627
|
+
/** Locale key per action kind. */
|
|
628
|
+
const KIND_KEY = {
|
|
629
|
+
ide: "header.ide",
|
|
630
|
+
terminal: "header.terminal",
|
|
631
|
+
start: "header.start"
|
|
632
|
+
};
|
|
633
|
+
/**
|
|
634
|
+
* The composer tool-row action group.
|
|
635
|
+
* @param props - input-zone runtime, settings mirror, actions, translator.
|
|
636
|
+
* @returns the three buttons, or null when the session has no workspace.
|
|
637
|
+
*/
|
|
638
|
+
function ComposerActions({ sessionId, useWorkspaces, useDevDockData, dataActions, t }) {
|
|
639
|
+
const workspace = useWorkspaces((state) => state.items.find((w) => w.sessionIds.includes(sessionId)));
|
|
640
|
+
const settings = useDevDockData((data) => data.settings);
|
|
641
|
+
const [states, setStates] = (0, react.useState)({
|
|
642
|
+
ide: "idle",
|
|
643
|
+
terminal: "idle",
|
|
644
|
+
start: "idle"
|
|
645
|
+
});
|
|
646
|
+
const [errors, setErrors] = (0, react.useState)({});
|
|
647
|
+
const [iconFailed, setIconFailed] = (0, react.useState)({});
|
|
648
|
+
const timer = (0, react.useRef)(null);
|
|
649
|
+
(0, react.useEffect)(() => () => {
|
|
650
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
651
|
+
}, []);
|
|
652
|
+
const editorPref = settings?.workspacePrefs.find((p) => p.workspaceId === workspace?.workspaceId)?.editor ?? "";
|
|
653
|
+
const terminalApp = settings?.terminalApp ?? "default";
|
|
654
|
+
const editorIconUrl = workspace === void 0 ? "" : `/dev-dock/workspace-editor-icon?workspaceId=${encodeURIComponent(workspace.workspaceId)}&v=${encodeURIComponent(editorPref)}`;
|
|
655
|
+
const terminalIconUrl = `/dev-dock/terminal-icon?app=${encodeURIComponent(terminalApp)}`;
|
|
656
|
+
(0, react.useEffect)(() => {
|
|
657
|
+
setIconFailed({});
|
|
658
|
+
}, [editorIconUrl, terminalIconUrl]);
|
|
659
|
+
if (workspace === void 0) return null;
|
|
660
|
+
const run = async (kind) => {
|
|
661
|
+
if (states[kind] === "busy") return;
|
|
662
|
+
setStates((current) => ({
|
|
663
|
+
...current,
|
|
664
|
+
[kind]: "busy"
|
|
665
|
+
}));
|
|
666
|
+
const answer = kind === "ide" ? await dataActions.openIde(workspace.workspaceId) : kind === "terminal" ? await dataActions.openTerminal(workspace.workspaceId) : await dataActions.start(workspace.workspaceId);
|
|
667
|
+
setStates((current) => ({
|
|
668
|
+
...current,
|
|
669
|
+
[kind]: answer.ok ? "ok" : "error"
|
|
670
|
+
}));
|
|
671
|
+
if (!answer.ok) setErrors((current) => ({
|
|
672
|
+
...current,
|
|
673
|
+
[kind]: answer.error ?? "unknown error"
|
|
674
|
+
}));
|
|
675
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
676
|
+
timer.current = setTimeout(() => {
|
|
677
|
+
setStates({
|
|
678
|
+
ide: "idle",
|
|
679
|
+
terminal: "idle",
|
|
680
|
+
start: "idle"
|
|
681
|
+
});
|
|
682
|
+
}, answer.ok ? 1500 : 4e3);
|
|
683
|
+
};
|
|
684
|
+
const kindIcon = (kind) => {
|
|
685
|
+
if (kind === "ide") return iconFailed.ide === true ? (0, react_jsx_runtime.jsx)(DevIdeAppIcon, { size: 16 }) : (0, react_jsx_runtime.jsx)("img", {
|
|
686
|
+
className: SessionActions_module_css_default.appIcon,
|
|
687
|
+
src: editorIconUrl,
|
|
688
|
+
alt: "",
|
|
689
|
+
onError: () => {
|
|
690
|
+
setIconFailed((c) => ({
|
|
691
|
+
...c,
|
|
692
|
+
ide: true
|
|
693
|
+
}));
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
if (kind === "terminal") return iconFailed.terminal === true ? (0, react_jsx_runtime.jsx)(DevTerminalAppIcon, { size: 16 }) : (0, react_jsx_runtime.jsx)("img", {
|
|
697
|
+
className: SessionActions_module_css_default.appIcon,
|
|
698
|
+
src: terminalIconUrl,
|
|
699
|
+
alt: "",
|
|
700
|
+
onError: () => {
|
|
701
|
+
setIconFailed((c) => ({
|
|
702
|
+
...c,
|
|
703
|
+
terminal: true
|
|
704
|
+
}));
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
return (0, react_jsx_runtime.jsx)(StartTile, {
|
|
708
|
+
ideSrc: editorIconUrl,
|
|
709
|
+
termSrc: terminalIconUrl
|
|
710
|
+
});
|
|
711
|
+
};
|
|
712
|
+
return (0, react_jsx_runtime.jsx)("span", {
|
|
713
|
+
className: SessionActions_module_css_default.group,
|
|
714
|
+
children: [
|
|
715
|
+
"ide",
|
|
716
|
+
"terminal",
|
|
717
|
+
"start"
|
|
718
|
+
].map((kind) => {
|
|
719
|
+
const state = states[kind];
|
|
720
|
+
const title = state === "error" ? t("header.error", { error: errors[kind] ?? "" }) : t(KIND_KEY[kind]);
|
|
721
|
+
return (0, react_jsx_runtime.jsx)("button", {
|
|
722
|
+
type: "button",
|
|
723
|
+
className: `${SessionActions_module_css_default.button} ${state === "error" ? SessionActions_module_css_default.error : ""}`,
|
|
724
|
+
title,
|
|
725
|
+
"aria-label": title,
|
|
726
|
+
"aria-disabled": state === "busy",
|
|
727
|
+
onClick: () => {
|
|
728
|
+
run(kind);
|
|
729
|
+
},
|
|
730
|
+
children: state === "ok" ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 16 }) : kindIcon(kind)
|
|
731
|
+
}, kind);
|
|
732
|
+
})
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
//#endregion
|
|
736
|
+
//#region \0dsh-css:/Users/liyu/Documents/www/DeepSeek/deepseek-harness/deepseek-harness-plugin/dev-dock/src/client/DevDockSettingsPage.module.css.mjs
|
|
737
|
+
const css = "._5fyaeq_page{flex-direction:column;gap:8px;display:flex}._5fyaeq_heading{color:var(--dsw-alias-label-primary);margin:12px 0 0;font-size:14px;font-weight:600}._5fyaeq_hint{color:var(--dsw-alias-label-secondary);margin:0 0 8px;font-size:12px;line-height:18px}._5fyaeq_rows{flex-direction:column;gap:6px;margin:0 0 8px;padding:0;list-style:none;display:flex}._5fyaeq_row{justify-content:space-between;align-items:center;gap:12px;display:flex}._5fyaeq_name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12.5px;font-weight:600;overflow:hidden}._5fyaeq_selector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:4px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}._5fyaeq_selector:hover{background:var(--dsw-alias-interactive-bg-hover)}._5fyaeq_chevron{color:var(--dsw-alias-label-secondary);transition:transform var(--ds-transition-duration-fast) var(--ds-ease-in-out);flex:none;display:inline-flex}._5fyaeq_chevronOpen{transform:rotate(180deg)}._5fyaeq_editorRow{align-items:center;gap:10px;margin:0 0 8px;display:flex}._5fyaeq_editorName{flex:none;align-items:center;gap:8px;width:150px;display:flex}._5fyaeq_editorIcon{border-radius:5px;flex:none;width:20px;height:20px}._5fyaeq_editorLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._5fyaeq_editorInput{flex:auto;min-width:0}._5fyaeq_editorSave{flex:none}._5fyaeq_refreshRow{align-items:center;gap:10px;margin-bottom:8px;display:flex}._5fyaeq_radioRow{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:center;gap:8px;margin-bottom:6px;font-size:12.5px;display:flex}._5fyaeq_error{color:var(--dsw-alias-state-error,var(--dsw-alias-label-error));font-size:12px}";
|
|
738
|
+
const tagId = "@liyuera/dsh-dev-dock/DevDockSettingsPage.module.css";
|
|
739
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
740
|
+
const tag = document.createElement("style");
|
|
741
|
+
tag.dataset.plugin = "@liyuera/dsh-dev-dock";
|
|
742
|
+
tag.dataset.pluginCss = tagId;
|
|
743
|
+
tag.textContent = css;
|
|
744
|
+
document.head.appendChild(tag);
|
|
745
|
+
}
|
|
746
|
+
var DevDockSettingsPage_module_css_default = {
|
|
747
|
+
"chevron": "_5fyaeq_chevron",
|
|
748
|
+
"chevronOpen": "_5fyaeq_chevronOpen",
|
|
749
|
+
"editorIcon": "_5fyaeq_editorIcon",
|
|
750
|
+
"editorInput": "_5fyaeq_editorInput",
|
|
751
|
+
"editorLabel": "_5fyaeq_editorLabel",
|
|
752
|
+
"editorName": "_5fyaeq_editorName",
|
|
753
|
+
"editorRow": "_5fyaeq_editorRow",
|
|
754
|
+
"editorSave": "_5fyaeq_editorSave",
|
|
755
|
+
"error": "_5fyaeq_error",
|
|
756
|
+
"heading": "_5fyaeq_heading",
|
|
757
|
+
"hint": "_5fyaeq_hint",
|
|
758
|
+
"name": "_5fyaeq_name",
|
|
759
|
+
"page": "_5fyaeq_page",
|
|
760
|
+
"radioRow": "_5fyaeq_radioRow",
|
|
761
|
+
"refreshRow": "_5fyaeq_refreshRow",
|
|
762
|
+
"row": "_5fyaeq_row",
|
|
763
|
+
"rows": "_5fyaeq_rows",
|
|
764
|
+
"selector": "_5fyaeq_selector"
|
|
765
|
+
};
|
|
766
|
+
//#endregion
|
|
767
|
+
//#region lib/types/client/DevDockSettingsPage.js
|
|
768
|
+
/**
|
|
769
|
+
* devDock settings page (`settings.section`): per-workspace editor
|
|
770
|
+
* preference, editor manual paths + detection refresh, and the terminal
|
|
771
|
+
* preference. Data rides the settings namespace mirror; desktop detection
|
|
772
|
+
* goes through the host route.
|
|
773
|
+
*/
|
|
774
|
+
/** Stable union of editor names for the preference selects. */
|
|
775
|
+
const EDITOR_OPTIONS = EDITOR_NAMES;
|
|
776
|
+
/**
|
|
777
|
+
* dsh-style editor pill: rounded-chrome trigger plus the primitives Menu
|
|
778
|
+
* trailing-check popup (same pattern as the permission preset selector).
|
|
779
|
+
* @param props - current editor, available options, change callback.
|
|
780
|
+
* @returns the pill and its menu.
|
|
781
|
+
*/
|
|
782
|
+
function WorkspaceEditorSelect({ value, options, onChange }) {
|
|
783
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
784
|
+
const items = [{
|
|
785
|
+
id: "",
|
|
786
|
+
label: "自动"
|
|
787
|
+
}, ...options.map((name) => ({
|
|
788
|
+
id: name,
|
|
789
|
+
label: name
|
|
790
|
+
}))];
|
|
791
|
+
const display = value === "" ? "自动" : value;
|
|
792
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
793
|
+
open,
|
|
794
|
+
items,
|
|
795
|
+
selectedId: value === "" ? "" : value,
|
|
796
|
+
onSelect: (id) => {
|
|
797
|
+
setOpen(false);
|
|
798
|
+
onChange(id);
|
|
799
|
+
},
|
|
800
|
+
onClose: () => {
|
|
801
|
+
setOpen(false);
|
|
802
|
+
},
|
|
803
|
+
align: "end",
|
|
804
|
+
side: "bottom",
|
|
805
|
+
anchor: (0, react_jsx_runtime.jsxs)("button", {
|
|
806
|
+
type: "button",
|
|
807
|
+
className: DevDockSettingsPage_module_css_default.selector,
|
|
808
|
+
onClick: () => {
|
|
809
|
+
setOpen(!open);
|
|
810
|
+
},
|
|
811
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: display }), (0, react_jsx_runtime.jsx)("span", {
|
|
812
|
+
className: `${DevDockSettingsPage_module_css_default.chevron} ${open ? DevDockSettingsPage_module_css_default.chevronOpen : ""}`,
|
|
813
|
+
"aria-hidden": true,
|
|
814
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, {})
|
|
815
|
+
})]
|
|
816
|
+
})
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* Render the devDock settings page.
|
|
821
|
+
* @param props - settings runtime, data hook, actions, translator.
|
|
822
|
+
* @returns the settings sections.
|
|
823
|
+
*/
|
|
824
|
+
function DevDockSettingsPage({ useWorkspaces, useDevDockData, dataActions, t }) {
|
|
825
|
+
const workspaces = useWorkspaces((state) => state.items);
|
|
826
|
+
const settings = useDevDockData((data) => data.settings);
|
|
827
|
+
const [drafts, setDrafts] = (0, react.useState)({});
|
|
828
|
+
const [detecting, setDetecting] = (0, react.useState)(false);
|
|
829
|
+
const [detectError, setDetectError] = (0, react.useState)("");
|
|
830
|
+
const [iconFailed, setIconFailed] = (0, react.useState)({});
|
|
831
|
+
const prefs = settings?.workspacePrefs ?? [];
|
|
832
|
+
const editors = settings?.editors ?? [];
|
|
833
|
+
const editorNames = [...new Set([...EDITOR_OPTIONS, ...editors.map((e) => e.name)])];
|
|
834
|
+
const prefOf = (workspaceId) => prefs.find((p) => p.workspaceId === workspaceId)?.editor ?? "";
|
|
835
|
+
const setPref = async (workspaceId, editor) => {
|
|
836
|
+
await dataActions.setWorkspacePref(workspaceId, editor);
|
|
837
|
+
};
|
|
838
|
+
const saveManual = async (name, value) => {
|
|
839
|
+
await dataActions.setEditorManualPath(name, value);
|
|
840
|
+
};
|
|
841
|
+
const refresh = async () => {
|
|
842
|
+
setDetecting(true);
|
|
843
|
+
setDetectError("");
|
|
844
|
+
const answer = await dataActions.listEditors();
|
|
845
|
+
setDetecting(false);
|
|
846
|
+
if (!answer.ok) setDetectError(answer.error ?? "detection failed");
|
|
847
|
+
};
|
|
848
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
849
|
+
className: DevDockSettingsPage_module_css_default.page,
|
|
850
|
+
children: [
|
|
851
|
+
(0, react_jsx_runtime.jsx)("h2", {
|
|
852
|
+
className: DevDockSettingsPage_module_css_default.heading,
|
|
853
|
+
children: t("settings.workspacePref.title")
|
|
854
|
+
}),
|
|
855
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
856
|
+
className: DevDockSettingsPage_module_css_default.hint,
|
|
857
|
+
children: t("settings.workspacePref.hint")
|
|
858
|
+
}),
|
|
859
|
+
workspaces.length === 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
860
|
+
className: DevDockSettingsPage_module_css_default.hint,
|
|
861
|
+
children: t("start.noWorkspace")
|
|
862
|
+
}),
|
|
863
|
+
(0, react_jsx_runtime.jsx)("ul", {
|
|
864
|
+
className: DevDockSettingsPage_module_css_default.rows,
|
|
865
|
+
children: workspaces.map((workspace) => (0, react_jsx_runtime.jsxs)("li", {
|
|
866
|
+
className: DevDockSettingsPage_module_css_default.row,
|
|
867
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
868
|
+
className: DevDockSettingsPage_module_css_default.name,
|
|
869
|
+
children: workspace.title || workspace.path
|
|
870
|
+
}), (0, react_jsx_runtime.jsx)(WorkspaceEditorSelect, {
|
|
871
|
+
value: prefOf(workspace.workspaceId),
|
|
872
|
+
options: editorNames,
|
|
873
|
+
onChange: (editor) => {
|
|
874
|
+
setPref(workspace.workspaceId, editor);
|
|
875
|
+
}
|
|
876
|
+
})]
|
|
877
|
+
}, workspace.workspaceId))
|
|
878
|
+
}),
|
|
879
|
+
(0, react_jsx_runtime.jsx)("h2", {
|
|
880
|
+
className: DevDockSettingsPage_module_css_default.heading,
|
|
881
|
+
children: t("settings.editors.title")
|
|
882
|
+
}),
|
|
883
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
884
|
+
className: DevDockSettingsPage_module_css_default.hint,
|
|
885
|
+
children: t("settings.editors.hint")
|
|
886
|
+
}),
|
|
887
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
888
|
+
className: DevDockSettingsPage_module_css_default.refreshRow,
|
|
889
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
890
|
+
size: "sm",
|
|
891
|
+
variant: "outline",
|
|
892
|
+
onClick: () => {
|
|
893
|
+
refresh();
|
|
894
|
+
},
|
|
895
|
+
disabled: detecting,
|
|
896
|
+
children: detecting ? `${t("settings.editors.refresh")}…` : t("settings.editors.refresh")
|
|
897
|
+
}), detectError !== "" && (0, react_jsx_runtime.jsx)("span", {
|
|
898
|
+
className: DevDockSettingsPage_module_css_default.error,
|
|
899
|
+
role: "alert",
|
|
900
|
+
children: detectError
|
|
901
|
+
})]
|
|
902
|
+
}),
|
|
903
|
+
(0, react_jsx_runtime.jsx)("ul", {
|
|
904
|
+
className: DevDockSettingsPage_module_css_default.rows,
|
|
905
|
+
children: editorNames.map((name) => {
|
|
906
|
+
const editor = editors.find((e) => e.name === name);
|
|
907
|
+
const manual = editor?.manualPath;
|
|
908
|
+
const detected = editor?.detectedPath ?? "";
|
|
909
|
+
const draft = drafts[name] ?? manual ?? detected;
|
|
910
|
+
return (0, react_jsx_runtime.jsxs)("li", {
|
|
911
|
+
className: DevDockSettingsPage_module_css_default.editorRow,
|
|
912
|
+
children: [
|
|
913
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
914
|
+
className: `${DevDockSettingsPage_module_css_default.name} ${DevDockSettingsPage_module_css_default.editorName}`,
|
|
915
|
+
children: [iconFailed[name] ? (0, react_jsx_runtime.jsx)(DevIdeIcon, { size: 16 }) : (0, react_jsx_runtime.jsx)("img", {
|
|
916
|
+
className: DevDockSettingsPage_module_css_default.editorIcon,
|
|
917
|
+
src: `/dev-dock/editor-icon?editor=${encodeURIComponent(name)}`,
|
|
918
|
+
alt: "",
|
|
919
|
+
onError: () => {
|
|
920
|
+
setIconFailed((current) => ({
|
|
921
|
+
...current,
|
|
922
|
+
[name]: true
|
|
923
|
+
}));
|
|
924
|
+
}
|
|
925
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
926
|
+
className: DevDockSettingsPage_module_css_default.editorLabel,
|
|
927
|
+
children: name
|
|
928
|
+
})]
|
|
929
|
+
}),
|
|
930
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
931
|
+
className: DevDockSettingsPage_module_css_default.editorInput,
|
|
932
|
+
value: draft,
|
|
933
|
+
placeholder: t("settings.editors.manual"),
|
|
934
|
+
onChange: (event) => {
|
|
935
|
+
setDrafts((current) => ({
|
|
936
|
+
...current,
|
|
937
|
+
[name]: event.target.value
|
|
938
|
+
}));
|
|
939
|
+
}
|
|
940
|
+
}),
|
|
941
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
942
|
+
size: "sm",
|
|
943
|
+
variant: "outline",
|
|
944
|
+
className: DevDockSettingsPage_module_css_default.editorSave,
|
|
945
|
+
onClick: () => {
|
|
946
|
+
saveManual(name, draft);
|
|
947
|
+
},
|
|
948
|
+
children: t("settings.editors.save")
|
|
949
|
+
})
|
|
950
|
+
]
|
|
951
|
+
}, name);
|
|
952
|
+
})
|
|
953
|
+
}),
|
|
954
|
+
(0, react_jsx_runtime.jsx)("h2", {
|
|
955
|
+
className: DevDockSettingsPage_module_css_default.heading,
|
|
956
|
+
children: t("settings.terminal.title")
|
|
957
|
+
}),
|
|
958
|
+
TERMINAL_APPS.map(({ key, labelKey }) => {
|
|
959
|
+
const failed = iconFailed[key];
|
|
960
|
+
return (0, react_jsx_runtime.jsxs)("label", {
|
|
961
|
+
className: DevDockSettingsPage_module_css_default.radioRow,
|
|
962
|
+
children: [
|
|
963
|
+
(0, react_jsx_runtime.jsx)("input", {
|
|
964
|
+
type: "radio",
|
|
965
|
+
name: "dev-dock-terminal",
|
|
966
|
+
checked: (settings?.terminalApp ?? "default") === key,
|
|
967
|
+
onChange: () => {
|
|
968
|
+
dataActions.setTerminalApp(key);
|
|
969
|
+
}
|
|
970
|
+
}),
|
|
971
|
+
failed ? (0, react_jsx_runtime.jsx)(DevTerminalIcon, { size: 16 }) : (0, react_jsx_runtime.jsx)("img", {
|
|
972
|
+
className: DevDockSettingsPage_module_css_default.editorIcon,
|
|
973
|
+
src: `/dev-dock/terminal-icon?app=${key}`,
|
|
974
|
+
alt: "",
|
|
975
|
+
onError: () => {
|
|
976
|
+
setIconFailed((current) => ({
|
|
977
|
+
...current,
|
|
978
|
+
[key]: true
|
|
979
|
+
}));
|
|
980
|
+
}
|
|
981
|
+
}),
|
|
982
|
+
(0, react_jsx_runtime.jsx)("span", { children: t(labelKey) })
|
|
983
|
+
]
|
|
984
|
+
}, key);
|
|
985
|
+
})
|
|
986
|
+
]
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
/** Terminal preference options with their icon route keys. */
|
|
990
|
+
const TERMINAL_APPS = [{
|
|
991
|
+
key: "default",
|
|
992
|
+
labelKey: "settings.terminal.default"
|
|
993
|
+
}, {
|
|
994
|
+
key: "iterm",
|
|
995
|
+
labelKey: "settings.terminal.iterm"
|
|
996
|
+
}];
|
|
997
|
+
//#endregion
|
|
998
|
+
//#region lib/types/client/locales.js
|
|
999
|
+
/**
|
|
1000
|
+
* devDock v2 browser copy: entry row, start-work dialog, per-session header
|
|
1001
|
+
* actions (IDE / terminal / start), and the settings page. Simplified from
|
|
1002
|
+
* v1: projects are dsh workspaces; desktop actions are deterministic.
|
|
1003
|
+
* @module @liyuera/dsh-dev-dock/client/locales
|
|
1004
|
+
*/
|
|
1005
|
+
/** devDock dictionary keys. */
|
|
1006
|
+
const NS = "devDock";
|
|
1007
|
+
/** zh dict. */
|
|
1008
|
+
const zh = {
|
|
1009
|
+
"start.button": "开始上班",
|
|
1010
|
+
"start.notice": "选择要启动的工作区项目(记住上次选择)",
|
|
1011
|
+
"start.confirm": "启动",
|
|
1012
|
+
"start.cancel": "取消",
|
|
1013
|
+
"start.running": "正在启动…",
|
|
1014
|
+
"start.done": "已打开 {opened} 个编辑器、{started} 个终端窗口",
|
|
1015
|
+
"start.empty": "没有可用的工作区项目",
|
|
1016
|
+
"start.noWorkspace": "请先在工作区添加项目",
|
|
1017
|
+
"header.ide": "用 IDE 打开",
|
|
1018
|
+
"header.terminal": "打开系统终端",
|
|
1019
|
+
"header.start": "启动(IDE + 终端)",
|
|
1020
|
+
"header.noWorkspace": "当前会话没有关联工作区",
|
|
1021
|
+
"header.error": "操作失败:{error}",
|
|
1022
|
+
"settings.title": "devDock",
|
|
1023
|
+
"settings.workspacePref.title": "工作区编辑器偏好",
|
|
1024
|
+
"settings.workspacePref.hint": "给每个工作区选择打开用的 IDE;不选则按内容自动检测(uni-app → HBuilderX,其它 → WebStorm)。",
|
|
1025
|
+
"settings.editors.title": "编辑器",
|
|
1026
|
+
"settings.editors.refresh": "重新检测",
|
|
1027
|
+
"settings.editors.manual": "手动路径",
|
|
1028
|
+
"settings.editors.save": "保存",
|
|
1029
|
+
"settings.editors.hint": "检测不到或需要指定时,可手动填写(如 HBuilderX)。",
|
|
1030
|
+
"settings.terminal.title": "终端",
|
|
1031
|
+
"settings.terminal.default": "Terminal.app(默认)",
|
|
1032
|
+
"settings.terminal.iterm": "iTerm2"
|
|
1033
|
+
};
|
|
1034
|
+
/** en dict. */
|
|
1035
|
+
const en = {
|
|
1036
|
+
"start.button": "Start Work",
|
|
1037
|
+
"start.notice": "Select workspace projects to start (last selection remembered)",
|
|
1038
|
+
"start.confirm": "Start",
|
|
1039
|
+
"start.cancel": "Cancel",
|
|
1040
|
+
"start.running": "Starting…",
|
|
1041
|
+
"start.done": "Opened {opened} editor(s) and {started} terminal(s)",
|
|
1042
|
+
"start.empty": "No workspace projects available",
|
|
1043
|
+
"start.noWorkspace": "Add projects in the workspace area first",
|
|
1044
|
+
"header.ide": "Open in IDE",
|
|
1045
|
+
"header.terminal": "Open system terminal",
|
|
1046
|
+
"header.start": "Start (IDE + terminal)",
|
|
1047
|
+
"header.noWorkspace": "This session has no associated workspace",
|
|
1048
|
+
"header.error": "Action failed: {error}",
|
|
1049
|
+
"settings.title": "devDock",
|
|
1050
|
+
"settings.workspacePref.title": "Workspace editor preference",
|
|
1051
|
+
"settings.workspacePref.hint": "Pick the IDE each workspace opens with; auto-detected when unset (uni-app → HBuilderX, other → WebStorm).",
|
|
1052
|
+
"settings.editors.title": "Editors",
|
|
1053
|
+
"settings.editors.refresh": "Re-detect",
|
|
1054
|
+
"settings.editors.manual": "Manual path",
|
|
1055
|
+
"settings.editors.save": "Save",
|
|
1056
|
+
"settings.editors.hint": "Set a manual path when detection misses (e.g. HBuilderX).",
|
|
1057
|
+
"settings.terminal.title": "Terminal",
|
|
1058
|
+
"settings.terminal.default": "Terminal.app (default)",
|
|
1059
|
+
"settings.terminal.iterm": "iTerm2"
|
|
1060
|
+
};
|
|
1061
|
+
//#endregion
|
|
1062
|
+
//#region lib/types/client/index.js
|
|
1063
|
+
/** Required services for data binding and slot contributions. */
|
|
1064
|
+
const inject = ["slots", "locale"];
|
|
1065
|
+
/**
|
|
1066
|
+
* Client plugin body: register dictionaries and every surface entry.
|
|
1067
|
+
* @param ctx - client root context.
|
|
1068
|
+
*/
|
|
1069
|
+
function apply(ctx) {
|
|
1070
|
+
ctx.effect(() => ctx.locale.register(NS, {
|
|
1071
|
+
zh,
|
|
1072
|
+
en
|
|
1073
|
+
}), "dev-dock: dictionaries");
|
|
1074
|
+
const t = ctx.locale.bind(NS);
|
|
1075
|
+
const view = createDevDockStore();
|
|
1076
|
+
const data = createDevDockData(ctx);
|
|
1077
|
+
const dataHandle = data.store;
|
|
1078
|
+
const dataActions = data.actions;
|
|
1079
|
+
const modalInjected = () => ({
|
|
1080
|
+
hooks: { devDockData: dataHandle },
|
|
1081
|
+
dataActions
|
|
1082
|
+
});
|
|
1083
|
+
const footerInjected = () => ({ hooks: { devDockData: dataHandle } });
|
|
1084
|
+
ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
|
|
1085
|
+
name: "sidebar.footer.action",
|
|
1086
|
+
id: "dev-dock-start",
|
|
1087
|
+
order: 5,
|
|
1088
|
+
locale: NS,
|
|
1089
|
+
store: view,
|
|
1090
|
+
inject: footerInjected
|
|
1091
|
+
}, StartWorkButton));
|
|
1092
|
+
const composerInjected = () => ({
|
|
1093
|
+
dataActions,
|
|
1094
|
+
hooks: { devDockData: dataHandle }
|
|
1095
|
+
});
|
|
1096
|
+
ctx.slots.inject("conversation.input.right", () => ctx.slots.register({
|
|
1097
|
+
name: "conversation.input.right",
|
|
1098
|
+
id: "dev-dock-actions",
|
|
1099
|
+
order: 10,
|
|
1100
|
+
locale: NS,
|
|
1101
|
+
inject: composerInjected
|
|
1102
|
+
}, ComposerActions));
|
|
1103
|
+
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
1104
|
+
name: "shell.overlay",
|
|
1105
|
+
id: "dev-dock-start-modal",
|
|
1106
|
+
order: 300,
|
|
1107
|
+
locale: NS,
|
|
1108
|
+
store: view,
|
|
1109
|
+
inject: modalInjected
|
|
1110
|
+
}, StartWorkModal));
|
|
1111
|
+
const settingsInjected = () => ({
|
|
1112
|
+
hooks: { devDockData: dataHandle },
|
|
1113
|
+
dataActions
|
|
1114
|
+
});
|
|
1115
|
+
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
1116
|
+
name: "settings.section",
|
|
1117
|
+
id: "dev-dock",
|
|
1118
|
+
order: 12,
|
|
1119
|
+
label: () => t("settings.title"),
|
|
1120
|
+
locale: NS,
|
|
1121
|
+
inject: settingsInjected
|
|
1122
|
+
}, DevDockSettingsPage));
|
|
1123
|
+
}
|
|
1124
|
+
//#endregion
|
|
1125
|
+
exports.apply = apply;
|
|
1126
|
+
exports.inject = inject;
|
|
1127
|
+
return module.exports;
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
//# sourceMappingURL=client.js.map
|