@shundoo-ai/dsh-cosmic 1.0.3-alpha.0 → 1.0.4-alpha.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shundoo-ai/dsh-cosmic",
3
- "version": "1.0.3-alpha.0",
3
+ "version": "1.0.4-alpha.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  ".config",
@@ -10,7 +10,7 @@ description: >
10
10
  | 职责 | 内容 | 载体 |
11
11
  |------|------|------|
12
12
  | ① 开启热部署 | 开 `jar_deploy_enable` 开关、连 IDEA MCP、生成 `dev.json` | `scripts/dev.py` + `assets/dev.json` |
13
- | ② 热加载 | 不重启、不碰 mc,把 jar 注入运行中 cosmic | `assets/kd-reloadjar-agent.jar` |
13
+ | ② 热加载 | 不重启、不碰 mc,把 jar 注入运行中 cosmic | `assets/kd-reloadjar-agent.jar`(**需先复制到机器级缓存再用**,见职责②§3) |
14
14
  | ③ build + 热部署 | 构建 jar(MCP 定位编译错误)→ 热加载 | IDEA MCP / gradle + agent |
15
15
 
16
16
  ## 触发场景
@@ -128,9 +128,23 @@ pwsh -File {SKILL_DIR}\scripts\cosmic-hotdeploy.ps1 -Module <模块名> -WhatIf
128
128
 
129
129
  ### 3. 热部署
130
130
 
131
+ > ⚠️ **别直接用 preset 里的 `{SKILL_DIR}/assets/kd-reloadjar-agent.jar`** —— 先把 agent jar 复制到**机器级缓存**再用(`{AGENT}`,见下)。原因:Attacher 会把这个 jar **载入运行中的 cosmic JVM**,而 JVM 的 classloader 会**长期持有**该文件句柄;preset 一旦升级,包管理器要**整目录替换**(每个文件都得能删/改名)→ 必然在这个 jar 上失败(Windows 报 `os error 32`/拒绝访问)。
132
+ >
133
+ > `{AGENT}` = `$DSH_HOME/cache/cosmic/agent/kd-reloadjar-agent-<sha1前8位>.jar`(**带内容哈希命名**,所以新版永远不会覆盖可能已被 JVM 载入的旧副本)。`init-python.{sh,ps1}` 会预先复制;`cosmic-hotdeploy.ps1` 也会自动解析并复制。手工操作时:
134
+
135
+ ```bash
136
+ # 先把 preset 里的原件复制到机器级缓存(哈希命名),再用缓存路径
137
+ AGENT_DIR="${DSH_HOME:-$HOME/.dsh}/cache/cosmic/agent"
138
+ SRC="{SKILL_DIR}/assets/kd-reloadjar-agent.jar"
139
+ HASH=$( (shasum -a 1 "$SRC" 2>/dev/null || sha1sum "$SRC") | cut -c1-8 )
140
+ AGENT="$AGENT_DIR/kd-reloadjar-agent-$HASH.jar"
141
+ mkdir -p "$AGENT_DIR" && [ -f "$AGENT" ] || cp "$SRC" "$AGENT"
142
+ ```
143
+
131
144
  ```bash
132
- <java_home>/bin/java -cp <java_home>/lib/tools.jar:{SKILL_DIR}/assets/kd-reloadjar-agent.jar kd.reloadjar.Attacher \
133
- <cosmicPID> {SKILL_DIR}/assets/kd-reloadjar-agent.jar \
145
+ # 用缓存副本调 Attacher(Windows 上把 : 换成 ;)
146
+ <java_home>/bin/java -cp <java_home>/lib/tools.jar:"$AGENT" kd.reloadjar.Attacher \
147
+ <cosmicPID> "$AGENT" \
134
148
  "<jar绝对路径1>,<jar绝对路径2>" \
135
149
  <account_id> <tenant_id> \
136
150
  <可选logFile绝对路径>
@@ -140,6 +154,7 @@ pwsh -File {SKILL_DIR}\scripts\cosmic-hotdeploy.ps1 -Module <模块名> -WhatIf
140
154
  - jar 路径可直接用构建产物 `build/libs/xxx.jar`,**无需拷到 lib/cus**。
141
155
  - 最后一个参数 `logFile` **可选**:填了则在开发机侧写成功/失败标记日志(`status=SUCCESS/FAILED`)。
142
156
  - classpath 分隔符:macOS/Linux 用 `:`,Windows 用 `;`。
157
+ - **Windows 直接用**「Windows:一条命令走完全程」里的 `cosmic-hotdeploy.ps1`(它已内置上述缓存逻辑)。
143
158
 
144
159
  ### 4. 验证
145
160
 
@@ -225,4 +240,4 @@ agent(`kd.reloadjar.ReloadAgent`)在 cosmic 进程内自动执行这两步
225
240
  | `assets/dev.json` | ① 开启热部署 | 空配置模板(`dev.py` 读它作字段基础,生成工作区 `.dsh/cosmic/config/dev.json`) |
226
241
  | `scripts/dev.py` | ① 开启热部署 | 环境配置脚本(`init`=读 `.kd/config.json` 覆盖 dev.json;`read`=只读;`__file__` 反推 skill 根) |
227
242
  | `scripts/cosmic-hotdeploy.ps1` | ②③ 热加载 / 构建+热部署 | **Windows 一键封装**(可移植:工作区自动推断、无硬编码路径):体检 / `-Module` 构建+热部署 / `-Clean` / `-Jar` 直传 / `-WhatIf`。见「Windows:一条命令走完全程」 |
228
- | `assets/kd-reloadjar-agent.jar` | ② 热加载 | 热重载 agent(含 `kd.reloadjar.ReloadAgent` + `Attacher`) |
243
+ | `assets/kd-reloadjar-agent.jar` | ② 热加载 | 热重载 agent(含 `kd.reloadjar.ReloadAgent` + `Attacher`)。⚠️ **原件不要直接加载** —— 先复制到 `$DSH_HOME/cache/cosmic/agent/kd-reloadjar-agent-<sha1前8位>.jar` 再用(避免 preset 升级时被 JVM 锁住,见职责②§3) |
@@ -68,8 +68,41 @@ if (-not $PresetDir) {
68
68
  if (-not $PresetDir) {
69
69
  throw "Cannot locate the cosmic skill bundle. Set DSH_PROFILE_DIR/DSH_HOME, or pass -PresetDir <path containing skills\cosmic-build>."
70
70
  }
71
- $agent = Join-Path $PresetDir 'skills\cosmic-build\skills\cosmic-vibe-coding\assets\kd-reloadjar-agent.jar'
72
- if (-not (Test-Path $agent)) { throw "Missing reload agent: $agent" }
71
+ $srcAgent = Join-Path $PresetDir 'skills\cosmic-build\skills\cosmic-vibe-coding\assets\kd-reloadjar-agent.jar'
72
+ if (-not (Test-Path $srcAgent)) { throw "Missing reload agent: $srcAgent" }
73
+
74
+ # ---- 0.2 Agent jar: use a machine-level, content-hashed COPY -- never load it from the preset ----
75
+ # Why: the Attacher loads this jar into the running cosmic JVM, and the JVM's classloader keeps
76
+ # the JarFile handle open for the JVM's lifetime. npm/pnpm upgrades replace the *whole package
77
+ # directory* (move the old dir away, put the new one in), which requires every file inside to be
78
+ # deletable/renamable -> the upgrade always fails on this jar (Windows: os error 32 / access
79
+ # denied). The old git-based layout never hit this because git only rewrites files whose content
80
+ # actually changed, and this jar rarely changes.
81
+ # Naming the copy with the content hash means a *new* preset version never overwrites an old copy
82
+ # that may already be loaded by a JVM.
83
+ $dshHome = if ($env:DSH_HOME) { $env:DSH_HOME }
84
+ elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dsh' }
85
+ elseif ($env:HOME) { Join-Path $env:HOME '.dsh' }
86
+ else { $null }
87
+ $agent = $srcAgent
88
+ if ($dshHome) {
89
+ $agentHash = (Get-FileHash $srcAgent -Algorithm SHA1).Hash.Substring(0, 8).ToLower()
90
+ $agentDir = Join-Path (Join-Path $dshHome 'cache\cosmic') 'agent'
91
+ $cachedAgent = Join-Path $agentDir "kd-reloadjar-agent-$agentHash.jar"
92
+ try {
93
+ if (-not (Test-Path $cachedAgent)) {
94
+ New-Item -ItemType Directory -Force -Path $agentDir | Out-Null
95
+ Copy-Item $srcAgent $cachedAgent -Force
96
+ }
97
+ $agent = $cachedAgent
98
+ # best-effort housekeeping: keep only the newest few hashed copies
99
+ Get-ChildItem $agentDir -Filter 'kd-reloadjar-agent-*.jar' -ErrorAction SilentlyContinue |
100
+ Sort-Object LastWriteTime -Descending | Select-Object -Skip 5 |
101
+ Remove-Item -Force -ErrorAction SilentlyContinue
102
+ } catch {
103
+ Write-Host "[agent] WARN cannot use the cached copy ($($_.Exception.Message)); falling back to the preset copy (preset upgrades may then hit a file lock)."
104
+ }
105
+ }
73
106
  $devScript = Join-Path $PresetDir 'skills\cosmic-build\skills\cosmic-vibe-coding\scripts\dev.py'
74
107
 
75
108
  # ---- 1. Read dev.json (env config produced by dev.py init) ----
@@ -142,6 +175,11 @@ Write-Host "[env] erp_url = $($dev.erp_url) (port $effPort)"
142
175
  Write-Host "[env] cosmic PID = $targetPid (owner=$owner)"
143
176
  Write-Host "[env] attacher JDK = $attacherJdk"
144
177
  Write-Host "[env] accountId = $accountId / tenantId = $tenantId"
178
+ if ($agent -ne $srcAgent) {
179
+ Write-Host "[agent] $agent (cached copy; the preset original is never loaded)"
180
+ } else {
181
+ Write-Host "[agent] $agent (PRESET ORIGINAL -- preset upgrades may hit a file lock while cosmic runs)"
182
+ }
145
183
 
146
184
  # ---- 4. Optional: build first ----
147
185
  if ($Module) {
@@ -47,3 +47,25 @@ Write-Host "==> 验证导入"
47
47
  uv run --python $VENV python -c "import pandas, numpy, plotly, jinja2, requests; print('OK', pandas.__version__, numpy.__version__, plotly.__version__, jinja2.__version__, 'requests', requests.__version__)"
48
48
 
49
49
  Write-Host "==> init-python 完成"
50
+
51
+ # 顺带把热部署用的 agent jar 预复制到机器级缓存(与 venv 同理:**不要把会被外部进程独占
52
+ # 加载的文件留在 preset 里**)。Attacher 会把这个 jar 载入运行中的 cosmic JVM,JVM 长期持有
53
+ # 其句柄;preset 升级要整目录替换 → 会在这个 jar 上失败(Windows os error 32 / 拒绝访问)。
54
+ # 文件名带内容哈希:新版不会覆盖可能已被 JVM 载入的旧副本。幂等。
55
+ $AgentSrc = Join-Path $ROOT "skills\cosmic-build\skills\cosmic-vibe-coding\assets\kd-reloadjar-agent.jar"
56
+ if (Test-Path $AgentSrc) {
57
+ $AgentDir = Join-Path $DshHome "cache\cosmic\agent"
58
+ $AgentHash = (Get-FileHash $AgentSrc -Algorithm SHA1).Hash.Substring(0, 8).ToLower()
59
+ $AgentDst = Join-Path $AgentDir "kd-reloadjar-agent-$AgentHash.jar"
60
+ if (-not (Test-Path $AgentDir)) { New-Item -ItemType Directory -Force -Path $AgentDir | Out-Null }
61
+ if (Test-Path $AgentDst) {
62
+ Write-Host "==> agent 缓存已存在: $AgentDst"
63
+ } else {
64
+ Copy-Item $AgentSrc $AgentDst -Force
65
+ Write-Host "==> agent 已缓存: $AgentDst"
66
+ }
67
+ # 只保留最近 5 份哈希副本(best-effort)
68
+ Get-ChildItem $AgentDir -Filter "kd-reloadjar-agent-*.jar" -ErrorAction SilentlyContinue |
69
+ Sort-Object LastWriteTime -Descending | Select-Object -Skip 5 |
70
+ Remove-Item -Force -ErrorAction SilentlyContinue
71
+ }
@@ -48,3 +48,22 @@ echo "==> 验证导入"
48
48
  uv run --python "$VENV" python -c 'import pandas, numpy, plotly, jinja2, requests; print("OK", pandas.__version__, numpy.__version__, plotly.__version__, jinja2.__version__, "requests", requests.__version__)'
49
49
 
50
50
  echo "==> init-python 完成"
51
+
52
+ # 4) 顺带把热部署用的 agent jar 预复制到机器级缓存(与 venv 同理:**不要把会被外部进程
53
+ # 独占加载的文件留在 preset 里**)。Attacher 会把这个 jar 载入运行中的 cosmic JVM,
54
+ # JVM 长期持有其句柄;preset 升级要整目录替换 → 会在这个 jar 上失败(Windows os error 32)。
55
+ # 文件名带内容哈希:新版不会覆盖可能已被 JVM 载入的旧副本。幂等。
56
+ AGENT_SRC="$ROOT/skills/cosmic-build/skills/cosmic-vibe-coding/assets/kd-reloadjar-agent.jar"
57
+ if [ -f "$AGENT_SRC" ]; then
58
+ AGENT_DIR="$DSH_HOME/cache/cosmic/agent"
59
+ AGENT_HASH="$( (shasum -a 1 "$AGENT_SRC" 2>/dev/null || sha1sum "$AGENT_SRC") | cut -c1-8 )"
60
+ AGENT_DST="$AGENT_DIR/kd-reloadjar-agent-$AGENT_HASH.jar"
61
+ mkdir -p "$AGENT_DIR"
62
+ if [ -f "$AGENT_DST" ]; then
63
+ echo "==> agent 缓存已存在: $AGENT_DST"
64
+ else
65
+ cp "$AGENT_SRC" "$AGENT_DST" && echo "==> agent 已缓存: $AGENT_DST"
66
+ fi
67
+ # 只保留最近 5 份哈希副本(best-effort)
68
+ ls -1t "$AGENT_DIR"/kd-reloadjar-agent-*.jar 2>/dev/null | tail -n +6 | while read -r old; do rm -f "$old" 2>/dev/null || true; done
69
+ fi