0sec-cli 0.15.0 → 0.17.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/0sec.js +322 -0
- package/README.md +63 -52
- package/attacks/data-exfiltration/pii-leakage.yaml +27 -0
- package/attacks/encoding-bypass/base64-encoding.yaml +24 -0
- package/attacks/jailbreak/dan-roleplay.yaml +27 -0
- package/attacks/jailbreak/hypothetical-scenario.yaml +25 -0
- package/attacks/jailbreak/multilingual-bypass.yaml +22 -0
- package/attacks/output-manipulation/harmful-content.yaml +25 -0
- package/attacks/prompt-injection/context-manipulation.yaml +32 -0
- package/attacks/prompt-injection/direct-injection.yaml +28 -0
- package/attacks/prompt-injection/indirect-injection.yaml +33 -0
- package/attacks/system-prompt-extraction/direct-ask.yaml +30 -0
- package/attacks/system-prompt-extraction/markdown-exfil.yaml +26 -0
- package/attacks/tool-misuse/ssrf-via-tools.yaml +27 -0
- package/chunks/adapt-loop-ECQG7454.js +18 -0
- package/chunks/adgraph-JLGA6RYI.js +54 -0
- package/chunks/agent/skills/frameworks/entra-id.yaml +63 -0
- package/chunks/agent/skills/frameworks/graphql-introspection.yaml +116 -0
- package/chunks/agent/skills/frameworks/nextjs.yaml +82 -0
- package/chunks/agent/skills/frameworks/python-web.yaml +85 -0
- package/chunks/agent/skills/frameworks/supabase.yaml +83 -0
- package/chunks/agent/skills/frameworks/wordpress-deep.yaml +122 -0
- package/chunks/agent/skills/techniques/ad-attack-paths.yaml +57 -0
- package/chunks/agent/skills/techniques/advisory-disclosure.yaml +59 -0
- package/chunks/agent/skills/techniques/assumption-mining.yaml +53 -0
- package/chunks/agent/skills/techniques/blind-exploitation.yaml +143 -0
- package/chunks/agent/skills/techniques/crypto-misuse.yaml +88 -0
- package/chunks/agent/skills/techniques/cve-poc-adaptation.yaml +82 -0
- package/chunks/agent/skills/techniques/entra-attack-paths.yaml +55 -0
- package/chunks/agent/skills/techniques/http-conformance-diff.yaml +48 -0
- package/chunks/agent/skills/techniques/jwt-attacks.yaml +137 -0
- package/chunks/agent/skills/techniques/kernel-weaponization.yaml +53 -0
- package/chunks/agent/skills/techniques/llm-excessive-agency.yaml +55 -0
- package/chunks/agent/skills/techniques/llm-insecure-output-handling.yaml +56 -0
- package/chunks/agent/skills/techniques/llm-prompt-injection.yaml +54 -0
- package/chunks/agent/skills/techniques/llm-prompt-layer-write.yaml +68 -0
- package/chunks/agent/skills/techniques/llm-rag-poisoning.yaml +57 -0
- package/chunks/agent/skills/techniques/llm-safety-eval.yaml +51 -0
- package/chunks/agent/skills/techniques/npm-ecosystem.yaml +51 -0
- package/chunks/agent/skills/techniques/poc-verification.yaml +55 -0
- package/chunks/agent/skills/techniques/race-condition.yaml +122 -0
- package/chunks/agent/skills/techniques/scoped-fix.yaml +49 -0
- package/chunks/agent/skills/techniques/seedless-depth-review.yaml +59 -0
- package/chunks/agent/skills/techniques/spec-differential.yaml +48 -0
- package/chunks/agent/skills/techniques/variant-hunting.yaml +55 -0
- package/chunks/agent/skills/vulnerabilities/cardano-eutxo-validators.yaml +72 -0
- package/chunks/agent/skills/vulnerabilities/command-injection.yaml +99 -0
- package/chunks/agent/skills/vulnerabilities/deserialization-chains.yaml +106 -0
- package/chunks/agent/skills/vulnerabilities/native-memory-safety.yaml +93 -0
- package/chunks/agent/skills/vulnerabilities/path-traversal.yaml +78 -0
- package/chunks/agent/skills/vulnerabilities/prototype-pollution.yaml +132 -0
- package/chunks/agent/skills/vulnerabilities/request-smuggling.yaml +129 -0
- package/chunks/agent/skills/vulnerabilities/sqli-advanced.yaml +102 -0
- package/chunks/agent/skills/vulnerabilities/ssrf-bypass.yaml +84 -0
- package/chunks/agent/skills/vulnerabilities/ssti-exploitation.yaml +112 -0
- package/chunks/agent/skills/vulnerabilities/structural-sqli.yaml +91 -0
- package/chunks/appsec-catalog-CBWHGTEL.js +24 -0
- package/chunks/artifact-scraper-GJEZMOHF.js +34 -0
- package/chunks/assumption-mining-BVMMUZHB.js +79 -0
- package/chunks/chunk-2CJ776PV.js +2430 -0
- package/chunks/chunk-2RMLOJVB.js +47 -0
- package/chunks/chunk-2SANI5RH.js +4728 -0
- package/chunks/chunk-3MOLBTLS.js +953 -0
- package/chunks/chunk-3QFDYBZQ.js +5108 -0
- package/chunks/chunk-47TQJWDH.js +3729 -0
- package/chunks/chunk-4Y4KQJXE.js +600 -0
- package/chunks/chunk-53G27VPS.js +136 -0
- package/chunks/chunk-57ZENEX2.js +169 -0
- package/chunks/chunk-5G3ZXFBW.js +182 -0
- package/chunks/chunk-6LKRLK2R.js +542 -0
- package/chunks/chunk-7DQEV5QI.js +287 -0
- package/chunks/chunk-A6CLR72I.js +235 -0
- package/chunks/chunk-BKZFDZ23.js +361 -0
- package/chunks/chunk-CLHCDHP4.js +471 -0
- package/chunks/chunk-D6S3IIPG.js +518 -0
- package/chunks/chunk-DN25OQQA.js +1070 -0
- package/chunks/chunk-DW5UWPFY.js +275 -0
- package/chunks/chunk-F3WBKITT.js +687 -0
- package/chunks/chunk-H2FFLZNK.js +3 -0
- package/chunks/chunk-H44E2CRN.js +193 -0
- package/chunks/chunk-HDWV7PGI.js +596 -0
- package/chunks/chunk-HE7LCA7G.js +381 -0
- package/chunks/chunk-HT6P7RY3.js +2597 -0
- package/chunks/chunk-IOL7D5YV.js +515 -0
- package/chunks/chunk-IORC6MQX.js +72828 -0
- package/chunks/chunk-IR537GON.js +49 -0
- package/chunks/chunk-K26SZ37E.js +5735 -0
- package/chunks/chunk-KKGE5RQE.js +1094 -0
- package/chunks/chunk-KLTNTE2Z.js +121 -0
- package/chunks/chunk-KTQDLNSR.js +1732 -0
- package/chunks/chunk-LOHTE223.js +2572 -0
- package/chunks/chunk-LP3HHYQU.js +245 -0
- package/chunks/chunk-MMLDQR4H.js +852 -0
- package/chunks/chunk-MYVT64FN.js +16 -0
- package/chunks/chunk-O462Y7P2.js +33019 -0
- package/chunks/chunk-OEFNRYI2.js +150 -0
- package/chunks/chunk-P6WKNFWX.js +1968 -0
- package/chunks/chunk-QI233I24.js +333 -0
- package/chunks/chunk-QJQKHO7G.js +917 -0
- package/chunks/chunk-QKICO43A.js +808 -0
- package/chunks/chunk-QOKTUOU2.js +102 -0
- package/chunks/chunk-RDZYQQLW.js +596 -0
- package/chunks/chunk-RJWOYEOG.js +271 -0
- package/chunks/chunk-RRMJC3ZE.js +105 -0
- package/chunks/chunk-RWONANDA.js +973 -0
- package/chunks/chunk-SAFFWQW4.js +5921 -0
- package/chunks/chunk-SF4KZ4O3.js +502 -0
- package/chunks/chunk-SNKTC4BP.js +1422 -0
- package/chunks/chunk-SOG2U7B3.js +662 -0
- package/chunks/chunk-SZJCPG2I.js +110 -0
- package/chunks/chunk-UJ4IK5PO.js +2010 -0
- package/chunks/chunk-UM3ZNQIM.js +9329 -0
- package/chunks/chunk-VGRDNSHA.js +3249 -0
- package/chunks/chunk-VQG4FT5D.js +685 -0
- package/chunks/chunk-WKNNZVJS.js +2798 -0
- package/chunks/chunk-WU6AFRAZ.js +1167 -0
- package/chunks/chunk-WVTBZEQO.js +1531 -0
- package/chunks/chunk-YLMN3N25.js +4054 -0
- package/chunks/commands-U3AMV5ZU.js +16795 -0
- package/chunks/corpus-v1.json +403 -0
- package/chunks/cost-ledger-ZCKMBJEN.js +13 -0
- package/chunks/data/appsec-archetypes.json +102 -0
- package/chunks/data/chromium-archetypes.json +204 -0
- package/chunks/data/freebsd-archetypes.json +171 -0
- package/chunks/data/kernel-archetypes.json +611 -0
- package/chunks/db-26NGQFKO.js +16 -0
- package/chunks/disclose-A6AEIEDA.js +132 -0
- package/chunks/dist-FDKALV4R.js +2772 -0
- package/chunks/dist-GL66KMUX.js +74 -0
- package/chunks/dist-JR67XKYO.js +159 -0
- package/chunks/eval-runner-DDLE5RQ3.js +27 -0
- package/chunks/example-manifest.json +95 -0
- package/chunks/exploit-agent-XP23ISN7.js +98 -0
- package/chunks/exploit-autoclimb-E6T7RRSC.js +81 -0
- package/chunks/exploit-climb-2FAUP6XU.js +358 -0
- package/chunks/fix-IG7LYXH3.js +12 -0
- package/chunks/github-issues-MJ6OYOOU.js +157 -0
- package/chunks/harness-HWOYFKFY.js +22 -0
- package/chunks/http-conformance-DU66MZIU.js +11 -0
- package/chunks/http-sender-GWH2IYEA.js +10 -0
- package/chunks/hunt-scan-XPELSPQQ.js +38 -0
- package/chunks/identity-6ZAIIWOR.js +191 -0
- package/chunks/kernel-primitive-TENE3R7T.js +44 -0
- package/chunks/kernel-vm-runner-4F6QSNFY.js +62 -0
- package/chunks/memsafety-scan-J7SECV5W.js +16 -0
- package/chunks/native-loop-NTONUDP7.js +54 -0
- package/chunks/npm-detectors-KB5Y5ZFX.js +69 -0
- package/chunks/npm-dynamic-discovery-AHROOZDB.js +13 -0
- package/chunks/orchestrate-ZUWAUWBC.js +62 -0
- package/chunks/pipeline-FCARFZU3.js +14 -0
- package/chunks/pre-recon-cve-66EB6G4M.js +351 -0
- package/chunks/prepare-MYY743TK.js +13 -0
- package/chunks/process-3Q7QJIOZ.js +13 -0
- package/chunks/replay-runner-RRR4E2A7.js +39 -0
- package/chunks/run-ESNN4V5W.js +32632 -0
- package/chunks/runtime-62ZQAH7H.js +43 -0
- package/chunks/runtime-J7PLXZNM.js +12 -0
- package/chunks/scan-stream-FHI2FYZE.js +96 -0
- package/chunks/scope-BI7BF4ZY.js +18 -0
- package/chunks/session-store-BCFQYDCE.js +28 -0
- package/chunks/source-files-PWRQR6LY.js +12 -0
- package/chunks/specdrift-WCLH6TTQ.js +19 -0
- package/chunks/variant-candidates-6KM6F6MD.js +13 -0
- package/chunks/web-recon-prepass-DPVCBRZA.js +1148 -0
- package/dashboard/assets/0sec-icon-66SreztZ.gif +0 -0
- package/dashboard/assets/bot-yILPnRgD.js +1 -0
- package/dashboard/assets/chevron-down-BeDJ-Vka.js +1 -0
- package/dashboard/assets/circle-alert-BEnMBMT-.js +1 -0
- package/dashboard/assets/client-DRYsuOGl.js +9 -0
- package/dashboard/assets/copy-Bi5vzoF9.js +1 -0
- package/dashboard/assets/desktop-CXTQonNm.js +32 -0
- package/dashboard/assets/desktop-NOekk4QS.css +1 -0
- package/dashboard/assets/dist-CmX-h7a4.js +1 -0
- package/dashboard/assets/dist-DAwYQmf_.js +45 -0
- package/dashboard/assets/findings-page-CACW9nw2.js +5 -0
- package/dashboard/assets/format-PoISqsES.js +1 -0
- package/dashboard/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dashboard/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dashboard/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dashboard/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dashboard/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
- package/dashboard/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
- package/dashboard/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dashboard/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
- package/dashboard/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
- package/dashboard/assets/jsx-runtime-C7oxC63R.js +1 -0
- package/dashboard/assets/live-page-DrgQqQK5.js +1 -0
- package/dashboard/assets/meta-tile-CcskIV_o.js +1 -0
- package/dashboard/assets/operations-BKE8T-vY.css +2 -0
- package/dashboard/assets/operations-D8nUP5_m.js +4 -0
- package/dashboard/assets/operations-app-CQQhG54n.js +2 -0
- package/dashboard/assets/overview-page-DTGS8dPo.js +1 -0
- package/dashboard/assets/page-header-MFVvEtZW.js +1 -0
- package/dashboard/assets/play-Dwo-9xt6.js +1 -0
- package/dashboard/assets/scans-page-ChVtq8Us.js +1 -0
- package/dashboard/assets/search-CiooTLck.js +1 -0
- package/dashboard/assets/siren-CCBwTSuk.js +1 -0
- package/dashboard/assets/table-BYS-nIVA.js +1 -0
- package/dashboard/assets/tabs-DivxbhQy.js +1 -0
- package/dashboard/desktop.html +21 -0
- package/dashboard/index.html +15 -0
- package/package.json +30 -18
- package/bin/0sec.cjs +0 -361
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __0secCreateRequire } from "node:module";
|
|
3
|
+
const require = __0secCreateRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
// packages/core/dist/agent/apply-patch.js
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { dirname } from "node:path";
|
|
8
|
+
var BEGIN = "*** Begin Patch";
|
|
9
|
+
var END = "*** End Patch";
|
|
10
|
+
function parsePatch(input) {
|
|
11
|
+
const text = input.replace(/\r\n/g, "\n");
|
|
12
|
+
const lines = text.split("\n");
|
|
13
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
14
|
+
lines.pop();
|
|
15
|
+
}
|
|
16
|
+
if (lines.length === 0 || lines[0].trim() !== BEGIN) {
|
|
17
|
+
throw new Error(`apply_patch: envelope must start with "${BEGIN}" (got: ${lines[0] ?? "<empty>"})`);
|
|
18
|
+
}
|
|
19
|
+
if (lines[lines.length - 1].trim() !== END) {
|
|
20
|
+
throw new Error(`apply_patch: envelope must end with "${END}"`);
|
|
21
|
+
}
|
|
22
|
+
const body = lines.slice(1, -1);
|
|
23
|
+
const ops = [];
|
|
24
|
+
let i = 0;
|
|
25
|
+
while (i < body.length) {
|
|
26
|
+
const line = body[i];
|
|
27
|
+
const trimmed = line.trim();
|
|
28
|
+
if (trimmed === "") {
|
|
29
|
+
i += 1;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const addMatch = /^\*\*\* Add File: (.+)$/.exec(trimmed);
|
|
33
|
+
const replaceMatch = /^\*\*\* Replace File: (.+)$/.exec(trimmed);
|
|
34
|
+
const updateMatch = /^\*\*\* Update File: (.+)$/.exec(trimmed);
|
|
35
|
+
const deleteMatch = /^\*\*\* Delete File: (.+)$/.exec(trimmed);
|
|
36
|
+
if (addMatch || replaceMatch) {
|
|
37
|
+
const path = (addMatch?.[1] ?? replaceMatch[1]).trim();
|
|
38
|
+
const overwrite = replaceMatch !== null;
|
|
39
|
+
i += 1;
|
|
40
|
+
const contentLines = [];
|
|
41
|
+
while (i < body.length && !isOpHeader(body[i])) {
|
|
42
|
+
const ln = body[i];
|
|
43
|
+
if (ln.length === 0) {
|
|
44
|
+
contentLines.push("");
|
|
45
|
+
} else if (ln[0] === "+") {
|
|
46
|
+
contentLines.push(ln.slice(1));
|
|
47
|
+
} else {
|
|
48
|
+
throw new Error(`apply_patch: Add/Replace body lines must start with "+" (got: ${JSON.stringify(ln)})`);
|
|
49
|
+
}
|
|
50
|
+
i += 1;
|
|
51
|
+
}
|
|
52
|
+
ops.push({
|
|
53
|
+
kind: "add",
|
|
54
|
+
path,
|
|
55
|
+
contents: contentLines.join("\n"),
|
|
56
|
+
overwrite
|
|
57
|
+
});
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (deleteMatch) {
|
|
61
|
+
ops.push({ kind: "delete", path: deleteMatch[1].trim() });
|
|
62
|
+
i += 1;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (updateMatch) {
|
|
66
|
+
const path = updateMatch[1].trim();
|
|
67
|
+
i += 1;
|
|
68
|
+
const hunks = [];
|
|
69
|
+
while (i < body.length && !isOpHeader(body[i])) {
|
|
70
|
+
const hunkLine = body[i];
|
|
71
|
+
if (!hunkLine.startsWith("@@")) {
|
|
72
|
+
throw new Error(`apply_patch: Update File body must begin with "@@ <anchor>" hunk header (got: ${JSON.stringify(hunkLine)})`);
|
|
73
|
+
}
|
|
74
|
+
const anchor = hunkLine.slice(2).trim();
|
|
75
|
+
i += 1;
|
|
76
|
+
const hunkBody = [];
|
|
77
|
+
while (i < body.length && !isOpHeader(body[i]) && !body[i].startsWith("@@")) {
|
|
78
|
+
const ln = body[i];
|
|
79
|
+
if (ln === "") {
|
|
80
|
+
hunkBody.push({ kind: "context", text: "" });
|
|
81
|
+
} else if (ln[0] === " ") {
|
|
82
|
+
hunkBody.push({ kind: "context", text: ln.slice(1) });
|
|
83
|
+
} else if (ln[0] === "+") {
|
|
84
|
+
hunkBody.push({ kind: "add", text: ln.slice(1) });
|
|
85
|
+
} else if (ln[0] === "-") {
|
|
86
|
+
hunkBody.push({ kind: "del", text: ln.slice(1) });
|
|
87
|
+
} else {
|
|
88
|
+
throw new Error(`apply_patch: Update hunk body lines must start with " ", "+", or "-" (got: ${JSON.stringify(ln)})`);
|
|
89
|
+
}
|
|
90
|
+
i += 1;
|
|
91
|
+
}
|
|
92
|
+
hunks.push({ anchor, body: hunkBody });
|
|
93
|
+
}
|
|
94
|
+
if (hunks.length === 0) {
|
|
95
|
+
throw new Error(`apply_patch: "Update File: ${path}" requires at least one "@@" hunk`);
|
|
96
|
+
}
|
|
97
|
+
ops.push({ kind: "update", path, hunks });
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
throw new Error(`apply_patch: unknown directive (got: ${JSON.stringify(trimmed)})`);
|
|
101
|
+
}
|
|
102
|
+
if (ops.length === 0) {
|
|
103
|
+
throw new Error("apply_patch: envelope contains no operations");
|
|
104
|
+
}
|
|
105
|
+
return ops;
|
|
106
|
+
}
|
|
107
|
+
function isOpHeader(line) {
|
|
108
|
+
return line.startsWith("*** Add File:") || line.startsWith("*** Replace File:") || line.startsWith("*** Update File:") || line.startsWith("*** Delete File:");
|
|
109
|
+
}
|
|
110
|
+
function applyPatchOps(ops, pathResolver) {
|
|
111
|
+
const applied = [];
|
|
112
|
+
for (const op of ops) {
|
|
113
|
+
const abs = pathResolver(op.path);
|
|
114
|
+
if (op.kind === "add") {
|
|
115
|
+
if (!op.overwrite && existsSync(abs)) {
|
|
116
|
+
throw new Error(`apply_patch: Add File "${op.path}" failed \u2014 file already exists. Use "*** Replace File: ${op.path}" to overwrite.`);
|
|
117
|
+
}
|
|
118
|
+
mkdirSync(dirname(abs), { recursive: true });
|
|
119
|
+
writeFileSync(abs, op.contents, "utf-8");
|
|
120
|
+
applied.push({ kind: "add", path: op.path });
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (op.kind === "delete") {
|
|
124
|
+
if (!existsSync(abs)) {
|
|
125
|
+
throw new Error(`apply_patch: Delete File "${op.path}" failed \u2014 file does not exist`);
|
|
126
|
+
}
|
|
127
|
+
unlinkSync(abs);
|
|
128
|
+
applied.push({ kind: "delete", path: op.path });
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (!existsSync(abs)) {
|
|
132
|
+
throw new Error(`apply_patch: Update File "${op.path}" failed \u2014 file does not exist`);
|
|
133
|
+
}
|
|
134
|
+
const original = readFileSync(abs, "utf-8");
|
|
135
|
+
const updated = applyUpdateHunks(original, op.path, op.hunks);
|
|
136
|
+
writeFileSync(abs, updated, "utf-8");
|
|
137
|
+
applied.push({ kind: "update", path: op.path });
|
|
138
|
+
}
|
|
139
|
+
return { applied };
|
|
140
|
+
}
|
|
141
|
+
function applyUpdateHunks(source, logicalPath, hunks) {
|
|
142
|
+
const hadTrailingNewline = source.endsWith("\n");
|
|
143
|
+
const sourceBody = hadTrailingNewline ? source.slice(0, -1) : source;
|
|
144
|
+
let lines = sourceBody.split("\n");
|
|
145
|
+
for (const hunk of hunks) {
|
|
146
|
+
const anchorIdx = locateAnchor(lines, hunk.anchor, logicalPath);
|
|
147
|
+
const { newLines, consumed } = applyOneHunk(lines, anchorIdx, hunk, logicalPath);
|
|
148
|
+
lines = [
|
|
149
|
+
...lines.slice(0, anchorIdx),
|
|
150
|
+
...newLines,
|
|
151
|
+
...lines.slice(anchorIdx + consumed)
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
return lines.join("\n") + (hadTrailingNewline ? "\n" : "");
|
|
155
|
+
}
|
|
156
|
+
function locateAnchor(lines, anchor, logicalPath) {
|
|
157
|
+
if (anchor === "") {
|
|
158
|
+
return 0;
|
|
159
|
+
}
|
|
160
|
+
const matches = [];
|
|
161
|
+
for (let i = 0; i < lines.length; i++) {
|
|
162
|
+
if (lines[i].includes(anchor)) {
|
|
163
|
+
matches.push(i);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (matches.length === 0) {
|
|
167
|
+
throw new Error(`apply_patch: anchor "${anchor}" not found in ${logicalPath}; refine the @@ anchor to a line that exists in the file`);
|
|
168
|
+
}
|
|
169
|
+
if (matches.length > 1) {
|
|
170
|
+
throw new Error(`apply_patch: context "${anchor}" matches ${matches.length} locations in ${logicalPath}; refine the @@ anchor to be unique`);
|
|
171
|
+
}
|
|
172
|
+
return matches[0];
|
|
173
|
+
}
|
|
174
|
+
function applyOneHunk(lines, anchorIdx, hunk, logicalPath) {
|
|
175
|
+
const newLines = [];
|
|
176
|
+
let cursor = anchorIdx;
|
|
177
|
+
for (const entry of hunk.body) {
|
|
178
|
+
if (entry.kind === "context") {
|
|
179
|
+
const observed = lines[cursor];
|
|
180
|
+
if (observed === void 0 || observed !== entry.text) {
|
|
181
|
+
throw new Error(`apply_patch: context mismatch in ${logicalPath} at line ${cursor + 1}: expected ${JSON.stringify(entry.text)}, got ${JSON.stringify(observed ?? "<eof>")}`);
|
|
182
|
+
}
|
|
183
|
+
newLines.push(entry.text);
|
|
184
|
+
cursor += 1;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (entry.kind === "del") {
|
|
188
|
+
const observed = lines[cursor];
|
|
189
|
+
if (observed === void 0 || observed !== entry.text) {
|
|
190
|
+
throw new Error(`apply_patch: removed line mismatch in ${logicalPath} at line ${cursor + 1}: expected ${JSON.stringify(entry.text)}, got ${JSON.stringify(observed ?? "<eof>")}`);
|
|
191
|
+
}
|
|
192
|
+
cursor += 1;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
newLines.push(entry.text);
|
|
196
|
+
}
|
|
197
|
+
return { newLines, consumed: cursor - anchorIdx };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// packages/core/dist/agent/tools/scope-path.js
|
|
201
|
+
import { lstatSync, realpathSync } from "node:fs";
|
|
202
|
+
import { basename, dirname as dirname2, isAbsolute, resolve, sep } from "node:path";
|
|
203
|
+
function pathEntryExists(path) {
|
|
204
|
+
try {
|
|
205
|
+
lstatSync(path);
|
|
206
|
+
return true;
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (error.code === "ENOENT")
|
|
209
|
+
return false;
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function canonicalizePath(path) {
|
|
214
|
+
const missingSegments = [];
|
|
215
|
+
let existingPath = path;
|
|
216
|
+
while (!pathEntryExists(existingPath)) {
|
|
217
|
+
const parent = dirname2(existingPath);
|
|
218
|
+
if (parent === existingPath) {
|
|
219
|
+
throw new Error(`Path does not have an existing parent: ${path}`);
|
|
220
|
+
}
|
|
221
|
+
missingSegments.unshift(basename(existingPath));
|
|
222
|
+
existingPath = parent;
|
|
223
|
+
}
|
|
224
|
+
return resolve(realpathSync(existingPath), ...missingSegments);
|
|
225
|
+
}
|
|
226
|
+
function isScopedPath(scopePath, inputPath) {
|
|
227
|
+
const root = realpathSync(scopePath);
|
|
228
|
+
const logicalCandidate = isAbsolute(inputPath) ? resolve(inputPath) : resolve(root, inputPath);
|
|
229
|
+
const candidate = canonicalizePath(logicalCandidate);
|
|
230
|
+
return candidate === root || candidate.startsWith(root + sep);
|
|
231
|
+
}
|
|
232
|
+
function resolveScopedPath(scopePath, inputPath) {
|
|
233
|
+
if (!isScopedPath(scopePath, inputPath)) {
|
|
234
|
+
throw new Error(`Path escapes the allowed scope: ${inputPath}`);
|
|
235
|
+
}
|
|
236
|
+
const root = realpathSync(scopePath);
|
|
237
|
+
const logicalCandidate = isAbsolute(inputPath) ? resolve(inputPath) : resolve(root, inputPath);
|
|
238
|
+
return canonicalizePath(logicalCandidate);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export {
|
|
242
|
+
parsePatch,
|
|
243
|
+
applyPatchOps,
|
|
244
|
+
resolveScopedPath
|
|
245
|
+
};
|