@mmmbuto/qwen-code-termux 0.16.1-termux → 0.18.0-termux
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/README.md +79 -109
- package/bundled/new-app/SKILL.md +22 -0
- package/bundled/qc-helper/SKILL.md +29 -24
- package/bundled/qc-helper/docs/_meta.ts +1 -0
- package/bundled/qc-helper/docs/configuration/_meta.ts +0 -3
- package/bundled/qc-helper/docs/configuration/settings.md +37 -31
- package/bundled/qc-helper/docs/configuration/themes.md +39 -0
- package/bundled/qc-helper/docs/features/_meta.ts +1 -3
- package/bundled/qc-helper/docs/features/approval-mode.md +35 -35
- package/bundled/qc-helper/docs/features/auto-mode.md +54 -9
- package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/channels/feishu.md +170 -0
- package/bundled/qc-helper/docs/features/commands.md +115 -35
- package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
- package/bundled/qc-helper/docs/features/headless.md +32 -0
- package/bundled/qc-helper/docs/features/markdown-rendering.md +21 -1
- package/bundled/qc-helper/docs/features/memory.md +22 -5
- package/bundled/qc-helper/docs/features/scheduled-tasks.md +1 -1
- package/bundled/qc-helper/docs/features/status-line.md +168 -32
- package/bundled/qc-helper/docs/features/sub-agents.md +60 -0
- package/bundled/qc-helper/docs/features/worktree.md +345 -0
- package/bundled/qc-helper/docs/overview.md +4 -4
- package/bundled/qc-helper/docs/quickstart.md +4 -4
- package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +221 -0
- package/bundled/qc-helper/docs/qwen-serve.md +234 -24
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +16 -0
- package/bundled/qc-helper/docs/support/Uninstall.md +19 -1
- package/bundled/qc-helper/docs/support/troubleshooting.md +2 -1
- package/bundled/simplify/SKILL.md +123 -0
- package/chunks/agent-IDS4HMOX.js +56 -0
- package/chunks/agent-headless-5Q2EUSPS.js +50 -0
- package/chunks/{anthropicContentGenerator-SSGKR6DO.js → anthropicContentGenerator-2HBRNQ3B.js} +52 -9
- package/chunks/{askUserQuestion-PJWUUXKN.js → askUserQuestion-75TDJVK2.js} +45 -3
- package/chunks/{ca-UZ7BANMN.js → ca-BARBRL6N.js} +89 -5
- package/chunks/{chunk-GGNTZ2NH.js → chunk-2Y5SYSD3.js} +368 -597
- package/chunks/{chunk-2LA2TREA.js → chunk-3AA2DK35.js} +1448 -207
- package/chunks/{chunk-I2V5WXHJ.js → chunk-3AUHFMSK.js} +80 -38
- package/chunks/chunk-3DHXZ6EV.js +241 -0
- package/chunks/{chunk-PR4T27R7.js → chunk-3HTIVKZE.js} +42 -8
- package/chunks/chunk-3HX5LZ6R.js +1798 -0
- package/chunks/chunk-3PJXIDKI.js +2517 -0
- package/chunks/{chunk-MYAKAFEC.js → chunk-55ZMG67I.js} +7451 -3517
- package/chunks/{chunk-66CXYE4B.js → chunk-5IFG2VC4.js} +293 -242
- package/chunks/chunk-64WXLC72.js +98 -0
- package/chunks/{chunk-C6WMLUNB.js → chunk-72LDN5PP.js} +1 -1
- package/chunks/{chunk-F23NCRJ2.js → chunk-A7B4ISQP.js} +1 -1
- package/chunks/chunk-B7HXHOHU.js +393 -0
- package/chunks/{chunk-XEGHDASV.js → chunk-D3RHSPAS.js} +435 -540
- package/chunks/{chunk-XKS5KBFJ.js → chunk-EYENRK4D.js} +694 -384
- package/chunks/chunk-H6BD2ELD.js +36 -0
- package/chunks/{chunk-XP27SJMH.js → chunk-HR7SV7AY.js} +79 -48
- package/chunks/{chunk-D5NTAHYL.js → chunk-IDX6COTE.js} +7 -2
- package/chunks/{chunk-SHT4VJWU.js → chunk-IWKSG2AR.js} +2 -2
- package/chunks/chunk-J37FGIOA.js +1623 -0
- package/chunks/chunk-J5MDQKJL.js +2230 -0
- package/chunks/{chunk-USE2VQ5P.js → chunk-JTQAQBTV.js} +21 -0
- package/chunks/{chunk-NCTLV2NB.js → chunk-KQJMQJPI.js} +1 -1
- package/chunks/{chunk-5FBA5XC2.js → chunk-KRIHGKNA.js} +1 -1
- package/chunks/chunk-LD2XBG6Z.js +102 -0
- package/chunks/{chunk-MAY32HXD.js → chunk-M6VTDSVR.js} +3 -1
- package/chunks/chunk-MRO43B25.js +30 -0
- package/chunks/{chunk-N4WOREMD.js → chunk-NVFMZBX2.js} +43 -3
- package/chunks/chunk-OHEGWO4L.js +264 -0
- package/chunks/{chunk-K6O2NBMF.js → chunk-OQ7NJIY7.js} +4604 -6397
- package/chunks/chunk-QQDPRDVW.js +25 -0
- package/chunks/{chunk-KXZ4TJB4.js → chunk-SEGYWKIH.js} +1 -1
- package/chunks/chunk-SKBPNJEW.js +45 -0
- package/chunks/{chunk-4AOCVI6J.js → chunk-SNGELLWX.js} +52 -6
- package/chunks/{chunk-3OCRHZA3.js → chunk-TD4OPI4T.js} +56742 -44104
- package/chunks/{chunk-DQ4QTG7E.js → chunk-VV4F63BD.js} +11 -11
- package/chunks/chunk-XBY7E2FX.js +605 -0
- package/chunks/{chunk-JKMBWLFB.js → chunk-YILFYI5W.js} +48 -26
- package/chunks/chunk-YOGAOMYB.js +159 -0
- package/chunks/{chunk-QWSRH265.js → chunk-Z2Z3GUXZ.js} +777 -776
- package/chunks/{chunk-SDHRQFOS.js → chunk-ZTZ4DDQE.js} +2 -2
- package/chunks/computer-use-W2TYQNEE.js +825 -0
- package/chunks/contextCommand-6FGX3A7J.js +52 -0
- package/chunks/{cron-create-3ZBBN7WB.js → cron-create-APL5LU6I.js} +3 -3
- package/chunks/{cron-delete-NAGKKIIG.js → cron-delete-4SBJSCN4.js} +3 -3
- package/chunks/{cron-list-PAGRXNAI.js → cron-list-2AMGOMVO.js} +3 -3
- package/chunks/{de-V4IE2OOZ.js → de-YGKK2BC4.js} +89 -5
- package/chunks/{devtools-TWVXEJQB.js → devtools-FM6GJPYG.js} +2 -1
- package/chunks/{dist-4L54HRX2.js → dist-4LXD6L6X.js} +24 -5
- package/chunks/dist-H6ONXVLG.js +94146 -0
- package/chunks/{dist-XKWIWPWQ.js → dist-KAZ3SEBX.js} +1083 -3856
- package/chunks/{dist-BXDUQ2QY.js → dist-PK7DFCAW.js} +1 -1
- package/chunks/{edit-NVO3FOAK.js → edit-ZCEZC264.js} +30 -22
- package/chunks/{en-HGJ2SPLM.js → en-DHGYHIHX.js} +127 -6
- package/chunks/{enter-worktree-UEBG4WFC.js → enter-worktree-BBHCFCHG.js} +30 -20
- package/chunks/enterPlanMode-3M6KTD3B.js +158 -0
- package/chunks/{exit-worktree-UZ3MAQZN.js → exit-worktree-73YPIEQO.js} +27 -19
- package/chunks/exitPlanMode-TYZM6BAE.js +703 -0
- package/chunks/{fr-CJULI7ZX.js → fr-JXBKPJKQ.js} +89 -5
- package/chunks/{geminiContentGenerator-3UZFXGNT.js → geminiContentGenerator-7N2V3VW2.js} +8 -6
- package/chunks/{getMachineId-bsd-JXOSIJV2.js → getMachineId-bsd-4CASPIU4.js} +4 -4
- package/chunks/{getMachineId-darwin-TE4QRR42.js → getMachineId-darwin-HPQPEMZR.js} +4 -4
- package/chunks/{getMachineId-linux-S3OL52XK.js → getMachineId-linux-AUARKYHL.js} +3 -3
- package/chunks/{getMachineId-unsupported-DWUSBAPX.js → getMachineId-unsupported-S32ZDA2T.js} +3 -3
- package/chunks/{getMachineId-win-AAC5P3AP.js → getMachineId-win-4EFLHYIJ.js} +4 -4
- package/chunks/{glob-KNHSFFFG.js → glob-5XBCPQ2A.js} +27 -19
- package/chunks/{grep-LACWDZW4.js → grep-VIUU3A7X.js} +30 -19
- package/chunks/{ja-L7CHRQEW.js → ja-TGPZSP2B.js} +89 -5
- package/chunks/{keychain-token-storage-335UOLJ6.js → keychain-token-storage-6IU6ORQN.js} +3 -3
- package/chunks/{ls-AGXQOKSG.js → ls-JRGYIGLY.js} +4 -4
- package/chunks/{lsp-UDMUHNPA.js → lsp-SHMKFOAC.js} +3 -3
- package/chunks/{monitor-ETKWPJEH.js → monitor-6R4LIJL5.js} +40 -25
- package/chunks/{multipart-parser-3QWGTLK3.js → multipart-parser-AJ4WASWR.js} +2 -2
- package/chunks/{notebook-edit-QJJLPNYT.js → notebook-edit-5E7ULDVQ.js} +28 -20
- package/chunks/{openaiContentGenerator-CNNN424U.js → openaiContentGenerator-ZVHFKM3O.js} +17 -14
- package/chunks/{pt-M6JULLEQ.js → pt-TIBG6BIO.js} +89 -5
- package/chunks/{qwenContentGenerator-BOLCGK3R.js → qwenContentGenerator-B2VTVSPJ.js} +31 -23
- package/chunks/{qwenOAuth2-EEJGROP7.js → qwenOAuth2-2KCKWDCF.js} +6 -4
- package/chunks/read-file-GIT7BCDR.js +27 -0
- package/chunks/ripGrep-MWKFVYMS.js +48 -0
- package/chunks/{ru-QILM4HBC.js → ru-JBCHCK4L.js} +89 -5
- package/chunks/scheduler-5VOOYGBH.js +308 -0
- package/chunks/send-message-4QNWQJF4.js +244 -0
- package/chunks/{serve-OLSI7WSR.js → serve-MN6HZBWN.js} +14262 -7414
- package/chunks/shell-NQZQGFM2.js +56 -0
- package/chunks/{skill-D6YRHTTI.js → skill-WCFW4644.js} +145 -119
- package/chunks/{src-TMOD5X6F.js → src-7XL4G4DC.js} +88 -46
- package/chunks/{src-4QH4FZ6I.js → src-IHA6DTUV.js} +452 -62
- package/chunks/{syntheticOutput-5PVFDDJ4.js → syntheticOutput-YTYS2ZMQ.js} +4 -4
- package/chunks/task-create-MPORPYN6.js +19 -0
- package/chunks/task-list-R2YDYPZT.js +151 -0
- package/chunks/{task-stop-AJKPSR6R.js → task-stop-SYWJYBCM.js} +3 -3
- package/chunks/task-update-E4NSLKMQ.js +408 -0
- package/chunks/team-create-7R7KA5IP.js +314 -0
- package/chunks/team-delete-25OIWUPN.js +116 -0
- package/chunks/{todoWrite-VLAUG4CA.js → todoWrite-4YHMIF4X.js} +16 -5
- package/chunks/{tool-search-MZGHUUKD.js → tool-search-YBRVZCLI.js} +29 -11
- package/chunks/{tts-notification-K3X7X7MN.js → tts-notification-7SOEMQK4.js} +5 -4
- package/chunks/{web-fetch-OILB464A.js → web-fetch-MFIRHIHI.js} +5 -5
- package/chunks/workflow-5RIKVCIE.js +960 -0
- package/chunks/{write-file-BIQAA57V.js → write-file-DMQTJZOM.js} +32 -24
- package/chunks/{zh-PWL2NKY3.js → zh-7H5OQC4I.js} +135 -11
- package/chunks/{zh-TW-S3YGWICZ.js → zh-TW-P4IDHD3M.js} +128 -11
- package/cli.js +45402 -20570
- package/examples/agent/agents/diary.md +86 -0
- package/examples/agent/qwen-extension.json +5 -0
- package/examples/commands/commands/fs/grep-code.md +3 -0
- package/examples/commands/qwen-extension.json +5 -0
- package/examples/context/QWEN.md +8 -0
- package/examples/context/qwen-extension.json +5 -0
- package/examples/mcp-server/example.ts +60 -0
- package/examples/mcp-server/package.json +18 -0
- package/examples/mcp-server/qwen-extension.json +12 -0
- package/examples/mcp-server/tsconfig.json +13 -0
- package/examples/skills/qwen-extension.json +5 -0
- package/examples/skills/skills/synonyms/SKILL.md +48 -0
- package/examples/starter/QWEN.md +30 -0
- package/examples/starter/README.md +59 -0
- package/examples/starter/agents/diary.md +86 -0
- package/examples/starter/commands/writing/polish.md +13 -0
- package/examples/starter/example.ts +64 -0
- package/examples/starter/package.json +18 -0
- package/examples/starter/qwen-extension.json +12 -0
- package/examples/starter/skills/synonyms/SKILL.md +48 -0
- package/examples/starter/tsconfig.json +13 -0
- package/fzfWorker.js +1083 -0
- package/locales/ca.js +118 -5
- package/locales/de.js +117 -5
- package/locales/en.js +169 -7
- package/locales/fr.js +119 -5
- package/locales/ja.js +114 -5
- package/locales/pt.js +117 -5
- package/locales/ru.js +116 -5
- package/locales/zh-TW.js +161 -12
- package/locales/zh.js +169 -12
- package/package.json +4 -2
- package/scripts/postinstall.cjs +2 -1
- package/bundled/qc-helper/docs/features/checkpointing.md +0 -77
- package/chunks/agent-7ZN3CRHR.js +0 -48
- package/chunks/chunk-6PCB2DEF.js +0 -434
- package/chunks/chunk-EM6ETG2K.js +0 -60
- package/chunks/chunk-G7YTSRES.js +0 -150
- package/chunks/contextCommand-7IBASARL.js +0 -44
- package/chunks/exitPlanMode-PZAMWIRW.js +0 -227
- package/chunks/multipart-parser-IXGBIOIN.js +0 -384
- package/chunks/read-file-CCUEUFG2.js +0 -24
- package/chunks/ripGrep-TADOH2HK.js +0 -40
- package/chunks/send-message-YL44UZFC.js +0 -151
- package/chunks/shell-7KKKC5G7.js +0 -48
- package/chunks/src-IPWIHNMI.js +0 -1406
- package/chunks/undici-F6ZOXSS5.js +0 -8
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Force strict mode and setup for ESM
|
|
2
|
+
"use strict";
|
|
3
|
+
import {
|
|
4
|
+
init_esbuild_shims
|
|
5
|
+
} from "./chunk-A4BMJM77.js";
|
|
6
|
+
import {
|
|
7
|
+
__name
|
|
8
|
+
} from "./chunk-J2S4EL5Y.js";
|
|
9
|
+
|
|
10
|
+
// packages/core/src/utils/abortController.ts
|
|
11
|
+
init_esbuild_shims();
|
|
12
|
+
import { setMaxListeners } from "node:events";
|
|
13
|
+
var DEFAULT_MAX_LISTENERS = 50;
|
|
14
|
+
function createAbortController(maxListeners = DEFAULT_MAX_LISTENERS) {
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
setMaxListeners(maxListeners, controller.signal);
|
|
17
|
+
return controller;
|
|
18
|
+
}
|
|
19
|
+
__name(createAbortController, "createAbortController");
|
|
20
|
+
function asSignal(parent) {
|
|
21
|
+
if (!parent) return void 0;
|
|
22
|
+
return parent instanceof AbortController ? parent.signal : parent;
|
|
23
|
+
}
|
|
24
|
+
__name(asSignal, "asSignal");
|
|
25
|
+
function createChildAbortController(parent, maxListeners) {
|
|
26
|
+
const child = createAbortController(maxListeners);
|
|
27
|
+
const parentSignal = asSignal(parent);
|
|
28
|
+
if (!parentSignal) return child;
|
|
29
|
+
if (parentSignal.aborted) {
|
|
30
|
+
child.abort(parentSignal.reason);
|
|
31
|
+
return child;
|
|
32
|
+
}
|
|
33
|
+
const weakParent = new WeakRef(parentSignal);
|
|
34
|
+
const handler = /* @__PURE__ */ __name(() => {
|
|
35
|
+
child.abort(weakParent.deref()?.reason);
|
|
36
|
+
}, "handler");
|
|
37
|
+
parentSignal.addEventListener("abort", handler, { once: true });
|
|
38
|
+
child.signal.addEventListener(
|
|
39
|
+
"abort",
|
|
40
|
+
() => {
|
|
41
|
+
weakParent.deref()?.removeEventListener("abort", handler);
|
|
42
|
+
},
|
|
43
|
+
{ once: true }
|
|
44
|
+
);
|
|
45
|
+
return child;
|
|
46
|
+
}
|
|
47
|
+
__name(createChildAbortController, "createChildAbortController");
|
|
48
|
+
function combineAbortSignals(signals, options) {
|
|
49
|
+
const controller = createAbortController(options?.maxListeners);
|
|
50
|
+
const alreadyAborted = signals.find((s) => s?.aborted);
|
|
51
|
+
if (alreadyAborted) {
|
|
52
|
+
controller.abort(alreadyAborted.reason);
|
|
53
|
+
return { signal: controller.signal, cleanup: /* @__PURE__ */ __name(() => {
|
|
54
|
+
}, "cleanup") };
|
|
55
|
+
}
|
|
56
|
+
const cleanups = [];
|
|
57
|
+
for (const sourceSignal of signals) {
|
|
58
|
+
if (!sourceSignal) continue;
|
|
59
|
+
if (sourceSignal.aborted) {
|
|
60
|
+
controller.abort(sourceSignal.reason);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
const handler = /* @__PURE__ */ __name(() => controller.abort(sourceSignal.reason), "handler");
|
|
64
|
+
sourceSignal.addEventListener("abort", handler, { once: true });
|
|
65
|
+
cleanups.push(() => sourceSignal.removeEventListener("abort", handler));
|
|
66
|
+
}
|
|
67
|
+
const timeoutMs = options?.timeoutMs;
|
|
68
|
+
if (timeoutMs !== void 0 && timeoutMs > 0 && !controller.signal.aborted) {
|
|
69
|
+
const timeoutId = setTimeout(() => {
|
|
70
|
+
controller.abort(new DOMException("Operation timed out", "TimeoutError"));
|
|
71
|
+
}, timeoutMs);
|
|
72
|
+
cleanups.push(() => clearTimeout(timeoutId));
|
|
73
|
+
}
|
|
74
|
+
let done = false;
|
|
75
|
+
const cleanup = /* @__PURE__ */ __name(() => {
|
|
76
|
+
if (done) return;
|
|
77
|
+
done = true;
|
|
78
|
+
for (const fn of cleanups) fn();
|
|
79
|
+
}, "cleanup");
|
|
80
|
+
if (controller.signal.aborted) {
|
|
81
|
+
cleanup();
|
|
82
|
+
} else {
|
|
83
|
+
controller.signal.addEventListener("abort", cleanup, { once: true });
|
|
84
|
+
}
|
|
85
|
+
return { signal: controller.signal, cleanup };
|
|
86
|
+
}
|
|
87
|
+
__name(combineAbortSignals, "combineAbortSignals");
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
createAbortController,
|
|
91
|
+
createChildAbortController,
|
|
92
|
+
combineAbortSignals
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* @license
|
|
96
|
+
* Copyright 2025 Qwen
|
|
97
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
98
|
+
*/
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
// Force strict mode and setup for ESM
|
|
2
|
+
"use strict";
|
|
3
|
+
import {
|
|
4
|
+
createDebugLogger,
|
|
5
|
+
isNodeError
|
|
6
|
+
} from "./chunk-HR7SV7AY.js";
|
|
7
|
+
import {
|
|
8
|
+
init_esbuild_shims
|
|
9
|
+
} from "./chunk-A4BMJM77.js";
|
|
10
|
+
import {
|
|
11
|
+
__name
|
|
12
|
+
} from "./chunk-J2S4EL5Y.js";
|
|
13
|
+
|
|
14
|
+
// packages/core/src/utils/atomicFileWrite.ts
|
|
15
|
+
init_esbuild_shims();
|
|
16
|
+
import * as crypto from "node:crypto";
|
|
17
|
+
import * as fsSync from "node:fs";
|
|
18
|
+
import * as fs from "node:fs/promises";
|
|
19
|
+
import * as path from "node:path";
|
|
20
|
+
var debugLogger = createDebugLogger("ATOMIC_WRITE");
|
|
21
|
+
async function renameWithRetry(src, dest, retries, delayMs, _renameImpl = fs.rename) {
|
|
22
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
23
|
+
try {
|
|
24
|
+
await _renameImpl(src, dest);
|
|
25
|
+
return;
|
|
26
|
+
} catch (error) {
|
|
27
|
+
const isRetryable = isNodeError(error) && (error.code === "EPERM" || error.code === "EACCES");
|
|
28
|
+
if (!isRetryable || attempt === retries) {
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
await new Promise(
|
|
32
|
+
(resolve2) => setTimeout(resolve2, delayMs * 2 ** attempt)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
__name(renameWithRetry, "renameWithRetry");
|
|
38
|
+
async function resolveSymlinkChain(filePath) {
|
|
39
|
+
const maxHops = 40;
|
|
40
|
+
let current = filePath;
|
|
41
|
+
for (let i = 0; i < maxHops; i++) {
|
|
42
|
+
let lstats;
|
|
43
|
+
try {
|
|
44
|
+
lstats = await fs.lstat(current);
|
|
45
|
+
} catch (err2) {
|
|
46
|
+
if (isNodeError(err2) && err2.code === "ENOENT") {
|
|
47
|
+
return current;
|
|
48
|
+
}
|
|
49
|
+
throw err2;
|
|
50
|
+
}
|
|
51
|
+
if (!lstats.isSymbolicLink()) {
|
|
52
|
+
return current;
|
|
53
|
+
}
|
|
54
|
+
const linkTarget = await fs.readlink(current);
|
|
55
|
+
if (path.isAbsolute(linkTarget)) {
|
|
56
|
+
current = linkTarget;
|
|
57
|
+
} else {
|
|
58
|
+
const parentDir = await fs.realpath(path.dirname(current));
|
|
59
|
+
current = path.resolve(parentDir, linkTarget);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const err = new Error(
|
|
63
|
+
`ELOOP: too many levels of symbolic links, resolve '${filePath}'`
|
|
64
|
+
);
|
|
65
|
+
err.code = "ELOOP";
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
__name(resolveSymlinkChain, "resolveSymlinkChain");
|
|
69
|
+
async function atomicWriteFile(filePath, data, options, _testFs) {
|
|
70
|
+
const retries = options?.retries ?? 3;
|
|
71
|
+
const delayMs = options?.delayMs ?? 50;
|
|
72
|
+
const flush = options?.flush ?? true;
|
|
73
|
+
const encoding = options?.encoding ?? "utf-8";
|
|
74
|
+
const renameImpl = _testFs?.rename ?? fs.rename;
|
|
75
|
+
const writeFileImpl = _testFs?.writeFile ?? fs.writeFile;
|
|
76
|
+
const openImpl = _testFs?.open ?? fs.open;
|
|
77
|
+
const chmodImpl = _testFs?.chmod ?? fs.chmod;
|
|
78
|
+
const fchmodImpl = _testFs?.fchmod ?? ((fh, mode) => fh.chmod(mode));
|
|
79
|
+
const unlinkImpl = _testFs?.unlink ?? fs.unlink;
|
|
80
|
+
const targetPath = options?.noFollow ? filePath : await resolveSymlinkChain(filePath).catch((err) => {
|
|
81
|
+
throw annotateWriteError(err, filePath);
|
|
82
|
+
});
|
|
83
|
+
let existingStat;
|
|
84
|
+
try {
|
|
85
|
+
existingStat = await fs.stat(targetPath);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
if (!isNodeError(err) || err.code !== "ENOENT") {
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
let existingMode;
|
|
92
|
+
if (!options?.forceMode || options?.mode === void 0) {
|
|
93
|
+
existingMode = existingStat !== void 0 ? existingStat.mode & 4095 : void 0;
|
|
94
|
+
}
|
|
95
|
+
const desiredMode = existingMode ?? options?.mode;
|
|
96
|
+
const writeOptions = {};
|
|
97
|
+
if (typeof data === "string") writeOptions.encoding = encoding;
|
|
98
|
+
if (flush) writeOptions.flush = true;
|
|
99
|
+
if (desiredMode !== void 0) writeOptions.mode = desiredMode;
|
|
100
|
+
const tryChmod = /* @__PURE__ */ __name(async (target) => {
|
|
101
|
+
if (desiredMode === void 0) return;
|
|
102
|
+
try {
|
|
103
|
+
await chmodImpl(target, desiredMode);
|
|
104
|
+
} catch (chmodErr) {
|
|
105
|
+
if (!isNodeError(chmodErr) || chmodErr.code !== "ENOSYS" && chmodErr.code !== "ENOTSUP") {
|
|
106
|
+
throw chmodErr;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}, "tryChmod");
|
|
110
|
+
const ownershipWouldChange = /* @__PURE__ */ __name(() => {
|
|
111
|
+
if (existingStat === void 0) return false;
|
|
112
|
+
if (process.platform === "win32") return false;
|
|
113
|
+
const euid = process.geteuid?.();
|
|
114
|
+
if (euid === void 0) return false;
|
|
115
|
+
return existingStat.uid !== euid;
|
|
116
|
+
}, "ownershipWouldChange");
|
|
117
|
+
if (existingStat !== void 0 && existingStat.isFile() && ownershipWouldChange()) {
|
|
118
|
+
await fs.writeFile(targetPath, data, writeOptions);
|
|
119
|
+
await tryChmod(targetPath);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const tmpPath = `${targetPath}.${crypto.randomBytes(6).toString("hex")}.tmp`;
|
|
123
|
+
try {
|
|
124
|
+
await writeFileImpl(tmpPath, data, writeOptions);
|
|
125
|
+
await tryChmod(tmpPath);
|
|
126
|
+
await renameWithRetry(tmpPath, targetPath, retries, delayMs, renameImpl);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
try {
|
|
129
|
+
await unlinkImpl(tmpPath);
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
if (isNodeError(error) && error.code === "EXDEV") {
|
|
133
|
+
try {
|
|
134
|
+
if (options?.noFollow) {
|
|
135
|
+
try {
|
|
136
|
+
await unlinkImpl(targetPath);
|
|
137
|
+
} catch (unlinkErr) {
|
|
138
|
+
if (!isNodeError(unlinkErr) || unlinkErr.code !== "ENOENT") {
|
|
139
|
+
throw unlinkErr;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const fd = await openImpl(
|
|
143
|
+
targetPath,
|
|
144
|
+
fsSync.constants.O_WRONLY | fsSync.constants.O_CREAT | fsSync.constants.O_EXCL,
|
|
145
|
+
desiredMode ?? 438
|
|
146
|
+
);
|
|
147
|
+
let writeOk = false;
|
|
148
|
+
try {
|
|
149
|
+
try {
|
|
150
|
+
await fd.writeFile(
|
|
151
|
+
typeof data === "string" ? Buffer.from(data, encoding) : data
|
|
152
|
+
);
|
|
153
|
+
if (flush) await fd.sync();
|
|
154
|
+
if (desiredMode !== void 0) {
|
|
155
|
+
try {
|
|
156
|
+
await fchmodImpl(fd, desiredMode);
|
|
157
|
+
} catch (chmodErr) {
|
|
158
|
+
if (!isNodeError(chmodErr) || chmodErr.code !== "ENOSYS" && chmodErr.code !== "ENOTSUP") {
|
|
159
|
+
throw chmodErr;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
writeOk = true;
|
|
164
|
+
} finally {
|
|
165
|
+
await fd.close();
|
|
166
|
+
}
|
|
167
|
+
} catch (writeErr) {
|
|
168
|
+
if (!writeOk) {
|
|
169
|
+
try {
|
|
170
|
+
await unlinkImpl(targetPath);
|
|
171
|
+
} catch (orphanErr) {
|
|
172
|
+
debugLogger.debug(
|
|
173
|
+
`orphan unlink failed for ${targetPath}:`,
|
|
174
|
+
orphanErr
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
throw writeErr;
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
await writeFileImpl(targetPath, data, writeOptions);
|
|
182
|
+
await tryChmod(targetPath);
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
} catch (fallbackError) {
|
|
186
|
+
throw annotateWriteError(fallbackError, targetPath);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
throw annotateWriteError(error, targetPath);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
__name(atomicWriteFile, "atomicWriteFile");
|
|
193
|
+
function annotateWriteError(error, targetPath, fnName = "atomicWriteFile") {
|
|
194
|
+
if (error instanceof Error && !error.message.startsWith(`${fnName}(`)) {
|
|
195
|
+
error.message = `${fnName}(${JSON.stringify(targetPath)}): ${error.message}`;
|
|
196
|
+
}
|
|
197
|
+
return error;
|
|
198
|
+
}
|
|
199
|
+
__name(annotateWriteError, "annotateWriteError");
|
|
200
|
+
async function atomicWriteJSON(filePath, data, options) {
|
|
201
|
+
await atomicWriteFile(filePath, JSON.stringify(data, null, 2), {
|
|
202
|
+
encoding: "utf-8",
|
|
203
|
+
...options
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
__name(atomicWriteJSON, "atomicWriteJSON");
|
|
207
|
+
function blockingSleep(ms) {
|
|
208
|
+
if (ms <= 0) return;
|
|
209
|
+
const sab = new SharedArrayBuffer(4);
|
|
210
|
+
const i32 = new Int32Array(sab);
|
|
211
|
+
Atomics.wait(i32, 0, 0, ms);
|
|
212
|
+
}
|
|
213
|
+
__name(blockingSleep, "blockingSleep");
|
|
214
|
+
function renameWithRetrySync(src, dest, retries, delayMs, _renameImpl = fsSync.renameSync) {
|
|
215
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
216
|
+
try {
|
|
217
|
+
_renameImpl(src, dest);
|
|
218
|
+
return;
|
|
219
|
+
} catch (error) {
|
|
220
|
+
const isRetryable = isNodeError(error) && (error.code === "EPERM" || error.code === "EACCES");
|
|
221
|
+
if (!isRetryable || attempt === retries) {
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
blockingSleep(delayMs * 2 ** attempt);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
__name(renameWithRetrySync, "renameWithRetrySync");
|
|
229
|
+
function resolveSymlinkChainSync(filePath) {
|
|
230
|
+
const maxHops = 40;
|
|
231
|
+
let current = filePath;
|
|
232
|
+
for (let i = 0; i < maxHops; i++) {
|
|
233
|
+
let lstats;
|
|
234
|
+
try {
|
|
235
|
+
lstats = fsSync.lstatSync(current);
|
|
236
|
+
} catch (err2) {
|
|
237
|
+
if (isNodeError(err2) && err2.code === "ENOENT") {
|
|
238
|
+
return current;
|
|
239
|
+
}
|
|
240
|
+
throw err2;
|
|
241
|
+
}
|
|
242
|
+
if (!lstats.isSymbolicLink()) {
|
|
243
|
+
return current;
|
|
244
|
+
}
|
|
245
|
+
const linkTarget = fsSync.readlinkSync(current);
|
|
246
|
+
if (path.isAbsolute(linkTarget)) {
|
|
247
|
+
current = linkTarget;
|
|
248
|
+
} else {
|
|
249
|
+
const parentDir = fsSync.realpathSync(path.dirname(current));
|
|
250
|
+
current = path.resolve(parentDir, linkTarget);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const err = new Error(
|
|
254
|
+
`ELOOP: too many levels of symbolic links, resolve '${filePath}'`
|
|
255
|
+
);
|
|
256
|
+
err.code = "ELOOP";
|
|
257
|
+
throw err;
|
|
258
|
+
}
|
|
259
|
+
__name(resolveSymlinkChainSync, "resolveSymlinkChainSync");
|
|
260
|
+
function atomicWriteFileSync(filePath, data, options, _testFs) {
|
|
261
|
+
const retries = options?.retries ?? 3;
|
|
262
|
+
const delayMs = options?.delayMs ?? 50;
|
|
263
|
+
const flush = options?.flush ?? true;
|
|
264
|
+
const encoding = options?.encoding ?? "utf-8";
|
|
265
|
+
const renameImpl = _testFs?.rename ?? fsSync.renameSync;
|
|
266
|
+
const writeFileImpl = _testFs?.writeFile ?? fsSync.writeFileSync;
|
|
267
|
+
const openImpl = _testFs?.open ?? fsSync.openSync;
|
|
268
|
+
const chmodImpl = _testFs?.chmod ?? fsSync.chmodSync;
|
|
269
|
+
const fchmodImpl = _testFs?.fchmod ?? fsSync.fchmodSync;
|
|
270
|
+
const unlinkImpl = _testFs?.unlink ?? fsSync.unlinkSync;
|
|
271
|
+
let targetPath;
|
|
272
|
+
if (options?.noFollow) {
|
|
273
|
+
targetPath = filePath;
|
|
274
|
+
} else {
|
|
275
|
+
try {
|
|
276
|
+
targetPath = resolveSymlinkChainSync(filePath);
|
|
277
|
+
} catch (err) {
|
|
278
|
+
throw annotateWriteError(err, filePath, "atomicWriteFileSync");
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const tmpPath = `${targetPath}.${crypto.randomBytes(6).toString("hex")}.tmp`;
|
|
282
|
+
let existingMode;
|
|
283
|
+
if (!options?.forceMode || options?.mode === void 0) {
|
|
284
|
+
try {
|
|
285
|
+
const stat2 = fsSync.statSync(targetPath);
|
|
286
|
+
existingMode = stat2.mode & 4095;
|
|
287
|
+
} catch (err) {
|
|
288
|
+
if (!isNodeError(err) || err.code !== "ENOENT") {
|
|
289
|
+
throw err;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const desiredMode = existingMode ?? options?.mode;
|
|
294
|
+
const writeOptions = {};
|
|
295
|
+
if (typeof data === "string") writeOptions.encoding = encoding;
|
|
296
|
+
if (flush) writeOptions.flush = true;
|
|
297
|
+
if (desiredMode !== void 0) writeOptions.mode = desiredMode;
|
|
298
|
+
const tryChmodSync = /* @__PURE__ */ __name((target) => {
|
|
299
|
+
if (desiredMode === void 0) return;
|
|
300
|
+
try {
|
|
301
|
+
chmodImpl(target, desiredMode);
|
|
302
|
+
} catch (chmodErr) {
|
|
303
|
+
if (!isNodeError(chmodErr) || chmodErr.code !== "ENOSYS" && chmodErr.code !== "ENOTSUP") {
|
|
304
|
+
throw chmodErr;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}, "tryChmodSync");
|
|
308
|
+
try {
|
|
309
|
+
writeFileImpl(tmpPath, data, writeOptions);
|
|
310
|
+
tryChmodSync(tmpPath);
|
|
311
|
+
renameWithRetrySync(tmpPath, targetPath, retries, delayMs, renameImpl);
|
|
312
|
+
} catch (error) {
|
|
313
|
+
try {
|
|
314
|
+
unlinkImpl(tmpPath);
|
|
315
|
+
} catch {
|
|
316
|
+
}
|
|
317
|
+
if (isNodeError(error) && error.code === "EXDEV") {
|
|
318
|
+
try {
|
|
319
|
+
if (options?.noFollow) {
|
|
320
|
+
try {
|
|
321
|
+
unlinkImpl(targetPath);
|
|
322
|
+
} catch (unlinkErr) {
|
|
323
|
+
if (!isNodeError(unlinkErr) || unlinkErr.code !== "ENOENT") {
|
|
324
|
+
throw unlinkErr;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const fd = openImpl(
|
|
328
|
+
targetPath,
|
|
329
|
+
fsSync.constants.O_WRONLY | fsSync.constants.O_CREAT | fsSync.constants.O_EXCL,
|
|
330
|
+
desiredMode ?? 438
|
|
331
|
+
);
|
|
332
|
+
let writeOk = false;
|
|
333
|
+
try {
|
|
334
|
+
try {
|
|
335
|
+
const buf = typeof data === "string" ? Buffer.from(data, encoding) : data;
|
|
336
|
+
fsSync.writeFileSync(fd, buf);
|
|
337
|
+
if (flush) fsSync.fsyncSync(fd);
|
|
338
|
+
if (desiredMode !== void 0) {
|
|
339
|
+
try {
|
|
340
|
+
fchmodImpl(fd, desiredMode);
|
|
341
|
+
} catch (chmodErr) {
|
|
342
|
+
if (!isNodeError(chmodErr) || chmodErr.code !== "ENOSYS" && chmodErr.code !== "ENOTSUP") {
|
|
343
|
+
throw chmodErr;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
writeOk = true;
|
|
348
|
+
} finally {
|
|
349
|
+
fsSync.closeSync(fd);
|
|
350
|
+
}
|
|
351
|
+
} catch (writeErr) {
|
|
352
|
+
if (!writeOk) {
|
|
353
|
+
try {
|
|
354
|
+
unlinkImpl(targetPath);
|
|
355
|
+
} catch (orphanErr) {
|
|
356
|
+
debugLogger.debug(
|
|
357
|
+
`orphan unlink failed for ${targetPath}:`,
|
|
358
|
+
orphanErr
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
throw writeErr;
|
|
363
|
+
}
|
|
364
|
+
} else {
|
|
365
|
+
writeFileImpl(targetPath, data, writeOptions);
|
|
366
|
+
tryChmodSync(targetPath);
|
|
367
|
+
}
|
|
368
|
+
return;
|
|
369
|
+
} catch (fallbackError) {
|
|
370
|
+
throw annotateWriteError(
|
|
371
|
+
fallbackError,
|
|
372
|
+
targetPath,
|
|
373
|
+
"atomicWriteFileSync"
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
throw annotateWriteError(error, targetPath, "atomicWriteFileSync");
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
__name(atomicWriteFileSync, "atomicWriteFileSync");
|
|
381
|
+
|
|
382
|
+
export {
|
|
383
|
+
renameWithRetry,
|
|
384
|
+
atomicWriteFile,
|
|
385
|
+
atomicWriteJSON,
|
|
386
|
+
renameWithRetrySync,
|
|
387
|
+
atomicWriteFileSync
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* @license
|
|
391
|
+
* Copyright 2025 Qwen Team
|
|
392
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
393
|
+
*/
|