dsh-cloud 0.2.1__tar.gz → 0.2.3__tar.gz

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.
Files changed (24) hide show
  1. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/PKG-INFO +1 -1
  2. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/pyproject.toml +1 -1
  3. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/cli.py +12 -3
  4. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/release-manifest.json +3 -3
  5. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/i18n/en.json +3 -4
  6. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/i18n/zh.json +3 -4
  7. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/wizard.py +37 -3
  8. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/LICENSE +0 -0
  9. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/README.md +0 -0
  10. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/build_backend.py +0 -0
  11. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/__init__.py +0 -0
  12. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/__main__.py +0 -0
  13. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/Caddyfile +0 -0
  14. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/compose.build.yml +0 -0
  15. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/compose.postgres.yml +0 -0
  16. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/models.curated.txt +0 -0
  17. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/models.json +0 -0
  18. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/pricing.cny.json +0 -0
  19. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/pricing.eur.json +0 -0
  20. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/pricing.gbp.json +0 -0
  21. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/pricing.hkd.json +0 -0
  22. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/pricing.jpy.json +0 -0
  23. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/config/pricing.usd.json +0 -0
  24. {dsh_cloud-0.2.1 → dsh_cloud-0.2.3}/src/dsh_cloud_cli/templates/docker-compose.yml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dsh-cloud
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: Safe self-host installer and lifecycle CLI for DSH Cloud Community Edition
5
5
  Requires-Python: >=3.11
6
6
  License-Expression: LicenseRef-DSH-Cloud-Community-1.0
@@ -5,7 +5,7 @@ backend-path = ["."]
5
5
 
6
6
  [project]
7
7
  name = "dsh-cloud"
8
- version = "0.2.1"
8
+ version = "0.2.3"
9
9
  description = "Safe self-host installer and lifecycle CLI for DSH Cloud Community Edition"
10
10
  requires-python = ">=3.11"
11
11
  dependencies = []
@@ -10,7 +10,8 @@ import shutil
10
10
  import subprocess
11
11
  import sys
12
12
 
13
- from .wizard import apply_answers, command_prefix, next_steps, prompt_answers, should_run_wizard
13
+ from .wizard import (apply_answers, command_prefix, init_summary, next_steps,
14
+ prompt_answers, should_run_wizard)
14
15
  from pathlib import Path
15
16
 
16
17
 
@@ -334,7 +335,15 @@ def execute(parsed: dict) -> dict:
334
335
  if parsed["options"].get("dryRun"):
335
336
  return {"json": value}
336
337
  initialize(parsed, manifest, value, answers)
337
- return {"json": {**value, "initialized": True}}
338
+ # 人在终端前看的是"写到哪了、下一步敲什么"; 脚本要的才是那坨 JSON。
339
+ if parsed["options"].get("json") or not sys.stdout.isatty():
340
+ return {"json": {**value, "initialized": True}}
341
+ return {"text": init_summary(
342
+ directory=value["directory"],
343
+ prefix=command_prefix(resolved=shutil.which("dsh-cloud") or "", entry=sys.argv[0]),
344
+ mode=value["mode"],
345
+ work_domain=(f"work.{parsed['options'].get('domain')}"
346
+ if value["mode"] == "selfhost" else ""))}
338
347
  if parsed["command"] == "start" and fresh_init and not parsed["options"].get("dryRun"):
339
348
  initialize(parsed, manifest, value, answers)
340
349
  if state.is_file():
@@ -376,7 +385,7 @@ def execute(parsed: dict) -> dict:
376
385
  return {"text": value["url"] + "\n"}
377
386
  env_text = (Path(value["directory"]) / ".env").read_text(encoding="utf-8")
378
387
  has_key = bool(re.search(r"^UPSTREAM_API_KEY=.+$", env_text, re.MULTILINE))
379
- prefix = command_prefix(on_path=bool(shutil.which("dsh-cloud")), entry=sys.argv[0])
388
+ prefix = command_prefix(resolved=shutil.which("dsh-cloud") or "", entry=sys.argv[0])
380
389
  return {"text": next_steps(url=value["url"], directory=value["directory"],
381
390
  has_upstream_key=has_key, project_name=value["projectName"],
382
391
  prefix=prefix,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "license": "LicenseRef-DSH-Cloud-Community-1.0",
5
5
  "stackSchema": 1,
6
6
  "databaseSchema": 1,
@@ -8,8 +8,8 @@
8
8
  "minUpgradeFrom": "0.1.0",
9
9
  "harnessRuntime": "0.1.0-rc.8",
10
10
  "images": {
11
- "server": "ghcr.io/agentsdanceai/dsh-cloud-server:0.2.1",
12
- "workspace": "ghcr.io/agentsdanceai/dsh-cloud-workspace:0.2.1"
11
+ "server": "ghcr.io/agentsdanceai/dsh-cloud-server:0.2.3",
12
+ "workspace": "ghcr.io/agentsdanceai/dsh-cloud-workspace:0.2.3"
13
13
  },
14
14
  "baseImages": {
15
15
  "python": "python:3.11-slim-bookworm@sha256:2e32f7d302adc1c37428355c1e646897c0c53f4fd60b6a551245fb90ee129f91",
@@ -132,10 +132,9 @@
132
132
  "download.android_meta": "Android 8+ · direct APK install (you need to allow apps from unknown sources)",
133
133
  "download.android_qr": "Or scan with your phone to install directly",
134
134
  "download.android_qr_alt": "QR code for the Android download",
135
+ "download.get_from_hosted": "Download from the official site",
135
136
  "download.h1": "Download the deepseek-harness-cloud desktop app",
136
137
  "download.help": "Trouble installing? Contact",
137
- "download.hosted_cta": "Or use the official hosted DSH Cloud (desktop builds and the cloud workspace included)",
138
- "download.hosted_link": "Go to dshcloud.online →",
139
138
  "download.ios_meta": "No install needed: open the cloud workspace in Safari, then Share → Add to Home Screen to use it like an app",
140
139
  "download.mac_arm64": "Download .dmg (Apple silicon)",
141
140
  "download.mac_meta": "Apple silicon (M series) and Intel · macOS 12+",
@@ -146,8 +145,7 @@
146
145
  "download.rebuild_notice_b": " — it has the same features and works on a phone.",
147
146
  "download.rebuild_notice_link": "browser-based cloud workspace",
148
147
  "download.rebuilding": "Rebuilding",
149
- "download.selfhost_howto": "Enabling the workspace needs its own hostname and the docker socket proxy (see the deployment guide); desktop builds can be produced from source.",
150
- "download.selfhost_notice": "This deployment has no desktop installer URLs configured, and the cloud workspace is off — both are things an operator turns on.",
148
+ "download.selfhost_notice": "This deployment ships no desktop installers; the buttons below point at the official site, dshcloud.online.",
151
149
  "download.sub": "Install it, sign in from inside the app, authorise the device in your browser, and you are ready to work.",
152
150
  "download.tip_mac_a": ": if the first launch says the developer cannot be verified, use ",
153
151
  "download.tip_mac_action": "Right-click → Open",
@@ -159,6 +157,7 @@
159
157
  "download.tip_win_end": ".",
160
158
  "download.tips_summary": "Security warnings on first launch (the current builds are unsigned)",
161
159
  "download.title": "Download — deepseek-harness-cloud",
160
+ "download.try_hosted_work": "Try the cloud workspace",
162
161
  "download.win_arm64_suffix": "and ARM64",
163
162
  "download.win_exe_arm64": "Download .exe (ARM64)",
164
163
  "download.win_exe_x64": "Download .exe (x64)",
@@ -132,10 +132,9 @@
132
132
  "download.android_meta": "Android 8+ · APK 直装(需允许安装未知来源应用)",
133
133
  "download.android_qr": "或用手机扫码直接安装",
134
134
  "download.android_qr_alt": "Android 安装包下载二维码",
135
+ "download.get_from_hosted": "从官方站点下载",
135
136
  "download.h1": "下载 deepseek-harness-cloud 桌面应用",
136
137
  "download.help": "安装遇到问题?联系",
137
- "download.hosted_cta": "或直接用官方托管版 DSH Cloud(含桌面端下载与云工作台)",
138
- "download.hosted_link": "前往 dshcloud.online →",
139
138
  "download.ios_meta": "无需安装:Safari 打开云工作台,「分享」→「添加到主屏幕」即可当 App 使用",
140
139
  "download.mac_arm64": "下载 .dmg(Apple 芯片)",
141
140
  "download.mac_meta": "Apple Silicon(M 系列)与 Intel · macOS 12+",
@@ -146,8 +145,7 @@
146
145
  "download.rebuild_notice_b": ",功能一致,手机也能用。",
147
146
  "download.rebuild_notice_link": "浏览器版云工作台",
148
147
  "download.rebuilding": "重新构建中",
149
- "download.selfhost_howto": "启用云工作台需要一个独立域名与 docker socket 代理,见部署文档;桌面端可从源码自行构建。",
150
- "download.selfhost_notice": "本部署没有配置桌面安装包下载地址,云工作台也未启用——这两项都属于运营方自行配置的部分。",
148
+ "download.selfhost_notice": "本部署未配置桌面安装包,下面的按钮指向官方站点 dshcloud.online。",
151
149
  "download.sub": "安装后在应用内登录,浏览器授权设备,即可开始使用。",
152
150
  "download.tip_mac_a": ":首次打开若提示\"无法验证开发者\",请在应用图标上",
153
151
  "download.tip_mac_action": "右键 → 打开",
@@ -159,6 +157,7 @@
159
157
  "download.tip_win_end": "。",
160
158
  "download.tips_summary": "首次打开的安全提示(当前安装包未签名)",
161
159
  "download.title": "下载 — deepseek-harness-cloud",
160
+ "download.try_hosted_work": "云端体验",
162
161
  "download.win_arm64_suffix": "与 ARM64",
163
162
  "download.win_exe_arm64": "下载 .exe(ARM64)",
164
163
  "download.win_exe_x64": "下载 .exe(x64)",
@@ -19,16 +19,22 @@ DEEPSEEK_BASE = "https://api.deepseek.com/v1"
19
19
  REPOSITORY = "https://github.com/AgentsDanceAI/deepseek-harness-cloud"
20
20
 
21
21
 
22
- def command_prefix(*, on_path: bool, entry: str = "") -> str:
22
+ def command_prefix(*, resolved: str = "", entry: str = "") -> str:
23
23
  """怎么拼出"再跑我一次" —— 按这个进程实际是怎么被启动的来。
24
24
 
25
25
  直接印 `dsh-cloud …` 对绝大多数人都是错的: uvx 用完什么都不留在 PATH 上,
26
26
  从源码跑更不会。所以按事实推断 (名字真在 PATH 上吗 / argv 长什么样), 而不是
27
27
  假设大家都 `uv tool install` 过。纯函数, 两个事实由调用方给, 便于测试。
28
28
  """
29
- if on_path:
29
+ # uvx 在**运行期间**把自己的 bin 挂上 PATH, 进程一退就没了 —— 落在 uv 缓存里
30
+ # 的那份不算"装过"。Node 侧 2026-08-26 实测被这个坑到: 面板印了裸 dsh-cloud,
31
+ # 照着敲得到 command not found。
32
+ def _ephemeral(path: str) -> bool:
33
+ return "/uv/" in path or "\\uv\\" in path or "uvx" in path
34
+
35
+ if resolved and not _ephemeral(resolved):
30
36
  return "dsh-cloud"
31
- if "/uv/" in entry or "\\uv\\" in entry or "uvx" in entry:
37
+ if _ephemeral(resolved) or _ephemeral(entry):
32
38
  return "uvx dsh-cloud"
33
39
  return f"{sys.executable} -m dsh_cloud_cli"
34
40
 
@@ -119,6 +125,34 @@ def next_steps(*, url: str, directory: str, has_upstream_key: bool,
119
125
  return "\n".join(lines)
120
126
 
121
127
 
128
+ def init_summary(*, directory: str, prefix: str = "dsh-cloud", mode: str = "trial",
129
+ work_domain: str = "") -> str:
130
+ """``init`` 的收尾摘要。
131
+
132
+ init 只写配置、不起容器, 所以不能用 next_steps (那张面板说的是"已就绪")。
133
+ 它原本无论如何都吐一整坨 JSON —— 那是给脚本解析的, 而人在终端前只想知道
134
+ "写到哪了、下一步敲什么"。带 --json 或非 TTY 时仍然只吐 JSON。
135
+ """
136
+ lines = [
137
+ "",
138
+ " 配置已写入,容器还没起",
139
+ "",
140
+ f" 目录 {directory}",
141
+ f" 启动 {prefix} up --dir {directory}",
142
+ "",
143
+ ]
144
+ if mode == "selfhost":
145
+ lines += [
146
+ " 这是对外服务的配置:绑 0.0.0.0、占用 80/443、申请真证书,",
147
+ " 请在目标服务器上启动,而不是本机。",
148
+ "",
149
+ ]
150
+ if work_domain:
151
+ lines += [f" 别忘了给 {work_domain} 加一条指向该服务器的 DNS 记录(云工作台按域名路由)", ""]
152
+ lines += [f" 启动前可以先过一遍 {directory}/.env", ""]
153
+ return "\n".join(lines)
154
+
155
+
122
156
  def _ask(prompt: str) -> str:
123
157
  """Read one line; EOF (Ctrl-D, or `start < /dev/null`) means "take the default"."""
124
158
  try:
File without changes
File without changes
File without changes