@rexvane/piweb 0.3.5 → 0.3.6

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": "@rexvane/piweb",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Modern web UI for the pi coding agent, driven by the official pi SDK without modifying pi",
@@ -101,13 +101,22 @@ export function assertStagingOutsideNodeModules(root) {
101
101
  return parent;
102
102
  }
103
103
 
104
- function tryLinkDependencies(root, staging) {
104
+ function linkOrCopyDependencies(root, staging, log) {
105
+ const target = path.join(root, "node_modules");
106
+ const linkPath = path.join(staging, "node_modules");
107
+ // Windows: junction 不需要符号链接权限;跨卷时 junction 也会失败(试回退)。
108
+ // POSIX(macOS/Linux): 目录符号链接即可,"junction" 类型会被 libuv 拒绝
109
+ // (0.3.5 的 Mac 现场:symlinkSync(..., 'junction') 抛 EINVAL)。
110
+ const type = process.platform === "win32" ? "junction" : "dir";
105
111
  try {
106
- fs.symlinkSync(path.join(root, "node_modules"), path.join(staging, "node_modules"), "junction");
107
- return true;
112
+ fs.symlinkSync(target, linkPath, type);
113
+ return;
108
114
  } catch {
109
- return false;
115
+ /* fall through to the copy */
110
116
  }
117
+ // 兜底:符号链接不可用(如无权限)时整份复制依赖。慢但保证构建可解析。
118
+ log("[piweb] Symlink unavailable; copying dependencies into the staging build (slower)...");
119
+ fs.cpSync(target, linkPath, { recursive: true, verbatimSymlinks: true });
111
120
  }
112
121
 
113
122
  function buildInStaging(root, nextBin, env, log, warn) {
@@ -117,13 +126,6 @@ function buildInStaging(root, nextBin, env, log, warn) {
117
126
  } catch {
118
127
  staging = fs.mkdtempSync(path.join(os.tmpdir(), "piweb-build-"));
119
128
  }
120
- // junction 不能跨卷:staging 与包不同盘时链接会失败,退回系统临时目录再试一次
121
- if (!tryLinkDependencies(root, staging) && path.parse(staging).root !== path.parse(os.tmpdir()).root) {
122
- try {
123
- fs.rmSync(staging, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
124
- } catch { /* proceed to the tmpdir attempt */ }
125
- staging = fs.mkdtempSync(path.join(os.tmpdir(), "piweb-build-"));
126
- }
127
129
  try {
128
130
  for (const entry of ["src", "public", "assets", "scripts", "bin"]) {
129
131
  const from = path.join(root, entry);
@@ -133,10 +135,7 @@ function buildInStaging(root, nextBin, env, log, warn) {
133
135
  const from = path.join(root, file);
134
136
  if (fs.existsSync(from)) fs.copyFileSync(from, path.join(staging, file));
135
137
  }
136
- if (!tryLinkDependencies(root, staging)) {
137
- warn("[piweb] Could not link dependencies into the staging build (junction unavailable).");
138
- return false;
139
- }
138
+ linkOrCopyDependencies(root, staging, log);
140
139
  log(`[piweb] Building in ${staging} ...`);
141
140
  const result = spawnSync(process.execPath, [nextBin, "build", "--webpack"], { cwd: staging, stdio: "inherit", env });
142
141
  const produced = path.join(staging, ".next", "BUILD_ID");
@@ -146,6 +145,8 @@ function buildInStaging(root, nextBin, env, log, warn) {
146
145
  fs.cpSync(path.join(staging, ".next"), target, { recursive: true });
147
146
  return fs.existsSync(path.join(target, "BUILD_ID"));
148
147
  } finally {
148
+ // 复制兜底时 staging 里是整份 node_modules,必须删掉;rmSync 跟随链接删除
149
+ // 的是链接本身(Node 14+ 目录符号链接不穿透),真实依赖不受影响。
149
150
  fs.rmSync(staging, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
150
151
  }
151
152
  }