tianshu-harness 3.23.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/LICENSE +189 -0
- package/README.en.md +1066 -0
- package/README.ja.md +1214 -0
- package/README.ko.md +1216 -0
- package/README.md +309 -0
- package/completions/rivet.bash +118 -0
- package/completions/rivet.fish +110 -0
- package/completions/rivet.ps1 +230 -0
- package/completions/rivet.zsh +187 -0
- package/dist/account-OAEKORZE.js +47 -0
- package/dist/account-login-V6FOLHJR.js +65 -0
- package/dist/account-status-KHNPPAFL.js +23 -0
- package/dist/agent/worker-process/child.js +407 -0
- package/dist/browser-cli-FLNY5ZHI.js +19 -0
- package/dist/browser-readiness-LWVGSBD5.js +12 -0
- package/dist/build-backends-5KXKR2S4.js +13 -0
- package/dist/build-options-66Y4ZE7C.js +9 -0
- package/dist/bundled-skills/brainstorming/SKILL.md +139 -0
- package/dist/bundled-skills/visual-acceptance/SKILL.md +64 -0
- package/dist/chain-7MAMFXZ3.js +10 -0
- package/dist/checkpoint-MND4DUIX.js +33 -0
- package/dist/chunk-2E6CK2RC.js +392 -0
- package/dist/chunk-2EBWGAXD.js +51 -0
- package/dist/chunk-2HDP7RMR.js +119 -0
- package/dist/chunk-2HKD2UFM.js +1000 -0
- package/dist/chunk-2VYRLULP.js +51 -0
- package/dist/chunk-2XN7PM4N.js +125 -0
- package/dist/chunk-35H7GVNR.js +66 -0
- package/dist/chunk-3C3R7JXY.js +77 -0
- package/dist/chunk-3VGD2FXB.js +118 -0
- package/dist/chunk-424AP7FM.js +534 -0
- package/dist/chunk-4J5TZGOE.js +3707 -0
- package/dist/chunk-4QJ3Y5JM.js +898 -0
- package/dist/chunk-4U2ET7ZY.js +1326 -0
- package/dist/chunk-4XPFLICE.js +876 -0
- package/dist/chunk-5B2OCU5P.js +31707 -0
- package/dist/chunk-5GGOGLSN.js +73 -0
- package/dist/chunk-5JRZPLI6.js +251 -0
- package/dist/chunk-5TQ3JYBU.js +397 -0
- package/dist/chunk-66JPZSGX.js +55 -0
- package/dist/chunk-6HSVXHCZ.js +764 -0
- package/dist/chunk-6S5FPUS7.js +21 -0
- package/dist/chunk-722LQO64.js +131 -0
- package/dist/chunk-73NJ7IT7.js +354 -0
- package/dist/chunk-7FW3I7WC.js +95 -0
- package/dist/chunk-7KUCBNLB.js +173 -0
- package/dist/chunk-7RDOV3DF.js +201 -0
- package/dist/chunk-A5MNH4ER.js +79 -0
- package/dist/chunk-ADIVZ2D5.js +15 -0
- package/dist/chunk-AE3P3F6W.js +366 -0
- package/dist/chunk-AERM3VGP.js +280 -0
- package/dist/chunk-AEWHC4WM.js +246 -0
- package/dist/chunk-AOVQ7VIF.js +169 -0
- package/dist/chunk-AOYHP3WI.js +12411 -0
- package/dist/chunk-B3YEBABJ.js +7160 -0
- package/dist/chunk-BCQXEZPJ.js +154 -0
- package/dist/chunk-BKTQAYO2.js +418 -0
- package/dist/chunk-BSECIPAQ.js +80 -0
- package/dist/chunk-BUIMGNDD.js +52 -0
- package/dist/chunk-BXHV3GSB.js +10320 -0
- package/dist/chunk-C6ZVZCPP.js +139 -0
- package/dist/chunk-CEZNQVWM.js +82 -0
- package/dist/chunk-CGFZGR7G.js +1492 -0
- package/dist/chunk-CGOADM2X.js +337 -0
- package/dist/chunk-CI4R6P2B.js +24 -0
- package/dist/chunk-D2TCGRSX.js +73 -0
- package/dist/chunk-D4PTYFOG.js +154 -0
- package/dist/chunk-D54ZWG4T.js +717 -0
- package/dist/chunk-DEBI37QB.js +145 -0
- package/dist/chunk-DWROHPXP.js +1051 -0
- package/dist/chunk-DZ6UOJ5D.js +92 -0
- package/dist/chunk-EBJTVRQN.js +81 -0
- package/dist/chunk-EGEI2RQA.js +1167 -0
- package/dist/chunk-EHHUASO5.js +1305 -0
- package/dist/chunk-EPKTIOED.js +41 -0
- package/dist/chunk-ER5JW2QZ.js +5681 -0
- package/dist/chunk-ETHFACAB.js +315 -0
- package/dist/chunk-EXUE5W2F.js +112 -0
- package/dist/chunk-EXXICUIW.js +73 -0
- package/dist/chunk-FFQSZJOO.js +169 -0
- package/dist/chunk-FHFKPGDO.js +85 -0
- package/dist/chunk-FW3QKMFX.js +158 -0
- package/dist/chunk-GD4ZNZ7W.js +30 -0
- package/dist/chunk-GHVMWF2I.js +581 -0
- package/dist/chunk-GMKAXSYQ.js +297 -0
- package/dist/chunk-HBVF6BWO.js +325 -0
- package/dist/chunk-HV4YGVMS.js +379 -0
- package/dist/chunk-ILBCKAV6.js +89 -0
- package/dist/chunk-J4U4AW46.js +440 -0
- package/dist/chunk-J6ESSM47.js +1791 -0
- package/dist/chunk-JBZHIC6T.js +2309 -0
- package/dist/chunk-JCFWOULR.js +245 -0
- package/dist/chunk-JRF5L6OD.js +131 -0
- package/dist/chunk-JSS75KCG.js +2014 -0
- package/dist/chunk-JSXWIWWJ.js +225 -0
- package/dist/chunk-JYV7I2QH.js +98 -0
- package/dist/chunk-KIOXTQQL.js +1596 -0
- package/dist/chunk-KWVTXT5B.js +89 -0
- package/dist/chunk-KX22RD6R.js +33 -0
- package/dist/chunk-LA6IPTGH.js +709 -0
- package/dist/chunk-LH5VCGLB.js +1796 -0
- package/dist/chunk-LQQ6XJ2Y.js +269 -0
- package/dist/chunk-MJQ55WZZ.js +65 -0
- package/dist/chunk-ML3UKMH3.js +40 -0
- package/dist/chunk-MOZPLHSU.js +5526 -0
- package/dist/chunk-NGEWJ4DF.js +89 -0
- package/dist/chunk-NH6VIOAR.js +211 -0
- package/dist/chunk-O5VZQKCB.js +26106 -0
- package/dist/chunk-OHSV42QB.js +748 -0
- package/dist/chunk-OO3TAHO5.js +4070 -0
- package/dist/chunk-OTNHSAGN.js +38282 -0
- package/dist/chunk-OUWAC7AQ.js +442 -0
- package/dist/chunk-OXMIV4WE.js +270 -0
- package/dist/chunk-P5KJURUR.js +229 -0
- package/dist/chunk-P6GJOVO6.js +307 -0
- package/dist/chunk-QARAGUXX.js +23 -0
- package/dist/chunk-R43HJCDX.js +2711 -0
- package/dist/chunk-RAXBAWRN.js +210 -0
- package/dist/chunk-RK3JHWPT.js +39 -0
- package/dist/chunk-RWA23GMM.js +24 -0
- package/dist/chunk-S4K4L6IM.js +179 -0
- package/dist/chunk-SAXK6LVF.js +124 -0
- package/dist/chunk-SEPGEJNK.js +1607 -0
- package/dist/chunk-SUJERP5I.js +285 -0
- package/dist/chunk-T3ED6BY2.js +913 -0
- package/dist/chunk-THKDVSEC.js +90 -0
- package/dist/chunk-TI4GSEL5.js +52 -0
- package/dist/chunk-TPI73L57.js +164 -0
- package/dist/chunk-TVHW77C7.js +338 -0
- package/dist/chunk-TWNHOSDT.js +1073 -0
- package/dist/chunk-UFMN76QD.js +347 -0
- package/dist/chunk-UHGLFRZE.js +205 -0
- package/dist/chunk-UTZYPKBF.js +15231 -0
- package/dist/chunk-UXNLELW6.js +25 -0
- package/dist/chunk-UXXS53EA.js +166 -0
- package/dist/chunk-V5DHFGI7.js +171 -0
- package/dist/chunk-V5YIPMHV.js +2353 -0
- package/dist/chunk-WMUWEO2C.js +754 -0
- package/dist/chunk-WOE3D7JM.js +945 -0
- package/dist/chunk-X2IK5LVR.js +2592 -0
- package/dist/chunk-XU2YXCDL.js +459 -0
- package/dist/chunk-YJG5HIX5.js +203 -0
- package/dist/chunk-Z3QE7TZM.js +72 -0
- package/dist/chunk-Z5Z3JHJY.js +64 -0
- package/dist/chunk-ZDIFBJFT.js +168 -0
- package/dist/chunk-ZGGCEXDC.js +176 -0
- package/dist/chunk-ZMZCZNKU.js +263 -0
- package/dist/chunk-ZNC5T65N.js +17 -0
- package/dist/chunk-ZO3I3A7O.js +308 -0
- package/dist/chunk-ZQKXBUB7.js +217 -0
- package/dist/chunk-ZTRINFM2.js +78 -0
- package/dist/chunk-ZU7JZCVP.js +193 -0
- package/dist/chunk-ZZAWNALS.js +350 -0
- package/dist/cli/entry.js +54 -0
- package/dist/connector-L5QQTR6Y.js +26 -0
- package/dist/context-62DC6EC3.js +31 -0
- package/dist/council-convene-NJWPNBDU.js +46 -0
- package/dist/create-agent-config-ODSQWNVC.js +55 -0
- package/dist/default-registry-2PU3BTAU.js +68 -0
- package/dist/deliver-task-KONV4C4M.js +57 -0
- package/dist/delivery-gate-v2-F2YVMVGK.js +27 -0
- package/dist/domain-knowledge-store-DDZ3F4J7.js +11 -0
- package/dist/fetch-core-ZPPYDSZH.js +14 -0
- package/dist/galaxy-K72BBDQN.js +91 -0
- package/dist/goal-criteria-SCALAU2D.js +141 -0
- package/dist/goal-persist-XWY2GDQX.js +19 -0
- package/dist/goal-tracker-FXMJ2GVK.js +11 -0
- package/dist/headless-LSB6I7PT.js +162 -0
- package/dist/headless-coordinator-VDPDMVUT.js +90 -0
- package/dist/inject-U55SMB6A.js +39 -0
- package/dist/login-flow-CD4ZGXOC.js +59 -0
- package/dist/logs-cli-SQVYFMMN.js +283 -0
- package/dist/loop-ULZYBDA3.js +76 -0
- package/dist/main.js +4064 -0
- package/dist/manager-ROZBCWPA.js +171 -0
- package/dist/manager-Z7XFFUOM.js +10670 -0
- package/dist/meridian-indexer-ZIW363L7.js +21 -0
- package/dist/native-resolver-PN34UIVV.js +13 -0
- package/dist/node_modules/better-sqlite3/lib/database.js +90 -0
- package/dist/node_modules/better-sqlite3/lib/index.js +3 -0
- package/dist/node_modules/better-sqlite3/lib/methods/aggregate.js +43 -0
- package/dist/node_modules/better-sqlite3/lib/methods/backup.js +67 -0
- package/dist/node_modules/better-sqlite3/lib/methods/function.js +31 -0
- package/dist/node_modules/better-sqlite3/lib/methods/inspect.js +7 -0
- package/dist/node_modules/better-sqlite3/lib/methods/pragma.js +12 -0
- package/dist/node_modules/better-sqlite3/lib/methods/serialize.js +16 -0
- package/dist/node_modules/better-sqlite3/lib/methods/table.js +189 -0
- package/dist/node_modules/better-sqlite3/lib/methods/transaction.js +78 -0
- package/dist/node_modules/better-sqlite3/lib/methods/wrappers.js +54 -0
- package/dist/node_modules/better-sqlite3/lib/sqlite-error.js +20 -0
- package/dist/node_modules/better-sqlite3/lib/util.js +12 -0
- package/dist/node_modules/better-sqlite3/package.json +59 -0
- package/dist/ownership-ledger-E3WIEKPL.js +9 -0
- package/dist/package.json +3 -0
- package/dist/path-grants-XRRXHXG7.js +40 -0
- package/dist/paths-LVV5IMQN.js +49 -0
- package/dist/plan-fact-anchors-LMVQZCW5.js +13 -0
- package/dist/plan-store-ODLTTPFB.js +17 -0
- package/dist/plan-templates-5FPFBOL6.js +109 -0
- package/dist/plugin-loader-ZZKX7ZE6.js +22 -0
- package/dist/prefix-budget-62OV5HQC.js +13 -0
- package/dist/project-trust-5WS5MOMU.js +31 -0
- package/dist/provider-cli-ALDQXIT7.js +37 -0
- package/dist/providers-XQYTAVPK.js +11 -0
- package/dist/proxy-resolver-V2Y6534D.js +15 -0
- package/dist/recovery-cli-KPGY6FY3.js +106 -0
- package/dist/review-discipline-MNSYCST5.js +55 -0
- package/dist/review-router-BVQZW3MX.js +18 -0
- package/dist/seed-capsules/seed-capsule-attack-methodology.md +62 -0
- package/dist/seed-capsules/seed-capsule-changgeng.md +31 -0
- package/dist/seed-capsules/seed-capsule-design-aesthetics.md +38 -0
- package/dist/seed-capsules/seed-capsule-diagnostic-ladder.md +54 -0
- package/dist/seed-capsules/seed-capsule-fu.md +39 -0
- package/dist/seed-capsules/seed-capsule-huagai.md +73 -0
- package/dist/seed-capsules/seed-capsule-kaiyang.md +65 -0
- package/dist/seed-capsules/seed-capsule-knowledge-work.md +40 -0
- package/dist/seed-capsules/seed-capsule-tanlang.md +47 -0
- package/dist/seed-capsules/seed-capsule-tianfu.md +23 -0
- package/dist/seed-capsules/seed-capsule-tianliang.md +63 -0
- package/dist/seed-capsules/seed-capsule-tianquan.md +32 -0
- package/dist/seed-capsules/seed-capsule-tianxuan-ccr.md +22 -0
- package/dist/seed-capsules/seed-capsule-tianxuan.md +64 -0
- package/dist/seed-capsules/seed-capsule-yaoguang.md +87 -0
- package/dist/serve-X2R2UTLF.js +170 -0
- package/dist/serve-agent-KHSU6RVV.js +965 -0
- package/dist/session-persist-HUUC772H.js +37 -0
- package/dist/session-registry-6XUD5C4Y.js +15 -0
- package/dist/skill-loader-CK3RMO47.js +48 -0
- package/dist/skills/cli-harness-sop.md +207 -0
- package/dist/spawn-git-4HFU65AH.js +29 -0
- package/dist/sse-EYUTBWUK.js +512 -0
- package/dist/starflow-NOFBMPFU.js +30 -0
- package/dist/streamableHttp-V67CNJMO.js +447 -0
- package/dist/task-contract-6XHBNJQK.js +32 -0
- package/dist/task-ledger-3K4TJIER.js +9 -0
- package/dist/team-orchestrate-S6NHZP7X.js +64 -0
- package/dist/title-extract-QX4XGCYN.js +50 -0
- package/dist/todo-QDXGRZZP.js +31 -0
- package/dist/todo-store-V3TTO5AH.js +12 -0
- package/dist/tool-preset-LU5BYEDZ.js +23 -0
- package/dist/tool-tiers-GD742YBN.js +23 -0
- package/dist/turndown.es-OI55K6C3.js +17373 -0
- package/dist/verification-attribution-EKG4CNUV.js +13 -0
- package/dist/volatile-git-MBTST7RA.js +15 -0
- package/dist/wave-checkpoint-XLIIHXQA.js +30 -0
- package/dist/web-cli-DUG4I35O.js +233 -0
- package/dist/web-search-3IK542AA.js +34 -0
- package/dist/workers/cpu-worker.js +45 -0
- package/dist/workflow-runner-HX7UBAYG.js +297 -0
- package/dist/worktree-baseline-O5NCU6M2.js +9 -0
- package/package.json +122 -0
- package/scripts/check-mobile-env.mjs +76 -0
- package/scripts/fetch-native-sqlite.js +392 -0
- package/scripts/prune-installed-wasms.js +45 -0
- package/scripts/tree-sitter-wasm-keep.js +40 -0
|
@@ -0,0 +1,1167 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --expose-gc --max-old-space-size=4096
|
|
2
|
+
import { createRequire as __rivetCreateRequire } from 'node:module'; const require = __rivetCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
init_esm_shims
|
|
5
|
+
} from "./chunk-5GGOGLSN.js";
|
|
6
|
+
|
|
7
|
+
// src/workers/cpu-tasks.ts
|
|
8
|
+
init_esm_shims();
|
|
9
|
+
|
|
10
|
+
// node_modules/diff/libesm/index.js
|
|
11
|
+
init_esm_shims();
|
|
12
|
+
|
|
13
|
+
// node_modules/diff/libesm/diff/base.js
|
|
14
|
+
init_esm_shims();
|
|
15
|
+
var Diff = class {
|
|
16
|
+
diff(oldStr, newStr, options = {}) {
|
|
17
|
+
let callback;
|
|
18
|
+
if (typeof options === "function") {
|
|
19
|
+
callback = options;
|
|
20
|
+
options = {};
|
|
21
|
+
} else if ("callback" in options) {
|
|
22
|
+
callback = options.callback;
|
|
23
|
+
}
|
|
24
|
+
const oldString = this.castInput(oldStr, options);
|
|
25
|
+
const newString = this.castInput(newStr, options);
|
|
26
|
+
const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
|
|
27
|
+
const newTokens = this.removeEmpty(this.tokenize(newString, options));
|
|
28
|
+
return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
|
|
29
|
+
}
|
|
30
|
+
diffWithOptionsObj(oldTokens, newTokens, options, callback) {
|
|
31
|
+
var _a;
|
|
32
|
+
const done = (value) => {
|
|
33
|
+
value = this.postProcess(value, options);
|
|
34
|
+
if (callback) {
|
|
35
|
+
setTimeout(function() {
|
|
36
|
+
callback(value);
|
|
37
|
+
}, 0);
|
|
38
|
+
return void 0;
|
|
39
|
+
} else {
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
44
|
+
let editLength = 1;
|
|
45
|
+
let maxEditLength = newLen + oldLen;
|
|
46
|
+
if (options.maxEditLength != null) {
|
|
47
|
+
maxEditLength = Math.min(maxEditLength, options.maxEditLength);
|
|
48
|
+
}
|
|
49
|
+
const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;
|
|
50
|
+
const abortAfterTimestamp = Date.now() + maxExecutionTime;
|
|
51
|
+
const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
|
|
52
|
+
let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
|
|
53
|
+
if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
54
|
+
return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
|
|
55
|
+
}
|
|
56
|
+
let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
|
|
57
|
+
const execEditLength = () => {
|
|
58
|
+
for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
|
|
59
|
+
let basePath;
|
|
60
|
+
const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
|
|
61
|
+
if (removePath) {
|
|
62
|
+
bestPath[diagonalPath - 1] = void 0;
|
|
63
|
+
}
|
|
64
|
+
let canAdd = false;
|
|
65
|
+
if (addPath) {
|
|
66
|
+
const addPathNewPos = addPath.oldPos - diagonalPath;
|
|
67
|
+
canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
|
|
68
|
+
}
|
|
69
|
+
const canRemove = removePath && removePath.oldPos + 1 < oldLen;
|
|
70
|
+
if (!canAdd && !canRemove) {
|
|
71
|
+
bestPath[diagonalPath] = void 0;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
|
|
75
|
+
basePath = this.addToPath(addPath, true, false, 0, options);
|
|
76
|
+
} else {
|
|
77
|
+
basePath = this.addToPath(removePath, false, true, 1, options);
|
|
78
|
+
}
|
|
79
|
+
newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
|
|
80
|
+
if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
|
|
81
|
+
return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
|
|
82
|
+
} else {
|
|
83
|
+
bestPath[diagonalPath] = basePath;
|
|
84
|
+
if (basePath.oldPos + 1 >= oldLen) {
|
|
85
|
+
maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
|
|
86
|
+
}
|
|
87
|
+
if (newPos + 1 >= newLen) {
|
|
88
|
+
minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
editLength++;
|
|
93
|
+
};
|
|
94
|
+
if (callback) {
|
|
95
|
+
(function exec() {
|
|
96
|
+
setTimeout(function() {
|
|
97
|
+
if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
|
|
98
|
+
return callback(void 0);
|
|
99
|
+
}
|
|
100
|
+
if (!execEditLength()) {
|
|
101
|
+
exec();
|
|
102
|
+
}
|
|
103
|
+
}, 0);
|
|
104
|
+
})();
|
|
105
|
+
} else {
|
|
106
|
+
while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
|
|
107
|
+
const ret = execEditLength();
|
|
108
|
+
if (ret) {
|
|
109
|
+
return ret;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
addToPath(path, added, removed, oldPosInc, options) {
|
|
115
|
+
const last = path.lastComponent;
|
|
116
|
+
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
117
|
+
return {
|
|
118
|
+
oldPos: path.oldPos + oldPosInc,
|
|
119
|
+
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
120
|
+
};
|
|
121
|
+
} else {
|
|
122
|
+
return {
|
|
123
|
+
oldPos: path.oldPos + oldPosInc,
|
|
124
|
+
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
|
|
129
|
+
const newLen = newTokens.length, oldLen = oldTokens.length;
|
|
130
|
+
let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
|
|
131
|
+
while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
|
|
132
|
+
newPos++;
|
|
133
|
+
oldPos++;
|
|
134
|
+
commonCount++;
|
|
135
|
+
if (options.oneChangePerToken) {
|
|
136
|
+
basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (commonCount && !options.oneChangePerToken) {
|
|
140
|
+
basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
|
|
141
|
+
}
|
|
142
|
+
basePath.oldPos = oldPos;
|
|
143
|
+
return newPos;
|
|
144
|
+
}
|
|
145
|
+
equals(left, right, options) {
|
|
146
|
+
if (options.comparator) {
|
|
147
|
+
return options.comparator(left, right);
|
|
148
|
+
} else {
|
|
149
|
+
return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
removeEmpty(array) {
|
|
153
|
+
const ret = [];
|
|
154
|
+
for (let i = 0; i < array.length; i++) {
|
|
155
|
+
if (array[i]) {
|
|
156
|
+
ret.push(array[i]);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return ret;
|
|
160
|
+
}
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
162
|
+
castInput(value, options) {
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
166
|
+
tokenize(value, options) {
|
|
167
|
+
return Array.from(value);
|
|
168
|
+
}
|
|
169
|
+
join(chars) {
|
|
170
|
+
return chars.join("");
|
|
171
|
+
}
|
|
172
|
+
postProcess(changeObjects, options) {
|
|
173
|
+
return changeObjects;
|
|
174
|
+
}
|
|
175
|
+
get useLongestToken() {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
buildValues(lastComponent, newTokens, oldTokens) {
|
|
179
|
+
const components = [];
|
|
180
|
+
let nextComponent;
|
|
181
|
+
while (lastComponent) {
|
|
182
|
+
components.push(lastComponent);
|
|
183
|
+
nextComponent = lastComponent.previousComponent;
|
|
184
|
+
delete lastComponent.previousComponent;
|
|
185
|
+
lastComponent = nextComponent;
|
|
186
|
+
}
|
|
187
|
+
components.reverse();
|
|
188
|
+
const componentLen = components.length;
|
|
189
|
+
let componentPos = 0, newPos = 0, oldPos = 0;
|
|
190
|
+
for (; componentPos < componentLen; componentPos++) {
|
|
191
|
+
const component = components[componentPos];
|
|
192
|
+
if (!component.removed) {
|
|
193
|
+
if (!component.added && this.useLongestToken) {
|
|
194
|
+
let value = newTokens.slice(newPos, newPos + component.count);
|
|
195
|
+
value = value.map(function(value2, i) {
|
|
196
|
+
const oldValue = oldTokens[oldPos + i];
|
|
197
|
+
return oldValue.length > value2.length ? oldValue : value2;
|
|
198
|
+
});
|
|
199
|
+
component.value = this.join(value);
|
|
200
|
+
} else {
|
|
201
|
+
component.value = this.join(newTokens.slice(newPos, newPos + component.count));
|
|
202
|
+
}
|
|
203
|
+
newPos += component.count;
|
|
204
|
+
if (!component.added) {
|
|
205
|
+
oldPos += component.count;
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
|
|
209
|
+
oldPos += component.count;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return components;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// node_modules/diff/libesm/diff/line.js
|
|
217
|
+
init_esm_shims();
|
|
218
|
+
var LineDiff = class extends Diff {
|
|
219
|
+
constructor() {
|
|
220
|
+
super(...arguments);
|
|
221
|
+
this.tokenize = tokenize;
|
|
222
|
+
}
|
|
223
|
+
equals(left, right, options) {
|
|
224
|
+
if (options.ignoreWhitespace) {
|
|
225
|
+
if (!options.newlineIsToken || !left.includes("\n")) {
|
|
226
|
+
left = left.trim();
|
|
227
|
+
}
|
|
228
|
+
if (!options.newlineIsToken || !right.includes("\n")) {
|
|
229
|
+
right = right.trim();
|
|
230
|
+
}
|
|
231
|
+
} else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
|
|
232
|
+
if (left.endsWith("\n")) {
|
|
233
|
+
left = left.slice(0, -1);
|
|
234
|
+
}
|
|
235
|
+
if (right.endsWith("\n")) {
|
|
236
|
+
right = right.slice(0, -1);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return super.equals(left, right, options);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
var lineDiff = new LineDiff();
|
|
243
|
+
function diffLines(oldStr, newStr, options) {
|
|
244
|
+
return lineDiff.diff(oldStr, newStr, options);
|
|
245
|
+
}
|
|
246
|
+
function tokenize(value, options) {
|
|
247
|
+
if (options.stripTrailingCr) {
|
|
248
|
+
value = value.replace(/\r\n/g, "\n");
|
|
249
|
+
}
|
|
250
|
+
const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
|
|
251
|
+
if (!linesAndNewlines[linesAndNewlines.length - 1]) {
|
|
252
|
+
linesAndNewlines.pop();
|
|
253
|
+
}
|
|
254
|
+
for (let i = 0; i < linesAndNewlines.length; i++) {
|
|
255
|
+
const line = linesAndNewlines[i];
|
|
256
|
+
if (i % 2 && !options.newlineIsToken) {
|
|
257
|
+
retLines[retLines.length - 1] += line;
|
|
258
|
+
} else {
|
|
259
|
+
retLines.push(line);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return retLines;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// node_modules/diff/libesm/patch/create.js
|
|
266
|
+
init_esm_shims();
|
|
267
|
+
function needsQuoting(s) {
|
|
268
|
+
for (let i = 0; i < s.length; i++) {
|
|
269
|
+
if (s[i] < " " || s[i] > "~" || s[i] === '"' || s[i] === "\\") {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
function quoteFileNameIfNeeded(s) {
|
|
276
|
+
if (!needsQuoting(s)) {
|
|
277
|
+
return s;
|
|
278
|
+
}
|
|
279
|
+
let result = '"';
|
|
280
|
+
const bytes = new TextEncoder().encode(s);
|
|
281
|
+
let i = 0;
|
|
282
|
+
while (i < bytes.length) {
|
|
283
|
+
const b = bytes[i];
|
|
284
|
+
if (b === 7) {
|
|
285
|
+
result += "\\a";
|
|
286
|
+
} else if (b === 8) {
|
|
287
|
+
result += "\\b";
|
|
288
|
+
} else if (b === 9) {
|
|
289
|
+
result += "\\t";
|
|
290
|
+
} else if (b === 10) {
|
|
291
|
+
result += "\\n";
|
|
292
|
+
} else if (b === 11) {
|
|
293
|
+
result += "\\v";
|
|
294
|
+
} else if (b === 12) {
|
|
295
|
+
result += "\\f";
|
|
296
|
+
} else if (b === 13) {
|
|
297
|
+
result += "\\r";
|
|
298
|
+
} else if (b === 34) {
|
|
299
|
+
result += '\\"';
|
|
300
|
+
} else if (b === 92) {
|
|
301
|
+
result += "\\\\";
|
|
302
|
+
} else if (b >= 32 && b <= 126) {
|
|
303
|
+
result += String.fromCharCode(b);
|
|
304
|
+
} else {
|
|
305
|
+
result += "\\" + b.toString(8).padStart(3, "0");
|
|
306
|
+
}
|
|
307
|
+
i++;
|
|
308
|
+
}
|
|
309
|
+
result += '"';
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
var INCLUDE_HEADERS = {
|
|
313
|
+
includeIndex: true,
|
|
314
|
+
includeUnderline: true,
|
|
315
|
+
includeFileHeaders: true
|
|
316
|
+
};
|
|
317
|
+
function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
318
|
+
let optionsObj;
|
|
319
|
+
if (!options) {
|
|
320
|
+
optionsObj = {};
|
|
321
|
+
} else if (typeof options === "function") {
|
|
322
|
+
optionsObj = { callback: options };
|
|
323
|
+
} else {
|
|
324
|
+
optionsObj = options;
|
|
325
|
+
}
|
|
326
|
+
if (typeof optionsObj.context === "undefined") {
|
|
327
|
+
optionsObj.context = 4;
|
|
328
|
+
}
|
|
329
|
+
const context = optionsObj.context;
|
|
330
|
+
if (optionsObj.newlineIsToken) {
|
|
331
|
+
throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
|
|
332
|
+
}
|
|
333
|
+
if (!optionsObj.callback) {
|
|
334
|
+
return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
|
|
335
|
+
} else {
|
|
336
|
+
const { callback } = optionsObj;
|
|
337
|
+
diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
|
|
338
|
+
const patch = diffLinesResultToPatch(diff);
|
|
339
|
+
callback(patch);
|
|
340
|
+
} }));
|
|
341
|
+
}
|
|
342
|
+
function diffLinesResultToPatch(diff) {
|
|
343
|
+
if (!diff) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
diff.push({ value: "", lines: [] });
|
|
347
|
+
function contextLines(lines) {
|
|
348
|
+
return lines.map(function(entry) {
|
|
349
|
+
return " " + entry;
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
const hunks = [];
|
|
353
|
+
let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
|
|
354
|
+
for (let i = 0; i < diff.length; i++) {
|
|
355
|
+
const current = diff[i], lines = current.lines || splitLines(current.value);
|
|
356
|
+
current.lines = lines;
|
|
357
|
+
if (current.added || current.removed) {
|
|
358
|
+
if (!oldRangeStart) {
|
|
359
|
+
const prev = diff[i - 1];
|
|
360
|
+
oldRangeStart = oldLine;
|
|
361
|
+
newRangeStart = newLine;
|
|
362
|
+
if (prev) {
|
|
363
|
+
curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
|
|
364
|
+
oldRangeStart -= curRange.length;
|
|
365
|
+
newRangeStart -= curRange.length;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
for (const line of lines) {
|
|
369
|
+
curRange.push((current.added ? "+" : "-") + line);
|
|
370
|
+
}
|
|
371
|
+
if (current.added) {
|
|
372
|
+
newLine += lines.length;
|
|
373
|
+
} else {
|
|
374
|
+
oldLine += lines.length;
|
|
375
|
+
}
|
|
376
|
+
} else {
|
|
377
|
+
if (oldRangeStart) {
|
|
378
|
+
if (lines.length <= context * 2 && i < diff.length - 2) {
|
|
379
|
+
for (const line of contextLines(lines)) {
|
|
380
|
+
curRange.push(line);
|
|
381
|
+
}
|
|
382
|
+
} else {
|
|
383
|
+
const contextSize = Math.min(lines.length, context);
|
|
384
|
+
for (const line of contextLines(lines.slice(0, contextSize))) {
|
|
385
|
+
curRange.push(line);
|
|
386
|
+
}
|
|
387
|
+
const hunk = {
|
|
388
|
+
oldStart: oldRangeStart,
|
|
389
|
+
oldLines: oldLine - oldRangeStart + contextSize,
|
|
390
|
+
newStart: newRangeStart,
|
|
391
|
+
newLines: newLine - newRangeStart + contextSize,
|
|
392
|
+
lines: curRange
|
|
393
|
+
};
|
|
394
|
+
hunks.push(hunk);
|
|
395
|
+
oldRangeStart = 0;
|
|
396
|
+
newRangeStart = 0;
|
|
397
|
+
curRange = [];
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
oldLine += lines.length;
|
|
401
|
+
newLine += lines.length;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
for (const hunk of hunks) {
|
|
405
|
+
for (let i = 0; i < hunk.lines.length; i++) {
|
|
406
|
+
if (hunk.lines[i].endsWith("\n")) {
|
|
407
|
+
hunk.lines[i] = hunk.lines[i].slice(0, -1);
|
|
408
|
+
} else {
|
|
409
|
+
hunk.lines.splice(i + 1, 0, "\");
|
|
410
|
+
i++;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
oldFileName,
|
|
416
|
+
newFileName,
|
|
417
|
+
oldHeader,
|
|
418
|
+
newHeader,
|
|
419
|
+
hunks
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function formatPatch(patch, headerOptions) {
|
|
424
|
+
var _a, _b, _c, _d, _e, _f;
|
|
425
|
+
if (!headerOptions) {
|
|
426
|
+
headerOptions = INCLUDE_HEADERS;
|
|
427
|
+
}
|
|
428
|
+
if (Array.isArray(patch)) {
|
|
429
|
+
if (patch.length > 1 && !headerOptions.includeFileHeaders && !patch.every((p) => p.isGit)) {
|
|
430
|
+
throw new Error("Cannot omit file headers on a multi-file patch. (The result would be unparseable; how would a tool trying to apply the patch know which changes are to which file?)");
|
|
431
|
+
}
|
|
432
|
+
return patch.map((p) => formatPatch(p, headerOptions)).join("\n");
|
|
433
|
+
}
|
|
434
|
+
const ret = [];
|
|
435
|
+
if (patch.isGit) {
|
|
436
|
+
headerOptions = INCLUDE_HEADERS;
|
|
437
|
+
if (!patch.oldFileName) {
|
|
438
|
+
throw new Error("oldFileName must be specified for Git patches");
|
|
439
|
+
}
|
|
440
|
+
if (!patch.newFileName) {
|
|
441
|
+
throw new Error("newFileName must be specified for Git patches");
|
|
442
|
+
}
|
|
443
|
+
let gitOldName = patch.oldFileName;
|
|
444
|
+
let gitNewName = patch.newFileName;
|
|
445
|
+
if (patch.isCreate && gitOldName === "/dev/null") {
|
|
446
|
+
gitOldName = gitNewName.replace(/^b\//, "a/");
|
|
447
|
+
} else if (patch.isDelete && gitNewName === "/dev/null") {
|
|
448
|
+
gitNewName = gitOldName.replace(/^a\//, "b/");
|
|
449
|
+
}
|
|
450
|
+
ret.push("diff --git " + quoteFileNameIfNeeded(gitOldName) + " " + quoteFileNameIfNeeded(gitNewName));
|
|
451
|
+
if (patch.isDelete) {
|
|
452
|
+
ret.push("deleted file mode " + ((_a = patch.oldMode) !== null && _a !== void 0 ? _a : "100644"));
|
|
453
|
+
}
|
|
454
|
+
if (patch.isCreate) {
|
|
455
|
+
ret.push("new file mode " + ((_b = patch.newMode) !== null && _b !== void 0 ? _b : "100644"));
|
|
456
|
+
}
|
|
457
|
+
if (patch.oldMode && patch.newMode && !patch.isDelete && !patch.isCreate) {
|
|
458
|
+
ret.push("old mode " + patch.oldMode);
|
|
459
|
+
ret.push("new mode " + patch.newMode);
|
|
460
|
+
}
|
|
461
|
+
if (patch.isRename) {
|
|
462
|
+
ret.push("rename from " + quoteFileNameIfNeeded(((_c = patch.oldFileName) !== null && _c !== void 0 ? _c : "").replace(/^a\//, "")));
|
|
463
|
+
ret.push("rename to " + quoteFileNameIfNeeded(((_d = patch.newFileName) !== null && _d !== void 0 ? _d : "").replace(/^b\//, "")));
|
|
464
|
+
}
|
|
465
|
+
if (patch.isCopy) {
|
|
466
|
+
ret.push("copy from " + quoteFileNameIfNeeded(((_e = patch.oldFileName) !== null && _e !== void 0 ? _e : "").replace(/^a\//, "")));
|
|
467
|
+
ret.push("copy to " + quoteFileNameIfNeeded(((_f = patch.newFileName) !== null && _f !== void 0 ? _f : "").replace(/^b\//, "")));
|
|
468
|
+
}
|
|
469
|
+
} else {
|
|
470
|
+
if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName && patch.oldFileName !== void 0) {
|
|
471
|
+
ret.push("Index: " + patch.oldFileName);
|
|
472
|
+
}
|
|
473
|
+
if (headerOptions.includeUnderline) {
|
|
474
|
+
ret.push("===================================================================");
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
const hasHunks = patch.hunks.length > 0;
|
|
478
|
+
if (headerOptions.includeFileHeaders && patch.oldFileName !== void 0 && patch.newFileName !== void 0 && (!patch.isGit || hasHunks)) {
|
|
479
|
+
ret.push("--- " + quoteFileNameIfNeeded(patch.oldFileName) + (patch.oldHeader ? " " + patch.oldHeader : ""));
|
|
480
|
+
ret.push("+++ " + quoteFileNameIfNeeded(patch.newFileName) + (patch.newHeader ? " " + patch.newHeader : ""));
|
|
481
|
+
}
|
|
482
|
+
for (let i = 0; i < patch.hunks.length; i++) {
|
|
483
|
+
const hunk = patch.hunks[i];
|
|
484
|
+
const oldStart = hunk.oldLines === 0 ? hunk.oldStart - 1 : hunk.oldStart;
|
|
485
|
+
const newStart = hunk.newLines === 0 ? hunk.newStart - 1 : hunk.newStart;
|
|
486
|
+
ret.push("@@ -" + oldStart + "," + hunk.oldLines + " +" + newStart + "," + hunk.newLines + " @@");
|
|
487
|
+
for (const line of hunk.lines) {
|
|
488
|
+
ret.push(line);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return ret.join("\n") + "\n";
|
|
492
|
+
}
|
|
493
|
+
function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
494
|
+
if (typeof options === "function") {
|
|
495
|
+
options = { callback: options };
|
|
496
|
+
}
|
|
497
|
+
if (!(options === null || options === void 0 ? void 0 : options.callback)) {
|
|
498
|
+
const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
|
|
499
|
+
if (!patchObj) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
return formatPatch(patchObj, options === null || options === void 0 ? void 0 : options.headerOptions);
|
|
503
|
+
} else {
|
|
504
|
+
const { callback } = options;
|
|
505
|
+
structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
|
|
506
|
+
if (!patchObj) {
|
|
507
|
+
callback(void 0);
|
|
508
|
+
} else {
|
|
509
|
+
callback(formatPatch(patchObj, options.headerOptions));
|
|
510
|
+
}
|
|
511
|
+
} }));
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
function splitLines(text) {
|
|
515
|
+
const hasTrailingNl = text.endsWith("\n");
|
|
516
|
+
const result = text.split("\n").map((line) => line + "\n");
|
|
517
|
+
if (hasTrailingNl) {
|
|
518
|
+
result.pop();
|
|
519
|
+
} else {
|
|
520
|
+
result.push(result.pop().slice(0, -1));
|
|
521
|
+
}
|
|
522
|
+
return result;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// src/workers/cpu-tasks.ts
|
|
526
|
+
import { createRequire } from "module";
|
|
527
|
+
import { readFileSync } from "fs";
|
|
528
|
+
|
|
529
|
+
// src/tools/line-endings.ts
|
|
530
|
+
init_esm_shims();
|
|
531
|
+
import { extname } from "path";
|
|
532
|
+
import { open } from "fs/promises";
|
|
533
|
+
var REQUIRED_EOL = {
|
|
534
|
+
".bat": "crlf",
|
|
535
|
+
".cmd": "crlf"
|
|
536
|
+
};
|
|
537
|
+
function detectEol(text) {
|
|
538
|
+
let crlf = 0;
|
|
539
|
+
let lf = 0;
|
|
540
|
+
for (let i = 0; i < text.length; i++) {
|
|
541
|
+
if (text.charCodeAt(i) === 10) {
|
|
542
|
+
if (i > 0 && text.charCodeAt(i - 1) === 13) crlf++;
|
|
543
|
+
else lf++;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
if (crlf === 0 && lf === 0) return null;
|
|
547
|
+
return crlf > lf ? "crlf" : "lf";
|
|
548
|
+
}
|
|
549
|
+
function toLf(text) {
|
|
550
|
+
return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
551
|
+
}
|
|
552
|
+
function applyEol(text, eol) {
|
|
553
|
+
const lf = toLf(text);
|
|
554
|
+
return eol === "crlf" ? lf.replace(/\n/g, "\r\n") : lf;
|
|
555
|
+
}
|
|
556
|
+
function requiredEol(filePath) {
|
|
557
|
+
return REQUIRED_EOL[extname(filePath).toLowerCase()] ?? null;
|
|
558
|
+
}
|
|
559
|
+
function chooseEol(filePath, existingEol, defaultEol = "lf") {
|
|
560
|
+
return requiredEol(filePath) ?? existingEol ?? defaultEol;
|
|
561
|
+
}
|
|
562
|
+
async function detectFileEol(filePath, sampleBytes = 65536) {
|
|
563
|
+
let fh;
|
|
564
|
+
try {
|
|
565
|
+
fh = await open(filePath, "r");
|
|
566
|
+
const buf = Buffer.alloc(sampleBytes);
|
|
567
|
+
const head = await fh.read(buf, 0, sampleBytes, 0);
|
|
568
|
+
const headEol = detectEol(buf.toString("utf-8", 0, head.bytesRead));
|
|
569
|
+
if (headEol !== null) return headEol;
|
|
570
|
+
const size = (await fh.stat()).size;
|
|
571
|
+
if (size <= sampleBytes) return null;
|
|
572
|
+
const tail = await fh.read(buf, 0, sampleBytes, size - sampleBytes);
|
|
573
|
+
return detectEol(buf.toString("utf-8", 0, tail.bytesRead));
|
|
574
|
+
} catch {
|
|
575
|
+
return null;
|
|
576
|
+
} finally {
|
|
577
|
+
await fh?.close().catch(() => {
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// src/tools/ast-grep-napi.ts
|
|
583
|
+
init_esm_shims();
|
|
584
|
+
function isModuleNotFound(err) {
|
|
585
|
+
const code = err?.code;
|
|
586
|
+
return code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND";
|
|
587
|
+
}
|
|
588
|
+
function flattenCause(err) {
|
|
589
|
+
const parts = [];
|
|
590
|
+
let cur = err;
|
|
591
|
+
for (let depth = 0; cur instanceof Error && depth < 4; depth++) {
|
|
592
|
+
parts.push(cur.message);
|
|
593
|
+
cur = cur.cause;
|
|
594
|
+
}
|
|
595
|
+
return [...new Set(parts)].join("\n \u21B3 cause: ");
|
|
596
|
+
}
|
|
597
|
+
async function loadAstGrepNapi(importer = () => import("@ast-grep/napi")) {
|
|
598
|
+
try {
|
|
599
|
+
return { ok: true, napi: await importer() };
|
|
600
|
+
} catch (err) {
|
|
601
|
+
const detail = err instanceof Error ? flattenCause(err) : String(err);
|
|
602
|
+
if (isModuleNotFound(err)) {
|
|
603
|
+
return {
|
|
604
|
+
ok: false,
|
|
605
|
+
message: `\u9519\u8BEF\uFF1A\u672A\u5B89\u88C5 @ast-grep/napi\uFF08\u6216\u7F3A\u5C11\u5F53\u524D\u5E73\u53F0\u7684\u539F\u751F\u5B50\u5305\uFF09\u3002\u8BF7\u8FD0\u884C\uFF1Anpm install @ast-grep/napi
|
|
606
|
+
\u539F\u59CB\u9519\u8BEF\uFF1A${detail}`
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
return {
|
|
610
|
+
ok: false,
|
|
611
|
+
message: `\u9519\u8BEF\uFF1A@ast-grep/napi \u5DF2\u5B89\u88C5\u4F46\u52A0\u8F7D\u5931\u8D25\u2014\u2014\u539F\u751F\u63D2\u4EF6\u65E0\u6CD5\u521D\u59CB\u5316\uFF0C\u5E38\u89C1\u4E8E\u5E73\u53F0/\u67B6\u6784\u4E0D\u5339\u914D\u3001\u6C99\u7BB1\u963B\u65AD dlopen\u3001\u6216\u5B89\u88C5\u6B8B\u7F3A\u3002
|
|
612
|
+
\u539F\u59CB\u9519\u8BEF\uFF1A${detail}
|
|
613
|
+
\u672C\u6B21\u8BF7\u6539\u7528 grep \u5B8C\u6210\u641C\u7D22\uFF1B\u4FEE\u590D\u53EF\u8BD5\uFF1Anpm rebuild @ast-grep/napi`
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// src/tools/ast-shared.ts
|
|
619
|
+
init_esm_shims();
|
|
620
|
+
import { existsSync, readdirSync, lstatSync } from "fs";
|
|
621
|
+
import { resolve, extname as extname2, join } from "path";
|
|
622
|
+
|
|
623
|
+
// src/platform/restricted-paths.ts
|
|
624
|
+
init_esm_shims();
|
|
625
|
+
var WINDOWS_RESTRICTED_PATTERNS = [
|
|
626
|
+
// Known ACL-restricted subdirs under AppData\Local — exact match only.
|
|
627
|
+
// Source: Windows ACL-restricted directories observed in production telemetry.
|
|
628
|
+
/AppData[\\/]Local[\\/]ElevatedDiagnostics([\\/]|$)/i,
|
|
629
|
+
/AppData[\\/]Local[\\/]Packages([\\/]|$)/i,
|
|
630
|
+
/AppData[\\/]Local[\\/]Microsoft[\\/]Windows[\\/]Notifications([\\/]|$)/i,
|
|
631
|
+
/AppData[\\/]Local[\\/]Microsoft[\\/]Windows[\\/]INetCache([\\/]|$)/i,
|
|
632
|
+
/AppData[\\/]Local[\\/]Microsoft[\\/]Windows[\\/]Temporary Internet Files([\\/]|$)/i,
|
|
633
|
+
/AppData[\\/]Local[\\/]Microsoft[\\/]WindowsApps([\\/]|$)/i,
|
|
634
|
+
/Windows[\\/]System32[\\/]config([\\/]|$)/i,
|
|
635
|
+
/Windows[\\/]CSC([\\/]|$)/i,
|
|
636
|
+
/(^|[\\/])System Volume Information([\\/]|$)/i,
|
|
637
|
+
/(^|[\\/])\$Recycle\.?Bin([\\/]|$)/i,
|
|
638
|
+
// matches $RECYCLE.BIN, $Recycle.Bin
|
|
639
|
+
/(^|[\\/])Config\.Msi([\\/]|$)/i
|
|
640
|
+
];
|
|
641
|
+
var MACOS_RESTRICTED_PATTERNS = [
|
|
642
|
+
/(^|\/)\.Spotlight-V100([/]|$)/i,
|
|
643
|
+
/(^|\/)\.fseventsd([/]|$)/i,
|
|
644
|
+
/(^|\/)\.TemporaryItems([/]|$)/i,
|
|
645
|
+
/(^|\/)\.DocumentRevisions-V100([/]|$)/i,
|
|
646
|
+
/(^|\/)\.Trashes([/]|$)/i
|
|
647
|
+
];
|
|
648
|
+
var LINUX_RESTRICTED_PATTERNS = [
|
|
649
|
+
/^\/proc\/\d+\/(fd|map_files|task\/\d+\/fd)([/]|$)/,
|
|
650
|
+
/^\/sys\/kernel\/debug([/]|$)/,
|
|
651
|
+
/^\/sys\/fs\/cgroup([/]|$)/,
|
|
652
|
+
/(^|\/)lost\+found([/]|$)/
|
|
653
|
+
];
|
|
654
|
+
var ALL_RESTRICTED = [
|
|
655
|
+
...WINDOWS_RESTRICTED_PATTERNS,
|
|
656
|
+
...MACOS_RESTRICTED_PATTERNS,
|
|
657
|
+
...LINUX_RESTRICTED_PATTERNS
|
|
658
|
+
];
|
|
659
|
+
function isRestrictedPath(path, code) {
|
|
660
|
+
if (code !== "EPERM" && code !== "EACCES") return false;
|
|
661
|
+
if (!path) return false;
|
|
662
|
+
return ALL_RESTRICTED.some((re) => re.test(path));
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// src/tools/scan-excludes.ts
|
|
666
|
+
init_esm_shims();
|
|
667
|
+
var SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
668
|
+
"node_modules",
|
|
669
|
+
".git",
|
|
670
|
+
"dist",
|
|
671
|
+
".next",
|
|
672
|
+
"build",
|
|
673
|
+
"target",
|
|
674
|
+
"__pycache__",
|
|
675
|
+
"TianshuData"
|
|
676
|
+
]);
|
|
677
|
+
function isScanExcludedDir(name) {
|
|
678
|
+
return SCAN_EXCLUDE_DIRS.has(name);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// src/tools/ast-shared.ts
|
|
682
|
+
var LANG_BY_EXT = {
|
|
683
|
+
".ts": "TypeScript",
|
|
684
|
+
".tsx": "Tsx",
|
|
685
|
+
".js": "JavaScript",
|
|
686
|
+
".jsx": "Tsx",
|
|
687
|
+
".html": "Html",
|
|
688
|
+
".css": "Css",
|
|
689
|
+
// Dynamic languages — registered via registerDynamicLanguage, parsed by name
|
|
690
|
+
// (lowercase), NOT via napi.Lang.X. See DYNAMIC_LANGS + ensureDynamicLangsRegistered.
|
|
691
|
+
".py": "python",
|
|
692
|
+
".pyi": "python",
|
|
693
|
+
".json": "json",
|
|
694
|
+
".jsonc": "json"
|
|
695
|
+
};
|
|
696
|
+
var DYNAMIC_LANGS = /* @__PURE__ */ new Set(["python", "json"]);
|
|
697
|
+
function isDynamicLang(langName) {
|
|
698
|
+
return DYNAMIC_LANGS.has(langName);
|
|
699
|
+
}
|
|
700
|
+
var dynamicLangsRegistered = false;
|
|
701
|
+
async function ensureDynamicLangsRegistered(napi) {
|
|
702
|
+
if (dynamicLangsRegistered) return;
|
|
703
|
+
dynamicLangsRegistered = true;
|
|
704
|
+
const registration = {};
|
|
705
|
+
try {
|
|
706
|
+
const pythonMod = await import("@ast-grep/lang-python");
|
|
707
|
+
registration.python = pythonMod.default ?? pythonMod;
|
|
708
|
+
} catch {
|
|
709
|
+
}
|
|
710
|
+
try {
|
|
711
|
+
const jsonMod = await import("@ast-grep/lang-json");
|
|
712
|
+
registration.json = jsonMod.default ?? jsonMod;
|
|
713
|
+
} catch {
|
|
714
|
+
}
|
|
715
|
+
if (Object.keys(registration).length > 0) {
|
|
716
|
+
try {
|
|
717
|
+
napi.registerDynamicLanguage(registration);
|
|
718
|
+
} catch {
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
function inferLang(filePath) {
|
|
723
|
+
const ext = extname2(filePath).toLowerCase();
|
|
724
|
+
return LANG_BY_EXT[ext] ?? null;
|
|
725
|
+
}
|
|
726
|
+
function resolveLang(explicit, filePath) {
|
|
727
|
+
if (explicit) return explicit;
|
|
728
|
+
return inferLang(filePath);
|
|
729
|
+
}
|
|
730
|
+
var MAX_PARSE_FILE_BYTES = 1024 * 1024;
|
|
731
|
+
function looksBinary(buf) {
|
|
732
|
+
const n = Math.min(buf.length, 8192);
|
|
733
|
+
for (let i = 0; i < n; i++) if (buf[i] === 0) return true;
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
function parseSkipReason(filePath, buf, maxBytes = MAX_PARSE_FILE_BYTES) {
|
|
737
|
+
if (buf.length > maxBytes) {
|
|
738
|
+
const mb = (buf.length / 1024 / 1024).toFixed(1);
|
|
739
|
+
return `${filePath}: \u8DF3\u8FC7\uFF08${mb}MB \u8D85\u8FC7 ${maxBytes / 1024 / 1024}MB \u89E3\u6790\u4E0A\u9650\uFF09`;
|
|
740
|
+
}
|
|
741
|
+
if (looksBinary(buf)) return `${filePath}: \u8DF3\u8FC7\uFF08\u4E8C\u8FDB\u5236\u5185\u5BB9\uFF09`;
|
|
742
|
+
return null;
|
|
743
|
+
}
|
|
744
|
+
function buildLangMap(napi) {
|
|
745
|
+
return {
|
|
746
|
+
TypeScript: napi.Lang.TypeScript,
|
|
747
|
+
Tsx: napi.Lang.Tsx,
|
|
748
|
+
JavaScript: napi.Lang.JavaScript,
|
|
749
|
+
Html: napi.Lang.Html,
|
|
750
|
+
Css: napi.Lang.Css
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
var BASE_EXCLUDE_DIRS = [
|
|
754
|
+
...SCAN_EXCLUDE_DIRS,
|
|
755
|
+
".rivet",
|
|
756
|
+
"out",
|
|
757
|
+
".turbo",
|
|
758
|
+
"coverage",
|
|
759
|
+
".nyc_output"
|
|
760
|
+
];
|
|
761
|
+
function resolveExcludeDirs() {
|
|
762
|
+
const env = process.env.RIVET_AST_EXCLUDE;
|
|
763
|
+
if (!env) return new Set(BASE_EXCLUDE_DIRS);
|
|
764
|
+
const extra = env.split(",").map((s) => s.trim()).filter(Boolean);
|
|
765
|
+
return /* @__PURE__ */ new Set([...BASE_EXCLUDE_DIRS, ...extra]);
|
|
766
|
+
}
|
|
767
|
+
var MAX_FILES = 5e3;
|
|
768
|
+
var MAX_DEPTH = 25;
|
|
769
|
+
var YIELD_EVERY_ENTRIES = 500;
|
|
770
|
+
async function collectFiles(searchPath) {
|
|
771
|
+
const excludeDirs = resolveExcludeDirs();
|
|
772
|
+
const abs = resolve(searchPath);
|
|
773
|
+
if (!existsSync(abs)) return [];
|
|
774
|
+
const stat = lstatSync(abs);
|
|
775
|
+
if (stat.isFile()) return [abs];
|
|
776
|
+
if (!stat.isDirectory()) return [];
|
|
777
|
+
const files = [];
|
|
778
|
+
let entriesSinceYield = 0;
|
|
779
|
+
const walk = async (dir, depth) => {
|
|
780
|
+
if (files.length >= MAX_FILES || depth > MAX_DEPTH) return;
|
|
781
|
+
let entries;
|
|
782
|
+
try {
|
|
783
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
784
|
+
} catch (err) {
|
|
785
|
+
const e = err;
|
|
786
|
+
if (depth > 0 && isRestrictedPath(String(e.path ?? e.message ?? ""), e.code ?? "")) return;
|
|
787
|
+
throw err;
|
|
788
|
+
}
|
|
789
|
+
for (const entry of entries) {
|
|
790
|
+
if (files.length >= MAX_FILES) return;
|
|
791
|
+
const full = join(dir, entry.name);
|
|
792
|
+
if (entry.isDirectory()) {
|
|
793
|
+
if (excludeDirs.has(entry.name)) continue;
|
|
794
|
+
await walk(full, depth + 1);
|
|
795
|
+
} else if (entry.isFile()) {
|
|
796
|
+
files.push(full);
|
|
797
|
+
}
|
|
798
|
+
if (++entriesSinceYield >= YIELD_EVERY_ENTRIES) {
|
|
799
|
+
entriesSinceYield = 0;
|
|
800
|
+
await new Promise((r) => setImmediate(r));
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
await walk(abs, 0);
|
|
805
|
+
return files;
|
|
806
|
+
}
|
|
807
|
+
function collectMetaVarNames(pattern) {
|
|
808
|
+
const seen = /* @__PURE__ */ new Set();
|
|
809
|
+
const vars = [];
|
|
810
|
+
const re = /\$(\$\$)?([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
811
|
+
let m;
|
|
812
|
+
while ((m = re.exec(pattern)) !== null) {
|
|
813
|
+
const name = m[2];
|
|
814
|
+
if (!seen.has(name)) {
|
|
815
|
+
seen.add(name);
|
|
816
|
+
vars.push({ name, multi: m[1] === "$$" });
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
return vars;
|
|
820
|
+
}
|
|
821
|
+
function resolveRuleOrPattern(pattern) {
|
|
822
|
+
try {
|
|
823
|
+
const parsed = JSON.parse(pattern);
|
|
824
|
+
if (parsed && typeof parsed === "object" && "rule" in parsed) {
|
|
825
|
+
return { ruleOrPattern: parsed, isRuleObject: true };
|
|
826
|
+
}
|
|
827
|
+
} catch {
|
|
828
|
+
}
|
|
829
|
+
return { ruleOrPattern: pattern, isRuleObject: false };
|
|
830
|
+
}
|
|
831
|
+
var AST_SCAN_SOFT_MS_DEFAULT = 3e4;
|
|
832
|
+
function astScanSoftMs() {
|
|
833
|
+
const parsed = Number(process.env.RIVET_AST_SCAN_TIMEOUT_MS);
|
|
834
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : AST_SCAN_SOFT_MS_DEFAULT;
|
|
835
|
+
}
|
|
836
|
+
function astScanUnavailable(reason) {
|
|
837
|
+
return `\u9519\u8BEF\uFF1AAST \u89E3\u6790\u4E0D\u53EF\u7528\uFF08${reason}\uFF09\u3002
|
|
838
|
+
\u89E3\u6790\u5728 worker \u7EBF\u7A0B\u6267\u884C\u4EE5\u907F\u514D\u51BB\u7ED3\u4E3B\u7EBF\u7A0B\uFF1B\u4E0D\u53EF\u7528\u65F6\u4E0D\u4F1A\u56DE\u9000\u4E3B\u7EBF\u7A0B\u89E3\u6790\u3002
|
|
839
|
+
\u672C\u6B21\u8BF7\u6539\u7528 grep \u5B8C\u6210\u641C\u7D22\uFF0C\u6216\u7F29\u5C0F paths \u540E\u91CD\u8BD5\u3002`;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
// src/workers/cpu-tasks.ts
|
|
843
|
+
function diffUnifiedRaw(relPath, before, after, timeout) {
|
|
844
|
+
return createTwoFilesPatch(relPath, relPath, before, after, "", "", {
|
|
845
|
+
context: 3,
|
|
846
|
+
timeout
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
function diffStructuredRaw(before, after, timeout) {
|
|
850
|
+
const patch = structuredPatch("a", "a", before, after, "", "", {
|
|
851
|
+
context: 0,
|
|
852
|
+
timeout
|
|
853
|
+
});
|
|
854
|
+
if (!patch) return void 0;
|
|
855
|
+
return { hunks: patch.hunks };
|
|
856
|
+
}
|
|
857
|
+
function diffLinesRaw(oldContent, newContent, timeout) {
|
|
858
|
+
return diffLines(oldContent, newContent, { timeout });
|
|
859
|
+
}
|
|
860
|
+
function parseEventsTailRaw(text, maxEvents) {
|
|
861
|
+
const all = parseEventsJsonlRaw(text);
|
|
862
|
+
if (all.length === 0) {
|
|
863
|
+
return { events: [], diskFirstSeq: 0, lastSeq: 0, artifactIds: [], total: 0 };
|
|
864
|
+
}
|
|
865
|
+
const artifactIds = [];
|
|
866
|
+
for (const e of all) {
|
|
867
|
+
if (e.type === "artifact") artifactIds.push(String(e.data.id));
|
|
868
|
+
}
|
|
869
|
+
return {
|
|
870
|
+
// delegation 事件豁免截尾(M1:stale 对账与回放依赖它们完整;被截尾的
|
|
871
|
+
// 早期 running 节点对账不可见,回放永久卡「运行中」)。与
|
|
872
|
+
// session-manager.trimEventRing 同语义——尾部窗口 + 保留 delegation。
|
|
873
|
+
events: tailExemptDelegation(all, maxEvents),
|
|
874
|
+
diskFirstSeq: all[0].seq,
|
|
875
|
+
lastSeq: all[all.length - 1].seq,
|
|
876
|
+
artifactIds,
|
|
877
|
+
total: all.length
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
function tailExemptDelegation(events, maxEvents) {
|
|
881
|
+
if (events.length <= maxEvents) return events;
|
|
882
|
+
const overflow = events.length - maxEvents;
|
|
883
|
+
const kept = [];
|
|
884
|
+
let dropped = 0;
|
|
885
|
+
for (const e of events) {
|
|
886
|
+
if (dropped < overflow && e.type !== "delegation") {
|
|
887
|
+
dropped++;
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
890
|
+
kept.push(e);
|
|
891
|
+
}
|
|
892
|
+
return kept;
|
|
893
|
+
}
|
|
894
|
+
function parseEventsJsonlRaw(text) {
|
|
895
|
+
const events = [];
|
|
896
|
+
for (const line of text.split("\n")) {
|
|
897
|
+
const trimmed = line.trim();
|
|
898
|
+
if (!trimmed) continue;
|
|
899
|
+
try {
|
|
900
|
+
const parsed = JSON.parse(trimmed);
|
|
901
|
+
if (parsed && typeof parsed.seq === "number" && typeof parsed.type === "string") {
|
|
902
|
+
events.push(parsed);
|
|
903
|
+
}
|
|
904
|
+
} catch {
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
events.sort((a, b) => a.seq - b.seq);
|
|
908
|
+
return events;
|
|
909
|
+
}
|
|
910
|
+
var _esbuild;
|
|
911
|
+
async function esbuildTransformRaw(content, options) {
|
|
912
|
+
if (_esbuild === void 0) {
|
|
913
|
+
try {
|
|
914
|
+
const req = createRequire(import.meta.url);
|
|
915
|
+
_esbuild = req("esbuild");
|
|
916
|
+
} catch {
|
|
917
|
+
_esbuild = null;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
if (!_esbuild) throw new Error("esbuild unavailable in worker");
|
|
921
|
+
await _esbuild.transform(content, options);
|
|
922
|
+
return true;
|
|
923
|
+
}
|
|
924
|
+
async function astScanRaw(args) {
|
|
925
|
+
const result = {
|
|
926
|
+
matches: [],
|
|
927
|
+
filesScanned: 0,
|
|
928
|
+
errors: [],
|
|
929
|
+
skipped: [],
|
|
930
|
+
degraded: []
|
|
931
|
+
};
|
|
932
|
+
const loaded = await loadAstGrepNapi();
|
|
933
|
+
if (!loaded.ok) {
|
|
934
|
+
result.loadError = loaded.message;
|
|
935
|
+
return result;
|
|
936
|
+
}
|
|
937
|
+
const napi = loaded.napi;
|
|
938
|
+
const langMap = buildLangMap(napi);
|
|
939
|
+
await ensureDynamicLangsRegistered(napi);
|
|
940
|
+
const { ruleOrPattern } = resolveRuleOrPattern(args.pattern);
|
|
941
|
+
const metaVarDefs = args.includeMeta ? collectMetaVarNames(args.pattern) : [];
|
|
942
|
+
for (const filePath of args.files) {
|
|
943
|
+
if (result.matches.length >= args.limit) break;
|
|
944
|
+
const langStr = resolveLang(args.explicitLang, filePath);
|
|
945
|
+
if (!langStr) {
|
|
946
|
+
result.errors.push(`${filePath}: \u4E0D\u652F\u6301\u7684\u8BED\u8A00\uFF08\u8BE5\u6269\u5C55\u540D\u65E0\u8BED\u6CD5\uFF09`);
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
const langValue = isDynamicLang(langStr) ? langStr : langMap[langStr];
|
|
950
|
+
if (typeof langValue !== "string") {
|
|
951
|
+
result.errors.push(`${filePath}: LANG_MAP \u5BF9 "${langStr}" \u8FD4\u56DE\u4E86\u975E\u5B57\u7B26\u4E32\u2014\u2014\u53EF\u80FD\u662F @ast-grep/napi API \u53D8\u66F4`);
|
|
952
|
+
continue;
|
|
953
|
+
}
|
|
954
|
+
let buf;
|
|
955
|
+
try {
|
|
956
|
+
buf = readFileSync(filePath);
|
|
957
|
+
} catch {
|
|
958
|
+
result.errors.push(`${filePath}: \u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6`);
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
const skipReason = parseSkipReason(filePath, buf, args.maxBytes);
|
|
962
|
+
if (skipReason) {
|
|
963
|
+
result.skipped.push(skipReason);
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
const source = buf.toString("utf-8");
|
|
967
|
+
result.filesScanned++;
|
|
968
|
+
let root;
|
|
969
|
+
try {
|
|
970
|
+
root = napi.parse(langValue, source).root();
|
|
971
|
+
} catch {
|
|
972
|
+
result.errors.push(`${filePath}: \u89E3\u6790\u9519\u8BEF`);
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
975
|
+
const errorNodes = root.findAll({ rule: { kind: "ERROR" } });
|
|
976
|
+
if (errorNodes.length > 0) {
|
|
977
|
+
result.degraded.push(`${filePath}: ${errorNodes.length} \u5904\u9519\u8BEF\u6062\u590D\u533A`);
|
|
978
|
+
}
|
|
979
|
+
let found;
|
|
980
|
+
try {
|
|
981
|
+
found = root.findAll(ruleOrPattern);
|
|
982
|
+
} catch {
|
|
983
|
+
result.errors.push(`${filePath}: pattern \u7F16\u8BD1\u9519\u8BEF`);
|
|
984
|
+
continue;
|
|
985
|
+
}
|
|
986
|
+
for (const node of found) {
|
|
987
|
+
if (result.matches.length >= args.limit) break;
|
|
988
|
+
const range = node.range();
|
|
989
|
+
const match = {
|
|
990
|
+
file: filePath,
|
|
991
|
+
line: range.start.line + 1,
|
|
992
|
+
column: range.start.column + 1,
|
|
993
|
+
matchText: node.text()
|
|
994
|
+
};
|
|
995
|
+
if (args.includeMeta) {
|
|
996
|
+
match.metaVariables = {};
|
|
997
|
+
for (const { name, multi } of metaVarDefs) {
|
|
998
|
+
if (multi) {
|
|
999
|
+
const mvs = node.getMultipleMatches(name);
|
|
1000
|
+
if (mvs && mvs.length > 0) {
|
|
1001
|
+
const texts = mvs.map((n) => n.text());
|
|
1002
|
+
const nodeCount = texts.length;
|
|
1003
|
+
const lineCount = texts.reduce((sum, t) => sum + t.split("\n").length, 0);
|
|
1004
|
+
const firstLine = texts[0].split("\n")[0].trim().slice(0, 50);
|
|
1005
|
+
match.metaVariables[name] = `${nodeCount}n/${lineCount}L: ${firstLine}`;
|
|
1006
|
+
}
|
|
1007
|
+
} else {
|
|
1008
|
+
const mv = node.getMatch(name);
|
|
1009
|
+
if (mv) match.metaVariables[name] = mv.text().slice(0, 120);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
result.matches.push(match);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
return result;
|
|
1017
|
+
}
|
|
1018
|
+
function interpolateTemplate(template, node) {
|
|
1019
|
+
let result = template;
|
|
1020
|
+
const vars = collectMetaVarNames(template);
|
|
1021
|
+
for (const { name, multi } of vars.sort((a, b) => b.name.length - a.name.length)) {
|
|
1022
|
+
if (multi) {
|
|
1023
|
+
const mvs = node.getMultipleMatches(name);
|
|
1024
|
+
if (mvs && mvs.length > 0) {
|
|
1025
|
+
result = result.replace(new RegExp(`\\$\\$\\${name}`, "g"), mvs.map((n) => n.text()).join(""));
|
|
1026
|
+
}
|
|
1027
|
+
} else {
|
|
1028
|
+
const mv = node.getMatch(name);
|
|
1029
|
+
if (mv) {
|
|
1030
|
+
result = result.replace(new RegExp(`\\$${name}\\b`, "g"), mv.text());
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
return result;
|
|
1035
|
+
}
|
|
1036
|
+
async function astEditComputeRaw(args) {
|
|
1037
|
+
const result = { files: [], errors: [] };
|
|
1038
|
+
const loaded = await loadAstGrepNapi();
|
|
1039
|
+
if (!loaded.ok) {
|
|
1040
|
+
result.loadError = loaded.message;
|
|
1041
|
+
return result;
|
|
1042
|
+
}
|
|
1043
|
+
const napi = loaded.napi;
|
|
1044
|
+
const langMap = buildLangMap(napi);
|
|
1045
|
+
await ensureDynamicLangsRegistered(napi);
|
|
1046
|
+
for (const filePath of args.files) {
|
|
1047
|
+
const langStr = resolveLang(args.explicitLang, filePath);
|
|
1048
|
+
if (!langStr) {
|
|
1049
|
+
result.errors.push(`${filePath}: \u4E0D\u652F\u6301\u7684\u8BED\u8A00`);
|
|
1050
|
+
continue;
|
|
1051
|
+
}
|
|
1052
|
+
const langValue = isDynamicLang(langStr) ? langStr : langMap[langStr];
|
|
1053
|
+
if (typeof langValue !== "string") {
|
|
1054
|
+
result.errors.push(`${filePath}: LANG_MAP \u5BF9 "${langStr}" \u8FD4\u56DE\u4E86\u975E\u5B57\u7B26\u4E32\u2014\u2014\u53EF\u80FD\u662F @ast-grep/napi API \u53D8\u66F4`);
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
let buf;
|
|
1058
|
+
try {
|
|
1059
|
+
buf = readFileSync(filePath);
|
|
1060
|
+
} catch {
|
|
1061
|
+
result.errors.push(`${filePath}: \u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6`);
|
|
1062
|
+
continue;
|
|
1063
|
+
}
|
|
1064
|
+
const skipReason = parseSkipReason(filePath, buf, args.maxBytes);
|
|
1065
|
+
if (skipReason) {
|
|
1066
|
+
result.errors.push(skipReason);
|
|
1067
|
+
continue;
|
|
1068
|
+
}
|
|
1069
|
+
const source = buf.toString("utf-8");
|
|
1070
|
+
const changes = [];
|
|
1071
|
+
let currentSource = source;
|
|
1072
|
+
for (const op of args.ops) {
|
|
1073
|
+
let root;
|
|
1074
|
+
try {
|
|
1075
|
+
root = napi.parse(langValue, currentSource).root();
|
|
1076
|
+
} catch {
|
|
1077
|
+
result.errors.push(`${filePath}: \u64CD\u4F5C "${op.find.slice(0, 40)}" \u89E3\u6790\u9519\u8BEF`);
|
|
1078
|
+
break;
|
|
1079
|
+
}
|
|
1080
|
+
const errorNodes = root.findAll({ rule: { kind: "ERROR" } });
|
|
1081
|
+
if (errorNodes.length > 0) {
|
|
1082
|
+
result.errors.push(`${filePath}: \u89E3\u6790\u9519\u8BEF\uFF08${errorNodes.length} \u4E2A\u8BED\u6CD5\u9519\u8BEF\uFF09`);
|
|
1083
|
+
break;
|
|
1084
|
+
}
|
|
1085
|
+
const { ruleOrPattern: pattern } = resolveRuleOrPattern(op.find);
|
|
1086
|
+
let found;
|
|
1087
|
+
try {
|
|
1088
|
+
found = root.findAll(pattern);
|
|
1089
|
+
} catch {
|
|
1090
|
+
result.errors.push(`${filePath}: \u6A21\u5F0F "${op.find.slice(0, 40)}" \u7F16\u8BD1\u9519\u8BEF`);
|
|
1091
|
+
continue;
|
|
1092
|
+
}
|
|
1093
|
+
if (found.length === 0) continue;
|
|
1094
|
+
const edits = [];
|
|
1095
|
+
const count = Math.min(found.length, args.limit);
|
|
1096
|
+
for (let i = 0; i < count; i++) {
|
|
1097
|
+
const node = found[i];
|
|
1098
|
+
const before = node.text();
|
|
1099
|
+
const range = node.range();
|
|
1100
|
+
changes.push({ before, after: interpolateTemplate(op.replace, node), line: range.start.line + 1 });
|
|
1101
|
+
edits.push({ startPos: range.start.index, endPos: range.end.index, insertedText: interpolateTemplate(op.replace, node) });
|
|
1102
|
+
}
|
|
1103
|
+
edits.sort((a, b) => a.startPos - b.startPos);
|
|
1104
|
+
const deduped = [];
|
|
1105
|
+
let skippedOverlap = 0;
|
|
1106
|
+
for (const e of edits) {
|
|
1107
|
+
const prev = deduped[deduped.length - 1];
|
|
1108
|
+
if (prev && e.startPos < prev.endPos) {
|
|
1109
|
+
skippedOverlap++;
|
|
1110
|
+
continue;
|
|
1111
|
+
}
|
|
1112
|
+
deduped.push(e);
|
|
1113
|
+
}
|
|
1114
|
+
if (skippedOverlap > 0) {
|
|
1115
|
+
result.errors.push(`${filePath}: \u5DF2\u8DF3\u8FC7 ${skippedOverlap} \u4E2A\u91CD\u53E0\u5339\u914D\uFF08"${op.find.slice(0, 40)}"\uFF09\u2014\u2014\u5D4C\u5957\u8303\u56F4\u4F1A\u7834\u574F\u7F16\u8F91`);
|
|
1116
|
+
}
|
|
1117
|
+
try {
|
|
1118
|
+
currentSource = root.commitEdits(deduped);
|
|
1119
|
+
} catch {
|
|
1120
|
+
result.errors.push(`${filePath}: \u64CD\u4F5C "${op.find.slice(0, 40)}" \u7684 commitEdits \u5931\u8D25`);
|
|
1121
|
+
break;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
if (changes.length > 0) {
|
|
1125
|
+
let syntaxOk = true;
|
|
1126
|
+
if (!args.dryRun) {
|
|
1127
|
+
try {
|
|
1128
|
+
const finalRoot = napi.parse(langValue, currentSource).root();
|
|
1129
|
+
const finalErrors = finalRoot.findAll({ rule: { kind: "ERROR" } });
|
|
1130
|
+
if (finalErrors.length > 0) {
|
|
1131
|
+
result.errors.push(`${filePath}: \u7F16\u8F91\u540E\u8BED\u6CD5\u9519\u8BEF\uFF08${finalErrors.length} \u4E2A ERROR \u8282\u70B9\uFF09\u2014\u2014\u6587\u4EF6\u672A\u5199\u5165\uFF0C\u66F4\u6539\u5DF2\u4E22\u5F03`);
|
|
1132
|
+
syntaxOk = false;
|
|
1133
|
+
}
|
|
1134
|
+
} catch {
|
|
1135
|
+
result.errors.push(`${filePath}: \u7F16\u8F91\u540E\u89E3\u6790\u5931\u8D25\u2014\u2014\u6587\u4EF6\u672A\u5199\u5165\uFF0C\u66F4\u6539\u5DF2\u4E22\u5F03`);
|
|
1136
|
+
syntaxOk = false;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
result.files.push({ file: filePath, newSource: currentSource, changes, syntaxOk, existingEol: detectEol(source) });
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
return result;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
export {
|
|
1146
|
+
isRestrictedPath,
|
|
1147
|
+
SCAN_EXCLUDE_DIRS,
|
|
1148
|
+
isScanExcludedDir,
|
|
1149
|
+
MAX_PARSE_FILE_BYTES,
|
|
1150
|
+
collectFiles,
|
|
1151
|
+
resolveRuleOrPattern,
|
|
1152
|
+
astScanSoftMs,
|
|
1153
|
+
astScanUnavailable,
|
|
1154
|
+
detectEol,
|
|
1155
|
+
toLf,
|
|
1156
|
+
applyEol,
|
|
1157
|
+
chooseEol,
|
|
1158
|
+
detectFileEol,
|
|
1159
|
+
diffUnifiedRaw,
|
|
1160
|
+
diffStructuredRaw,
|
|
1161
|
+
diffLinesRaw,
|
|
1162
|
+
parseEventsTailRaw,
|
|
1163
|
+
parseEventsJsonlRaw,
|
|
1164
|
+
esbuildTransformRaw,
|
|
1165
|
+
astScanRaw,
|
|
1166
|
+
astEditComputeRaw
|
|
1167
|
+
};
|