dsh-edge 0.2.0 → 0.3.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +13 -10
- package/README.zh.md +13 -10
- package/THIRD_PARTY_NOTICES.md +447 -348
- package/dist/assets/{index-BNMwCG9c.css → index-C6eRlFa6.css} +1 -1
- package/dist/assets/{index-CA9Bpko5.js → index-ClqxG24t.js} +35 -35
- package/dist/index.html +3 -3
- package/dist/plugins/@deepseek-ai/dsh-api-gateway/client.js +84 -55
- package/dist/plugins/@deepseek-ai/dsh-client-connection/client.js +10 -6
- package/dist/plugins/@deepseek-ai/dsh-client-runtime/client.js +15 -6
- package/dist/plugins/@deepseek-ai/dsh-client-ui-attachment/client.js +782 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +188 -72
- package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +46 -13
- package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +1 -1
- package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +287 -128
- package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +46 -9
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +26 -0
- package/package.json +25 -22
- package/scripts/cli.mjs +56 -1
- package/scripts/install.d.mts +31 -0
- package/scripts/install.mjs +304 -16
- package/scripts/legal-files.mjs +5 -1
- package/scripts/wrangler-config-core.mjs +28 -0
- package/scripts/wrangler-config.d.mts +1 -0
- package/worker/direct/index.js +1021 -991
- package/worker/isolated/index.js +677 -647
|
@@ -230,7 +230,7 @@ window.__ModuleLoader__.load({
|
|
|
230
230
|
}
|
|
231
231
|
//#endregion
|
|
232
232
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-user-questions/src/client/QuestionComposer.module.css.mjs
|
|
233
|
-
const css = ".Mbwy4a_frame{padding:6px calc(var(--dsh-composer-side-clearance) + 16px) 10px;justify-content:center;display:flex}.Mbwy4a_card{width:100%;max-width:var(--dsh-chat-content-width);border:1px solid var(--dsw-alias-border-l2-darkmode-thin);background:var(--dsw-specific-input-major);max-height:min(60vh,520px);box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:20px;flex-direction:column;padding:0 0 10px;display:flex;overflow:hidden}.Mbwy4a_card,.Mbwy4a_card *{box-sizing:border-box}.Mbwy4a_cardMinimized{max-height:none}.Mbwy4a_cardMinimized .Mbwy4a_header{padding-bottom:14px}.Mbwy4a_headerActions{flex-shrink:0;align-items:center;gap:4px;display:flex}.Mbwy4a_header{flex-shrink:0;justify-content:space-between;align-items:flex-start;gap:16px;padding:20px 16px 0 24px;display:flex}.Mbwy4a_headingBlock{min-width:0}.Mbwy4a_eyebrow{color:var(--dsw-alias-label-tertiary);margin-bottom:5px;font-size:11px;line-height:16px}.Mbwy4a_title{margin:0;font-size:16px;font-weight:500;line-height:22px}.Mbwy4a_detail{margin:0 2px 8px}.Mbwy4a_footerActions{flex-shrink:0;align-items:center;gap:12px;display:flex}.Mbwy4a_pager{flex-shrink:0;align-items:center;gap:6px;display:flex}.Mbwy4a_progress{color:var(--dsw-alias-label-secondary);white-space:nowrap;word-spacing:-2px;padding:0 4px;font-size:14px;font-weight:500;line-height:24px}.Mbwy4a_iconButton{width:24px;height:24px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;place-items:center;padding:0;display:grid}.Mbwy4a_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.Mbwy4a_iconButton:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.Mbwy4a_body{overscroll-behavior:contain;flex-direction:column;flex:auto;min-height:0;display:flex;overflow-y:auto}.Mbwy4a_options{flex-direction:column;gap:1px;margin:8px 0 0;padding:4px 12px;display:flex}.Mbwy4a_option{width:100%;min-height:40px;color:inherit;text-align:left;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:12px;flex-shrink:0;align-items:flex-start;gap:8px;padding:8px 12px 8px 8px;transition:background-color .12s,border-color .12s;display:flex}.Mbwy4a_option:hover:not(:disabled),.Mbwy4a_optionSelected{background:var(--dsw-alias-interactive-bg-hover)}.Mbwy4a_optionSelected{border-color:var(--dsw-alias-border-l2)}.Mbwy4a_option:disabled{cursor:default}.Mbwy4a_number{background:var(--dsw-alias-bg-overlay);width:20px;height:20px;color:var(--dsw-alias-label-secondary);border-radius:6px;flex:0 0 20px;place-items:center;margin-top:2px;font-size:12px;font-weight:500;line-height:18px;display:grid}.Mbwy4a_checkbox{flex:0 0 20px;place-items:center;width:20px;height:20px;margin-top:2px;display:grid}.Mbwy4a_checkbox:before{content:\"\";border:1px solid var(--dsw-alias-border-l4);border-radius:4px;grid-area:1/1;width:14px;height:14px;transition:background-color .12s,border-color .12s}.Mbwy4a_checkbox>svg{grid-area:1/1}.Mbwy4a_checkboxChecked{color:var(--dsw-alias-label-primary-foreground)}.Mbwy4a_checkboxChecked:before{border-color:var(--dsw-alias-label-primary);background:var(--dsw-alias-label-primary)}.Mbwy4a_optionCopy{flex:1;min-width:0}.Mbwy4a_optionLine{flex-wrap:wrap;align-items:baseline;gap:2px 6px;display:flex}.Mbwy4a_optionLabel{font-size:14px;font-weight:500;line-height:24px}.Mbwy4a_badge{background:var(--dsw-specific-sidebar-nav-item-active-accent);color:var(--dsw-alias-button-info-fill);border-radius:6px;padding:0 4px;font-size:11px;font-weight:600;line-height:18px}.Mbwy4a_description{color:var(--dsw-alias-label-tertiary);font-size:14px;font-weight:400;line-height:24px}.Mbwy4a_customRow{border:1px solid #0000;border-radius:12px;flex-shrink:0;align-items:flex-start;gap:8px;width:100%;min-height:40px;padding:8px 12px 8px 8px;transition:background-color .12s,border-color .12s;display:flex}.Mbwy4a_customRow:hover,.Mbwy4a_customRow:focus-within,.Mbwy4a_customRowActive{background:var(--dsw-alias-interactive-bg-hover)}.Mbwy4a_customRow:focus-within,.Mbwy4a_customRowActive{border-color:var(--dsw-alias-border-l2)}.
|
|
233
|
+
const css = ".Mbwy4a_frame{padding:6px calc(var(--dsh-composer-side-clearance) + 16px) 10px;justify-content:center;display:flex}.Mbwy4a_card{width:100%;max-width:var(--dsh-chat-content-width);border:1px solid var(--dsw-alias-border-l2-darkmode-thin);background:var(--dsw-specific-input-major);max-height:min(60vh,520px);box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:20px;flex-direction:column;padding:0 0 10px;display:flex;overflow:hidden}.Mbwy4a_card,.Mbwy4a_card *{box-sizing:border-box}.Mbwy4a_cardMinimized{max-height:none}.Mbwy4a_cardMinimized .Mbwy4a_header{padding-bottom:14px}.Mbwy4a_headerActions{flex-shrink:0;align-items:center;gap:4px;display:flex}.Mbwy4a_header{flex-shrink:0;justify-content:space-between;align-items:flex-start;gap:16px;padding:20px 16px 0 24px;display:flex}.Mbwy4a_headingBlock{min-width:0}.Mbwy4a_eyebrow{color:var(--dsw-alias-label-tertiary);margin-bottom:5px;font-size:11px;line-height:16px}.Mbwy4a_title{margin:0;font-size:16px;font-weight:500;line-height:22px}.Mbwy4a_detail{margin:0 2px 8px}.Mbwy4a_footerActions{flex-shrink:0;align-items:center;gap:12px;display:flex}.Mbwy4a_pager{flex-shrink:0;align-items:center;gap:6px;display:flex}.Mbwy4a_progress{color:var(--dsw-alias-label-secondary);white-space:nowrap;word-spacing:-2px;padding:0 4px;font-size:14px;font-weight:500;line-height:24px}.Mbwy4a_iconButton{width:24px;height:24px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;place-items:center;padding:0;display:grid}.Mbwy4a_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.Mbwy4a_iconButton:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.Mbwy4a_body{overscroll-behavior:contain;flex-direction:column;flex:auto;min-height:0;display:flex;overflow-y:auto}.Mbwy4a_options{flex-direction:column;gap:1px;margin:8px 0 0;padding:4px 12px;display:flex}.Mbwy4a_option{width:100%;min-height:40px;color:inherit;text-align:left;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:12px;flex-shrink:0;align-items:flex-start;gap:8px;padding:8px 12px 8px 8px;transition:background-color .12s,border-color .12s;display:flex}.Mbwy4a_option:hover:not(:disabled),.Mbwy4a_optionSelected{background:var(--dsw-alias-interactive-bg-hover)}.Mbwy4a_optionSelected{border-color:var(--dsw-alias-border-l2)}.Mbwy4a_option:disabled{cursor:default}.Mbwy4a_number{background:var(--dsw-alias-bg-overlay);width:20px;height:20px;color:var(--dsw-alias-label-secondary);border-radius:6px;flex:0 0 20px;place-items:center;margin-top:2px;font-size:12px;font-weight:500;line-height:18px;display:grid}.Mbwy4a_checkbox{flex:0 0 20px;place-items:center;width:20px;height:20px;margin-top:2px;display:grid}.Mbwy4a_checkbox:before{content:\"\";border:1px solid var(--dsw-alias-border-l4);border-radius:4px;grid-area:1/1;width:14px;height:14px;transition:background-color .12s,border-color .12s}.Mbwy4a_checkbox>svg{grid-area:1/1}.Mbwy4a_checkboxChecked{color:var(--dsw-alias-label-primary-foreground)}.Mbwy4a_checkboxChecked:before{border-color:var(--dsw-alias-label-primary);background:var(--dsw-alias-label-primary)}.Mbwy4a_optionCopy{flex:1;min-width:0}.Mbwy4a_optionLine{flex-wrap:wrap;align-items:baseline;gap:2px 6px;display:flex}.Mbwy4a_optionLabel{font-size:14px;font-weight:500;line-height:24px}.Mbwy4a_badge{background:var(--dsw-specific-sidebar-nav-item-active-accent);color:var(--dsw-alias-button-info-fill);border-radius:6px;padding:0 4px;font-size:11px;font-weight:600;line-height:18px}.Mbwy4a_description{color:var(--dsw-alias-label-tertiary);font-size:14px;font-weight:400;line-height:24px}.Mbwy4a_customRow{border:1px solid #0000;border-radius:12px;flex-shrink:0;align-items:flex-start;gap:8px;width:100%;min-height:40px;padding:8px 12px 8px 8px;transition:background-color .12s,border-color .12s;display:flex}.Mbwy4a_customRow:hover,.Mbwy4a_customRow:focus-within,.Mbwy4a_customRowActive{background:var(--dsw-alias-interactive-bg-hover)}.Mbwy4a_customRow:focus-within,.Mbwy4a_customRowActive{border-color:var(--dsw-alias-border-l2)}.Mbwy4a_field{--dsh-answer-field-padding:0;min-width:0;display:grid}.Mbwy4a_field>*{min-width:0;padding:var(--dsh-answer-field-padding);font:inherit;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere;grid-area:1/1;font-size:14px;line-height:24px}.Mbwy4a_fieldMirror{box-sizing:content-box;visibility:hidden;max-height:144px;overflow:hidden}.Mbwy4a_fieldInput{resize:none;color:var(--dsw-alias-label-primary);caret-color:var(--dsw-alias-state-business-primary);background:0 0;border:none;outline:none;overflow-y:auto}.Mbwy4a_fieldInput::placeholder{color:var(--dsw-alias-label-caption)}.Mbwy4a_customInline{flex:1}.Mbwy4a_customBlock{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);--dsh-answer-field-padding:8px 12px;border-radius:10px;flex-shrink:0;min-height:64px;margin:0 12px}.Mbwy4a_customBlock:focus-within{border-color:var(--dsw-alias-state-business-primary)}.Mbwy4a_footer{flex-shrink:0;justify-content:space-between;align-items:center;gap:12px;margin-top:12px;padding:0 10px 0 18px;display:flex}.Mbwy4a_feedback{min-height:16px;color:var(--dsw-alias-state-error-primary);text-align:right;flex:1;font-size:11px;line-height:16px}@media (width<=720px){.Mbwy4a_card{border-radius:16px}.Mbwy4a_header{padding:10px 12px 0 18px}.Mbwy4a_options{padding:4px 8px}.Mbwy4a_title{font-size:15px;line-height:21px}.Mbwy4a_option,.Mbwy4a_customRow{padding:8px 6px}.Mbwy4a_footer{align-items:flex-end;padding:0 10px}.Mbwy4a_footerActions{flex-shrink:0}}@media (prefers-reduced-motion:reduce){.Mbwy4a_option,.Mbwy4a_customRow{transition:none}}";
|
|
234
234
|
const tagId = "@deepseek-ai/dsh-client-ui-user-questions/QuestionComposer.module.css";
|
|
235
235
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
236
236
|
const tag = document.createElement("style");
|
|
@@ -246,14 +246,17 @@ window.__ModuleLoader__.load({
|
|
|
246
246
|
"cardMinimized": "Mbwy4a_cardMinimized",
|
|
247
247
|
"checkbox": "Mbwy4a_checkbox",
|
|
248
248
|
"checkboxChecked": "Mbwy4a_checkboxChecked",
|
|
249
|
-
"
|
|
249
|
+
"customBlock": "Mbwy4a_customBlock",
|
|
250
|
+
"customInline": "Mbwy4a_customInline",
|
|
250
251
|
"customRow": "Mbwy4a_customRow",
|
|
251
252
|
"customRowActive": "Mbwy4a_customRowActive",
|
|
252
|
-
"customTextarea": "Mbwy4a_customTextarea",
|
|
253
253
|
"description": "Mbwy4a_description",
|
|
254
254
|
"detail": "Mbwy4a_detail",
|
|
255
255
|
"eyebrow": "Mbwy4a_eyebrow",
|
|
256
256
|
"feedback": "Mbwy4a_feedback",
|
|
257
|
+
"field": "Mbwy4a_field",
|
|
258
|
+
"fieldInput": "Mbwy4a_fieldInput",
|
|
259
|
+
"fieldMirror": "Mbwy4a_fieldMirror",
|
|
257
260
|
"footer": "Mbwy4a_footer",
|
|
258
261
|
"footerActions": "Mbwy4a_footerActions",
|
|
259
262
|
"frame": "Mbwy4a_frame",
|
|
@@ -294,6 +297,42 @@ window.__ModuleLoader__.load({
|
|
|
294
297
|
return event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229;
|
|
295
298
|
}
|
|
296
299
|
/**
|
|
300
|
+
* Auto-growing free-text answer: a textarea, so a long answer soft-wraps and
|
|
301
|
+
* Shift+Enter breaks a line, over a hidden mirror that owns the height.
|
|
302
|
+
*
|
|
303
|
+
* The mirror renders the draft plus a trailing newline in normal flow and so
|
|
304
|
+
* sizes the grid row (counting rows by '\n' cannot see soft wraps); the
|
|
305
|
+
* textarea shares that one cell and stretches to it, and `rows={1}` keeps the
|
|
306
|
+
* control's own intrinsic height out of the row sizing so the mirror alone
|
|
307
|
+
* decides. Past the mirror's cap the textarea scrolls itself — it is the only
|
|
308
|
+
* scrollport in the stack, there being no second glyph layer to keep aligned.
|
|
309
|
+
* Mirror and textarea MUST share font, line-height, padding and wrapping rules
|
|
310
|
+
* or the two heights diverge.
|
|
311
|
+
*
|
|
312
|
+
* @param props - field shape, draft text, and the field's event handlers.
|
|
313
|
+
* @returns The mirrored auto-growing field.
|
|
314
|
+
*/
|
|
315
|
+
function AnswerField(props) {
|
|
316
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
317
|
+
className: clsx(QuestionComposer_module_css_default.field, props.variant === "inline" ? QuestionComposer_module_css_default.customInline : QuestionComposer_module_css_default.customBlock),
|
|
318
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
319
|
+
"aria-hidden": true,
|
|
320
|
+
className: QuestionComposer_module_css_default.fieldMirror,
|
|
321
|
+
children: `${props.value}\n`
|
|
322
|
+
}), (0, react_jsx_runtime.jsx)("textarea", {
|
|
323
|
+
autoFocus: props.autoFocus,
|
|
324
|
+
className: QuestionComposer_module_css_default.fieldInput,
|
|
325
|
+
value: props.value,
|
|
326
|
+
disabled: props.disabled,
|
|
327
|
+
rows: 1,
|
|
328
|
+
placeholder: props.placeholder,
|
|
329
|
+
onFocus: props.onFocus,
|
|
330
|
+
onChange: props.onChange,
|
|
331
|
+
onKeyDown: props.onKeyDown
|
|
332
|
+
})]
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
297
336
|
* Composer takeover boundary; the carrier key keys local drafts, so a
|
|
298
337
|
* same-request replay (same key, new carrier object) preserves them.
|
|
299
338
|
*
|
|
@@ -538,21 +577,19 @@ window.__ModuleLoader__.load({
|
|
|
538
577
|
className: QuestionComposer_module_css_default.number,
|
|
539
578
|
"aria-hidden": "true",
|
|
540
579
|
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 12 })
|
|
541
|
-
}), (0, react_jsx_runtime.jsx)(
|
|
542
|
-
|
|
543
|
-
className: QuestionComposer_module_css_default.customInput,
|
|
580
|
+
}), (0, react_jsx_runtime.jsx)(AnswerField, {
|
|
581
|
+
variant: "inline",
|
|
544
582
|
value: draft.custom,
|
|
545
583
|
disabled: busy !== null,
|
|
546
584
|
placeholder: t("custom.placeholder"),
|
|
547
585
|
onChange: draftCustom,
|
|
548
586
|
onKeyDown: continueFromCustom
|
|
549
587
|
})]
|
|
550
|
-
}) : (0, react_jsx_runtime.jsx)(
|
|
588
|
+
}) : (0, react_jsx_runtime.jsx)(AnswerField, {
|
|
551
589
|
autoFocus: !focusedQuestions.current.has(index),
|
|
552
|
-
|
|
590
|
+
variant: "block",
|
|
553
591
|
value: draft.custom,
|
|
554
592
|
disabled: busy !== null,
|
|
555
|
-
rows: 2,
|
|
556
593
|
placeholder: t("custom.placeholder"),
|
|
557
594
|
onFocus: () => {
|
|
558
595
|
focusedQuestions.current.add(index);
|
|
@@ -1657,6 +1657,32 @@ window.__ModuleLoader__.load({
|
|
|
1657
1657
|
const groupExpansion = useStore((s) => s.groupExpansion);
|
|
1658
1658
|
const sessionOrderByAccount = useStore((s) => s.sessionOrderByAccount);
|
|
1659
1659
|
const sessionUpdatedAtByAccount = useStore((s) => s.sessionUpdatedAtByAccount);
|
|
1660
|
+
const currentBlankSessionId = useSessions((state) => {
|
|
1661
|
+
const current = state.current;
|
|
1662
|
+
return current !== void 0 && state.byId[current]?.blank === true ? current : void 0;
|
|
1663
|
+
});
|
|
1664
|
+
const currentBlankAccount = currentBlankSessionId === void 0 ? void 0 : workspaces.find((workspace) => workspace.sessionIds.includes(currentBlankSessionId))?.workspaceId ?? "";
|
|
1665
|
+
const promotedBlank = (0, react.useRef)(void 0);
|
|
1666
|
+
(0, react.useEffect)(() => {
|
|
1667
|
+
if (currentBlankSessionId === void 0 || currentBlankAccount === void 0) {
|
|
1668
|
+
promotedBlank.current = void 0;
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
if (promotedBlank.current?.sessionId === currentBlankSessionId && promotedBlank.current.accountKey === currentBlankAccount) return;
|
|
1672
|
+
promotedBlank.current = {
|
|
1673
|
+
sessionId: currentBlankSessionId,
|
|
1674
|
+
accountKey: currentBlankAccount
|
|
1675
|
+
};
|
|
1676
|
+
for (const accountKey of new Set([currentBlankAccount, FLAT_SESSION_ORDER_KEY])) {
|
|
1677
|
+
const previous = sessionOrderByAccount[accountKey] ?? [];
|
|
1678
|
+
actions.setSessionOrder(accountKey, [currentBlankSessionId, ...previous.filter((id) => id !== currentBlankSessionId)]);
|
|
1679
|
+
}
|
|
1680
|
+
}, [
|
|
1681
|
+
actions.setSessionOrder,
|
|
1682
|
+
currentBlankAccount,
|
|
1683
|
+
currentBlankSessionId,
|
|
1684
|
+
sessionOrderByAccount
|
|
1685
|
+
]);
|
|
1660
1686
|
(0, react.useEffect)(() => {
|
|
1661
1687
|
if (workspacePhase !== "ready") return;
|
|
1662
1688
|
actions.retainAccountKeys([
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-edge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-alpha.2",
|
|
4
4
|
"description": "Run DeepSeek Harness on Cloudflare Workers as an independent community project",
|
|
5
5
|
"author": "pawaca",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"dshEdge": {
|
|
44
|
-
"upstreamVersion": "0.1.
|
|
44
|
+
"upstreamVersion": "0.1.1-rc.1"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@clack/prompts": "1.7.0",
|
|
@@ -54,27 +54,30 @@
|
|
|
54
54
|
"@cloudflare/computer": "0.2.0",
|
|
55
55
|
"@cloudflare/workers-types": "5.20260812.1",
|
|
56
56
|
"@deepseek-ai/cordis": "4.0.1",
|
|
57
|
-
"@deepseek-ai/dsh-agent": "0.1.
|
|
58
|
-
"@deepseek-ai/dsh-agent-loop": "0.1.
|
|
59
|
-
"@deepseek-ai/dsh-anonymous-user-id": "0.1.
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
61
|
-
"@deepseek-ai/dsh-
|
|
62
|
-
"@deepseek-ai/dsh-
|
|
63
|
-
"@deepseek-ai/dsh-
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
65
|
-
"@deepseek-ai/dsh-llm
|
|
66
|
-
"@deepseek-ai/dsh-
|
|
67
|
-
"@deepseek-ai/dsh-session
|
|
68
|
-
"@deepseek-ai/dsh-session-
|
|
69
|
-
"@deepseek-ai/dsh-session-
|
|
70
|
-
"@deepseek-ai/dsh-
|
|
71
|
-
"@deepseek-ai/dsh-
|
|
72
|
-
"@deepseek-ai/dsh-
|
|
73
|
-
"@deepseek-ai/dsh-tool-
|
|
74
|
-
"@deepseek-ai/dsh-
|
|
75
|
-
"@deepseek-ai/dsh-
|
|
76
|
-
"@deepseek-ai/dsh-web
|
|
57
|
+
"@deepseek-ai/dsh-agent": "0.1.1-rc.1",
|
|
58
|
+
"@deepseek-ai/dsh-agent-loop": "0.1.1-rc.1",
|
|
59
|
+
"@deepseek-ai/dsh-anonymous-user-id": "0.1.1-rc.1",
|
|
60
|
+
"@deepseek-ai/dsh-attachment": "0.1.1-rc.1",
|
|
61
|
+
"@deepseek-ai/dsh-brand": "0.1.1-rc.1",
|
|
62
|
+
"@deepseek-ai/dsh-credentials": "0.1.1-rc.1",
|
|
63
|
+
"@deepseek-ai/dsh-host-apiproxy": "0.1.1-rc.1",
|
|
64
|
+
"@deepseek-ai/dsh-launch-environment": "0.1.1-rc.1",
|
|
65
|
+
"@deepseek-ai/dsh-llm": "0.1.1-rc.1",
|
|
66
|
+
"@deepseek-ai/dsh-llm-deepseek": "0.1.1-rc.1",
|
|
67
|
+
"@deepseek-ai/dsh-session": "0.1.1-rc.1",
|
|
68
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.1-rc.1",
|
|
69
|
+
"@deepseek-ai/dsh-session-query": "0.1.1-rc.1",
|
|
70
|
+
"@deepseek-ai/dsh-session-title": "0.1.1-rc.1",
|
|
71
|
+
"@deepseek-ai/dsh-settings": "0.1.1-rc.1",
|
|
72
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.1-rc.1",
|
|
73
|
+
"@deepseek-ai/dsh-tool-call-timeout-policy": "0.1.1-rc.1",
|
|
74
|
+
"@deepseek-ai/dsh-tool-web": "0.1.1-rc.1",
|
|
75
|
+
"@deepseek-ai/dsh-tools": "0.1.1-rc.1",
|
|
76
|
+
"@deepseek-ai/dsh-web": "0.1.1-rc.1",
|
|
77
|
+
"@deepseek-ai/dsh-web-search-deepseek": "0.1.1-rc.1",
|
|
77
78
|
"just-bash": "3.3.0",
|
|
79
|
+
"fast-png": "8.0.0",
|
|
80
|
+
"jpeg-js": "0.4.4",
|
|
78
81
|
"playwright": "^1.49.0",
|
|
79
82
|
"typescript": "^6.0.3",
|
|
80
83
|
"vitest": "^4.1.8",
|
package/scripts/cli.mjs
CHANGED
|
@@ -133,6 +133,58 @@ export function createInstallerUi(
|
|
|
133
133
|
],
|
|
134
134
|
})))
|
|
135
135
|
},
|
|
136
|
+
async selectInitialAttachmentStorage() {
|
|
137
|
+
note([
|
|
138
|
+
'This Worker predates image attachments, so no existing image references need migration.',
|
|
139
|
+
'The selected backend is pinned for future upgrades and is not changed automatically.',
|
|
140
|
+
].join('\n'), 'Choose image storage once')
|
|
141
|
+
return await requireAnswer(await clack.select(withOutput({
|
|
142
|
+
message: 'Where should this Worker store new images?',
|
|
143
|
+
initialValue: 'temporary-do',
|
|
144
|
+
signal,
|
|
145
|
+
options: [
|
|
146
|
+
{
|
|
147
|
+
value: 'temporary-do',
|
|
148
|
+
label: 'Durable Object — no R2 setup',
|
|
149
|
+
hint: 'recommended for Workers Free; 64 MiB per instance',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
value: 'private-r2',
|
|
153
|
+
label: 'Private R2 bucket',
|
|
154
|
+
hint: 'requires an enabled R2 subscription; includes a free tier',
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
})))
|
|
158
|
+
},
|
|
159
|
+
async r2SubscriptionUnavailable({ activationUrl, canSwitchToDurableObject }) {
|
|
160
|
+
note([
|
|
161
|
+
'Cloudflare requires R2 to be enabled before dsh-edge can create a private bucket.',
|
|
162
|
+
`Enable R2: ${activationUrl}`,
|
|
163
|
+
'R2 Standard includes monthly free usage, but activation requires Dashboard checkout.',
|
|
164
|
+
'After checkout completes, return here and retry.',
|
|
165
|
+
].join('\n'), 'R2 is not enabled for this account')
|
|
166
|
+
const options = [
|
|
167
|
+
...(canSwitchToDurableObject
|
|
168
|
+
? [{
|
|
169
|
+
value: 'temporary-do',
|
|
170
|
+
label: 'Use Durable Object storage',
|
|
171
|
+
hint: 'continue now without R2; 64 MiB per instance',
|
|
172
|
+
}]
|
|
173
|
+
: []),
|
|
174
|
+
{
|
|
175
|
+
value: 'retry',
|
|
176
|
+
label: 'Retry R2',
|
|
177
|
+
hint: 'choose this after enabling R2 in the Dashboard',
|
|
178
|
+
},
|
|
179
|
+
{ value: 'cancel', label: 'Cancel installation' },
|
|
180
|
+
]
|
|
181
|
+
return await requireAnswer(await clack.select(withOutput({
|
|
182
|
+
message: 'How should dsh-edge continue?',
|
|
183
|
+
initialValue: canSwitchToDurableObject ? 'temporary-do' : 'retry',
|
|
184
|
+
signal,
|
|
185
|
+
options,
|
|
186
|
+
})))
|
|
187
|
+
},
|
|
136
188
|
async selectOwnerSecretMode() {
|
|
137
189
|
return await requireAnswer(await clack.select(withOutput({
|
|
138
190
|
message: 'Set the owner access key',
|
|
@@ -166,7 +218,10 @@ export function createInstallerUi(
|
|
|
166
218
|
`Account: ${summary.accountLabel}`,
|
|
167
219
|
`Worker: ${summary.workerName}`,
|
|
168
220
|
`Cost: ${summary.paid ? 'Workers Paid is required' : 'Works on Workers Free'}`,
|
|
169
|
-
|
|
221
|
+
`Images: ${summary.attachmentStorage === 'temporary-do'
|
|
222
|
+
? 'stored in this instance (64 MiB limit)'
|
|
223
|
+
: 'stored privately in Cloudflare R2'}`,
|
|
224
|
+
...(command === 'upgrade' ? ['Existing Durable Object data is preserved.', 'You will re-enter the two Worker secrets after confirming.'] : []),
|
|
170
225
|
].join('\n'), command === 'upgrade' ? 'Upgrade summary' : 'Installation summary')
|
|
171
226
|
return await requireAnswer(await clack.confirm(withOutput({
|
|
172
227
|
message: command === 'upgrade' ? 'Upgrade this instance?' : 'Install this instance?',
|
package/scripts/install.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type RuntimeMode = 'direct' | 'isolated'
|
|
2
2
|
export type InstallerCommand = 'install' | 'upgrade'
|
|
3
|
+
export type AttachmentStorage = 'private-r2' | 'temporary-do'
|
|
3
4
|
|
|
4
5
|
export interface CloudflareAccount {
|
|
5
6
|
id: string
|
|
@@ -21,6 +22,11 @@ export interface InstallerUi {
|
|
|
21
22
|
selectAccount(choices: Array<{ value: string; label: string; hint?: string }>): Promise<string>
|
|
22
23
|
workerName(initialValue: string, validate: (value: string) => string | undefined): Promise<string>
|
|
23
24
|
workerConflict(workerName: string): Promise<'rename' | 'update' | 'cancel'>
|
|
25
|
+
selectInitialAttachmentStorage(): Promise<AttachmentStorage>
|
|
26
|
+
r2SubscriptionUnavailable(options: {
|
|
27
|
+
activationUrl: string
|
|
28
|
+
canSwitchToDurableObject: boolean
|
|
29
|
+
}): Promise<'retry' | 'temporary-do' | 'cancel'>
|
|
24
30
|
selectOwnerSecretMode(): Promise<'generate' | 'custom'>
|
|
25
31
|
ownerSecret(validate: (value: string) => string | undefined): Promise<string>
|
|
26
32
|
deepSeekKey(validate: (value: string) => string | undefined): Promise<string>
|
|
@@ -30,6 +36,8 @@ export interface InstallerUi {
|
|
|
30
36
|
accountLabel: string
|
|
31
37
|
workerName: string
|
|
32
38
|
paid: boolean
|
|
39
|
+
temporary: boolean
|
|
40
|
+
attachmentStorage: AttachmentStorage
|
|
33
41
|
}): Promise<boolean>
|
|
34
42
|
acceptTemporaryTerms(): Promise<boolean>
|
|
35
43
|
deploymentStart?(message: string): void
|
|
@@ -58,6 +66,7 @@ export interface InstallResult {
|
|
|
58
66
|
publicUrl: string
|
|
59
67
|
versionId?: string
|
|
60
68
|
account?: CloudflareAccount
|
|
69
|
+
attachmentStorage: AttachmentStorage
|
|
61
70
|
claimUrl?: string
|
|
62
71
|
mode: RuntimeMode
|
|
63
72
|
ownerSecret: string
|
|
@@ -86,6 +95,17 @@ export function validateWorkerName(value: string): string | undefined
|
|
|
86
95
|
export function validateOwnerSecret(value: string): string | undefined
|
|
87
96
|
export function validateDeepSeekKey(value: string): string | undefined
|
|
88
97
|
export function generateOwnerSecret(): string
|
|
98
|
+
export function attachmentBucketName(workerName: string): string
|
|
99
|
+
export function ensureR2Bucket(options: {
|
|
100
|
+
bucketName: string
|
|
101
|
+
runWrangler: (args: string[], options?: {
|
|
102
|
+
environment?: NodeJS.ProcessEnv
|
|
103
|
+
signal?: AbortSignal
|
|
104
|
+
}) => Promise<CommandResult>
|
|
105
|
+
environment?: NodeJS.ProcessEnv
|
|
106
|
+
profile?: string
|
|
107
|
+
signal?: AbortSignal
|
|
108
|
+
}): Promise<{ bucketName: string; created: boolean }>
|
|
89
109
|
export function wranglerEnvironment(environment?: NodeJS.ProcessEnv): NodeJS.ProcessEnv
|
|
90
110
|
export function unauthenticatedEnvironment(environment?: NodeJS.ProcessEnv): NodeJS.ProcessEnv
|
|
91
111
|
export function wranglerDeployArgs(options: {
|
|
@@ -99,6 +119,17 @@ export function wranglerDeployArgs(options: {
|
|
|
99
119
|
export function parseDeploymentOutput(source: string): { publicUrl: string; versionId?: string }
|
|
100
120
|
export function parseClaimUrl(source: string): string | undefined
|
|
101
121
|
export function parseWorkerExistence(result: CommandResult): boolean
|
|
122
|
+
export function detectExistingAttachmentStorage(options: {
|
|
123
|
+
workerName: string
|
|
124
|
+
mode: RuntimeMode
|
|
125
|
+
runWrangler: (args: string[], options?: {
|
|
126
|
+
environment?: NodeJS.ProcessEnv
|
|
127
|
+
signal?: AbortSignal
|
|
128
|
+
}) => Promise<CommandResult>
|
|
129
|
+
environment?: NodeJS.ProcessEnv
|
|
130
|
+
profile?: string
|
|
131
|
+
signal?: AbortSignal
|
|
132
|
+
}): Promise<AttachmentStorage | undefined>
|
|
102
133
|
export function truncateUtf8Tail(value: string, maxBytes: number): string
|
|
103
134
|
export function createOutputForwarder(
|
|
104
135
|
source: NodeJS.ReadableStream,
|