jishushell 0.4.24 → 0.5.15
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/INSTALL-NOTICE +11 -0
- package/apps/anythingllm-container.yaml +287 -0
- package/apps/browserless-chromium-container.yaml +90 -0
- package/apps/filebrowser-container.yaml +163 -0
- package/apps/hermes-container.yaml +36 -2
- package/apps/ollama-binary.yaml +91 -90
- package/apps/ollama-cpu-container.yaml +8 -1
- package/apps/ollama-with-hollama-binary.yaml +91 -90
- package/apps/openclaw-binary.yaml +38 -1
- package/apps/openclaw-container.yaml +45 -2
- package/apps/openclaw-with-ollama-container.yaml +11 -2
- package/apps/openclaw-with-searxng-container.yaml +26 -2
- package/apps/openwebui-container.yaml +45 -1
- package/apps/playwright-container.yaml +7 -1
- package/apps/searxng-container.yaml +58 -7
- package/apps/weknora-container.yaml +471 -0
- package/dist/cli/app.js +79 -9
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/doctor.d.ts +12 -12
- package/dist/cli/doctor.js +242 -55
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/llm.d.ts +4 -3
- package/dist/cli/llm.js +4 -3
- package/dist/cli/llm.js.map +1 -1
- package/dist/cli/panel.d.ts +6 -5
- package/dist/cli/panel.js +10 -9
- package/dist/cli/panel.js.map +1 -1
- package/dist/config.d.ts +19 -0
- package/dist/config.js +99 -1
- package/dist/config.js.map +1 -1
- package/dist/control.d.ts +7 -6
- package/dist/control.js +7 -6
- package/dist/control.js.map +1 -1
- package/dist/install.js +3 -3
- package/dist/install.js.map +1 -1
- package/dist/routes/agent-apps.d.ts +1 -1
- package/dist/routes/agent-apps.js +1 -1
- package/dist/routes/apps.js +44 -11
- package/dist/routes/apps.js.map +1 -1
- package/dist/routes/auth.js +5 -2
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/backup.js +64 -11
- package/dist/routes/backup.js.map +1 -1
- package/dist/routes/external-mounts.d.ts +17 -0
- package/dist/routes/external-mounts.js +73 -0
- package/dist/routes/external-mounts.js.map +1 -0
- package/dist/routes/file-mounts.d.ts +13 -0
- package/dist/routes/file-mounts.js +90 -0
- package/dist/routes/file-mounts.js.map +1 -0
- package/dist/routes/files-organize.d.ts +28 -0
- package/dist/routes/files-organize.js +167 -0
- package/dist/routes/files-organize.js.map +1 -0
- package/dist/routes/files.d.ts +31 -0
- package/dist/routes/files.js +321 -0
- package/dist/routes/files.js.map +1 -0
- package/dist/routes/instances.js +826 -17
- package/dist/routes/instances.js.map +1 -1
- package/dist/routes/internal.d.ts +2 -0
- package/dist/routes/internal.js +59 -0
- package/dist/routes/internal.js.map +1 -0
- package/dist/routes/llm.js +24 -35
- package/dist/routes/llm.js.map +1 -1
- package/dist/routes/setup.js +10 -10
- package/dist/routes/setup.js.map +1 -1
- package/dist/routes/system.js +1 -1
- package/dist/routes/system.js.map +1 -1
- package/dist/routes/webdav.d.ts +17 -0
- package/dist/routes/webdav.js +114 -0
- package/dist/routes/webdav.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +751 -20
- package/dist/server.js.map +1 -1
- package/dist/services/agent-apps/catalog.js +4 -3
- package/dist/services/agent-apps/catalog.js.map +1 -1
- package/dist/services/agent-apps/index.d.ts +1 -1
- package/dist/services/agent-apps/index.js +1 -1
- package/dist/services/agent-apps/installers/adapter.d.ts +1 -1
- package/dist/services/agent-apps/installers/adapter.js +1 -1
- package/dist/services/agent-apps/installers/shell-script.d.ts +1 -1
- package/dist/services/agent-apps/installers/shell-script.js +3 -3
- package/dist/services/agent-apps/installers/shell-script.js.map +1 -1
- package/dist/services/agent-apps/types.d.ts +2 -2
- package/dist/services/agent-apps/types.js +1 -1
- package/dist/services/app/app-compiler.d.ts +1 -1
- package/dist/services/app/app-compiler.js +5 -5
- package/dist/services/app/app-compiler.js.map +1 -1
- package/dist/services/app/app-manager.d.ts +25 -1
- package/dist/services/app/app-manager.js +829 -150
- package/dist/services/app/app-manager.js.map +1 -1
- package/dist/services/app/custom-manager.js.map +1 -1
- package/dist/services/app/hermes-agent-manager.js +7 -4
- package/dist/services/app/hermes-agent-manager.js.map +1 -1
- package/dist/services/app/ollama-manager.js +1 -1
- package/dist/services/app/ollama-manager.js.map +1 -1
- package/dist/services/app/openclaw-manager.js +20 -3
- package/dist/services/app/openclaw-manager.js.map +1 -1
- package/dist/services/app/platform-transform.d.ts +32 -0
- package/dist/services/app/platform-transform.js +65 -0
- package/dist/services/app/platform-transform.js.map +1 -0
- package/dist/services/app/provide-resolver.d.ts +29 -0
- package/dist/services/app/provide-resolver.js +112 -0
- package/dist/services/app/provide-resolver.js.map +1 -0
- package/dist/services/app-passwords.d.ts +61 -0
- package/dist/services/app-passwords.js +173 -0
- package/dist/services/app-passwords.js.map +1 -0
- package/dist/services/backup-manager.d.ts +11 -0
- package/dist/services/backup-manager.js +177 -4
- package/dist/services/backup-manager.js.map +1 -1
- package/dist/services/capability-endpoint-validator.d.ts +41 -0
- package/dist/services/capability-endpoint-validator.js +104 -0
- package/dist/services/capability-endpoint-validator.js.map +1 -0
- package/dist/services/capability-health.d.ts +16 -0
- package/dist/services/capability-health.js +121 -0
- package/dist/services/capability-health.js.map +1 -0
- package/dist/services/capability-registry.d.ts +106 -0
- package/dist/services/capability-registry.js +313 -0
- package/dist/services/capability-registry.js.map +1 -0
- package/dist/services/connection-apply.d.ts +91 -0
- package/dist/services/connection-apply.js +475 -0
- package/dist/services/connection-apply.js.map +1 -0
- package/dist/services/connection-resolver.d.ts +65 -0
- package/dist/services/connection-resolver.js +281 -0
- package/dist/services/connection-resolver.js.map +1 -0
- package/dist/services/connection-transactor.d.ts +39 -0
- package/dist/services/connection-transactor.js +351 -0
- package/dist/services/connection-transactor.js.map +1 -0
- package/dist/services/external-mounts.d.ts +40 -0
- package/dist/services/external-mounts.js +187 -0
- package/dist/services/external-mounts.js.map +1 -0
- package/dist/services/files-manager.d.ts +252 -0
- package/dist/services/files-manager.js +1075 -0
- package/dist/services/files-manager.js.map +1 -0
- package/dist/services/files-mounts.d.ts +42 -0
- package/dist/services/files-mounts.js +207 -0
- package/dist/services/files-mounts.js.map +1 -0
- package/dist/services/instance-manager.d.ts +13 -0
- package/dist/services/instance-manager.js +138 -46
- package/dist/services/instance-manager.js.map +1 -1
- package/dist/services/llm-proxy/index.d.ts +16 -2
- package/dist/services/llm-proxy/index.js +48 -44
- package/dist/services/llm-proxy/index.js.map +1 -1
- package/dist/services/llm-proxy/probe.d.ts +6 -0
- package/dist/services/llm-proxy/probe.js +85 -0
- package/dist/services/llm-proxy/probe.js.map +1 -0
- package/dist/services/llm-proxy/ssrf.d.ts +1 -0
- package/dist/services/llm-proxy/ssrf.js +24 -9
- package/dist/services/llm-proxy/ssrf.js.map +1 -1
- package/dist/services/nomad-manager.d.ts +4 -0
- package/dist/services/nomad-manager.js +428 -35
- package/dist/services/nomad-manager.js.map +1 -1
- package/dist/services/organize/applier.d.ts +46 -0
- package/dist/services/organize/applier.js +218 -0
- package/dist/services/organize/applier.js.map +1 -0
- package/dist/services/organize/rules.d.ts +57 -0
- package/dist/services/organize/rules.js +286 -0
- package/dist/services/organize/rules.js.map +1 -0
- package/dist/services/organize/scanner.d.ts +50 -0
- package/dist/services/organize/scanner.js +366 -0
- package/dist/services/organize/scanner.js.map +1 -0
- package/dist/services/organize/store.d.ts +14 -0
- package/dist/services/organize/store.js +82 -0
- package/dist/services/organize/store.js.map +1 -0
- package/dist/services/panel-manager.js +20 -1
- package/dist/services/panel-manager.js.map +1 -1
- package/dist/services/process-manager.js +4 -3
- package/dist/services/process-manager.js.map +1 -1
- package/dist/services/runtime/adapters/hermes.d.ts +30 -1
- package/dist/services/runtime/adapters/hermes.js +219 -6
- package/dist/services/runtime/adapters/hermes.js.map +1 -1
- package/dist/services/runtime/adapters/openclaw-mcporter.d.ts +45 -0
- package/dist/services/runtime/adapters/openclaw-mcporter.js +108 -0
- package/dist/services/runtime/adapters/openclaw-mcporter.js.map +1 -0
- package/dist/services/runtime/adapters/openclaw-routes.d.ts +8 -2
- package/dist/services/runtime/adapters/openclaw-routes.js +68 -0
- package/dist/services/runtime/adapters/openclaw-routes.js.map +1 -1
- package/dist/services/runtime/adapters/openclaw.d.ts +177 -0
- package/dist/services/runtime/adapters/openclaw.js +1171 -11
- package/dist/services/runtime/adapters/openclaw.js.map +1 -1
- package/dist/services/runtime/instance.d.ts +1 -1
- package/dist/services/runtime/instance.js +1 -1
- package/dist/services/runtime/instance.js.map +1 -1
- package/dist/services/runtime/mcp-shims/anythingllm-shim.d.ts +46 -0
- package/dist/services/runtime/mcp-shims/anythingllm-shim.js +281 -0
- package/dist/services/runtime/mcp-shims/anythingllm-shim.js.map +1 -0
- package/dist/services/runtime/mcp-shims/drive-shim.d.ts +54 -0
- package/dist/services/runtime/mcp-shims/drive-shim.js +489 -0
- package/dist/services/runtime/mcp-shims/drive-shim.js.map +1 -0
- package/dist/services/runtime/mcp-shims/firewall.d.ts +26 -0
- package/dist/services/runtime/mcp-shims/firewall.js +129 -0
- package/dist/services/runtime/mcp-shims/firewall.js.map +1 -0
- package/dist/services/runtime/mcp-shims/searxng-shim.d.ts +27 -0
- package/dist/services/runtime/mcp-shims/searxng-shim.js +125 -0
- package/dist/services/runtime/mcp-shims/searxng-shim.js.map +1 -0
- package/dist/services/runtime/mcp-shims/write-mcp-entry.d.ts +83 -0
- package/dist/services/runtime/mcp-shims/write-mcp-entry.js +127 -0
- package/dist/services/runtime/mcp-shims/write-mcp-entry.js.map +1 -0
- package/dist/services/runtime/migrations.d.ts +8 -0
- package/dist/services/runtime/migrations.js +100 -0
- package/dist/services/runtime/migrations.js.map +1 -1
- package/dist/services/runtime/types.d.ts +46 -0
- package/dist/services/setup-manager.js +99 -24
- package/dist/services/setup-manager.js.map +1 -1
- package/dist/services/suggestions.d.ts +27 -0
- package/dist/services/suggestions.js +133 -0
- package/dist/services/suggestions.js.map +1 -0
- package/dist/services/task-registry.js +4 -2
- package/dist/services/task-registry.js.map +1 -1
- package/dist/services/telemetry/device-fingerprint.d.ts +1 -1
- package/dist/services/telemetry/device-fingerprint.js +1 -1
- package/dist/services/types-shim.d.ts +16 -0
- package/dist/services/types-shim.js +2 -0
- package/dist/services/types-shim.js.map +1 -0
- package/dist/services/webdav/server.d.ts +24 -0
- package/dist/services/webdav/server.js +420 -0
- package/dist/services/webdav/server.js.map +1 -0
- package/dist/services/webdav/xml-builder.d.ts +73 -0
- package/dist/services/webdav/xml-builder.js +156 -0
- package/dist/services/webdav/xml-builder.js.map +1 -0
- package/dist/services/workspace-builder.d.ts +29 -0
- package/dist/services/workspace-builder.js +188 -0
- package/dist/services/workspace-builder.js.map +1 -0
- package/dist/types.d.ts +231 -1
- package/dist/utils/instance-lock.d.ts +22 -0
- package/dist/utils/instance-lock.js +48 -0
- package/dist/utils/instance-lock.js.map +1 -0
- package/dist/utils/path-locks.d.ts +30 -0
- package/dist/utils/path-locks.js +63 -0
- package/dist/utils/path-locks.js.map +1 -0
- package/dist/utils/path-safety.d.ts +41 -0
- package/dist/utils/path-safety.js +119 -0
- package/dist/utils/path-safety.js.map +1 -0
- package/dist/utils/safe-json.js +55 -22
- package/dist/utils/safe-json.js.map +1 -1
- package/dist/utils/safe-write.d.ts +24 -0
- package/dist/utils/safe-write.js +82 -0
- package/dist/utils/safe-write.js.map +1 -0
- package/install/jishu-install.sh +323 -27
- package/install/jishu-uninstall.sh +353 -20
- package/package.json +18 -1
- package/public/assets/Dashboard-BdWPtroF.js +1 -0
- package/public/assets/{HermesChatPanel-mFSureyc.js → HermesChatPanel-B_2HlVBQ.js} +1 -1
- package/public/assets/HermesConfigForm-DVlhg3WV.js +4 -0
- package/public/assets/{InitPassword-CVA8wQA6.js → InitPassword-D7glTExX.js} +1 -1
- package/public/assets/InstanceDetail-CxSy2cpe.js +92 -0
- package/public/assets/{Login-BWsZH2mu.js → Login-Cfr5c2sv.js} +1 -1
- package/public/assets/NewInstance-BIYDmJis.js +1 -0
- package/public/assets/ProviderRecommendations-BuRnvRcI.js +1 -0
- package/public/assets/Settings-Cc-tYBil.js +1 -0
- package/public/assets/Setup-lGZEk5jq.js +1 -0
- package/public/assets/{WeixinLoginPanel-CnjR8xMu.js → WeixinLoginPanel-CoGqzxeV.js} +2 -2
- package/public/assets/index-87IJXG-w.css +1 -0
- package/public/assets/index-BZc5zH7u.js +19 -0
- package/public/assets/providers-DtNXh9JD.js +1 -0
- package/public/assets/registry-BWnkJgZ1.js +2 -0
- package/public/assets/{usePolling-Do5Erqm_.js → usePolling-CwwT9KrC.js} +1 -1
- package/public/assets/{vendor-i18n-ucpM0OR0.js → vendor-i18n-y9V7Sfuu.js} +1 -1
- package/public/assets/{vendor-react-Bk1hRGiY.js → vendor-react-BWrEVJVb.js} +6 -6
- package/public/index.html +4 -4
- package/scripts/check-app-spec.mjs +457 -0
- package/scripts/check-i18n.mjs +154 -0
- package/scripts/check-new-file-tests.mjs +230 -0
- package/scripts/check-quarantine-expiry.mjs +105 -0
- package/scripts/perf/README.md +49 -0
- package/scripts/perf/auth.js +99 -0
- package/scripts/perf/config.js +63 -0
- package/scripts/perf/instances.js +143 -0
- package/scripts/perf/proxy.js +96 -0
- package/scripts/run.sh +4 -4
- package/scripts/smoke/files-w1.sh +142 -0
- package/scripts/smoke-backend.mjs +122 -0
- package/scripts/smoke-post-publish.mjs +346 -0
- package/public/assets/Dashboard-B-JoOjBQ.js +0 -1
- package/public/assets/HermesConfigForm-DvR05LK1.js +0 -4
- package/public/assets/InstanceDetail-DcZW2QGO.js +0 -91
- package/public/assets/NewInstance-BCIrAd86.js +0 -1
- package/public/assets/Settings-xkDcduFz.js +0 -1
- package/public/assets/Setup-Cfuwj4gV.js +0 -1
- package/public/assets/index-CPhVFEsx.css +0 -1
- package/public/assets/index-DQsM6Joa.js +0 -19
- package/public/assets/providers-V-vwrExZ.js +0 -1
- package/public/assets/registry-B4UFJdpA.js +0 -2
package/dist/utils/safe-json.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { chmodSync, existsSync, readFileSync, writeFileSync, renameSync, copyFileSync, openSync, fdatasyncSync, closeSync, mkdirSync } from "fs";
|
|
1
|
+
import { chmodSync, existsSync, readFileSync, writeFileSync, renameSync, copyFileSync, openSync, fdatasyncSync, closeSync, mkdirSync, rmSync } from "fs";
|
|
2
2
|
import { dirname } from "path";
|
|
3
3
|
const BACKUP_SUFFIXES = [".bak", ".bak.1", ".bak.2"];
|
|
4
4
|
function recoverJson(path, label, mode) {
|
|
@@ -48,34 +48,67 @@ function withWriteLock(path, fn) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
function atomicWriteJson(path, data, fsync, mode) {
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const dir = dirname(path);
|
|
52
|
+
mkdirSync(dir, { recursive: true });
|
|
53
|
+
const tmp = `${path}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
|
|
53
54
|
const json = typeof data === "string" ? data : JSON.stringify(data);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
try {
|
|
56
|
+
writeFileSync(tmp, json, { mode });
|
|
57
|
+
chmodSync(tmp, mode);
|
|
58
|
+
JSON.parse(readFileSync(tmp, "utf-8"));
|
|
59
|
+
if (fsync) {
|
|
60
|
+
let fd = null;
|
|
61
|
+
try {
|
|
62
|
+
fd = openSync(tmp, "r");
|
|
63
|
+
fdatasyncSync(fd);
|
|
64
|
+
}
|
|
65
|
+
catch { }
|
|
66
|
+
finally {
|
|
67
|
+
if (fd !== null)
|
|
68
|
+
try {
|
|
69
|
+
closeSync(fd);
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
}
|
|
62
73
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
if (existsSync(path)) {
|
|
75
|
+
try {
|
|
76
|
+
if (existsSync(path + ".bak.1"))
|
|
77
|
+
copyFileSync(path + ".bak.1", path + ".bak.2");
|
|
78
|
+
}
|
|
79
|
+
catch { }
|
|
80
|
+
try {
|
|
81
|
+
if (existsSync(path + ".bak"))
|
|
82
|
+
copyFileSync(path + ".bak", path + ".bak.1");
|
|
83
|
+
}
|
|
84
|
+
catch { }
|
|
85
|
+
copyFileSync(path, path + ".bak");
|
|
69
86
|
}
|
|
70
|
-
|
|
87
|
+
renameSync(tmp, path);
|
|
88
|
+
chmodSync(path, mode);
|
|
89
|
+
if (fsync) {
|
|
90
|
+
let dirFd = null;
|
|
91
|
+
try {
|
|
92
|
+
dirFd = openSync(dir, "r");
|
|
93
|
+
fdatasyncSync(dirFd);
|
|
94
|
+
}
|
|
95
|
+
catch { }
|
|
96
|
+
finally {
|
|
97
|
+
if (dirFd !== null)
|
|
98
|
+
try {
|
|
99
|
+
closeSync(dirFd);
|
|
100
|
+
}
|
|
101
|
+
catch { }
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
71
106
|
try {
|
|
72
|
-
|
|
73
|
-
copyFileSync(path + ".bak", path + ".bak.1");
|
|
107
|
+
rmSync(tmp, { force: true });
|
|
74
108
|
}
|
|
75
109
|
catch { }
|
|
76
|
-
|
|
110
|
+
throw err;
|
|
77
111
|
}
|
|
78
|
-
renameSync(tmp, path);
|
|
79
112
|
}
|
|
80
113
|
export function safeWriteJson(path, data, fsync = false) {
|
|
81
114
|
withWriteLock(path, () => atomicWriteJson(path, data, fsync, 0o644));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-json.js","sourceRoot":"","sources":["../../src/utils/safe-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"safe-json.js","sourceRoot":"","sources":["../../src/utils/safe-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AACzJ,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAErD,SAAS,WAAW,CAAI,IAAY,EAAE,KAAa,EAAE,IAAY;IAC/D,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,SAAS;QAC7B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YAClD,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,8BAA8B,CAAC,EAAE,CAAC,CAAC;gBAClE,MAAM,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC;gBAC1B,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnD,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACrB,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACxB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,qBAAqB,CAAC,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,YAAY,CAA0B,IAAY,EAAE,KAAa;IAC/E,OAAO,WAAW,CAAI,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAA0B,IAAY,EAAE,KAAa;IACrF,OAAO,WAAW,CAAI,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEhD,SAAS,aAAa,CAAC,IAAY,EAAE,EAAc;IACjD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,GAAG,MAAM,EAAE,CAAC;YACnC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,6CAA6C,IAAI,eAAe,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IACD,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACpC,IAAI,CAAC;QACH,EAAE,EAAE,CAAC;IACP,CAAC;YAAS,CAAC;QACT,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,IAAS,EAAE,KAAc,EAAE,IAAY;IAC5E,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9F,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACpE,IAAI,CAAC;QACH,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,EAAE,GAAkB,IAAI,CAAC;YAC7B,IAAI,CAAC;gBAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;oBACpD,CAAC;gBAAC,IAAI,EAAE,KAAK,IAAI;oBAAE,IAAI,CAAC;wBAAC,SAAS,CAAC,EAAE,CAAC,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;YAAC,CAAC;QAC9D,CAAC;QACD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC;gBAAC,IAAI,UAAU,CAAC,IAAI,GAAG,QAAQ,CAAC;oBAAE,YAAY,CAAC,IAAI,GAAG,QAAQ,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACjG,IAAI,CAAC;gBAAC,IAAI,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC;oBAAE,YAAY,CAAC,IAAI,GAAG,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAC7F,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC;QACpC,CAAC;QACD,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtB,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,KAAK,GAAkB,IAAI,CAAC;YAChC,IAAI,CAAC;gBAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;oBAC1D,CAAC;gBAAC,IAAI,KAAK,KAAK,IAAI;oBAAE,IAAI,CAAC;wBAAC,SAAS,CAAC,KAAK,CAAC,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;YAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YAAC,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAC9C,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,IAAS,EAAE,KAAK,GAAG,KAAK;IAClE,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,IAAS,EAAE,KAAK,GAAG,KAAK;IACxE,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
export interface AtomicWriteOptions {
|
|
3
|
+
/** Compute streaming sha256 of the data while writing. Default: undefined */
|
|
4
|
+
hash?: "sha256";
|
|
5
|
+
/** Expected total size; if set and actual differs, throws. Default: no check */
|
|
6
|
+
expectedSize?: number;
|
|
7
|
+
/** Write mode (POSIX) of the final file. Default 0o644 */
|
|
8
|
+
mode?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface AtomicWriteResult {
|
|
11
|
+
size: number;
|
|
12
|
+
hash?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Stream `source` to `targetPath` atomically.
|
|
16
|
+
*
|
|
17
|
+
* Memory peak is the Node stream high-water-mark (~64KB), regardless of the
|
|
18
|
+
* total file size. Suitable for arbitrarily large files.
|
|
19
|
+
*/
|
|
20
|
+
export declare function atomicWriteStream(targetPath: string, source: Readable, opts?: AtomicWriteOptions): Promise<AtomicWriteResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Convenience wrapper for small Buffer writes. Uses the same atomic pipeline.
|
|
23
|
+
*/
|
|
24
|
+
export declare function safeWriteBuffer(targetPath: string, buf: Buffer, opts?: AtomicWriteOptions): Promise<AtomicWriteResult>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic streaming writer (W1 PR-2).
|
|
3
|
+
*
|
|
4
|
+
* Main API is `atomicWriteStream` — pipes a Readable to a tmp file with
|
|
5
|
+
* optional streaming sha256, fdatasyncs, then renames to target. On any
|
|
6
|
+
* error the tmp is removed.
|
|
7
|
+
*
|
|
8
|
+
* `safeWriteBuffer` is a convenience wrapper for small Buffer payloads
|
|
9
|
+
* (e.g. .app-skills.json). It internally streams a single chunk.
|
|
10
|
+
*
|
|
11
|
+
* The caller is responsible for:
|
|
12
|
+
* - ensuring dirname(targetPath) exists (use mkdirSync recursive)
|
|
13
|
+
* - path validation (see path-safety.ts)
|
|
14
|
+
* - concurrent-write serialization on the same path (see path-locks.ts)
|
|
15
|
+
*/
|
|
16
|
+
import { createWriteStream, openSync, fdatasyncSync, closeSync, renameSync, unlinkSync, existsSync, } from "node:fs";
|
|
17
|
+
import { pipeline } from "node:stream/promises";
|
|
18
|
+
import { Readable, Transform } from "node:stream";
|
|
19
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
20
|
+
/**
|
|
21
|
+
* Stream `source` to `targetPath` atomically.
|
|
22
|
+
*
|
|
23
|
+
* Memory peak is the Node stream high-water-mark (~64KB), regardless of the
|
|
24
|
+
* total file size. Suitable for arbitrarily large files.
|
|
25
|
+
*/
|
|
26
|
+
export async function atomicWriteStream(targetPath, source, opts = {}) {
|
|
27
|
+
const tmp = makeTmpName(targetPath);
|
|
28
|
+
let size = 0;
|
|
29
|
+
let hasher;
|
|
30
|
+
const writeStream = createWriteStream(tmp, { mode: opts.mode ?? 0o644 });
|
|
31
|
+
// We need a single Transform that both counts size and (optionally) hashes.
|
|
32
|
+
const counter = new Transform({
|
|
33
|
+
transform(chunk, _enc, cb) {
|
|
34
|
+
size += chunk.length;
|
|
35
|
+
hasher?.update(chunk);
|
|
36
|
+
cb(null, chunk);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
if (opts.hash === "sha256") {
|
|
40
|
+
hasher = createHash("sha256");
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
await pipeline(source, counter, writeStream);
|
|
44
|
+
if (opts.expectedSize !== undefined && size !== opts.expectedSize) {
|
|
45
|
+
throw new Error(`expected ${opts.expectedSize} bytes, got ${size}`);
|
|
46
|
+
}
|
|
47
|
+
// fdatasync tmp file before rename for crash safety
|
|
48
|
+
const fd = openSync(tmp, "r+");
|
|
49
|
+
try {
|
|
50
|
+
fdatasyncSync(fd);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
closeSync(fd);
|
|
54
|
+
}
|
|
55
|
+
renameSync(tmp, targetPath);
|
|
56
|
+
return hasher
|
|
57
|
+
? { size, hash: hasher.digest("hex") }
|
|
58
|
+
: { size };
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
try {
|
|
62
|
+
if (existsSync(tmp))
|
|
63
|
+
unlinkSync(tmp);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// best-effort cleanup; surface the original error
|
|
67
|
+
}
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Convenience wrapper for small Buffer writes. Uses the same atomic pipeline.
|
|
73
|
+
*/
|
|
74
|
+
export async function safeWriteBuffer(targetPath, buf, opts = {}) {
|
|
75
|
+
const source = Readable.from([buf]);
|
|
76
|
+
return atomicWriteStream(targetPath, source, opts);
|
|
77
|
+
}
|
|
78
|
+
function makeTmpName(target) {
|
|
79
|
+
const rand = randomBytes(8).toString("hex");
|
|
80
|
+
return `${target}.tmp.${process.pid}.${Date.now()}.${rand}`;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=safe-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-write.js","sourceRoot":"","sources":["../../src/utils/safe-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,aAAa,EACb,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgBtD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAkB,EAClB,MAAgB,EAChB,OAA2B,EAAE;IAE7B,MAAM,GAAG,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,IAAI,MAAiD,CAAC;IACtD,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;IAEzE,4EAA4E;IAC5E,MAAM,OAAO,GAAG,IAAI,SAAS,CAAC;QAC5B,SAAS,CAAC,KAAa,EAAE,IAAI,EAAE,EAAE;YAC/B,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YACrB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACtB,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClB,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAE7C,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,YAAY,eAAe,IAAI,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,oDAAoD;QACpD,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC;YACH,aAAa,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,SAAS,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;QAED,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAE5B,OAAO,MAAM;YACX,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YACtC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,GAAG,CAAC;gBAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,kDAAkD;QACpD,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,GAAW,EACX,OAA2B,EAAE;IAE7B,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,OAAO,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,OAAO,GAAG,MAAM,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC;AAC9D,CAAC"}
|