dsh-edge 0.10.0 → 0.11.0

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.
@@ -9,178 +9,8 @@ window.__ModuleLoader__.load({
9
9
  //#endregion
10
10
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
11
11
  let react = require("react");
12
- let react_jsx_runtime = require("react/jsx-runtime");
13
12
  let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
14
- //#region \0dsh-edge-css:src/client/EdgeDirectoryFlow.module.css.mjs
15
- const css$1 = "._f3UMG_overlay{z-index:999;position:fixed;inset:0}._f3UMG_popover{background:var(--dsh-surface-2,#252526);border:1px solid var(--dsh-border,#3e3e42);z-index:1000;border-radius:8px;flex-direction:column;gap:8px;padding:12px;display:flex;position:fixed;box-shadow:0 8px 24px #0006,0 2px 8px #0000004d}._f3UMG_title{color:var(--dsh-text-1,#ccc);font-size:12px;font-weight:600}._f3UMG_inputGroup{border:1px solid var(--dsh-border,#3e3e42);border-radius:6px;transition:border-color .15s;display:flex;overflow:hidden}._f3UMG_inputGroup:focus-within{border-color:var(--dsh-accent,#3b82f6)}._f3UMG_inputGroup._f3UMG_error{border-color:var(--dsh-error,#ef4444)}._f3UMG_prefix{background:var(--dsh-surface-1,#1a1a1a);color:var(--dsh-text-3,#6b6b6b);white-space:nowrap;font-size:12px;font-family:var(--dsh-font-mono,\"SF Mono\", \"Menlo\", monospace);user-select:none;border-right:1px solid var(--dsh-border,#3e3e42);align-items:center;padding:6px 2px 6px 8px;display:flex}._f3UMG_input{background:var(--dsh-surface-3,#2d2d2d);color:var(--dsh-text-1,#ccc);font-size:12px;font-family:var(--dsh-font-mono,\"SF Mono\", \"Menlo\", monospace);border:none;outline:none;flex:1;min-width:0;padding:6px 8px}._f3UMG_input::placeholder{color:var(--dsh-text-3,#6b6b6b)}._f3UMG_hint{color:var(--dsh-text-3,#6b6b6b);font-size:11px;line-height:1.4}._f3UMG_errorText{color:var(--dsh-error,#ef4444);font-size:11px;line-height:1.4}._f3UMG_submitBtn{background:var(--dsh-accent,#3b82f6);color:#fff;cursor:pointer;border:none;border-radius:6px;width:100%;padding:6px 0;font-size:12px;font-weight:500;transition:opacity .15s}._f3UMG_submitBtn:hover{opacity:.9}._f3UMG_submitBtn:disabled{opacity:.4;cursor:not-allowed}";
16
- const tagId$1 = "dsh-edge-client-ui/src/client/EdgeDirectoryFlow.module.css";
17
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
18
- const tag = document.createElement("style");
19
- tag.dataset.plugin = "dsh-edge-client-ui";
20
- tag.dataset.pluginCss = tagId$1;
21
- tag.textContent = css$1;
22
- document.head.appendChild(tag);
23
- }
24
- var EdgeDirectoryFlow_module_css_default = {
25
- "error": "_f3UMG_error",
26
- "errorText": "_f3UMG_errorText",
27
- "hint": "_f3UMG_hint",
28
- "input": "_f3UMG_input",
29
- "inputGroup": "_f3UMG_inputGroup",
30
- "overlay": "_f3UMG_overlay",
31
- "popover": "_f3UMG_popover",
32
- "prefix": "_f3UMG_prefix",
33
- "submitBtn": "_f3UMG_submitBtn",
34
- "title": "_f3UMG_title"
35
- };
36
- //#endregion
37
- //#region ../../../packages/client/ui-edge/src/client/EdgeDirectoryFlow.tsx
38
- const WORKSPACE_PREFIX = "/workspace/";
39
- const POPOVER_WIDTH = 260;
40
- const VIEWPORT_MARGIN = 8;
41
- function validate$1(name, t) {
42
- if (name.length === 0) return null;
43
- if (name.includes("/")) return t("workspaceNewErrorSlash");
44
- if (name === "." || name === "..") return t("workspaceNewErrorTraversal");
45
- if (name.includes("\0")) return t("workspaceNewErrorChars");
46
- return "";
47
- }
48
- function findAnchorButton(slotEl) {
49
- let node = slotEl?.parentElement ?? null;
50
- while (node !== null) {
51
- const btn = node.querySelector("button[aria-label]");
52
- if (btn !== null) return btn;
53
- node = node.parentElement;
54
- }
55
- return null;
56
- }
57
- function computeAnchor(btn, popover) {
58
- if (btn === null) return {
59
- top: 60,
60
- left: 12
61
- };
62
- const rect = btn.getBoundingClientRect();
63
- const left = Math.min(rect.left, window.innerWidth - POPOVER_WIDTH - VIEWPORT_MARGIN);
64
- const panelHeight = popover?.offsetHeight ?? 160;
65
- const belowTop = rect.bottom + 6;
66
- const aboveTop = rect.top - panelHeight - 6;
67
- return {
68
- top: belowTop + panelHeight + VIEWPORT_MARGIN <= window.innerHeight ? belowTop : Math.max(VIEWPORT_MARGIN, aboveTop),
69
- left: Math.max(VIEWPORT_MARGIN, left)
70
- };
71
- }
72
- function EdgeDirectoryFlow(props) {
73
- const { open, busy, onPicked, onCancel, t } = props;
74
- const [name, setName] = (0, react.useState)("");
75
- const [anchor, setAnchor] = (0, react.useState)(null);
76
- const inputRef = (0, react.useRef)(null);
77
- const popoverRef = (0, react.useRef)(null);
78
- const slotRef = (0, react.useRef)(null);
79
- const btnRef = (0, react.useRef)(null);
80
- (0, react.useEffect)(() => {
81
- if (!open) {
82
- setAnchor(null);
83
- btnRef.current = null;
84
- return;
85
- }
86
- setName("");
87
- btnRef.current = findAnchorButton(slotRef.current);
88
- setAnchor(computeAnchor(btnRef.current, popoverRef.current));
89
- requestAnimationFrame(() => inputRef.current?.focus());
90
- const recompute = () => setAnchor(computeAnchor(btnRef.current, popoverRef.current));
91
- window.addEventListener("resize", recompute);
92
- window.addEventListener("scroll", recompute, true);
93
- return () => {
94
- window.removeEventListener("resize", recompute);
95
- window.removeEventListener("scroll", recompute, true);
96
- };
97
- }, [open]);
98
- (0, react.useLayoutEffect)(() => {
99
- if (!open || popoverRef.current === null) return;
100
- const next = computeAnchor(btnRef.current, popoverRef.current);
101
- setAnchor((prev) => prev !== null && prev.top === next.top && prev.left === next.left ? prev : next);
102
- });
103
- (0, react.useEffect)(() => {
104
- if (!open) return;
105
- const handleClickOutside = (e) => {
106
- if (popoverRef.current && !popoverRef.current.contains(e.target)) onCancel();
107
- };
108
- const handleEscape = (e) => {
109
- if (e.key === "Escape") {
110
- e.stopPropagation();
111
- onCancel();
112
- }
113
- };
114
- document.addEventListener("mousedown", handleClickOutside, true);
115
- document.addEventListener("keydown", handleEscape, true);
116
- return () => {
117
- document.removeEventListener("mousedown", handleClickOutside, true);
118
- document.removeEventListener("keydown", handleEscape, true);
119
- };
120
- }, [open, onCancel]);
121
- const handleKeyDown = (0, react.useCallback)((e) => {
122
- if (e.key === "Enter") {
123
- if (validate$1(name, t) === "") onPicked(WORKSPACE_PREFIX + name);
124
- }
125
- }, [
126
- name,
127
- onPicked,
128
- t
129
- ]);
130
- if (!open || anchor === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { ref: slotRef });
131
- const validation = validate$1(name, t);
132
- const isValid = validation === "";
133
- const isError = validation !== null && validation !== "";
134
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { ref: slotRef }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
135
- ref: popoverRef,
136
- className: EdgeDirectoryFlow_module_css_default.popover,
137
- style: {
138
- top: anchor.top,
139
- left: anchor.left,
140
- width: POPOVER_WIDTH
141
- },
142
- children: [
143
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
144
- className: EdgeDirectoryFlow_module_css_default.title,
145
- children: t("workspaceNewTitle")
146
- }),
147
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
148
- className: `${EdgeDirectoryFlow_module_css_default.inputGroup}${isError ? ` ${EdgeDirectoryFlow_module_css_default.error}` : ""}`,
149
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
150
- className: EdgeDirectoryFlow_module_css_default.prefix,
151
- children: WORKSPACE_PREFIX
152
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
153
- ref: inputRef,
154
- className: EdgeDirectoryFlow_module_css_default.input,
155
- type: "text",
156
- placeholder: t("workspaceNewPlaceholder"),
157
- value: name,
158
- onChange: (e) => setName(e.target.value),
159
- onKeyDown: handleKeyDown,
160
- disabled: busy
161
- })]
162
- }),
163
- isError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
164
- className: EdgeDirectoryFlow_module_css_default.errorText,
165
- children: validation
166
- }),
167
- !isError && !isValid && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
168
- className: EdgeDirectoryFlow_module_css_default.hint,
169
- children: t("workspaceNewHint")
170
- }),
171
- isValid && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
172
- className: EdgeDirectoryFlow_module_css_default.hint,
173
- children: [WORKSPACE_PREFIX, name]
174
- }),
175
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
176
- className: EdgeDirectoryFlow_module_css_default.submitBtn,
177
- disabled: !isValid || busy,
178
- onClick: () => onPicked(WORKSPACE_PREFIX + name),
179
- children: busy ? t("workspaceNewCreating") : t("workspaceNewCreate")
180
- })
181
- ]
182
- })] });
183
- }
13
+ let react_jsx_runtime = require("react/jsx-runtime");
184
14
  //#endregion
185
15
  //#region ../../../packages/client/ui-edge/src/client/store.ts
186
16
  var import_umd = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -656,15 +486,7 @@ window.__ModuleLoader__.load({
656
486
  ownerIntro: "Signing out clears this browser’s owner session. Your deployment and data remain unchanged.",
657
487
  signOut: "Sign out",
658
488
  signingOut: "Signing out…",
659
- signOutFailed: "Could not sign out. Try again.",
660
- workspaceNewTitle: "New Workspace",
661
- workspaceNewPlaceholder: "project-name",
662
- workspaceNewHint: "Enter a project directory name",
663
- workspaceNewCreate: "Create",
664
- workspaceNewCreating: "Creating…",
665
- workspaceNewErrorSlash: "Name cannot contain /",
666
- workspaceNewErrorTraversal: "Invalid directory name",
667
- workspaceNewErrorChars: "Invalid characters"
489
+ signOutFailed: "Could not sign out. Try again."
668
490
  };
669
491
  /** Simplified Chinese copy for the Edge settings page. */
670
492
  const zh = {
@@ -698,15 +520,7 @@ window.__ModuleLoader__.load({
698
520
  ownerIntro: "退出只会清除此浏览器的 Owner 会话,不会改变部署或数据。",
699
521
  signOut: "退出登录",
700
522
  signingOut: "正在退出…",
701
- signOutFailed: "退出失败,请重试。",
702
- workspaceNewTitle: "新建工作空间",
703
- workspaceNewPlaceholder: "项目名称",
704
- workspaceNewHint: "输入项目目录名称",
705
- workspaceNewCreate: "创建",
706
- workspaceNewCreating: "创建中…",
707
- workspaceNewErrorSlash: "名称不能包含 /",
708
- workspaceNewErrorTraversal: "无效的目录名称",
709
- workspaceNewErrorChars: "包含无效字符"
523
+ signOutFailed: "退出失败,请重试。"
710
524
  };
711
525
  //#endregion
712
526
  //#region ../../../packages/client/ui-edge/src/client/index.ts
@@ -749,39 +563,64 @@ window.__ModuleLoader__.load({
749
563
  locale: "settings.edge",
750
564
  inject: injected
751
565
  }, EdgeSettingsSection));
752
- slots.inject("conversation.hero.workspace.directoryFlow", () => slots.inject("sidebar.workspaces.directoryFlow", function* () {
753
- yield slots.register({
754
- name: "conversation.hero.workspace.directoryFlow",
755
- locale: "settings.edge"
756
- }, EdgeDirectoryFlow);
757
- yield slots.register({
758
- name: "sidebar.workspaces.directoryFlow",
759
- locale: "settings.edge"
760
- }, EdgeDirectoryFlow);
761
- }));
762
- ctx.inject(["workspaces"], () => {
763
- const workspaces = ctx.workspaces;
764
- const originalOpenPath = workspaces.openPath.bind(workspaces);
765
- workspaces.openPath = async (path) => {
766
- try {
767
- await originalOpenPath(path);
768
- } catch {
769
- const url = `/api/workspace/file?path=${encodeURIComponent(path)}`;
770
- const res = await globalThis.fetch(url);
771
- if (!res.ok) throw new Error(`path open failed: ${res.status === 413 ? "file too large" : await res.text()}`);
772
- const blob = await res.blob();
773
- const blobUrl = URL.createObjectURL(blob);
774
- const a = document.createElement("a");
775
- a.href = blobUrl;
776
- a.download = path.split("/").pop() ?? "file";
777
- a.click();
778
- URL.revokeObjectURL(blobUrl);
779
- }
780
- };
566
+ ctx.inject(["remote.session"], (scope) => {
567
+ scope.effect(() => {
568
+ const session = scope.get("remote.session");
569
+ const descriptor = session === void 0 ? void 0 : Object.getOwnPropertyDescriptor(session, "openWorkspacePath");
570
+ const upstream = descriptor?.get?.bind(session);
571
+ if (session === void 0 || descriptor === void 0 || upstream === void 0) return () => {};
572
+ Object.defineProperty(session, "openWorkspacePath", {
573
+ configurable: true,
574
+ enumerable: true,
575
+ get: () => async (request) => {
576
+ const result = await upstream()(request);
577
+ if (result.ok || result.error.code === "gateway/bad-request") return result;
578
+ return await downloadWorkspaceFile(request.path);
579
+ }
580
+ });
581
+ return () => {
582
+ Object.defineProperty(session, "openWorkspacePath", descriptor);
583
+ };
584
+ }, "ui-edge: workspace file download fallback");
781
585
  });
782
586
  }
587
+ /** Fetch one workspace file through the Edge route and hand it to the browser as a download. */
588
+ async function downloadWorkspaceFile(path) {
589
+ if (path === "." || path.endsWith("/.") || path.endsWith("/")) return {
590
+ ok: false,
591
+ error: {
592
+ code: "gateway/internal",
593
+ message: "Folders cannot be downloaded from the Edge workspace; open a file instead."
594
+ }
595
+ };
596
+ const res = await globalThis.fetch(`/api/workspace/file?path=${encodeURIComponent(path)}`, { credentials: "same-origin" });
597
+ if (!res.ok) return {
598
+ ok: false,
599
+ error: {
600
+ code: "gateway/internal",
601
+ message: res.status === 413 ? "file too large" : await res.text()
602
+ }
603
+ };
604
+ const blob = await res.blob();
605
+ const blobUrl = URL.createObjectURL(blob);
606
+ const anchor = document.createElement("a");
607
+ anchor.href = blobUrl;
608
+ anchor.download = path.split("/").pop() ?? "file";
609
+ try {
610
+ anchor.click();
611
+ } finally {
612
+ setTimeout(() => {
613
+ URL.revokeObjectURL(blobUrl);
614
+ }, 0);
615
+ }
616
+ return {
617
+ ok: true,
618
+ value: { opened: true }
619
+ };
620
+ }
783
621
  //#endregion
784
622
  exports.apply = apply;
623
+ exports.downloadWorkspaceFile = downloadWorkspaceFile;
785
624
  exports.inject = inject;
786
625
  return module.exports;
787
626
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-edge",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Your DeepSeek Harness, anywhere — deploy a persistent personal coding agent to Cloudflare Workers in one command",
5
5
  "author": "pawaca",
6
6
  "license": "MIT",
@@ -61,6 +61,7 @@
61
61
  "@deepseek-ai/dsh-agent-loop": "0.1.2-rc.1",
62
62
  "@deepseek-ai/dsh-anonymous-user-id": "0.1.2-rc.1",
63
63
  "@deepseek-ai/dsh-api-gateway": "0.1.2-rc.1",
64
+ "@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1",
64
65
  "@deepseek-ai/dsh-api-session-controller": "0.1.2-rc.1",
65
66
  "@deepseek-ai/dsh-api-settings-controller": "0.1.2-rc.1",
66
67
  "@deepseek-ai/dsh-api-workspace-controller": "0.1.2-rc.1",
@@ -72,20 +73,26 @@
72
73
  "@deepseek-ai/dsh-compaction-basic": "0.1.2-rc.1",
73
74
  "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.2-rc.1",
74
75
  "@deepseek-ai/dsh-credentials": "0.1.2-rc.1",
76
+ "@deepseek-ai/dsh-file-reference": "0.1.2-rc.1",
75
77
  "@deepseek-ai/dsh-fs": "0.1.2-rc.1",
76
78
  "@deepseek-ai/dsh-goal": "0.1.2-rc.1",
77
79
  "@deepseek-ai/dsh-goal-round-driver": "0.1.2-rc.1",
80
+ "@deepseek-ai/dsh-host-directory-picker": "0.1.2-rc.1",
81
+ "@deepseek-ai/dsh-host-plugin-inventory": "0.1.2-rc.1",
78
82
  "@deepseek-ai/dsh-launch-environment": "0.1.2-rc.1",
79
83
  "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
80
84
  "@deepseek-ai/dsh-llm-deepseek": "0.1.2-rc.1",
81
85
  "@deepseek-ai/dsh-message-feedback": "0.1.2-rc.1",
82
86
  "@deepseek-ai/dsh-output-retention": "0.1.2-rc.1",
87
+ "@deepseek-ai/dsh-plan-mode": "0.1.2-rc.1",
83
88
  "@deepseek-ai/dsh-sandbox": "0.1.2-rc.1",
89
+ "@deepseek-ai/dsh-scope": "0.1.2-rc.1",
84
90
  "@deepseek-ai/dsh-session": "0.1.2-rc.1",
85
91
  "@deepseek-ai/dsh-session-persistence": "0.1.2-rc.1",
86
92
  "@deepseek-ai/dsh-session-projection": "0.1.2-rc.1",
87
93
  "@deepseek-ai/dsh-session-projection-cache": "0.1.2-rc.1",
88
94
  "@deepseek-ai/dsh-session-query": "0.1.2-rc.1",
95
+ "@deepseek-ai/dsh-session-reference": "0.1.2-rc.1",
89
96
  "@deepseek-ai/dsh-session-title": "0.1.2-rc.1",
90
97
  "@deepseek-ai/dsh-session-title-first-prompt-llm": "0.1.2-rc.1",
91
98
  "@deepseek-ai/dsh-session-title-llm": "0.1.2-rc.1",
@@ -98,6 +105,7 @@
98
105
  "@deepseek-ai/dsh-system-prompt": "0.1.2-rc.1",
99
106
  "@deepseek-ai/dsh-timeout": "0.1.2-rc.1",
100
107
  "@deepseek-ai/dsh-token-meter": "0.1.2-rc.1",
108
+ "@deepseek-ai/dsh-tool-ask-user": "0.1.2-rc.1",
101
109
  "@deepseek-ai/dsh-tool-call-timeout-policy": "0.1.2-rc.1",
102
110
  "@deepseek-ai/dsh-tool-fs": "0.1.2-rc.1",
103
111
  "@deepseek-ai/dsh-tool-goal": "0.1.2-rc.1",
@@ -106,6 +114,7 @@
106
114
  "@deepseek-ai/dsh-tools": "0.1.2-rc.1",
107
115
  "@deepseek-ai/dsh-typert-protocol": "0.1.2-rc.1",
108
116
  "@deepseek-ai/dsh-typert-registry": "0.1.2-rc.1",
117
+ "@deepseek-ai/dsh-user-questions": "0.1.2-rc.1",
109
118
  "@deepseek-ai/dsh-util-values": "0.1.2-rc.1",
110
119
  "@deepseek-ai/dsh-web": "0.1.2-rc.1",
111
120
  "@deepseek-ai/dsh-web-fetch-http": "0.1.2-rc.1",