0sec-cli 0.17.0 → 0.18.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 +40 -35
- package/README.md +9 -0
- package/chunks/{adapt-loop-ECQG7454.js → adapt-loop-SMH6V4PD.js} +4 -4
- package/chunks/{artifact-scraper-GJEZMOHF.js → artifact-scraper-HQ7HLP6V.js} +2 -2
- package/chunks/{assumption-mining-BVMMUZHB.js → assumption-mining-5SNIVVDN.js} +13 -13
- package/chunks/{chunk-SZJCPG2I.js → chunk-242TMK6G.js} +1 -1
- package/chunks/{chunk-HE7LCA7G.js → chunk-2JCCA2JL.js} +1 -1
- package/chunks/{chunk-SNKTC4BP.js → chunk-3KPWWJCI.js} +1 -1
- package/chunks/{chunk-IORC6MQX.js → chunk-5JI7L7KV.js} +1557 -145
- package/chunks/{chunk-KKGE5RQE.js → chunk-6L26OBWI.js} +1 -1
- package/chunks/{chunk-HT6P7RY3.js → chunk-72CISA2D.js} +1 -1
- package/chunks/{chunk-VGRDNSHA.js → chunk-AD7WXDH6.js} +3 -2
- package/chunks/{chunk-QOKTUOU2.js → chunk-ADOLI6DT.js} +1 -1
- package/chunks/{chunk-HDWV7PGI.js → chunk-AHTBZC3E.js} +2 -2
- package/chunks/{chunk-D6S3IIPG.js → chunk-ASUR522M.js} +3 -3
- package/chunks/{chunk-CLHCDHP4.js → chunk-ATATQACO.js} +1 -1
- package/chunks/{chunk-KTQDLNSR.js → chunk-BATRQBOR.js} +1 -1
- package/chunks/{chunk-K26SZ37E.js → chunk-BFR2CDV5.js} +7 -7
- package/chunks/{chunk-A6CLR72I.js → chunk-BFRB6HB2.js} +1 -1
- package/chunks/{chunk-H44E2CRN.js → chunk-BVAZO4WA.js} +1 -1
- package/chunks/{chunk-O462Y7P2.js → chunk-BZNEY2ZS.js} +334 -128
- package/chunks/{chunk-DN25OQQA.js → chunk-C2WXWFBB.js} +1 -1
- package/chunks/{chunk-QJQKHO7G.js → chunk-CMKXP5RR.js} +1 -1
- package/chunks/{chunk-2CJ776PV.js → chunk-GMT2AZKM.js} +23 -14
- package/chunks/{chunk-47TQJWDH.js → chunk-JQHOLLTD.js} +3 -3
- package/chunks/{chunk-MMLDQR4H.js → chunk-N7BOUYEV.js} +3 -3
- package/chunks/{chunk-QKICO43A.js → chunk-SVJEDVYK.js} +1 -1
- package/chunks/{chunk-3QFDYBZQ.js → chunk-TSK2AG6J.js} +18 -18
- package/chunks/{chunk-UJ4IK5PO.js → chunk-U5FLXGHT.js} +1 -1
- package/chunks/{chunk-SOG2U7B3.js → chunk-UCYRA73C.js} +1 -1
- package/chunks/{chunk-2SANI5RH.js → chunk-UR4ELX2Y.js} +61 -5
- package/chunks/{chunk-UM3ZNQIM.js → chunk-WEBMRWEG.js} +17 -9
- package/chunks/{chunk-RDZYQQLW.js → chunk-WXQ6BJ6A.js} +1 -1
- package/chunks/{chunk-4Y4KQJXE.js → chunk-XM5NLHYU.js} +6 -6
- package/chunks/{chunk-LOHTE223.js → chunk-YYRBQVFE.js} +1 -1
- package/chunks/{chunk-WKNNZVJS.js → chunk-Z5FA2XOX.js} +1 -1
- package/chunks/{commands-U3AMV5ZU.js → commands-TBC2F5CE.js} +635 -431
- package/chunks/{cost-ledger-ZCKMBJEN.js → cost-ledger-NU63MYZM.js} +2 -2
- package/chunks/{db-26NGQFKO.js → db-KFWOAUUB.js} +3 -3
- package/chunks/{disclose-A6AEIEDA.js → disclose-EKTWSCGW.js} +2 -2
- package/chunks/{dist-GL66KMUX.js → dist-4MAW5X6L.js} +2 -2
- package/chunks/{dist-FDKALV4R.js → dist-4YICS2J2.js} +29 -25
- package/chunks/{dist-JR67XKYO.js → dist-FMGSR3DW.js} +1 -1
- package/chunks/{eval-runner-DDLE5RQ3.js → eval-runner-7ZF472KV.js} +8 -8
- package/chunks/{exploit-agent-XP23ISN7.js → exploit-agent-45YQOHPJ.js} +1 -1
- package/chunks/{exploit-autoclimb-E6T7RRSC.js → exploit-autoclimb-UZGEMGYT.js} +1 -1
- package/chunks/{exploit-climb-2FAUP6XU.js → exploit-climb-SG23KB2G.js} +2 -2
- package/chunks/{harness-HWOYFKFY.js → harness-7ODOLOWU.js} +3 -3
- package/chunks/{hunt-scan-XPELSPQQ.js → hunt-scan-MMKUOETU.js} +11 -11
- package/chunks/{kernel-primitive-TENE3R7T.js → kernel-primitive-7U6CWHXD.js} +2 -2
- package/chunks/{kernel-vm-runner-4F6QSNFY.js → kernel-vm-runner-3JAU4O6J.js} +2 -2
- package/chunks/{native-loop-NTONUDP7.js → native-loop-RJCJPOUS.js} +7 -7
- package/chunks/{orchestrate-ZUWAUWBC.js → orchestrate-OC2VZN2X.js} +26 -26
- package/chunks/{pipeline-FCARFZU3.js → pipeline-BZK5BLJR.js} +2 -2
- package/chunks/{process-3Q7QJIOZ.js → process-LQRCS5OY.js} +3 -3
- package/chunks/{replay-runner-RRR4E2A7.js → replay-runner-45G3VU7X.js} +2 -2
- package/chunks/{run-ESNN4V5W.js → run-D56MPDKY.js} +324 -240
- package/chunks/{runtime-62ZQAH7H.js → runtime-G7YWIO3B.js} +5 -5
- package/chunks/{session-store-BCFQYDCE.js → session-store-GZ4A4KYT.js} +2 -2
- package/chunks/{variant-candidates-6KM6F6MD.js → variant-candidates-YERCYMPD.js} +3 -3
- package/chunks/{web-recon-prepass-DPVCBRZA.js → web-recon-prepass-JJGPEOLE.js} +3 -3
- package/package.json +1 -1
|
@@ -3,10 +3,10 @@ import { createRequire as __0secCreateRequire } from "node:module";
|
|
|
3
3
|
const require = __0secCreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
registerOrchestrateCommand
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XM5NLHYU.js";
|
|
7
7
|
import {
|
|
8
8
|
registerDbCommand
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-WXQ6BJ6A.js";
|
|
10
10
|
import {
|
|
11
11
|
canUseOpenTui,
|
|
12
12
|
isBunRuntime
|
|
@@ -33,12 +33,13 @@ import {
|
|
|
33
33
|
runLogin,
|
|
34
34
|
runUnified,
|
|
35
35
|
startCodexDeviceAuth
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import "./chunk-
|
|
36
|
+
} from "./chunk-TSK2AG6J.js";
|
|
37
|
+
import "./chunk-BVAZO4WA.js";
|
|
38
38
|
import {
|
|
39
|
+
InvalidArgumentError,
|
|
39
40
|
Option,
|
|
40
41
|
performAutoUpdate
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-AD7WXDH6.js";
|
|
42
43
|
import {
|
|
43
44
|
DEFAULT_THEME_NAME,
|
|
44
45
|
SETTING_DEFS,
|
|
@@ -68,7 +69,7 @@ import {
|
|
|
68
69
|
validateTheme,
|
|
69
70
|
writeInstalledTheme,
|
|
70
71
|
writePresentationLine
|
|
71
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-GMT2AZKM.js";
|
|
72
73
|
import {
|
|
73
74
|
AjvJsonSchemaValidator,
|
|
74
75
|
CallToolRequestSchema,
|
|
@@ -174,6 +175,7 @@ import {
|
|
|
174
175
|
runCliPathTraversalReplayFixture,
|
|
175
176
|
runEnsembleCraft,
|
|
176
177
|
runReproductionBundle,
|
|
178
|
+
runSecureProject,
|
|
177
179
|
runTournament,
|
|
178
180
|
safeParse,
|
|
179
181
|
safeParseAsync,
|
|
@@ -190,19 +192,19 @@ import {
|
|
|
190
192
|
toScopeFile,
|
|
191
193
|
withVariantFeatureFlags,
|
|
192
194
|
writeAgentActionEvidenceBundle
|
|
193
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-5JI7L7KV.js";
|
|
194
196
|
import {
|
|
195
197
|
RateLimiter,
|
|
196
198
|
enumerateJsChunkUrls,
|
|
197
199
|
parseRateLimitFlag
|
|
198
|
-
} from "./chunk-
|
|
200
|
+
} from "./chunk-CMKXP5RR.js";
|
|
199
201
|
import {
|
|
200
202
|
source_default
|
|
201
203
|
} from "./chunk-SF4KZ4O3.js";
|
|
202
204
|
import {
|
|
203
205
|
getEvalCategories,
|
|
204
206
|
runEval
|
|
205
|
-
} from "./chunk-
|
|
207
|
+
} from "./chunk-AHTBZC3E.js";
|
|
206
208
|
import {
|
|
207
209
|
oracleForCategory
|
|
208
210
|
} from "./chunk-WVTBZEQO.js";
|
|
@@ -217,14 +219,14 @@ import {
|
|
|
217
219
|
DETECTOR_REGISTRY,
|
|
218
220
|
resolveDetectors
|
|
219
221
|
} from "./chunk-RWONANDA.js";
|
|
220
|
-
import "./chunk-
|
|
221
|
-
import "./chunk-
|
|
222
|
+
import "./chunk-BATRQBOR.js";
|
|
223
|
+
import "./chunk-2JCCA2JL.js";
|
|
222
224
|
import {
|
|
223
225
|
adaptAndVerify
|
|
224
|
-
} from "./chunk-
|
|
225
|
-
import "./chunk-
|
|
226
|
-
import "./chunk-
|
|
227
|
-
import "./chunk-
|
|
226
|
+
} from "./chunk-ASUR522M.js";
|
|
227
|
+
import "./chunk-BFRB6HB2.js";
|
|
228
|
+
import "./chunk-JQHOLLTD.js";
|
|
229
|
+
import "./chunk-3KPWWJCI.js";
|
|
228
230
|
import {
|
|
229
231
|
runSourceFix
|
|
230
232
|
} from "./chunk-F3WBKITT.js";
|
|
@@ -233,7 +235,7 @@ import {
|
|
|
233
235
|
LocalShellRunner,
|
|
234
236
|
QemuRunner,
|
|
235
237
|
runDeterministicReplay
|
|
236
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-C2WXWFBB.js";
|
|
237
239
|
import {
|
|
238
240
|
runHttpConformanceCheck
|
|
239
241
|
} from "./chunk-IOL7D5YV.js";
|
|
@@ -246,7 +248,7 @@ import {
|
|
|
246
248
|
runSpecdriftScan
|
|
247
249
|
} from "./chunk-BKZFDZ23.js";
|
|
248
250
|
import "./chunk-53G27VPS.js";
|
|
249
|
-
import "./chunk-
|
|
251
|
+
import "./chunk-BFR2CDV5.js";
|
|
250
252
|
import "./chunk-RJWOYEOG.js";
|
|
251
253
|
import {
|
|
252
254
|
ToolExecutor,
|
|
@@ -276,17 +278,17 @@ import {
|
|
|
276
278
|
targetRequiresScope,
|
|
277
279
|
validateAwsCredentials,
|
|
278
280
|
verifyImprovementLedger
|
|
279
|
-
} from "./chunk-
|
|
281
|
+
} from "./chunk-BZNEY2ZS.js";
|
|
280
282
|
import {
|
|
281
283
|
buildIntelDossier,
|
|
282
284
|
lookupCve,
|
|
283
285
|
searchAdvisories,
|
|
284
286
|
searchSimilar,
|
|
285
287
|
searchTargetHistory
|
|
286
|
-
} from "./chunk-
|
|
288
|
+
} from "./chunk-YYRBQVFE.js";
|
|
287
289
|
import "./chunk-3MOLBTLS.js";
|
|
288
290
|
import "./chunk-P6WKNFWX.js";
|
|
289
|
-
import "./chunk-
|
|
291
|
+
import "./chunk-UCYRA73C.js";
|
|
290
292
|
import "./chunk-LP3HHYQU.js";
|
|
291
293
|
import "./chunk-KLTNTE2Z.js";
|
|
292
294
|
import {
|
|
@@ -295,12 +297,12 @@ import {
|
|
|
295
297
|
resolveOsecDbPath,
|
|
296
298
|
resolveOsecRunStorage,
|
|
297
299
|
writeOsecRunReport
|
|
298
|
-
} from "./chunk-
|
|
300
|
+
} from "./chunk-72CISA2D.js";
|
|
299
301
|
import "./chunk-QI233I24.js";
|
|
300
|
-
import "./chunk-
|
|
302
|
+
import "./chunk-242TMK6G.js";
|
|
301
303
|
import {
|
|
302
304
|
runFileReviewPipeline
|
|
303
|
-
} from "./chunk-
|
|
305
|
+
} from "./chunk-Z5FA2XOX.js";
|
|
304
306
|
import "./chunk-RRMJC3ZE.js";
|
|
305
307
|
import "./chunk-H2FFLZNK.js";
|
|
306
308
|
import {
|
|
@@ -323,24 +325,24 @@ import {
|
|
|
323
325
|
renderReproducibilityManifest,
|
|
324
326
|
renderVendorNotificationMarkdown,
|
|
325
327
|
transition
|
|
326
|
-
} from "./chunk-
|
|
328
|
+
} from "./chunk-U5FLXGHT.js";
|
|
327
329
|
import {
|
|
328
330
|
EmptyPocError,
|
|
329
331
|
detectVersionRange,
|
|
330
332
|
renderAdvisoryMarkdown,
|
|
331
333
|
verifyAgainstRef
|
|
332
|
-
} from "./chunk-
|
|
334
|
+
} from "./chunk-WEBMRWEG.js";
|
|
333
335
|
import {
|
|
334
336
|
findCveArtifacts,
|
|
335
337
|
normaliseCveId
|
|
336
|
-
} from "./chunk-
|
|
338
|
+
} from "./chunk-SVJEDVYK.js";
|
|
337
339
|
import {
|
|
338
340
|
ScopePolicy,
|
|
339
341
|
loadScope
|
|
340
342
|
} from "./chunk-57ZENEX2.js";
|
|
341
343
|
import {
|
|
342
344
|
createRuntime
|
|
343
|
-
} from "./chunk-
|
|
345
|
+
} from "./chunk-N7BOUYEV.js";
|
|
344
346
|
import {
|
|
345
347
|
CloudAuthMissingError,
|
|
346
348
|
CloudClient,
|
|
@@ -352,11 +354,11 @@ import {
|
|
|
352
354
|
LlmApiRuntime,
|
|
353
355
|
features,
|
|
354
356
|
loadCloudCredentials
|
|
355
|
-
} from "./chunk-
|
|
356
|
-
import "./chunk-
|
|
357
|
+
} from "./chunk-UR4ELX2Y.js";
|
|
358
|
+
import "./chunk-ATATQACO.js";
|
|
357
359
|
import {
|
|
358
360
|
eventBus
|
|
359
|
-
} from "./chunk-
|
|
361
|
+
} from "./chunk-ADOLI6DT.js";
|
|
360
362
|
import {
|
|
361
363
|
AgentActionScenarioSchema,
|
|
362
364
|
DEFAULT_AUTONOMY_MODE,
|
|
@@ -371,7 +373,7 @@ import {
|
|
|
371
373
|
parseAgentActionEvidenceManifest,
|
|
372
374
|
pocStepArraySchema,
|
|
373
375
|
reportSummarySchema
|
|
374
|
-
} from "./chunk-
|
|
376
|
+
} from "./chunk-6L26OBWI.js";
|
|
375
377
|
import {
|
|
376
378
|
ZodOptional,
|
|
377
379
|
external_exports
|
|
@@ -519,7 +521,7 @@ function registerScanCommand(program) {
|
|
|
519
521
|
).option("--base <branch>", "Base branch for `--emit pr` (default: main)").option("--dry-run", "For `--emit pr`: print git/gh commands instead of running them. Auto-enabled if `gh auth status` fails.", false).option("--emit-out-dir <path>", "Directory for `--emit pr` rollup files (default: system temp)").option("--resume <run-id>", "Resume a previous run from its journal on disk (0sec#374). Locates the run's journal, rehydrates agent state, and continues from the last entry.").option("--branch-from <entry-index>", "Branch the journal at the given entry index before resuming (requires --resume). Copies entries 0..N into a new run and resumes from there.").option("--verbose", "Show detailed output", false).option("--replay", "Replay the last scan's results", false).action(async (opts) => {
|
|
520
522
|
if (opts.replay) {
|
|
521
523
|
try {
|
|
522
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
524
|
+
const { osecDB: osecDB2 } = await import("./dist-4MAW5X6L.js");
|
|
523
525
|
const db = new osecDB2(opts.dbPath);
|
|
524
526
|
const scans = db.listScans(1);
|
|
525
527
|
if (scans.length === 0) {
|
|
@@ -646,7 +648,7 @@ function registerScanCommand(program) {
|
|
|
646
648
|
process.exit(2);
|
|
647
649
|
}
|
|
648
650
|
try {
|
|
649
|
-
const { loadScope: loadScope2 } = await import("./dist-
|
|
651
|
+
const { loadScope: loadScope2 } = await import("./dist-4YICS2J2.js");
|
|
650
652
|
const policy = loadScope2(scopeFile);
|
|
651
653
|
const verdict = policy.match(String(opts.target));
|
|
652
654
|
if (!verdict.allowed) {
|
|
@@ -673,7 +675,7 @@ function registerScanCommand(program) {
|
|
|
673
675
|
loadScope: loadScope2,
|
|
674
676
|
resolveAttribution: resolveAttribution2,
|
|
675
677
|
extractAttributionFromScopeJson: extractAttributionFromScopeJson2
|
|
676
|
-
} = await import("./dist-
|
|
678
|
+
} = await import("./dist-4YICS2J2.js");
|
|
677
679
|
const policy = scopeFile ? loadScope2(scopeFile) : void 0;
|
|
678
680
|
resolveAttribution2({
|
|
679
681
|
scopeFileBlock: policy ? extractAttributionFromScopeJson2(policy.raw) : void 0,
|
|
@@ -691,7 +693,7 @@ function registerScanCommand(program) {
|
|
|
691
693
|
loadScope: loadScope2,
|
|
692
694
|
resolveEngagementProfile: resolveEngagementProfile2,
|
|
693
695
|
extractEngagementFromScopeJson: extractEngagementFromScopeJson2
|
|
694
|
-
} = await import("./dist-
|
|
696
|
+
} = await import("./dist-4YICS2J2.js");
|
|
695
697
|
const policy = scopeFile ? loadScope2(scopeFile) : void 0;
|
|
696
698
|
resolveEngagementProfile2({
|
|
697
699
|
scopeFileBlock: policy ? extractEngagementFromScopeJson2(policy.raw) : void 0,
|
|
@@ -720,7 +722,7 @@ function registerScanCommand(program) {
|
|
|
720
722
|
const rateLimit = opts.rateLimit;
|
|
721
723
|
if (rateLimit !== void 0 && rateLimit !== "") {
|
|
722
724
|
try {
|
|
723
|
-
const { parseRateLimitFlag: parseRateLimitFlag2 } = await import("./dist-
|
|
725
|
+
const { parseRateLimitFlag: parseRateLimitFlag2 } = await import("./dist-4YICS2J2.js");
|
|
724
726
|
parseRateLimitFlag2(rateLimit);
|
|
725
727
|
} catch (err) {
|
|
726
728
|
console.error(source_default.red(err instanceof Error ? err.message : String(err)));
|
|
@@ -889,7 +891,7 @@ function registerResumeCommand(program) {
|
|
|
889
891
|
|
|
890
892
|
// packages/cli/src/commands/replay.ts
|
|
891
893
|
async function replayScan(opts) {
|
|
892
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
894
|
+
const { osecDB: osecDB2 } = await import("./dist-4MAW5X6L.js");
|
|
893
895
|
const db = new osecDB2(opts.dbPath);
|
|
894
896
|
const requestedScan = opts.scan;
|
|
895
897
|
let scanRecord;
|
|
@@ -958,7 +960,7 @@ function registerReplayCommand(program) {
|
|
|
958
960
|
try {
|
|
959
961
|
const { isBunRuntime: isBunRuntime2, canUseOpenTui: canUseOpenTui2 } = await import("./runtime-J7PLXZNM.js");
|
|
960
962
|
if (isBunRuntime2() && canUseOpenTui2()) {
|
|
961
|
-
const { showOpenTuiReplay } = await import("./run-
|
|
963
|
+
const { showOpenTuiReplay } = await import("./run-D56MPDKY.js");
|
|
962
964
|
await showOpenTuiReplay({ dbPath: opts.dbPath, scanId: opts.scan });
|
|
963
965
|
return;
|
|
964
966
|
}
|
|
@@ -979,7 +981,7 @@ function registerHistoryCommand(program) {
|
|
|
979
981
|
const limit2 = Number.parseInt(opts.limit ?? "10", 10);
|
|
980
982
|
const { isBunRuntime: isBunRuntime2, canUseOpenTui: canUseOpenTui2 } = await import("./runtime-J7PLXZNM.js");
|
|
981
983
|
if (opts.dbPath && isBunRuntime2() && canUseOpenTui2()) {
|
|
982
|
-
const { showOpenTuiHistory } = await import("./run-
|
|
984
|
+
const { showOpenTuiHistory } = await import("./run-D56MPDKY.js");
|
|
983
985
|
await showOpenTuiHistory({ dbPath: opts.dbPath, limit: limit2 });
|
|
984
986
|
return;
|
|
985
987
|
}
|
|
@@ -1170,7 +1172,7 @@ function registerFindingsCommand(program) {
|
|
|
1170
1172
|
const selectedDbPath = resolveDbPath(resolved);
|
|
1171
1173
|
const { isBunRuntime: isBunRuntime2, canUseOpenTui: canUseOpenTui2 } = await import("./runtime-J7PLXZNM.js");
|
|
1172
1174
|
if (selectedDbPath && isBunRuntime2() && canUseOpenTui2()) {
|
|
1173
|
-
const { showOpenTuiFindings } = await import("./run-
|
|
1175
|
+
const { showOpenTuiFindings } = await import("./run-D56MPDKY.js");
|
|
1174
1176
|
await showOpenTuiFindings({
|
|
1175
1177
|
dbPath: selectedDbPath,
|
|
1176
1178
|
scan: resolved.scan,
|
|
@@ -1193,7 +1195,7 @@ function registerFindingsCommand(program) {
|
|
|
1193
1195
|
const selectedDbPath = resolveDbPath(resolved);
|
|
1194
1196
|
const { isBunRuntime: isBunRuntime2, canUseOpenTui: canUseOpenTui2 } = await import("./runtime-J7PLXZNM.js");
|
|
1195
1197
|
if (selectedDbPath && isBunRuntime2() && canUseOpenTui2()) {
|
|
1196
|
-
const { showOpenTuiFindings } = await import("./run-
|
|
1198
|
+
const { showOpenTuiFindings } = await import("./run-D56MPDKY.js");
|
|
1197
1199
|
await showOpenTuiFindings({
|
|
1198
1200
|
dbPath: selectedDbPath,
|
|
1199
1201
|
scan: resolved.scan,
|
|
@@ -1251,7 +1253,7 @@ function registerFindingsCommand(program) {
|
|
|
1251
1253
|
console.log(` ${source_default.dim(finding.evidenceAnalysis)}`);
|
|
1252
1254
|
}
|
|
1253
1255
|
{
|
|
1254
|
-
const { summarizeTriageProvenance, formatTriageProvenance } = await import("./dist-
|
|
1256
|
+
const { summarizeTriageProvenance, formatTriageProvenance } = await import("./dist-4YICS2J2.js");
|
|
1255
1257
|
const provenance = summarizeTriageProvenance({
|
|
1256
1258
|
...finding,
|
|
1257
1259
|
layerVerdicts: parseLayerVerdicts(finding.layerVerdicts)
|
|
@@ -1295,17 +1297,84 @@ function registerFindingsCommand(program) {
|
|
|
1295
1297
|
});
|
|
1296
1298
|
}
|
|
1297
1299
|
|
|
1300
|
+
// packages/cli/src/commands/secure.ts
|
|
1301
|
+
import { createHash } from "node:crypto";
|
|
1302
|
+
import { homedir } from "node:os";
|
|
1303
|
+
import { join, resolve } from "node:path";
|
|
1304
|
+
function positiveInteger(value) {
|
|
1305
|
+
const parsed = Number(value);
|
|
1306
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
|
1307
|
+
throw new InvalidArgumentError("Must be a positive integer.");
|
|
1308
|
+
}
|
|
1309
|
+
return parsed;
|
|
1310
|
+
}
|
|
1311
|
+
function positiveAmount(value) {
|
|
1312
|
+
const parsed = Number(value);
|
|
1313
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
1314
|
+
throw new InvalidArgumentError("Must be a positive finite dollar amount.");
|
|
1315
|
+
}
|
|
1316
|
+
return parsed;
|
|
1317
|
+
}
|
|
1318
|
+
function registerSecureCommand(program) {
|
|
1319
|
+
program.command("secure").description("Investigate, reproduce, repair, test, and independently verify a repository; retain evidence and optionally open repair PRs").argument("<repo>", "Local Git repository or HTTPS Git URL; execution occurs in the current worker, not a newly provisioned sandbox").requiredOption("--test-command <command>", "Operator-approved regression command; must pass before and after repair").option("--setup-command <command>", "Operator-approved setup/build command run in each disposable checkout").option("--state-dir <path>", "Persistent run directory; defaults to a stable per-repository path so learnings accumulate").option("--runtime <runtime>", "Native repair runtime: auto or api", "api").option("-m, --model <model>", "Model for investigation and repair; inherits configured provider when omitted").option("--timeout <ms>", "Whole workflow deadline in milliseconds", positiveInteger, 36e5).option("--cost-ceiling <usd>", "Whole workflow model cost ceiling in USD", positiveAmount).option("--max-findings <n>", "Maximum findings to repair; remaining findings keep the run blocked", positiveInteger, 10).option("--max-attempts <n>", "Maximum repair candidates per finding", positiveInteger, 3).option("--max-turns <n>", "Maximum model turns per repair phase", positiveInteger, 30).option("--resume", "Resume the compatible persisted run for this repository; never blindly replays publication", false).option("--publish", "Publish verified patches as PRs using authorized repository credentials; never merge or deploy", false).option("--rules <text>", 'Plain-English team repair standards (e.g. "minimal diffs, no new dependencies")').option("--format <format>", "Output format: json", "json").action(async (repo, options) => {
|
|
1320
|
+
if (options.format !== "json") throw new InvalidArgumentError("--format must be json.");
|
|
1321
|
+
if (!["api", "auto"].includes(options.runtime)) throw new InvalidArgumentError("--runtime must be api or auto.");
|
|
1322
|
+
if (!options.testCommand.trim()) throw new InvalidArgumentError("--test-command cannot be blank.");
|
|
1323
|
+
if (options.setupCommand !== void 0 && !options.setupCommand.trim()) throw new InvalidArgumentError("--setup-command cannot be blank.");
|
|
1324
|
+
const repoKey = createHash("sha256").update(resolve(repo)).digest("hex").slice(0, 12);
|
|
1325
|
+
const stateDir = resolve(options.stateDir ?? join(homedir(), ".0sec", "secure", repoKey));
|
|
1326
|
+
const controller = new AbortController();
|
|
1327
|
+
const cancel = () => controller.abort(new Error("Workflow cancelled by operator"));
|
|
1328
|
+
process.once("SIGINT", cancel);
|
|
1329
|
+
process.once("SIGTERM", cancel);
|
|
1330
|
+
const cloudOutput = process.env["0SEC_EMIT_RESULT_LINE"] === "1" || Boolean(process.env["0SEC_CLOUD_SINK"]);
|
|
1331
|
+
const onEvent = (event) => {
|
|
1332
|
+
if (cloudOutput) process.stdout.write(`0SEC_SECURE_EVENT=${JSON.stringify(event)}
|
|
1333
|
+
`);
|
|
1334
|
+
else process.stderr.write(`[secure:${event.phase}] ${event.message}
|
|
1335
|
+
`);
|
|
1336
|
+
};
|
|
1337
|
+
try {
|
|
1338
|
+
const result = await runSecureProject({
|
|
1339
|
+
repoRoot: repo,
|
|
1340
|
+
stateDir,
|
|
1341
|
+
testCommand: options.testCommand,
|
|
1342
|
+
setupCommand: options.setupCommand,
|
|
1343
|
+
runtime: options.runtime,
|
|
1344
|
+
model: options.model,
|
|
1345
|
+
timeoutMs: options.timeout,
|
|
1346
|
+
costCeilingUsd: options.costCeiling,
|
|
1347
|
+
maxFindings: options.maxFindings,
|
|
1348
|
+
maxAttempts: options.maxAttempts,
|
|
1349
|
+
maxTurns: options.maxTurns,
|
|
1350
|
+
resume: options.resume,
|
|
1351
|
+
publish: options.publish,
|
|
1352
|
+
rules: options.rules,
|
|
1353
|
+
signal: controller.signal,
|
|
1354
|
+
onEvent
|
|
1355
|
+
});
|
|
1356
|
+
process.stdout.write(cloudOutput ? `0SEC_RESULT=${JSON.stringify(result)}
|
|
1357
|
+
` : `${JSON.stringify(result, null, 2)}
|
|
1358
|
+
`);
|
|
1359
|
+
process.exitCode = { completed: 0, blocked: 2, failed: 3, cancelled: 130 }[result.status];
|
|
1360
|
+
} finally {
|
|
1361
|
+
process.removeListener("SIGINT", cancel);
|
|
1362
|
+
process.removeListener("SIGTERM", cancel);
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1298
1367
|
// packages/cli/src/commands/review.ts
|
|
1299
1368
|
import { readFile } from "node:fs/promises";
|
|
1300
1369
|
|
|
1301
1370
|
// packages/cli/src/commands/review-harness-tier2.ts
|
|
1302
|
-
import { resolve, join, basename } from "node:path";
|
|
1371
|
+
import { resolve as resolve2, join as join2, basename } from "node:path";
|
|
1303
1372
|
import { existsSync as existsSync3 } from "node:fs";
|
|
1304
1373
|
var VALID_BUILD_SYSTEMS = /* @__PURE__ */ new Set(["autotools", "cmake", "meson", "auto"]);
|
|
1305
1374
|
var VALID_SANITIZERS = /* @__PURE__ */ new Set(["asan", "ubsan", "msan"]);
|
|
1306
1375
|
async function runHarnessTier2(args2) {
|
|
1307
|
-
const { buildTier2Harness, extractCorpus } = await import("./dist-
|
|
1308
|
-
const repoAbs =
|
|
1376
|
+
const { buildTier2Harness, extractCorpus } = await import("./dist-4YICS2J2.js");
|
|
1377
|
+
const repoAbs = resolve2(args2.repo);
|
|
1309
1378
|
if (!existsSync3(repoAbs)) {
|
|
1310
1379
|
throw new Error(`Tier-2: repo path '${repoAbs}' does not exist.`);
|
|
1311
1380
|
}
|
|
@@ -1315,8 +1384,8 @@ async function runHarnessTier2(args2) {
|
|
|
1315
1384
|
);
|
|
1316
1385
|
}
|
|
1317
1386
|
const sanitizers = parseSanitizers(args2.sanitizers);
|
|
1318
|
-
const outputDir =
|
|
1319
|
-
const corpusDir =
|
|
1387
|
+
const outputDir = resolve2(args2.outputDir ?? join2(repoAbs, ".0sec-out", "tier2"));
|
|
1388
|
+
const corpusDir = join2(outputDir, "corpus");
|
|
1320
1389
|
const functionName = args2.functionName ?? deriveDefaultFunctionName(repoAbs);
|
|
1321
1390
|
const header = args2.header ?? `${functionName}.h`;
|
|
1322
1391
|
console.log(
|
|
@@ -1391,7 +1460,7 @@ function deriveDefaultFunctionName(repoPath) {
|
|
|
1391
1460
|
}
|
|
1392
1461
|
|
|
1393
1462
|
// packages/cli/src/commands/review-harness-tier3.ts
|
|
1394
|
-
import { resolve as
|
|
1463
|
+
import { resolve as resolve3, join as join3, basename as basename2 } from "node:path";
|
|
1395
1464
|
import { existsSync as existsSync4 } from "node:fs";
|
|
1396
1465
|
var VALID_BUILD_SYSTEMS2 = /* @__PURE__ */ new Set(["autotools", "cmake", "meson", "auto"]);
|
|
1397
1466
|
var VALID_SANITIZERS2 = /* @__PURE__ */ new Set(["asan", "ubsan", "msan"]);
|
|
@@ -1400,8 +1469,8 @@ async function runHarnessTier3(args2) {
|
|
|
1400
1469
|
buildTier2Harness,
|
|
1401
1470
|
extractCorpus,
|
|
1402
1471
|
runTier3Validation
|
|
1403
|
-
} = await import("./dist-
|
|
1404
|
-
const repoAbs =
|
|
1472
|
+
} = await import("./dist-4YICS2J2.js");
|
|
1473
|
+
const repoAbs = resolve3(args2.repo);
|
|
1405
1474
|
if (!existsSync4(repoAbs)) {
|
|
1406
1475
|
throw new Error(`Tier-3: repo path '${repoAbs}' does not exist.`);
|
|
1407
1476
|
}
|
|
@@ -1411,8 +1480,8 @@ async function runHarnessTier3(args2) {
|
|
|
1411
1480
|
);
|
|
1412
1481
|
}
|
|
1413
1482
|
const sanitizers = parseSanitizers2(args2.sanitizers);
|
|
1414
|
-
const outputDir =
|
|
1415
|
-
const corpusDir =
|
|
1483
|
+
const outputDir = resolve3(args2.outputDir ?? join3(repoAbs, ".0sec-out", "tier3"));
|
|
1484
|
+
const corpusDir = join3(outputDir, "corpus");
|
|
1416
1485
|
const functionName = args2.functionName ?? deriveDefaultFunctionName2(repoAbs);
|
|
1417
1486
|
const header = args2.header ?? `${functionName}.h`;
|
|
1418
1487
|
console.log(
|
|
@@ -1620,7 +1689,7 @@ function registerReviewCommand(program) {
|
|
|
1620
1689
|
let seedFindings;
|
|
1621
1690
|
const seedPath = opts.seedFindings;
|
|
1622
1691
|
if (seedPath) {
|
|
1623
|
-
const { readSeedFindings } = await import("./dist-
|
|
1692
|
+
const { readSeedFindings } = await import("./dist-4YICS2J2.js");
|
|
1624
1693
|
seedFindings = readSeedFindings(seedPath);
|
|
1625
1694
|
console.log(
|
|
1626
1695
|
source_default.cyan(
|
|
@@ -1636,7 +1705,7 @@ function registerReviewCommand(program) {
|
|
|
1636
1705
|
);
|
|
1637
1706
|
}
|
|
1638
1707
|
if (fixCommit) {
|
|
1639
|
-
const { huntAppFixVariants, appFixVariantsToSeedFindings } = await import("./dist-
|
|
1708
|
+
const { huntAppFixVariants, appFixVariantsToSeedFindings } = await import("./dist-4YICS2J2.js");
|
|
1640
1709
|
const result = huntAppFixVariants({
|
|
1641
1710
|
repoPath: repo,
|
|
1642
1711
|
fixCommit
|
|
@@ -1764,7 +1833,7 @@ function registerReviewCommand(program) {
|
|
|
1764
1833
|
|
|
1765
1834
|
// packages/cli/src/commands/fix.ts
|
|
1766
1835
|
import { mkdir, readFile as readFile2, writeFile } from "node:fs/promises";
|
|
1767
|
-
import { dirname, resolve as
|
|
1836
|
+
import { dirname, resolve as resolve4 } from "node:path";
|
|
1768
1837
|
var FIX_RUNTIMES = {
|
|
1769
1838
|
api: true
|
|
1770
1839
|
};
|
|
@@ -1781,7 +1850,7 @@ function isNativeRuntime(runtime) {
|
|
|
1781
1850
|
async function loadFinding(path) {
|
|
1782
1851
|
let raw;
|
|
1783
1852
|
try {
|
|
1784
|
-
raw = JSON.parse(await readFile2(
|
|
1853
|
+
raw = JSON.parse(await readFile2(resolve4(path), "utf8"));
|
|
1785
1854
|
} catch (error) {
|
|
1786
1855
|
throw new Error(`failed to read finding JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
1787
1856
|
}
|
|
@@ -1797,7 +1866,7 @@ async function loadFinding(path) {
|
|
|
1797
1866
|
async function loadVerificationResult(path) {
|
|
1798
1867
|
let raw;
|
|
1799
1868
|
try {
|
|
1800
|
-
raw = JSON.parse(await readFile2(
|
|
1869
|
+
raw = JSON.parse(await readFile2(resolve4(path), "utf8"));
|
|
1801
1870
|
} catch (error) {
|
|
1802
1871
|
throw new Error(`failed to read verification result JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
1803
1872
|
}
|
|
@@ -1841,7 +1910,7 @@ function createFixRuntime(type, opts) {
|
|
|
1841
1910
|
return runtime;
|
|
1842
1911
|
}
|
|
1843
1912
|
async function writePatch(path, patch) {
|
|
1844
|
-
const resolved =
|
|
1913
|
+
const resolved = resolve4(path);
|
|
1845
1914
|
await mkdir(dirname(resolved), { recursive: true });
|
|
1846
1915
|
await writeFile(resolved, `${patch}
|
|
1847
1916
|
`, "utf8");
|
|
@@ -1879,7 +1948,7 @@ function registerFixCommand(program) {
|
|
|
1879
1948
|
throw new Error(`runtime '${runtimeType}' is not available`);
|
|
1880
1949
|
}
|
|
1881
1950
|
const result = await runSourceFix({
|
|
1882
|
-
repoRoot:
|
|
1951
|
+
repoRoot: resolve4(repo),
|
|
1883
1952
|
finding,
|
|
1884
1953
|
runtime,
|
|
1885
1954
|
testCommand: opts.testCommand,
|
|
@@ -1896,6 +1965,139 @@ function registerFixCommand(program) {
|
|
|
1896
1965
|
});
|
|
1897
1966
|
}
|
|
1898
1967
|
|
|
1968
|
+
// packages/cli/src/commands/connect.ts
|
|
1969
|
+
import { execFileSync } from "node:child_process";
|
|
1970
|
+
import { existsSync as existsSync5, mkdtempSync, readFileSync as readFileSync2, rmSync } from "node:fs";
|
|
1971
|
+
import { tmpdir } from "node:os";
|
|
1972
|
+
import { join as join4 } from "node:path";
|
|
1973
|
+
function detectTestCommand(repoUrl) {
|
|
1974
|
+
const dir = mkdtempSync(join4(tmpdir(), "0sec-connect-"));
|
|
1975
|
+
try {
|
|
1976
|
+
execFileSync("git", ["clone", "--depth", "1", "--quiet", repoUrl, dir], {
|
|
1977
|
+
timeout: 12e4,
|
|
1978
|
+
stdio: "pipe"
|
|
1979
|
+
});
|
|
1980
|
+
if (existsSync5(join4(dir, "package.json"))) {
|
|
1981
|
+
const pkg = JSON.parse(readFileSync2(join4(dir, "package.json"), "utf8"));
|
|
1982
|
+
const test = pkg.scripts?.test;
|
|
1983
|
+
if (test && !test.includes("no test specified")) {
|
|
1984
|
+
const runner = pkg.packageManager?.startsWith("pnpm") ? "pnpm" : pkg.packageManager?.startsWith("yarn") ? "yarn" : existsSync5(join4(dir, "pnpm-lock.yaml")) ? "pnpm" : existsSync5(join4(dir, "yarn.lock")) ? "yarn" : "npm";
|
|
1985
|
+
return { command: runner === "npm" ? "npm test" : `${runner} test`, source: "package.json" };
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
if (existsSync5(join4(dir, "Makefile"))) {
|
|
1989
|
+
const make = readFileSync2(join4(dir, "Makefile"), "utf8");
|
|
1990
|
+
if (/^test:/m.test(make)) return { command: "make test", source: "Makefile" };
|
|
1991
|
+
}
|
|
1992
|
+
if (existsSync5(join4(dir, "pyproject.toml")) || existsSync5(join4(dir, "pytest.ini")) || existsSync5(join4(dir, "tox.ini"))) {
|
|
1993
|
+
return { command: "python3 -m pytest", source: "python project files" };
|
|
1994
|
+
}
|
|
1995
|
+
if (existsSync5(join4(dir, "Cargo.toml"))) return { command: "cargo test", source: "Cargo.toml" };
|
|
1996
|
+
if (existsSync5(join4(dir, "go.mod"))) return { command: "go test ./...", source: "go.mod" };
|
|
1997
|
+
return null;
|
|
1998
|
+
} catch {
|
|
1999
|
+
return null;
|
|
2000
|
+
} finally {
|
|
2001
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
function registerConnectCommand(program) {
|
|
2005
|
+
program.command("connect").description("Connect a repository: 0sec starts securing it now and keeps it secure on a schedule").argument("<repo>", "HTTPS git URL of the repository you own or are authorized to assess").option("--test-command <command>", "Regression command; auto-detected from the repo when omitted").option("--setup-command <command>", "Setup/build command run before tests (e.g. pnpm install)").option("-m, --model <model>", "Model for the managed runs; defaults to the cloud routing default").option("--cost-ceiling <usd>", "Per-run model cost ceiling in USD", (v) => {
|
|
2006
|
+
const n = Number(v);
|
|
2007
|
+
if (!Number.isFinite(n) || n <= 0) throw new InvalidArgumentError("Must be a positive dollar amount.");
|
|
2008
|
+
return n;
|
|
2009
|
+
}).option("--cron <expression>", "Recurring schedule (cron). Default: daily at 03:00 UTC", "0 3 * * *").option("--no-schedule", "Only run once, do not install a recurring schedule").action(async (repo, options) => {
|
|
2010
|
+
if (!/^https:\/\/[^\s]+\.git$|^https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/?$/.test(repo)) {
|
|
2011
|
+
throw new InvalidArgumentError("repo must be an HTTPS git URL (e.g. https://github.com/org/repo)");
|
|
2012
|
+
}
|
|
2013
|
+
let creds;
|
|
2014
|
+
try {
|
|
2015
|
+
creds = loadCloudCredentials();
|
|
2016
|
+
} catch (error) {
|
|
2017
|
+
if (error instanceof CloudAuthMissingError) {
|
|
2018
|
+
process.stderr.write(
|
|
2019
|
+
`${source_default.red("Not authenticated.")} Run ${source_default.bold("0sec auth login")} first, then connect again.
|
|
2020
|
+
`
|
|
2021
|
+
);
|
|
2022
|
+
process.exitCode = 2;
|
|
2023
|
+
return;
|
|
2024
|
+
}
|
|
2025
|
+
throw error;
|
|
2026
|
+
}
|
|
2027
|
+
const client = new CloudClient({ host: creds.host, token: creds.token });
|
|
2028
|
+
try {
|
|
2029
|
+
await client.pingHealth();
|
|
2030
|
+
} catch (error) {
|
|
2031
|
+
if (error instanceof CloudUnauthorizedError) {
|
|
2032
|
+
process.stderr.write(`${source_default.red("Cloud token rejected.")} Run ${source_default.bold("0sec auth login")} again.
|
|
2033
|
+
`);
|
|
2034
|
+
process.exitCode = 2;
|
|
2035
|
+
return;
|
|
2036
|
+
}
|
|
2037
|
+
throw error;
|
|
2038
|
+
}
|
|
2039
|
+
let testCommand = options.testCommand;
|
|
2040
|
+
if (!testCommand) {
|
|
2041
|
+
process.stderr.write("Detecting test command\u2026\n");
|
|
2042
|
+
const detected = detectTestCommand(repo);
|
|
2043
|
+
if (!detected) {
|
|
2044
|
+
process.stderr.write(
|
|
2045
|
+
`${source_default.red("Could not detect a test command.")} Pass ${source_default.bold("--test-command")} explicitly (e.g. --test-command "npm test").
|
|
2046
|
+
`
|
|
2047
|
+
);
|
|
2048
|
+
process.exitCode = 1;
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
testCommand = detected.command;
|
|
2052
|
+
process.stderr.write(`Detected ${source_default.bold(testCommand)} (from ${detected.source}).
|
|
2053
|
+
`);
|
|
2054
|
+
}
|
|
2055
|
+
const secureConfig = {
|
|
2056
|
+
repo,
|
|
2057
|
+
test_command: testCommand,
|
|
2058
|
+
...options.setupCommand ? { setup_command: options.setupCommand } : {},
|
|
2059
|
+
...options.model ? { model: options.model } : {},
|
|
2060
|
+
...options.costCeiling ? { cost_ceiling_usd: options.costCeiling } : {}
|
|
2061
|
+
};
|
|
2062
|
+
process.stderr.write("Starting the first secure run\u2026\n");
|
|
2063
|
+
const scan2 = await client.postJson("/api/scans", {
|
|
2064
|
+
target: repo,
|
|
2065
|
+
scan_mode: "secure",
|
|
2066
|
+
secure_config: secureConfig
|
|
2067
|
+
});
|
|
2068
|
+
let schedule = null;
|
|
2069
|
+
if (options.schedule) {
|
|
2070
|
+
if (!scan2.target_id) {
|
|
2071
|
+
process.stderr.write(source_default.yellow("Scan created without a target id \u2014 skipping schedule.\n"));
|
|
2072
|
+
} else {
|
|
2073
|
+
schedule = await client.postJson(
|
|
2074
|
+
"/api/scan-schedules",
|
|
2075
|
+
{
|
|
2076
|
+
target_id: scan2.target_id,
|
|
2077
|
+
cron_expression: options.cron,
|
|
2078
|
+
scan_mode: "secure",
|
|
2079
|
+
secure_config: secureConfig
|
|
2080
|
+
}
|
|
2081
|
+
);
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
const scanUrl = `${creds.host}/cloud/scans/${scan2.id}`;
|
|
2085
|
+
process.stdout.write(
|
|
2086
|
+
[
|
|
2087
|
+
"",
|
|
2088
|
+
source_default.green.bold("Connected."),
|
|
2089
|
+
` Repository: ${repo}`,
|
|
2090
|
+
` Test command: ${testCommand}`,
|
|
2091
|
+
` First run: ${scanUrl}`,
|
|
2092
|
+
schedule ? ` Schedule: ${options.cron} (next: ${schedule.next_run_at ?? "pending"})` : " Schedule: none (one-shot run)",
|
|
2093
|
+
"",
|
|
2094
|
+
"0sec will investigate, reproduce, repair, and verify. Verified patches and evidence are retained on the scan for your review.",
|
|
2095
|
+
""
|
|
2096
|
+
].join("\n")
|
|
2097
|
+
);
|
|
2098
|
+
});
|
|
2099
|
+
}
|
|
2100
|
+
|
|
1899
2101
|
// packages/cli/src/commands/audit.ts
|
|
1900
2102
|
var SUPPORTED_AUDIT_ECOSYSTEMS = /* @__PURE__ */ new Set(["npm", "pypi", "cargo", "oci"]);
|
|
1901
2103
|
function registerAuditCommand(program) {
|
|
@@ -1942,7 +2144,7 @@ function registerDoctorCommand(program) {
|
|
|
1942
2144
|
program.command("doctor").description("Check local runtime prerequisites and suggest the next command").action(async () => {
|
|
1943
2145
|
const { isBunRuntime: isBunRuntime2, canUseOpenTui: canUseOpenTui2 } = await import("./runtime-J7PLXZNM.js");
|
|
1944
2146
|
if (isBunRuntime2() && canUseOpenTui2()) {
|
|
1945
|
-
const { showOpenTuiDoctor } = await import("./run-
|
|
2147
|
+
const { showOpenTuiDoctor } = await import("./run-D56MPDKY.js");
|
|
1946
2148
|
await showOpenTuiDoctor();
|
|
1947
2149
|
return;
|
|
1948
2150
|
}
|
|
@@ -1979,11 +2181,11 @@ function registerDoctorCommand(program) {
|
|
|
1979
2181
|
import { createServer } from "node:http";
|
|
1980
2182
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
1981
2183
|
import { execFile, spawn } from "node:child_process";
|
|
1982
|
-
import { existsSync as
|
|
1983
|
-
import { dirname as dirname2, extname, join as
|
|
2184
|
+
import { existsSync as existsSync6, mkdirSync, mkdtempSync as mkdtempSync2, readFileSync as readFileSync3, rmSync as rmSync2, writeFileSync } from "node:fs";
|
|
2185
|
+
import { dirname as dirname2, extname, join as join5, resolve as resolve5, sep } from "node:path";
|
|
1984
2186
|
import { fileURLToPath } from "node:url";
|
|
1985
2187
|
import { URL as URL2 } from "node:url";
|
|
1986
|
-
import { tmpdir } from "node:os";
|
|
2188
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
1987
2189
|
import { isIP } from "node:net";
|
|
1988
2190
|
|
|
1989
2191
|
// packages/cli/src/desktop/console-gateway.ts
|
|
@@ -2478,7 +2680,7 @@ function sendFile(res, filePath, controlToken) {
|
|
|
2478
2680
|
"Content-Type": contentType,
|
|
2479
2681
|
"Cache-Control": ext === ".html" ? "no-store" : "public, max-age=300"
|
|
2480
2682
|
});
|
|
2481
|
-
let content =
|
|
2683
|
+
let content = readFileSync3(filePath);
|
|
2482
2684
|
if (controlToken && ext === ".html") {
|
|
2483
2685
|
content = content.toString().replace(
|
|
2484
2686
|
"</head>",
|
|
@@ -2488,7 +2690,7 @@ function sendFile(res, filePath, controlToken) {
|
|
|
2488
2690
|
res.end(content);
|
|
2489
2691
|
}
|
|
2490
2692
|
function readJson(req) {
|
|
2491
|
-
return new Promise((
|
|
2693
|
+
return new Promise((resolve27, reject) => {
|
|
2492
2694
|
let data = "";
|
|
2493
2695
|
req.on("data", (chunk) => {
|
|
2494
2696
|
data += chunk;
|
|
@@ -2498,7 +2700,7 @@ function readJson(req) {
|
|
|
2498
2700
|
});
|
|
2499
2701
|
req.on("end", () => {
|
|
2500
2702
|
try {
|
|
2501
|
-
|
|
2703
|
+
resolve27(data ? JSON.parse(data) : {});
|
|
2502
2704
|
} catch (err) {
|
|
2503
2705
|
reject(err);
|
|
2504
2706
|
}
|
|
@@ -2964,7 +3166,7 @@ function parseControlPath(pathname) {
|
|
|
2964
3166
|
};
|
|
2965
3167
|
}
|
|
2966
3168
|
function resolveCliEntrypoint() {
|
|
2967
|
-
return
|
|
3169
|
+
return resolve5(process.argv[1] ?? join5(process.cwd(), "dist", "index.js"));
|
|
2968
3170
|
}
|
|
2969
3171
|
function startManagedDaemon(args2) {
|
|
2970
3172
|
if (managedDaemon?.child.exitCode === null && !managedDaemon.child.killed) {
|
|
@@ -3086,41 +3288,41 @@ function groupByKey(rows, key) {
|
|
|
3086
3288
|
}
|
|
3087
3289
|
function materializeEmbeddedDashboardAssets(assets) {
|
|
3088
3290
|
if (assets.length === 0) return null;
|
|
3089
|
-
const assetDir =
|
|
3291
|
+
const assetDir = mkdtempSync2(join5(tmpdir2(), "0sec-dashboard-"));
|
|
3090
3292
|
try {
|
|
3091
3293
|
for (const [relativePath, contentBase64] of assets) {
|
|
3092
|
-
const candidate =
|
|
3294
|
+
const candidate = resolve5(assetDir, `.${relativePath.replaceAll("\\", "/")}`);
|
|
3093
3295
|
if (candidate === assetDir || !candidate.startsWith(`${assetDir}${sep}`)) {
|
|
3094
3296
|
throw new Error(`Invalid embedded dashboard asset path: ${JSON.stringify(relativePath)}`);
|
|
3095
3297
|
}
|
|
3096
3298
|
mkdirSync(dirname2(candidate), { recursive: true, mode: 448 });
|
|
3097
3299
|
writeFileSync(candidate, Buffer.from(contentBase64, "base64"), { mode: 384 });
|
|
3098
3300
|
}
|
|
3099
|
-
if (!
|
|
3301
|
+
if (!existsSync6(join5(assetDir, "index.html"))) {
|
|
3100
3302
|
throw new Error("Embedded dashboard assets do not contain index.html.");
|
|
3101
3303
|
}
|
|
3102
3304
|
} catch (error) {
|
|
3103
|
-
|
|
3305
|
+
rmSync2(assetDir, { recursive: true, force: true });
|
|
3104
3306
|
throw error;
|
|
3105
3307
|
}
|
|
3106
3308
|
return {
|
|
3107
3309
|
path: assetDir,
|
|
3108
|
-
cleanup: () =>
|
|
3310
|
+
cleanup: () => rmSync2(assetDir, { recursive: true, force: true })
|
|
3109
3311
|
};
|
|
3110
3312
|
}
|
|
3111
3313
|
function resolveDashboardAssetDir(explicitAssetDir) {
|
|
3112
|
-
const moduleDir =
|
|
3314
|
+
const moduleDir = resolve5(fileURLToPath(new URL2(".", import.meta.url)));
|
|
3113
3315
|
const candidates = [
|
|
3114
|
-
...explicitAssetDir ? [
|
|
3115
|
-
|
|
3116
|
-
|
|
3316
|
+
...explicitAssetDir ? [resolve5(explicitAssetDir)] : [],
|
|
3317
|
+
join5(moduleDir, "dashboard"),
|
|
3318
|
+
join5(moduleDir, "..", "dashboard"),
|
|
3117
3319
|
// A source checkout must serve the freshly built workspace dashboard,
|
|
3118
3320
|
// not an unrelated stale root bundle left by an earlier packaging run.
|
|
3119
|
-
|
|
3120
|
-
|
|
3321
|
+
join5(process.cwd(), "packages", "dashboard", "dist"),
|
|
3322
|
+
join5(process.cwd(), "dist", "dashboard")
|
|
3121
3323
|
];
|
|
3122
3324
|
for (const candidate of candidates) {
|
|
3123
|
-
if (
|
|
3325
|
+
if (existsSync6(join5(candidate, "index.html"))) {
|
|
3124
3326
|
return { path: candidate };
|
|
3125
3327
|
}
|
|
3126
3328
|
}
|
|
@@ -3130,10 +3332,10 @@ function resolveDashboardAssetDir(explicitAssetDir) {
|
|
|
3130
3332
|
}
|
|
3131
3333
|
function resolveAssetPath(assetDir, pathname) {
|
|
3132
3334
|
const trimmed = pathname === "/" ? "/index.html" : pathname;
|
|
3133
|
-
const assetRoot =
|
|
3134
|
-
const candidate =
|
|
3335
|
+
const assetRoot = resolve5(assetDir);
|
|
3336
|
+
const candidate = resolve5(assetRoot, `.${trimmed}`);
|
|
3135
3337
|
if (candidate !== assetRoot && !candidate.startsWith(`${assetRoot}${sep}`)) return null;
|
|
3136
|
-
if (!
|
|
3338
|
+
if (!existsSync6(candidate)) return null;
|
|
3137
3339
|
return candidate;
|
|
3138
3340
|
}
|
|
3139
3341
|
function requireControlToken(req, res, controlToken) {
|
|
@@ -3269,7 +3471,7 @@ data: ${JSON.stringify(event)}
|
|
|
3269
3471
|
`);
|
|
3270
3472
|
}
|
|
3271
3473
|
async function handleApiRequest(req, res, pathname, dbPath, controlToken) {
|
|
3272
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
3474
|
+
const { osecDB: osecDB2 } = await import("./dist-4MAW5X6L.js");
|
|
3273
3475
|
if (isPresentationEventsStreamPath(pathname)) {
|
|
3274
3476
|
if (req.method !== "GET") {
|
|
3275
3477
|
json(res, 405, { error: "Method not allowed" });
|
|
@@ -3323,7 +3525,7 @@ async function handleApiRequest(req, res, pathname, dbPath, controlToken) {
|
|
|
3323
3525
|
return true;
|
|
3324
3526
|
}
|
|
3325
3527
|
if (controlPath.action === "recover-stale-workers") {
|
|
3326
|
-
const { recoverStaleWorkers } = await import("./orchestrate-
|
|
3528
|
+
const { recoverStaleWorkers } = await import("./orchestrate-OC2VZN2X.js");
|
|
3327
3529
|
const body = await readJson(req);
|
|
3328
3530
|
const recovered = recoverStaleWorkers(
|
|
3329
3531
|
dbPath,
|
|
@@ -3407,8 +3609,8 @@ async function handleApiRequest(req, res, pathname, dbPath, controlToken) {
|
|
|
3407
3609
|
return true;
|
|
3408
3610
|
}
|
|
3409
3611
|
if (controlPath.action === "reset-database") {
|
|
3410
|
-
const { resetOsecDatabase } = await import("./dist-
|
|
3411
|
-
const { seedVerificationWorkbench } = await import("./db-
|
|
3612
|
+
const { resetOsecDatabase } = await import("./dist-4MAW5X6L.js");
|
|
3613
|
+
const { seedVerificationWorkbench } = await import("./db-KFWOAUUB.js");
|
|
3412
3614
|
const body = await readJson(req);
|
|
3413
3615
|
const seed = typeof body.seed === "string" ? body.seed.trim().toLowerCase() : "verification";
|
|
3414
3616
|
if (!["verification", "empty"].includes(seed)) {
|
|
@@ -3708,7 +3910,7 @@ function registerDashboardCommand(program) {
|
|
|
3708
3910
|
json(res, 404, { error: "Asset not found" });
|
|
3709
3911
|
return;
|
|
3710
3912
|
}
|
|
3711
|
-
sendFile(res,
|
|
3913
|
+
sendFile(res, join5(assetDir, "index.html"), controlToken);
|
|
3712
3914
|
} catch (err) {
|
|
3713
3915
|
json(res, 500, { error: err instanceof Error ? err.message : String(err) });
|
|
3714
3916
|
}
|
|
@@ -3753,7 +3955,7 @@ function registerTuiCommand(program) {
|
|
|
3753
3955
|
program.command("tui").alias("watch").description("Open the unified engagement control plane (Bun-only)").action(async () => {
|
|
3754
3956
|
const { isBunRuntime: isBunRuntime2 } = await import("./runtime-J7PLXZNM.js");
|
|
3755
3957
|
if (isBunRuntime2()) {
|
|
3756
|
-
const { showOpenTuiHome } = await import("./run-
|
|
3958
|
+
const { showOpenTuiHome } = await import("./run-D56MPDKY.js");
|
|
3757
3959
|
await showOpenTuiHome();
|
|
3758
3960
|
return;
|
|
3759
3961
|
}
|
|
@@ -4662,7 +4864,7 @@ var McpServer = class {
|
|
|
4662
4864
|
let task = createTaskResult.task;
|
|
4663
4865
|
const pollInterval = task.pollInterval ?? 5e3;
|
|
4664
4866
|
while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
|
|
4665
|
-
await new Promise((
|
|
4867
|
+
await new Promise((resolve27) => setTimeout(resolve27, pollInterval));
|
|
4666
4868
|
const updatedTask = await extra.taskStore.getTask(taskId);
|
|
4667
4869
|
if (!updatedTask) {
|
|
4668
4870
|
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
|
|
@@ -5287,12 +5489,12 @@ var StdioServerTransport = class {
|
|
|
5287
5489
|
this.onclose?.();
|
|
5288
5490
|
}
|
|
5289
5491
|
send(message) {
|
|
5290
|
-
return new Promise((
|
|
5492
|
+
return new Promise((resolve27) => {
|
|
5291
5493
|
const json2 = serializeMessage(message);
|
|
5292
5494
|
if (this._stdout.write(json2)) {
|
|
5293
|
-
|
|
5495
|
+
resolve27();
|
|
5294
5496
|
} else {
|
|
5295
|
-
this._stdout.once("drain",
|
|
5497
|
+
this._stdout.once("drain", resolve27);
|
|
5296
5498
|
}
|
|
5297
5499
|
});
|
|
5298
5500
|
}
|
|
@@ -5406,9 +5608,9 @@ function toolResultToMcp(result) {
|
|
|
5406
5608
|
return toTextResult(text2, { success: true, output: result.output });
|
|
5407
5609
|
}
|
|
5408
5610
|
function withToolTimeout(task, timeoutMs) {
|
|
5409
|
-
return new Promise((
|
|
5611
|
+
return new Promise((resolve27) => {
|
|
5410
5612
|
const timer = setTimeout(() => {
|
|
5411
|
-
|
|
5613
|
+
resolve27({
|
|
5412
5614
|
success: false,
|
|
5413
5615
|
output: null,
|
|
5414
5616
|
error: `MCP tool timed out after ${timeoutMs}ms`
|
|
@@ -5417,11 +5619,11 @@ function withToolTimeout(task, timeoutMs) {
|
|
|
5417
5619
|
task.then(
|
|
5418
5620
|
(result) => {
|
|
5419
5621
|
clearTimeout(timer);
|
|
5420
|
-
|
|
5622
|
+
resolve27(result);
|
|
5421
5623
|
},
|
|
5422
5624
|
(error) => {
|
|
5423
5625
|
clearTimeout(timer);
|
|
5424
|
-
|
|
5626
|
+
resolve27({
|
|
5425
5627
|
success: false,
|
|
5426
5628
|
output: null,
|
|
5427
5629
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -5609,11 +5811,11 @@ function rowToFinding(row) {
|
|
|
5609
5811
|
};
|
|
5610
5812
|
}
|
|
5611
5813
|
async function openStore(dbPath) {
|
|
5612
|
-
const { MemoryStore } = await import("./dist-
|
|
5814
|
+
const { MemoryStore } = await import("./dist-4YICS2J2.js");
|
|
5613
5815
|
return new MemoryStore(dbPath);
|
|
5614
5816
|
}
|
|
5615
5817
|
async function loadFinding2(dbPath, findingId) {
|
|
5616
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
5818
|
+
const { osecDB: osecDB2 } = await import("./dist-4MAW5X6L.js");
|
|
5617
5819
|
const db = new osecDB2(dbPath);
|
|
5618
5820
|
try {
|
|
5619
5821
|
const rows = db.listFindings({ limit: 5e3 });
|
|
@@ -5688,7 +5890,7 @@ async function runMemoryRemove(id, dbPath) {
|
|
|
5688
5890
|
async function runMarkFp(findingId, opts) {
|
|
5689
5891
|
const row = await loadFinding2(opts.dbPath, findingId);
|
|
5690
5892
|
const finding = rowToFinding(row);
|
|
5691
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
5893
|
+
const { osecDB: osecDB2 } = await import("./dist-4MAW5X6L.js");
|
|
5692
5894
|
const db = new osecDB2(opts.dbPath);
|
|
5693
5895
|
try {
|
|
5694
5896
|
db.updateFindingTriage(row.id, "suppressed", opts.reason);
|
|
@@ -5748,11 +5950,11 @@ function registerTriageCommand(program) {
|
|
|
5748
5950
|
}
|
|
5749
5951
|
|
|
5750
5952
|
// packages/cli/src/commands/eval.ts
|
|
5751
|
-
import { readFileSync as
|
|
5953
|
+
import { readFileSync as readFileSync4, existsSync as existsSync7 } from "node:fs";
|
|
5752
5954
|
function parseAuthFlag2(value) {
|
|
5753
5955
|
let raw;
|
|
5754
|
-
if (!value.trimStart().startsWith("{") &&
|
|
5755
|
-
raw =
|
|
5956
|
+
if (!value.trimStart().startsWith("{") && existsSync7(value)) {
|
|
5957
|
+
raw = readFileSync4(value, "utf-8");
|
|
5756
5958
|
} else {
|
|
5757
5959
|
raw = value;
|
|
5758
5960
|
}
|
|
@@ -5903,8 +6105,8 @@ function registerEvalCommand(program) {
|
|
|
5903
6105
|
}
|
|
5904
6106
|
|
|
5905
6107
|
// packages/cli/src/commands/bench.ts
|
|
5906
|
-
import { readFileSync as
|
|
5907
|
-
import { resolve as
|
|
6108
|
+
import { readFileSync as readFileSync9, existsSync as existsSync12, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
6109
|
+
import { resolve as resolve10, join as join10 } from "node:path";
|
|
5908
6110
|
import { performance } from "node:perf_hooks";
|
|
5909
6111
|
|
|
5910
6112
|
// packages/benchmark/dist/bench-integrations/xbow.js
|
|
@@ -5912,11 +6114,11 @@ import { randomBytes as randomBytes2 } from "node:crypto";
|
|
|
5912
6114
|
|
|
5913
6115
|
// packages/benchmark/dist/xbow-runner.js
|
|
5914
6116
|
import { execSync, spawnSync } from "node:child_process";
|
|
5915
|
-
import { readFileSync as
|
|
5916
|
-
import { join as
|
|
6117
|
+
import { readFileSync as readFileSync5, existsSync as existsSync8, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, readdirSync } from "node:fs";
|
|
6118
|
+
import { join as join6, dirname as dirname3, resolve as resolve6 } from "node:path";
|
|
5917
6119
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
5918
6120
|
import { randomBytes } from "node:crypto";
|
|
5919
|
-
import { tmpdir as
|
|
6121
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
5920
6122
|
|
|
5921
6123
|
// packages/benchmark/dist/wilson.js
|
|
5922
6124
|
var Z_95 = 1.959963984540054;
|
|
@@ -6067,13 +6269,13 @@ function normalizeBenchmarkRepo(repo) {
|
|
|
6067
6269
|
}
|
|
6068
6270
|
function cacheDirForRepo(repo) {
|
|
6069
6271
|
const slug = repo.replace(/^https?:\/\//, "").replace(/^git@/, "").replace(/\.git$/, "").replace(/[^\w.-]+/g, "_");
|
|
6070
|
-
return
|
|
6272
|
+
return join6(tmpdir3(), `0sec-xbow-cache`, slug);
|
|
6071
6273
|
}
|
|
6072
6274
|
function ensureBenchmarkRepo(repo, ref) {
|
|
6073
6275
|
const url = normalizeBenchmarkRepo(repo);
|
|
6074
6276
|
const dest = cacheDirForRepo(url);
|
|
6075
|
-
const benchDir =
|
|
6076
|
-
if (
|
|
6277
|
+
const benchDir = join6(dest, "benchmarks");
|
|
6278
|
+
if (existsSync8(benchDir)) {
|
|
6077
6279
|
if (!jsonOutput) {
|
|
6078
6280
|
console.log(` using cached benchmark repo at ${dest}`);
|
|
6079
6281
|
}
|
|
@@ -6124,20 +6326,20 @@ function chooseBetterResult(a, b) {
|
|
|
6124
6326
|
return b.durationMs < a.durationMs ? b : a;
|
|
6125
6327
|
}
|
|
6126
6328
|
function loadXbowChallenges(xbowPath = XBOW_PATH) {
|
|
6127
|
-
const benchDir =
|
|
6128
|
-
if (!
|
|
6329
|
+
const benchDir = join6(xbowPath, "benchmarks");
|
|
6330
|
+
if (!existsSync8(benchDir)) {
|
|
6129
6331
|
throw new Error(`XBOW benchmarks not found at ${benchDir}. Clone them or pass --benchmark-path / XBOW_PATH.`);
|
|
6130
6332
|
}
|
|
6131
6333
|
const dirs = readdirSync(benchDir).filter((d) => d.startsWith("XBEN-")).sort();
|
|
6132
6334
|
const challenges = [];
|
|
6133
6335
|
for (const dir of dirs) {
|
|
6134
|
-
const configPath =
|
|
6135
|
-
const yamlPath =
|
|
6336
|
+
const configPath = join6(benchDir, dir, "benchmark.json");
|
|
6337
|
+
const yamlPath = join6(benchDir, dir, "benchmark.yaml");
|
|
6136
6338
|
let config;
|
|
6137
|
-
if (
|
|
6138
|
-
config = JSON.parse(
|
|
6139
|
-
} else if (
|
|
6140
|
-
const yaml =
|
|
6339
|
+
if (existsSync8(configPath)) {
|
|
6340
|
+
config = JSON.parse(readFileSync5(configPath, "utf8"));
|
|
6341
|
+
} else if (existsSync8(yamlPath)) {
|
|
6342
|
+
const yaml = readFileSync5(yamlPath, "utf8");
|
|
6141
6343
|
config = {
|
|
6142
6344
|
name: yaml.match(/name:\s*(.+)/)?.[1]?.trim() ?? dir,
|
|
6143
6345
|
description: yaml.match(/content:\s*(.+)/)?.[1]?.trim() ?? "",
|
|
@@ -6155,7 +6357,7 @@ function loadXbowChallenges(xbowPath = XBOW_PATH) {
|
|
|
6155
6357
|
level: parseInt(config.level ?? "2"),
|
|
6156
6358
|
tags: config.tags ?? [],
|
|
6157
6359
|
winCondition: config.win_condition ?? "flag",
|
|
6158
|
-
path:
|
|
6360
|
+
path: join6(benchDir, dir)
|
|
6159
6361
|
});
|
|
6160
6362
|
}
|
|
6161
6363
|
return challenges;
|
|
@@ -6257,7 +6459,7 @@ async function runChallengeOnce(challenge, model) {
|
|
|
6257
6459
|
});
|
|
6258
6460
|
try {
|
|
6259
6461
|
if (useAgentic) {
|
|
6260
|
-
const dbPath =
|
|
6462
|
+
const dbPath = join6(tmpdir3(), `0sec-xbow-${challenge.id}-${Date.now()}.db`);
|
|
6261
6463
|
const hint = challenge.description ? `
|
|
6262
6464
|
Challenge hint: ${challenge.description}` : "";
|
|
6263
6465
|
const repoPath = whiteBox ? challenge.path : void 0;
|
|
@@ -6322,7 +6524,7 @@ Challenge hint: ${challenge.description}` : "";
|
|
|
6322
6524
|
}
|
|
6323
6525
|
if (report.trace && Array.isArray(report.trace) && report.trace.length > 0) {
|
|
6324
6526
|
try {
|
|
6325
|
-
const tracesDir =
|
|
6527
|
+
const tracesDir = join6(__dirname, "..", "results", "traces");
|
|
6326
6528
|
mkdirSync2(tracesDir, { recursive: true });
|
|
6327
6529
|
const tracePayload = {
|
|
6328
6530
|
challengeId: challenge.id,
|
|
@@ -6331,7 +6533,7 @@ Challenge hint: ${challenge.description}` : "";
|
|
|
6331
6533
|
turns: report.benchmarkMeta?.attackTurns ?? 0,
|
|
6332
6534
|
messages: sanitizeTrace(report.trace)
|
|
6333
6535
|
};
|
|
6334
|
-
writeFileSync2(
|
|
6536
|
+
writeFileSync2(join6(tracesDir, `${challenge.id}-trace.json`), JSON.stringify(tracePayload, null, 2));
|
|
6335
6537
|
} catch (traceErr) {
|
|
6336
6538
|
if (!jsonOutput) {
|
|
6337
6539
|
console.log(` [trace] failed to write trace for ${challenge.id}: ${traceErr instanceof Error ? traceErr.message : String(traceErr)}`);
|
|
@@ -6594,12 +6796,12 @@ async function main() {
|
|
|
6594
6796
|
}
|
|
6595
6797
|
console.log("");
|
|
6596
6798
|
}
|
|
6597
|
-
const resultsDir =
|
|
6799
|
+
const resultsDir = join6(__dirname, "..", "results");
|
|
6598
6800
|
mkdirSync2(resultsDir, { recursive: true });
|
|
6599
|
-
const latestPath =
|
|
6600
|
-
if (!freshRun &&
|
|
6801
|
+
const latestPath = join6(resultsDir, "xbow-latest.json");
|
|
6802
|
+
if (!freshRun && existsSync8(latestPath)) {
|
|
6601
6803
|
try {
|
|
6602
|
-
const existing = JSON.parse(
|
|
6804
|
+
const existing = JSON.parse(readFileSync5(latestPath, "utf8"));
|
|
6603
6805
|
const existingById = new Map(existing.results.map((r) => [r.id, r]));
|
|
6604
6806
|
for (const r of report.results) {
|
|
6605
6807
|
existingById.set(r.id, r);
|
|
@@ -6645,7 +6847,7 @@ function isXbowRunnerEntrypoint(moduleUrl, argvPath = process.argv[1]) {
|
|
|
6645
6847
|
if (!argvPath || !/(?:^|[/\\])xbow-runner\.(?:[cm]?[jt]s)$/.test(argvPath)) {
|
|
6646
6848
|
return false;
|
|
6647
6849
|
}
|
|
6648
|
-
return moduleUrl === pathToFileURL(
|
|
6850
|
+
return moduleUrl === pathToFileURL(resolve6(argvPath)).href;
|
|
6649
6851
|
}
|
|
6650
6852
|
if (isXbowRunnerEntrypoint(import.meta.url))
|
|
6651
6853
|
main().then(() => {
|
|
@@ -6745,35 +6947,35 @@ function createXbowBenchIntegration(opts = {}) {
|
|
|
6745
6947
|
}
|
|
6746
6948
|
|
|
6747
6949
|
// packages/benchmark/dist/bench-integrations/cybergym.js
|
|
6748
|
-
import { createHash as
|
|
6749
|
-
import { readFileSync as
|
|
6950
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
6951
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
6750
6952
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
6751
6953
|
|
|
6752
6954
|
// packages/benchmark/dist/cybergym-runner.js
|
|
6753
|
-
import { execFileSync } from "node:child_process";
|
|
6754
|
-
import { readFileSync as
|
|
6755
|
-
import { join as
|
|
6955
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
6956
|
+
import { readFileSync as readFileSync6, existsSync as existsSync9, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync3, mkdtempSync as mkdtempSync3, rmSync as rmSync3 } from "node:fs";
|
|
6957
|
+
import { join as join7, dirname as dirname4, isAbsolute, resolve as resolve7 } from "node:path";
|
|
6756
6958
|
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
6757
|
-
import { createHash } from "node:crypto";
|
|
6758
|
-
import { tmpdir as
|
|
6959
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
6960
|
+
import { tmpdir as tmpdir4 } from "node:os";
|
|
6759
6961
|
var __dirname2 = dirname4(fileURLToPath3(import.meta.url));
|
|
6760
6962
|
var CYBERGYM_CORPUS_PATH = "results/cybergym-v1.jsonl";
|
|
6761
|
-
function resolveCorpusPath(override, packageRoot =
|
|
6963
|
+
function resolveCorpusPath(override, packageRoot = join7(__dirname2, "..")) {
|
|
6762
6964
|
const requested = override ?? process.env.CYBERGYM_CORPUS_PATH;
|
|
6763
6965
|
if (requested && requested.length > 0) {
|
|
6764
|
-
return isAbsolute(requested) ? requested :
|
|
6966
|
+
return isAbsolute(requested) ? requested : join7(process.cwd(), requested);
|
|
6765
6967
|
}
|
|
6766
|
-
return
|
|
6968
|
+
return join7(packageRoot, CYBERGYM_CORPUS_PATH);
|
|
6767
6969
|
}
|
|
6768
6970
|
function parseTaskDir(taskDir, taskId, difficulty = "level1") {
|
|
6769
|
-
if (!
|
|
6971
|
+
if (!existsSync9(taskDir)) {
|
|
6770
6972
|
throw new Error(`CyberGym task dir not found: ${taskDir}`);
|
|
6771
6973
|
}
|
|
6772
|
-
const descPath =
|
|
6773
|
-
if (!
|
|
6974
|
+
const descPath = join7(taskDir, "description.txt");
|
|
6975
|
+
if (!existsSync9(descPath)) {
|
|
6774
6976
|
throw new Error(`CyberGym task dir missing description.txt: ${taskDir}`);
|
|
6775
6977
|
}
|
|
6776
|
-
const description =
|
|
6978
|
+
const description = readFileSync6(descPath, "utf8");
|
|
6777
6979
|
const repoRoot = locateOrUnpackRepo(taskDir);
|
|
6778
6980
|
return {
|
|
6779
6981
|
taskId: taskId ?? deriveTaskId(taskDir, description),
|
|
@@ -6784,15 +6986,15 @@ function parseTaskDir(taskDir, taskId, difficulty = "level1") {
|
|
|
6784
6986
|
};
|
|
6785
6987
|
}
|
|
6786
6988
|
function locateOrUnpackRepo(taskDir) {
|
|
6787
|
-
const unpacked =
|
|
6788
|
-
if (
|
|
6989
|
+
const unpacked = join7(taskDir, "repo-vul");
|
|
6990
|
+
if (existsSync9(unpacked))
|
|
6789
6991
|
return unpacked;
|
|
6790
|
-
const tarball =
|
|
6791
|
-
if (!
|
|
6992
|
+
const tarball = join7(taskDir, "repo-vul.tar.gz");
|
|
6993
|
+
if (!existsSync9(tarball)) {
|
|
6792
6994
|
throw new Error(`CyberGym task dir has neither repo-vul/ nor repo-vul.tar.gz: ${taskDir}`);
|
|
6793
6995
|
}
|
|
6794
6996
|
mkdirSync3(unpacked, { recursive: true });
|
|
6795
|
-
|
|
6997
|
+
execFileSync2("tar", ["-xzf", tarball, "-C", unpacked], { stdio: "pipe" });
|
|
6796
6998
|
return unpacked;
|
|
6797
6999
|
}
|
|
6798
7000
|
function deriveTaskId(taskDir, description) {
|
|
@@ -6807,24 +7009,24 @@ function cleanupOwnedTaskDir(taskDir) {
|
|
|
6807
7009
|
if (!ownedTaskDirs.has(taskDir))
|
|
6808
7010
|
return;
|
|
6809
7011
|
try {
|
|
6810
|
-
|
|
7012
|
+
rmSync3(taskDir, { recursive: true, force: true });
|
|
6811
7013
|
} catch {
|
|
6812
7014
|
}
|
|
6813
7015
|
ownedTaskDirs.delete(taskDir);
|
|
6814
7016
|
}
|
|
6815
7017
|
function generateTask(taskId, difficulty, harnessDir) {
|
|
6816
|
-
if (!
|
|
7018
|
+
if (!existsSync9(harnessDir)) {
|
|
6817
7019
|
throw new Error(`CyberGym harness dir not found: ${harnessDir}. Set --harness-dir or CYBERGYM_HARNESS to the sunblaze-ucb/cybergym checkout (needs #1027).`);
|
|
6818
7020
|
}
|
|
6819
|
-
const outDir =
|
|
7021
|
+
const outDir = mkdtempSync3(join7(tmpdir4(), "cybergym-task-"));
|
|
6820
7022
|
ownedTaskDirs.add(outDir);
|
|
6821
|
-
const maskMap = process.env.CYBERGYM_MASK_MAP ??
|
|
6822
|
-
const modernEntrypoint =
|
|
7023
|
+
const maskMap = process.env.CYBERGYM_MASK_MAP ?? join7(harnessDir, "mask_map.json");
|
|
7024
|
+
const modernEntrypoint = join7(harnessDir, "src", "cybergym", "task", "gen_task.py");
|
|
6823
7025
|
const python = process.env.CYBERGYM_PYTHON ?? "python3";
|
|
6824
|
-
if (
|
|
6825
|
-
const dataDir = process.env.CYBERGYM_DATA_DIR ??
|
|
7026
|
+
if (existsSync9(modernEntrypoint)) {
|
|
7027
|
+
const dataDir = process.env.CYBERGYM_DATA_DIR ?? join7(dirname4(harnessDir), "data", "data");
|
|
6826
7028
|
const server = process.env.CYBERGYM_SERVER ?? "http://127.0.0.1:8666";
|
|
6827
|
-
|
|
7029
|
+
execFileSync2(python, [
|
|
6828
7030
|
"-m",
|
|
6829
7031
|
"cybergym.task.gen_task",
|
|
6830
7032
|
"--task-id",
|
|
@@ -6837,18 +7039,18 @@ function generateTask(taskId, difficulty, harnessDir) {
|
|
|
6837
7039
|
dataDir,
|
|
6838
7040
|
"--server",
|
|
6839
7041
|
server,
|
|
6840
|
-
...
|
|
7042
|
+
...existsSync9(maskMap) ? ["--mask-map", maskMap] : []
|
|
6841
7043
|
], { stdio: "pipe", cwd: harnessDir });
|
|
6842
7044
|
} else {
|
|
6843
|
-
|
|
6844
|
-
|
|
7045
|
+
execFileSync2(python, [
|
|
7046
|
+
join7(harnessDir, "gen_task.py"),
|
|
6845
7047
|
"--task-id",
|
|
6846
7048
|
taskId,
|
|
6847
7049
|
"--difficulty",
|
|
6848
7050
|
difficulty,
|
|
6849
7051
|
"--out-dir",
|
|
6850
7052
|
outDir,
|
|
6851
|
-
...
|
|
7053
|
+
...existsSync9(maskMap) ? ["--mask-map", maskMap] : []
|
|
6852
7054
|
], { stdio: "pipe", cwd: harnessDir });
|
|
6853
7055
|
}
|
|
6854
7056
|
return parseTaskDir(outDir, taskId, difficulty);
|
|
@@ -6875,14 +7077,14 @@ async function verifyThroughOracleBridge(bridge, capability, agentId, pocId, fet
|
|
|
6875
7077
|
return JSON.stringify(record2);
|
|
6876
7078
|
}
|
|
6877
7079
|
var submitToOracle = async (task, pocPath) => {
|
|
6878
|
-
const submitScript =
|
|
6879
|
-
if (!
|
|
7080
|
+
const submitScript = join7(task.taskDir, "submit.sh");
|
|
7081
|
+
if (!existsSync9(submitScript)) {
|
|
6880
7082
|
throw new Error(`CyberGym task missing submit.sh: ${task.taskDir}`);
|
|
6881
7083
|
}
|
|
6882
7084
|
const harnessDir = process.env.CYBERGYM_HARNESS ?? "/root/cybergym";
|
|
6883
7085
|
const server = process.env.CYBERGYM_SERVER ?? "http://127.0.0.1:8666";
|
|
6884
|
-
const pocdbPath = process.env.CYBERGYM_POCDB ??
|
|
6885
|
-
const submitOut =
|
|
7086
|
+
const pocdbPath = process.env.CYBERGYM_POCDB ?? join7(harnessDir, "server_poc", "poc.db");
|
|
7087
|
+
const submitOut = execFileSync2("bash", [submitScript, pocPath], {
|
|
6886
7088
|
cwd: task.taskDir,
|
|
6887
7089
|
encoding: "utf8",
|
|
6888
7090
|
stdio: "pipe"
|
|
@@ -6899,8 +7101,8 @@ var submitToOracle = async (task, pocPath) => {
|
|
|
6899
7101
|
}
|
|
6900
7102
|
verifyOut = await verifyThroughOracleBridge(bridge, capability, agentId, submit.pocId);
|
|
6901
7103
|
} else {
|
|
6902
|
-
verifyOut =
|
|
6903
|
-
|
|
7104
|
+
verifyOut = execFileSync2("python3", [
|
|
7105
|
+
join7(harnessDir, "scripts", "verify_agent_result.py"),
|
|
6904
7106
|
"--server",
|
|
6905
7107
|
server,
|
|
6906
7108
|
"--pocdb_path",
|
|
@@ -6918,13 +7120,13 @@ ${verifyOut}`.trim()
|
|
|
6918
7120
|
};
|
|
6919
7121
|
};
|
|
6920
7122
|
var submitVulOnly = async (task, pocPath) => {
|
|
6921
|
-
const submitScript =
|
|
6922
|
-
if (!
|
|
7123
|
+
const submitScript = join7(task.taskDir, "submit.sh");
|
|
7124
|
+
if (!existsSync9(submitScript)) {
|
|
6923
7125
|
throw new Error(`CyberGym task missing submit.sh: ${task.taskDir}`);
|
|
6924
7126
|
}
|
|
6925
7127
|
let submitOut;
|
|
6926
7128
|
try {
|
|
6927
|
-
submitOut =
|
|
7129
|
+
submitOut = execFileSync2("bash", [submitScript, pocPath], {
|
|
6928
7130
|
cwd: task.taskDir,
|
|
6929
7131
|
encoding: "utf8",
|
|
6930
7132
|
stdio: "pipe"
|
|
@@ -6942,9 +7144,9 @@ var submitVulOnly = async (task, pocPath) => {
|
|
|
6942
7144
|
return { ...submit, raw: submitOut.trim() };
|
|
6943
7145
|
};
|
|
6944
7146
|
function extractAgentId(submitScriptPath) {
|
|
6945
|
-
if (!
|
|
7147
|
+
if (!existsSync9(submitScriptPath))
|
|
6946
7148
|
return void 0;
|
|
6947
|
-
const src =
|
|
7149
|
+
const src = readFileSync6(submitScriptPath, "utf8");
|
|
6948
7150
|
return /["']agent_id["']\s*:\s*["']([0-9a-fA-F-]+)["']/.exec(src)?.[1];
|
|
6949
7151
|
}
|
|
6950
7152
|
function verdictFromPocRecords(out, pocId, vulExitFallback) {
|
|
@@ -6998,7 +7200,7 @@ function parseSubmitOutput(out) {
|
|
|
6998
7200
|
};
|
|
6999
7201
|
}
|
|
7000
7202
|
var runEngineDefault = async (task, opts) => {
|
|
7001
|
-
const dbPath =
|
|
7203
|
+
const dbPath = join7(tmpdir4(), `0sec-cybergym-${sanitizeId(task.taskId)}-${Date.now()}.db`);
|
|
7002
7204
|
const memory = process.env.CYBERGYM_MEMORY_DB ? new CraftMemoryStore(process.env.CYBERGYM_MEMORY_DB) : void 0;
|
|
7003
7205
|
const cpgPath = process.env.CYBERGYM_CPG_PATH;
|
|
7004
7206
|
const adversarialReviewModel = process.env.CYBERGYM_ADVERSARIAL_REVIEW_MODEL?.trim();
|
|
@@ -7144,14 +7346,14 @@ function extractPocPath(findings) {
|
|
|
7144
7346
|
for (const f of findings) {
|
|
7145
7347
|
const ev = f?.evidence;
|
|
7146
7348
|
const req = ev?.request;
|
|
7147
|
-
if (typeof req === "string" && req.length > 0 && req !== "N/A (userspace crash artifact)" &&
|
|
7349
|
+
if (typeof req === "string" && req.length > 0 && req !== "N/A (userspace crash artifact)" && existsSync9(req)) {
|
|
7148
7350
|
return req;
|
|
7149
7351
|
}
|
|
7150
7352
|
}
|
|
7151
7353
|
return void 0;
|
|
7152
7354
|
}
|
|
7153
7355
|
function detectLanguage(repoRoot) {
|
|
7154
|
-
if (
|
|
7356
|
+
if (existsSync9(join7(repoRoot, "CMakeLists.txt")))
|
|
7155
7357
|
return "cpp";
|
|
7156
7358
|
return "c";
|
|
7157
7359
|
}
|
|
@@ -7572,14 +7774,14 @@ function appendToCorpus(results, corpusPath) {
|
|
|
7572
7774
|
const lines = results.map((r) => sampleToJsonl(resultToSample(r)));
|
|
7573
7775
|
if (lines.length === 0)
|
|
7574
7776
|
return;
|
|
7575
|
-
if (
|
|
7777
|
+
if (existsSync9(corpusPath)) {
|
|
7576
7778
|
appendFileSync(corpusPath, lines.join("\n") + "\n");
|
|
7577
7779
|
} else {
|
|
7578
7780
|
writeFileSync3(corpusPath, lines.join("\n") + "\n");
|
|
7579
7781
|
}
|
|
7580
7782
|
}
|
|
7581
7783
|
function sha256File(path) {
|
|
7582
|
-
return
|
|
7784
|
+
return createHash2("sha256").update(readFileSync6(path)).digest("hex");
|
|
7583
7785
|
}
|
|
7584
7786
|
function sanitizeId(id) {
|
|
7585
7787
|
return id.replace(/[^\w.-]+/g, "_");
|
|
@@ -7675,7 +7877,7 @@ function resolveTasks(cfg) {
|
|
|
7675
7877
|
}
|
|
7676
7878
|
let taskIds = [];
|
|
7677
7879
|
if (cfg.subset) {
|
|
7678
|
-
taskIds =
|
|
7880
|
+
taskIds = readFileSync6(cfg.subset, "utf8").split("\n").map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#"));
|
|
7679
7881
|
} else if (cfg.taskId) {
|
|
7680
7882
|
taskIds = [cfg.taskId];
|
|
7681
7883
|
}
|
|
@@ -7764,7 +7966,7 @@ function isCyberGymRunnerEntrypoint(moduleUrl, argvPath = process.argv[1]) {
|
|
|
7764
7966
|
if (!argvPath || !/(?:^|[/\\])cybergym-runner\.(?:[cm]?[jt]s)$/.test(argvPath)) {
|
|
7765
7967
|
return false;
|
|
7766
7968
|
}
|
|
7767
|
-
return moduleUrl === pathToFileURL2(
|
|
7969
|
+
return moduleUrl === pathToFileURL2(resolve7(argvPath)).href;
|
|
7768
7970
|
}
|
|
7769
7971
|
if (isCyberGymRunnerEntrypoint(import.meta.url)) {
|
|
7770
7972
|
main2().then(() => process.exit(0)).catch((err) => {
|
|
@@ -7781,10 +7983,10 @@ var CYBERGYM_ORACLE_CONFIG = {
|
|
|
7781
7983
|
version: 1
|
|
7782
7984
|
};
|
|
7783
7985
|
function sha256(bytes) {
|
|
7784
|
-
return `sha256:${
|
|
7986
|
+
return `sha256:${createHash3("sha256").update(bytes).digest("hex")}`;
|
|
7785
7987
|
}
|
|
7786
7988
|
function cyberGymBenchOracleEvaluatorAttestation() {
|
|
7787
|
-
const codeDigest = sha256(
|
|
7989
|
+
const codeDigest = sha256(readFileSync7(fileURLToPath4(import.meta.url)));
|
|
7788
7990
|
const configDigest = sha256(Buffer.from(`${JSON.stringify(CYBERGYM_ORACLE_CONFIG)}
|
|
7789
7991
|
`));
|
|
7790
7992
|
const bundleDigest = sha256(Buffer.from(`${JSON.stringify({ schemaVersion: 1, codeDigest, configDigest })}
|
|
@@ -7813,7 +8015,7 @@ function createCyberGymManifest(taskIds, opts = {}) {
|
|
|
7813
8015
|
});
|
|
7814
8016
|
}
|
|
7815
8017
|
function loadCyberGymTaskIds(subsetPath) {
|
|
7816
|
-
const taskIds =
|
|
8018
|
+
const taskIds = readFileSync7(subsetPath, "utf8").split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
7817
8019
|
const seen = /* @__PURE__ */ new Set();
|
|
7818
8020
|
for (const taskId of taskIds) {
|
|
7819
8021
|
if (seen.has(taskId))
|
|
@@ -7952,20 +8154,20 @@ function createCyberGymBenchIntegration(opts = {}) {
|
|
|
7952
8154
|
import {
|
|
7953
8155
|
closeSync,
|
|
7954
8156
|
constants,
|
|
7955
|
-
existsSync as
|
|
8157
|
+
existsSync as existsSync10,
|
|
7956
8158
|
fstatSync,
|
|
7957
8159
|
fsyncSync,
|
|
7958
8160
|
linkSync,
|
|
7959
8161
|
lstatSync,
|
|
7960
8162
|
mkdirSync as mkdirSync4,
|
|
7961
8163
|
openSync,
|
|
7962
|
-
readFileSync as
|
|
7963
|
-
rmSync as
|
|
8164
|
+
readFileSync as readFileSync8,
|
|
8165
|
+
rmSync as rmSync4,
|
|
7964
8166
|
unlinkSync,
|
|
7965
8167
|
writeSync
|
|
7966
8168
|
} from "node:fs";
|
|
7967
|
-
import { createHash as
|
|
7968
|
-
import { basename as basename3, dirname as dirname5, join as
|
|
8169
|
+
import { createHash as createHash4, randomUUID as randomUUID3 } from "node:crypto";
|
|
8170
|
+
import { basename as basename3, dirname as dirname5, join as join8, resolve as resolve8 } from "node:path";
|
|
7969
8171
|
var REQUIRED_0SEC_CHECKS = [
|
|
7970
8172
|
"build",
|
|
7971
8173
|
"ecosystem-audit-smoke (cargo)",
|
|
@@ -7997,7 +8199,7 @@ function digest(value, label) {
|
|
|
7997
8199
|
}
|
|
7998
8200
|
return result;
|
|
7999
8201
|
}
|
|
8000
|
-
function
|
|
8202
|
+
function positiveInteger2(value, label) {
|
|
8001
8203
|
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
8002
8204
|
throw new Error(`${label} must be a positive integer`);
|
|
8003
8205
|
}
|
|
@@ -8037,7 +8239,7 @@ function stringArray(value, label) {
|
|
|
8037
8239
|
return strings;
|
|
8038
8240
|
}
|
|
8039
8241
|
function readArtifactBytes(pathValue, label) {
|
|
8040
|
-
const path =
|
|
8242
|
+
const path = resolve8(pathValue);
|
|
8041
8243
|
const stat3 = lstatSync(path);
|
|
8042
8244
|
if (!stat3.isFile() || stat3.isSymbolicLink()) {
|
|
8043
8245
|
throw new Error(`${label} must be a regular non-symlink file`);
|
|
@@ -8050,7 +8252,7 @@ function readArtifactBytes(pathValue, label) {
|
|
|
8050
8252
|
if (stat3.dev !== before.dev || stat3.ino !== before.ino || stat3.size !== before.size || stat3.mtimeMs !== before.mtimeMs) {
|
|
8051
8253
|
throw new Error(`${label} changed before it was opened`);
|
|
8052
8254
|
}
|
|
8053
|
-
const content =
|
|
8255
|
+
const content = readFileSync8(fd);
|
|
8054
8256
|
const after = fstatSync(fd);
|
|
8055
8257
|
if (before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeMs !== after.mtimeMs) {
|
|
8056
8258
|
throw new Error(`${label} changed while it was being read`);
|
|
@@ -8061,7 +8263,7 @@ function readArtifactBytes(pathValue, label) {
|
|
|
8061
8263
|
}
|
|
8062
8264
|
}
|
|
8063
8265
|
function sha256Bytes(content) {
|
|
8064
|
-
return `sha256:${
|
|
8266
|
+
return `sha256:${createHash4("sha256").update(content).digest("hex")}`;
|
|
8065
8267
|
}
|
|
8066
8268
|
function readArtifactJsonWithDigest(pathValue, label) {
|
|
8067
8269
|
const content = readArtifactBytes(pathValue, label);
|
|
@@ -8101,9 +8303,9 @@ function parseCandidateMetadata(value) {
|
|
|
8101
8303
|
calibrationEmptyFindings: change?.kind === "feature_flag" && knobs?.["calibration.empty_findings"] === true,
|
|
8102
8304
|
change: { kind: text(change.kind, "candidate.change.kind"), knobs: parsedKnobs },
|
|
8103
8305
|
budget: {
|
|
8104
|
-
maxRuns:
|
|
8306
|
+
maxRuns: positiveInteger2(budget.maxRuns, "candidate.budget.maxRuns"),
|
|
8105
8307
|
maxUsd: finiteNonNegative(budget.maxUsd, "candidate.budget.maxUsd"),
|
|
8106
|
-
maxWallClockMinutes:
|
|
8308
|
+
maxWallClockMinutes: positiveInteger2(
|
|
8107
8309
|
budget.maxWallClockMinutes,
|
|
8108
8310
|
"candidate.budget.maxWallClockMinutes"
|
|
8109
8311
|
)
|
|
@@ -8205,7 +8407,7 @@ function caseResult(value, manifestCase, label, configuredPassAtK, configuredAtt
|
|
|
8205
8407
|
if (!Array.isArray(raw.tags) || JSON.stringify(raw.tags) !== JSON.stringify(manifestCase.tags)) {
|
|
8206
8408
|
throw new Error(`${label}.tags do not match its manifest case`);
|
|
8207
8409
|
}
|
|
8208
|
-
const passAtK =
|
|
8410
|
+
const passAtK = positiveInteger2(raw.passAtK, `${label}.passAtK`);
|
|
8209
8411
|
if (passAtK !== (manifestCase.passAtK ?? configuredPassAtK)) {
|
|
8210
8412
|
throw new Error(`${label}.passAtK does not match its manifest or tournament config`);
|
|
8211
8413
|
}
|
|
@@ -8280,12 +8482,12 @@ function validateScorecard(value, manifest, label) {
|
|
|
8280
8482
|
}
|
|
8281
8483
|
const totals = record(raw.totals, `${label}.totals`);
|
|
8282
8484
|
const config = record(raw.config, `${label}.config`);
|
|
8283
|
-
|
|
8485
|
+
positiveInteger2(config.passAtK, `${label}.config.passAtK`);
|
|
8284
8486
|
const attemptPolicy = text(config.attemptPolicy, `${label}.config.attemptPolicy`);
|
|
8285
8487
|
if (attemptPolicy !== "pass-at-k" && attemptPolicy !== "independent-repeat") {
|
|
8286
8488
|
throw new Error(`${label}.config.attemptPolicy is invalid`);
|
|
8287
8489
|
}
|
|
8288
|
-
|
|
8490
|
+
positiveInteger2(config.maxTurns, `${label}.config.maxTurns`);
|
|
8289
8491
|
nullableCost(config.costCeilingUsd, `${label}.config.costCeilingUsd`);
|
|
8290
8492
|
if (typeof config.ciSubset !== "boolean") throw new Error(`${label}.config.ciSubset must be boolean`);
|
|
8291
8493
|
const cases = nonNegativeInteger(totals.cases, `${label}.totals.cases`);
|
|
@@ -8401,7 +8603,7 @@ function parseTournamentPair(value, label) {
|
|
|
8401
8603
|
throw new Error(`${label} tournament manifest does not match its manifest`);
|
|
8402
8604
|
}
|
|
8403
8605
|
const config = record(tournamentRaw.config, `${label}.tournament.config`);
|
|
8404
|
-
|
|
8606
|
+
positiveInteger2(config.passAtK, `${label}.tournament.config.passAtK`);
|
|
8405
8607
|
const attemptPolicy = text(
|
|
8406
8608
|
config.attemptPolicy,
|
|
8407
8609
|
`${label}.tournament.config.attemptPolicy`
|
|
@@ -8416,7 +8618,7 @@ function parseTournamentPair(value, label) {
|
|
|
8416
8618
|
if (schedule !== "variant-major" && schedule !== "case-major") {
|
|
8417
8619
|
throw new Error(`${label}.tournament.config.schedule is invalid`);
|
|
8418
8620
|
}
|
|
8419
|
-
|
|
8621
|
+
positiveInteger2(config.maxTurns, `${label}.tournament.config.maxTurns`);
|
|
8420
8622
|
nullableCost(config.costCeilingUsd, `${label}.tournament.config.costCeilingUsd`);
|
|
8421
8623
|
if (typeof config.ciSubset !== "boolean") {
|
|
8422
8624
|
throw new Error(`${label}.tournament.config.ciSubset must be boolean`);
|
|
@@ -8779,11 +8981,11 @@ function canonicalJson(value) {
|
|
|
8779
8981
|
`;
|
|
8780
8982
|
}
|
|
8781
8983
|
function writeCanonicalJsonAtomic(outputValue, value) {
|
|
8782
|
-
const output =
|
|
8984
|
+
const output = resolve8(outputValue);
|
|
8783
8985
|
const parent = dirname5(output);
|
|
8784
8986
|
mkdirSync4(parent, { recursive: true });
|
|
8785
|
-
if (
|
|
8786
|
-
const temporary =
|
|
8987
|
+
if (existsSync10(output)) throw new Error(`output already exists: ${output}`);
|
|
8988
|
+
const temporary = join8(parent, `.${basename3(output)}.${process.pid}.${randomUUID3()}.tmp`);
|
|
8787
8989
|
let fd;
|
|
8788
8990
|
try {
|
|
8789
8991
|
fd = openSync(temporary, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY, 384);
|
|
@@ -8795,52 +8997,52 @@ function writeCanonicalJsonAtomic(outputValue, value) {
|
|
|
8795
8997
|
linkSync(temporary, output);
|
|
8796
8998
|
unlinkSync(temporary);
|
|
8797
8999
|
} catch (error) {
|
|
8798
|
-
if (
|
|
9000
|
+
if (existsSync10(output)) throw new Error(`output already exists: ${output}`);
|
|
8799
9001
|
throw error;
|
|
8800
9002
|
}
|
|
8801
9003
|
} finally {
|
|
8802
9004
|
if (fd !== void 0) closeSync(fd);
|
|
8803
|
-
if (
|
|
9005
|
+
if (existsSync10(temporary)) unlinkSync(temporary);
|
|
8804
9006
|
}
|
|
8805
9007
|
}
|
|
8806
9008
|
function writeImprovementBundleAtomic(outputDirectoryValue, bundle) {
|
|
8807
|
-
const outputDirectory =
|
|
9009
|
+
const outputDirectory = resolve8(outputDirectoryValue);
|
|
8808
9010
|
const parent = dirname5(outputDirectory);
|
|
8809
9011
|
mkdirSync4(parent, { recursive: true });
|
|
8810
9012
|
try {
|
|
8811
9013
|
mkdirSync4(outputDirectory, { mode: 448 });
|
|
8812
9014
|
} catch (error) {
|
|
8813
|
-
if (
|
|
9015
|
+
if (existsSync10(outputDirectory)) throw new Error(`output already exists: ${outputDirectory}`);
|
|
8814
9016
|
throw error;
|
|
8815
9017
|
}
|
|
8816
9018
|
try {
|
|
8817
|
-
writeCanonicalJsonAtomic(
|
|
9019
|
+
writeCanonicalJsonAtomic(join8(outputDirectory, "result.json"), bundle.result);
|
|
8818
9020
|
writeCanonicalJsonAtomic(
|
|
8819
|
-
|
|
9021
|
+
join8(outputDirectory, "execution-evidence.json"),
|
|
8820
9022
|
bundle.executionEvidence
|
|
8821
9023
|
);
|
|
8822
|
-
writeCanonicalJsonAtomic(
|
|
9024
|
+
writeCanonicalJsonAtomic(join8(outputDirectory, "COMPLETE"), { schemaVersion: 1 });
|
|
8823
9025
|
} catch (error) {
|
|
8824
|
-
|
|
9026
|
+
rmSync4(outputDirectory, { recursive: true, force: true });
|
|
8825
9027
|
throw error;
|
|
8826
9028
|
}
|
|
8827
9029
|
}
|
|
8828
9030
|
function writePromotionAssessmentBundleAtomic(outputDirectoryValue, bundle) {
|
|
8829
|
-
const outputDirectory =
|
|
9031
|
+
const outputDirectory = resolve8(outputDirectoryValue);
|
|
8830
9032
|
const parent = dirname5(outputDirectory);
|
|
8831
9033
|
mkdirSync4(parent, { recursive: true });
|
|
8832
9034
|
try {
|
|
8833
9035
|
mkdirSync4(outputDirectory, { mode: 448 });
|
|
8834
9036
|
} catch (error) {
|
|
8835
|
-
if (
|
|
9037
|
+
if (existsSync10(outputDirectory)) throw new Error(`output already exists: ${outputDirectory}`);
|
|
8836
9038
|
throw error;
|
|
8837
9039
|
}
|
|
8838
9040
|
try {
|
|
8839
|
-
writeCanonicalJsonAtomic(
|
|
8840
|
-
writeCanonicalJsonAtomic(
|
|
8841
|
-
writeCanonicalJsonAtomic(
|
|
9041
|
+
writeCanonicalJsonAtomic(join8(outputDirectory, "promotion-decision.json"), bundle.decision);
|
|
9042
|
+
writeCanonicalJsonAtomic(join8(outputDirectory, "ledger.json"), bundle.ledger);
|
|
9043
|
+
writeCanonicalJsonAtomic(join8(outputDirectory, "COMPLETE"), { schemaVersion: 1 });
|
|
8842
9044
|
} catch (error) {
|
|
8843
|
-
|
|
9045
|
+
rmSync4(outputDirectory, { recursive: true, force: true });
|
|
8844
9046
|
throw error;
|
|
8845
9047
|
}
|
|
8846
9048
|
}
|
|
@@ -8963,13 +9165,13 @@ function registerBenchImprovementCommand(bench) {
|
|
|
8963
9165
|
}
|
|
8964
9166
|
|
|
8965
9167
|
// packages/cli/src/commands/bench-calibration.ts
|
|
8966
|
-
import { existsSync as
|
|
8967
|
-
import { join as
|
|
9168
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync5, rmSync as rmSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
9169
|
+
import { join as join9, resolve as resolve9 } from "node:path";
|
|
8968
9170
|
var CALIBRATION_CHAMPION_ID2 = "calibration-champion";
|
|
8969
9171
|
var CALIBRATION_CHALLENGER_ID2 = "calibration-challenger";
|
|
8970
9172
|
function materializeObjectiveOracleEvaluator(outputDirectoryValue) {
|
|
8971
|
-
const outputDirectory =
|
|
8972
|
-
if (
|
|
9173
|
+
const outputDirectory = resolve9(outputDirectoryValue);
|
|
9174
|
+
if (existsSync11(outputDirectory)) {
|
|
8973
9175
|
throw new Error(`evaluator output already exists: ${outputDirectory}`);
|
|
8974
9176
|
}
|
|
8975
9177
|
mkdirSync5(outputDirectory, { recursive: false, mode: 448 });
|
|
@@ -8992,15 +9194,15 @@ function materializeObjectiveOracleEvaluator(outputDirectoryValue) {
|
|
|
8992
9194
|
if (sha256Bytes(bundle) !== attestation.bundleDigest) {
|
|
8993
9195
|
throw new Error("evaluator bundle bytes do not match their attestation");
|
|
8994
9196
|
}
|
|
8995
|
-
writeFileSync4(
|
|
8996
|
-
writeFileSync4(
|
|
8997
|
-
writeFileSync4(
|
|
8998
|
-
writeFileSync4(
|
|
9197
|
+
writeFileSync4(join9(outputDirectory, "evaluator.js"), code, { flag: "wx", mode: 384 });
|
|
9198
|
+
writeFileSync4(join9(outputDirectory, "evaluator-config.json"), config, { flag: "wx", mode: 384 });
|
|
9199
|
+
writeFileSync4(join9(outputDirectory, "evaluator-bundle.json"), bundle, { flag: "wx", mode: 384 });
|
|
9200
|
+
writeFileSync4(join9(outputDirectory, "COMPLETE"), '{"schemaVersion":1}\n', {
|
|
8999
9201
|
flag: "wx",
|
|
9000
9202
|
mode: 384
|
|
9001
9203
|
});
|
|
9002
9204
|
} catch (error) {
|
|
9003
|
-
|
|
9205
|
+
rmSync5(outputDirectory, { recursive: true, force: true });
|
|
9004
9206
|
throw error;
|
|
9005
9207
|
}
|
|
9006
9208
|
}
|
|
@@ -9061,11 +9263,11 @@ function registerBenchCalibrationCommand(bench) {
|
|
|
9061
9263
|
bench.command("calibrate").description("Emit a sealed, provider-free no-uplift tournament for 0research calibration").requiredOption("--manifest <path>", "corpus manifest path").option("--case-id <id>", "exact pre-registered case id (repeatable)", collect2, []).requiredOption("--manifest-id <id>", "sealed calibration slice id").requiredOption("--tournament-output <path>", "create-once sealed calibration evidence").option("--evaluator-output-dir <path>", "create-once exact evaluator code/config/bundle").action(async (opts) => {
|
|
9062
9264
|
const caseIds = opts.caseId;
|
|
9063
9265
|
if (caseIds.length === 0) throw new Error("--case-id must be supplied at least once");
|
|
9064
|
-
if (
|
|
9065
|
-
throw new Error(`tournament output already exists: ${
|
|
9266
|
+
if (existsSync11(resolve9(String(opts.tournamentOutput)))) {
|
|
9267
|
+
throw new Error(`tournament output already exists: ${resolve9(String(opts.tournamentOutput))}`);
|
|
9066
9268
|
}
|
|
9067
|
-
if (opts.evaluatorOutputDir &&
|
|
9068
|
-
throw new Error(`evaluator output already exists: ${
|
|
9269
|
+
if (opts.evaluatorOutputDir && existsSync11(resolve9(String(opts.evaluatorOutputDir)))) {
|
|
9270
|
+
throw new Error(`evaluator output already exists: ${resolve9(String(opts.evaluatorOutputDir))}`);
|
|
9069
9271
|
}
|
|
9070
9272
|
const source = await loadManifest(String(opts.manifest));
|
|
9071
9273
|
const manifest = subsetManifest(source, caseIds, String(opts.manifestId));
|
|
@@ -9100,17 +9302,17 @@ function selectRunManifest(source, opts) {
|
|
|
9100
9302
|
}
|
|
9101
9303
|
function resolveManifestPath(manifestPath, bundledCorpusPath = corpusV1Path()) {
|
|
9102
9304
|
if (manifestPath) return manifestPath;
|
|
9103
|
-
if (
|
|
9305
|
+
if (existsSync12(bundledCorpusPath)) return bundledCorpusPath;
|
|
9104
9306
|
throw new Error(
|
|
9105
9307
|
"No bundled benchmark corpus is available. Pass --manifest <path> to run an external or public corpus."
|
|
9106
9308
|
);
|
|
9107
9309
|
}
|
|
9108
9310
|
function validateCaptureDestination(outputValue, ledgerValue) {
|
|
9109
|
-
const output =
|
|
9110
|
-
if (output ===
|
|
9311
|
+
const output = resolve10(outputValue);
|
|
9312
|
+
if (output === resolve10(ledgerValue)) {
|
|
9111
9313
|
throw new Error("--tournament-output must differ from --ledger");
|
|
9112
9314
|
}
|
|
9113
|
-
if (
|
|
9315
|
+
if (existsSync12(output)) throw new Error(`tournament output already exists: ${output}`);
|
|
9114
9316
|
}
|
|
9115
9317
|
async function measureOperation(operation, monotonicClock = () => performance.now()) {
|
|
9116
9318
|
const startedAt = monotonicClock();
|
|
@@ -9124,7 +9326,7 @@ async function measureOperation(operation, monotonicClock = () => performance.no
|
|
|
9124
9326
|
function parseVariants(opts) {
|
|
9125
9327
|
if (opts.variants) {
|
|
9126
9328
|
const path = String(opts.variants);
|
|
9127
|
-
const raw =
|
|
9329
|
+
const raw = existsSync12(path) ? readFileSync9(path, "utf8") : String(opts.variants);
|
|
9128
9330
|
let parsed;
|
|
9129
9331
|
try {
|
|
9130
9332
|
parsed = JSON.parse(raw);
|
|
@@ -9335,10 +9537,10 @@ function registerBenchCommand(program) {
|
|
|
9335
9537
|
...opts.title ? { title: String(opts.title) } : {},
|
|
9336
9538
|
keepRuns: Number(opts.keepRuns)
|
|
9337
9539
|
});
|
|
9338
|
-
const outDir =
|
|
9540
|
+
const outDir = resolve10(String(opts.out));
|
|
9339
9541
|
mkdirSync6(outDir, { recursive: true });
|
|
9340
|
-
const mdPath =
|
|
9341
|
-
const jsonPath =
|
|
9542
|
+
const mdPath = join10(outDir, "scoreboard.md");
|
|
9543
|
+
const jsonPath = join10(outDir, "scoreboard.json");
|
|
9342
9544
|
writeFileSync5(mdPath, markdown, "utf8");
|
|
9343
9545
|
writeFileSync5(jsonPath, JSON.stringify(json2, null, 2) + "\n", "utf8");
|
|
9344
9546
|
console.log(source_default.green(` wrote ${mdPath}`));
|
|
@@ -9347,8 +9549,8 @@ function registerBenchCommand(program) {
|
|
|
9347
9549
|
}
|
|
9348
9550
|
|
|
9349
9551
|
// packages/cli/src/commands/ingest.ts
|
|
9350
|
-
import { readFileSync as
|
|
9351
|
-
import { resolve as
|
|
9552
|
+
import { readFileSync as readFileSync10, statSync } from "node:fs";
|
|
9553
|
+
import { resolve as resolve11 } from "node:path";
|
|
9352
9554
|
var VALID_FORMATS = ["auto", "kasan", "ubsan", "oops", "syzkaller", "generic"];
|
|
9353
9555
|
var VALID_OUTPUT_FORMATS = ["terminal", "json", "sarif"];
|
|
9354
9556
|
function registerIngestCommand(program) {
|
|
@@ -9377,7 +9579,7 @@ function registerIngestCommand(program) {
|
|
|
9377
9579
|
if (inputPath && directReproducerPath) {
|
|
9378
9580
|
throw new Error("Do not pass a crash-report path together with --reproducer or --syz.");
|
|
9379
9581
|
}
|
|
9380
|
-
const resolved = inputPath ?
|
|
9582
|
+
const resolved = inputPath ? resolve11(inputPath) : "";
|
|
9381
9583
|
const stat3 = inputPath ? statSync(resolved) : void 0;
|
|
9382
9584
|
const reviewSubsystem = opts.reviewSubsystem === true;
|
|
9383
9585
|
if (reviewSubsystem && !opts.tree) {
|
|
@@ -9403,7 +9605,7 @@ function registerIngestCommand(program) {
|
|
|
9403
9605
|
reviewKernelCrashSubsystems,
|
|
9404
9606
|
verifyStandaloneKernelReproducer,
|
|
9405
9607
|
verifyKernelCrash
|
|
9406
|
-
} = await import("./dist-
|
|
9608
|
+
} = await import("./dist-4YICS2J2.js");
|
|
9407
9609
|
let kernelBuild;
|
|
9408
9610
|
if (opts.kernelTree) {
|
|
9409
9611
|
kernelBuild = prepareKernelVmArtifacts({
|
|
@@ -9423,14 +9625,14 @@ function registerIngestCommand(program) {
|
|
|
9423
9625
|
if (outputFormat === "sarif") {
|
|
9424
9626
|
throw new Error("--output sarif is not supported for standalone reproducers.");
|
|
9425
9627
|
}
|
|
9426
|
-
const reproPath =
|
|
9628
|
+
const reproPath = resolve11(directReproducerPath);
|
|
9427
9629
|
console.log(source_default.blue(`Running ${directReproducerLanguage} reproducer: ${reproPath}`));
|
|
9428
9630
|
const verification = await verifyStandaloneKernelReproducer({
|
|
9429
9631
|
raw: "",
|
|
9430
9632
|
crashType: "unknown",
|
|
9431
9633
|
faultingFunction: "unknown",
|
|
9432
9634
|
stackFrames: [],
|
|
9433
|
-
reproducer:
|
|
9635
|
+
reproducer: readFileSync10(reproPath, "utf8"),
|
|
9434
9636
|
reproducerLanguage: directReproducerLanguage
|
|
9435
9637
|
});
|
|
9436
9638
|
const directResult = {
|
|
@@ -9481,7 +9683,7 @@ ${verdict} ${source_default.white(verification.reproducedCrashType ?? "no crash
|
|
|
9481
9683
|
}
|
|
9482
9684
|
if (reviewSubsystem) {
|
|
9483
9685
|
const reviewResult = await reviewKernelCrashSubsystems(artifacts, {
|
|
9484
|
-
tree:
|
|
9686
|
+
tree: resolve11(opts.tree),
|
|
9485
9687
|
runtime: opts.runtime ?? "auto",
|
|
9486
9688
|
apiKey: opts.apiKey,
|
|
9487
9689
|
model: opts.model,
|
|
@@ -9705,7 +9907,7 @@ Ingested ${findings.length} finding${findings.length > 1 ? "s" : ""}:
|
|
|
9705
9907
|
}
|
|
9706
9908
|
|
|
9707
9909
|
// packages/cli/src/commands/kernel.ts
|
|
9708
|
-
import { readFileSync as
|
|
9910
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "node:fs";
|
|
9709
9911
|
var VALID_OUTPUT_FORMATS2 = ["terminal", "json", "sarif"];
|
|
9710
9912
|
function parsePositiveInt(value, name, max) {
|
|
9711
9913
|
const parsed = Number.parseInt(value, 10);
|
|
@@ -9803,7 +10005,7 @@ function registerKernelCommand(program) {
|
|
|
9803
10005
|
const details = parsePositiveInt(opts.details, "--details", 100);
|
|
9804
10006
|
const detailDelayMs = parsePositiveInt(opts.detailDelay, "--detail-delay", 5e3);
|
|
9805
10007
|
const subsystems = opts.subsystems.split(",").map((value) => value.trim()).filter(Boolean);
|
|
9806
|
-
const { defaultSyzbotFetcher, mineSyzbotQueue, toHuntCandidates } = await import("./dist-
|
|
10008
|
+
const { defaultSyzbotFetcher, mineSyzbotQueue, toHuntCandidates } = await import("./dist-4YICS2J2.js");
|
|
9807
10009
|
const result = await mineSyzbotQueue({
|
|
9808
10010
|
fetch: defaultSyzbotFetcher,
|
|
9809
10011
|
fetchDetail: defaultSyzbotFetcher,
|
|
@@ -9822,9 +10024,9 @@ function registerKernelCommand(program) {
|
|
|
9822
10024
|
});
|
|
9823
10025
|
kernel.command("weights").description("Generate an LLM-derived syzkaller choice_weights.json for a kernelCTF target").requiredOption("--target <version>", "Target kernel version, e.g. 6.12.101").option("--crash-summary <path>", "File with recent crash descriptions to inform weighting").option("--enabled-syscalls <path>", "JSON array file of manager-enabled syscall names to constrain the plan").option("--from-file <path>", "Validate/normalize a raw model JSON plan instead of calling the API").option("-m, --model <model>", "Override model (default: env/auto-detected)").option("--max-entries <n>", "Maximum weighted syscalls", "48").option("--dry-run", "Print the weights file instead of writing").option("-o, --out <path>", "Output path for choice_weights.json").action(async (opts) => {
|
|
9824
10026
|
try {
|
|
9825
|
-
const crashSummary = opts.crashSummary ?
|
|
9826
|
-
const enabledSyscalls = opts.enabledSyscalls ? JSON.parse(
|
|
9827
|
-
const result = opts.fromFile ? syzChoiceWeightsFromPlan(
|
|
10027
|
+
const crashSummary = opts.crashSummary ? readFileSync11(opts.crashSummary, "utf8") : void 0;
|
|
10028
|
+
const enabledSyscalls = opts.enabledSyscalls ? JSON.parse(readFileSync11(opts.enabledSyscalls, "utf8")) : void 0;
|
|
10029
|
+
const result = opts.fromFile ? syzChoiceWeightsFromPlan(readFileSync11(opts.fromFile, "utf8"), {
|
|
9828
10030
|
target: opts.target,
|
|
9829
10031
|
crashSummary,
|
|
9830
10032
|
maxEntries: parsePositiveInt(opts.maxEntries, "--max-entries", 128)
|
|
@@ -9855,7 +10057,7 @@ function registerKernelCommand(program) {
|
|
|
9855
10057
|
`Invalid output format '${opts.output}'. Valid: ${VALID_OUTPUT_FORMATS2.join(", ")}`
|
|
9856
10058
|
);
|
|
9857
10059
|
}
|
|
9858
|
-
const { runKernelVariantHunt } = await import("./dist-
|
|
10060
|
+
const { runKernelVariantHunt } = await import("./dist-4YICS2J2.js");
|
|
9859
10061
|
const report = await runKernelVariantHunt({
|
|
9860
10062
|
tree: opts.tree,
|
|
9861
10063
|
advisory: opts.advisory,
|
|
@@ -9881,9 +10083,9 @@ function registerKernelCommand(program) {
|
|
|
9881
10083
|
}
|
|
9882
10084
|
|
|
9883
10085
|
// packages/cli/src/commands/disclose.ts
|
|
9884
|
-
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as
|
|
9885
|
-
import { resolve as
|
|
9886
|
-
import { homedir } from "node:os";
|
|
10086
|
+
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync13, readFileSync as readFileSync12 } from "node:fs";
|
|
10087
|
+
import { resolve as resolve12, join as join11, dirname as dirname6 } from "node:path";
|
|
10088
|
+
import { homedir as homedir2 } from "node:os";
|
|
9887
10089
|
var STATUS_COLOUR = {
|
|
9888
10090
|
"still-vulnerable": (s) => source_default.green(s),
|
|
9889
10091
|
"partial-fix": (s) => source_default.yellow(s),
|
|
@@ -9954,11 +10156,11 @@ var VERDICT_COLOUR = {
|
|
|
9954
10156
|
could_not_run: (s) => source_default.red(s)
|
|
9955
10157
|
};
|
|
9956
10158
|
function resolveOutputDir(opts, scanId) {
|
|
9957
|
-
if (opts.outputDir) return
|
|
9958
|
-
return
|
|
10159
|
+
if (opts.outputDir) return resolve12(opts.outputDir);
|
|
10160
|
+
return join11(homedir2(), "0sec", "disclosures", `scan-${scanId.slice(0, 8)}`);
|
|
9959
10161
|
}
|
|
9960
10162
|
async function disclose(findingId, opts) {
|
|
9961
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
10163
|
+
const { osecDB: osecDB2 } = await import("./dist-4MAW5X6L.js");
|
|
9962
10164
|
const db = new osecDB2(opts.dbPath);
|
|
9963
10165
|
try {
|
|
9964
10166
|
let routeDroppedFinding2 = function(args2) {
|
|
@@ -9975,7 +10177,7 @@ async function disclose(findingId, opts) {
|
|
|
9975
10177
|
};
|
|
9976
10178
|
if (!opts.dryRun) {
|
|
9977
10179
|
mkdirSync7(droppedDir, { recursive: true });
|
|
9978
|
-
const reasonPath =
|
|
10180
|
+
const reasonPath = join11(droppedDir, droppedFilename(droppedEntry));
|
|
9979
10181
|
const body = formatDroppedReason({
|
|
9980
10182
|
finding,
|
|
9981
10183
|
scanId,
|
|
@@ -10028,7 +10230,7 @@ async function disclose(findingId, opts) {
|
|
|
10028
10230
|
);
|
|
10029
10231
|
}
|
|
10030
10232
|
const outputDir = resolveOutputDir(opts, scanId);
|
|
10031
|
-
const imagesDir =
|
|
10233
|
+
const imagesDir = join11(outputDir, "images");
|
|
10032
10234
|
if (!opts.dryRun) mkdirSync7(outputDir, { recursive: true });
|
|
10033
10235
|
const freezeOn = !opts.noScreenshots && !opts.dryRun && isFreezeAvailable();
|
|
10034
10236
|
const reverifyOn = !!opts.repo;
|
|
@@ -10046,7 +10248,7 @@ async function disclose(findingId, opts) {
|
|
|
10046
10248
|
throw new Error(`--reverify-rps must be a positive number, got: ${opts.reverifyRps}`);
|
|
10047
10249
|
}
|
|
10048
10250
|
const scopeAllowlist = opts.scopeAllowlist ? opts.scopeAllowlist.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
10049
|
-
const droppedDir =
|
|
10251
|
+
const droppedDir = join11(outputDir, "_dropped");
|
|
10050
10252
|
console.log(source_default.red.bold("\n \u25C6 0sec") + source_default.gray(` disclose \u2014 ${selected.length} finding${selected.length === 1 ? "" : "s"}`));
|
|
10051
10253
|
console.log(source_default.gray(` output: ${outputDir}${opts.dryRun ? " (dry-run \u2014 nothing written)" : ""}`));
|
|
10052
10254
|
console.log(source_default.gray(` screenshots: ${freezeOn ? "on (freeze)" : opts.noScreenshots ? "disabled" : opts.dryRun ? "skipped (dry-run)" : "disabled (freeze not on PATH)"}`));
|
|
@@ -10082,7 +10284,7 @@ async function disclose(findingId, opts) {
|
|
|
10082
10284
|
console.log(source_default.red(` behavioural reverify failed on ${row.id.slice(0, 8)}: ${err instanceof Error ? err.message : String(err)}`));
|
|
10083
10285
|
}
|
|
10084
10286
|
if (behaviouralReport && !opts.dryRun) {
|
|
10085
|
-
const execPath =
|
|
10287
|
+
const execPath = join11(outputDir, `${finding.id.slice(0, 8)}.execution.json`);
|
|
10086
10288
|
writeFileSync7(execPath, JSON.stringify(behaviouralReport, null, 2), "utf8");
|
|
10087
10289
|
db.saveFindingPocExecution(finding.id, behaviouralReport);
|
|
10088
10290
|
}
|
|
@@ -10187,10 +10389,10 @@ async function disclose(findingId, opts) {
|
|
|
10187
10389
|
}
|
|
10188
10390
|
throw err;
|
|
10189
10391
|
}
|
|
10190
|
-
const path =
|
|
10392
|
+
const path = join11(outputDir, rendered.filename);
|
|
10191
10393
|
let state = "wrote";
|
|
10192
10394
|
if (!opts.dryRun) {
|
|
10193
|
-
if (
|
|
10395
|
+
if (existsSync13(path)) {
|
|
10194
10396
|
state = "skipped-exists";
|
|
10195
10397
|
} else {
|
|
10196
10398
|
writeFileSync7(path, rendered.markdown, "utf8");
|
|
@@ -10219,7 +10421,7 @@ async function disclose(findingId, opts) {
|
|
|
10219
10421
|
);
|
|
10220
10422
|
}
|
|
10221
10423
|
if (!opts.dryRun) {
|
|
10222
|
-
const indexPath =
|
|
10424
|
+
const indexPath = join11(outputDir, "INDEX.md");
|
|
10223
10425
|
const indexContent = assembleBundleIndex(results, { scanIds });
|
|
10224
10426
|
writeFileSync7(indexPath, indexContent, "utf8");
|
|
10225
10427
|
console.log("\n " + source_default.gray(`wrote ${indexPath}`));
|
|
@@ -10231,7 +10433,7 @@ async function disclose(findingId, opts) {
|
|
|
10231
10433
|
function discloseEvidencePack(findingPath, opts) {
|
|
10232
10434
|
let finding;
|
|
10233
10435
|
try {
|
|
10234
|
-
const raw =
|
|
10436
|
+
const raw = readFileSync12(resolve12(findingPath), "utf8");
|
|
10235
10437
|
finding = JSON.parse(raw);
|
|
10236
10438
|
} catch (err) {
|
|
10237
10439
|
console.error(source_default.red(`Failed to read finding JSON '${findingPath}': ${err instanceof Error ? err.message : String(err)}`));
|
|
@@ -10266,8 +10468,8 @@ Refusing to draft a vendor notification for an unreproduced finding. Pass --allo
|
|
|
10266
10468
|
return;
|
|
10267
10469
|
}
|
|
10268
10470
|
if (opts.out) {
|
|
10269
|
-
writeFileSync7(
|
|
10270
|
-
console.log(source_default.gray(`DRAFT vendor-notification written to ${
|
|
10471
|
+
writeFileSync7(resolve12(opts.out), md, "utf8");
|
|
10472
|
+
console.log(source_default.gray(`DRAFT vendor-notification written to ${resolve12(opts.out)} (not sent).`));
|
|
10271
10473
|
return;
|
|
10272
10474
|
}
|
|
10273
10475
|
console.log(md);
|
|
@@ -10276,7 +10478,7 @@ function discloseTrack(findingId, opts) {
|
|
|
10276
10478
|
let record2;
|
|
10277
10479
|
try {
|
|
10278
10480
|
if (opts.record) {
|
|
10279
|
-
const raw =
|
|
10481
|
+
const raw = readFileSync12(resolve12(opts.record), "utf8");
|
|
10280
10482
|
const loaded = JSON.parse(raw);
|
|
10281
10483
|
if (!opts.to) {
|
|
10282
10484
|
console.error(source_default.red("--record requires --to <status> to apply a transition."));
|
|
@@ -10305,15 +10507,15 @@ function discloseTrack(findingId, opts) {
|
|
|
10305
10507
|
}
|
|
10306
10508
|
const json2 = JSON.stringify(record2, null, 2);
|
|
10307
10509
|
if (opts.out) {
|
|
10308
|
-
writeFileSync7(
|
|
10309
|
-
console.log(source_default.gray(`Disclosure record (status: ${record2.status}) written to ${
|
|
10510
|
+
writeFileSync7(resolve12(opts.out), json2, "utf8");
|
|
10511
|
+
console.log(source_default.gray(`Disclosure record (status: ${record2.status}) written to ${resolve12(opts.out)} \u2014 intent only, nothing sent.`));
|
|
10310
10512
|
return;
|
|
10311
10513
|
}
|
|
10312
10514
|
console.log(json2);
|
|
10313
10515
|
}
|
|
10314
10516
|
function discloseReview(findingPath, opts) {
|
|
10315
|
-
const jsonPath =
|
|
10316
|
-
const raw =
|
|
10517
|
+
const jsonPath = resolve12(findingPath);
|
|
10518
|
+
const raw = readFileSync12(jsonPath, "utf8");
|
|
10317
10519
|
const finding = JSON.parse(raw);
|
|
10318
10520
|
const manifest = assembleReproducibilityManifest(finding, {
|
|
10319
10521
|
timestamp: opts.timestamp,
|
|
@@ -10323,9 +10525,9 @@ function discloseReview(findingPath, opts) {
|
|
|
10323
10525
|
});
|
|
10324
10526
|
const rendered = renderReproducibilityManifest(manifest);
|
|
10325
10527
|
if (opts.out) {
|
|
10326
|
-
const outPath =
|
|
10528
|
+
const outPath = resolve12(opts.out);
|
|
10327
10529
|
const outDir = dirname6(outPath);
|
|
10328
|
-
if (!
|
|
10530
|
+
if (!existsSync13(outDir)) {
|
|
10329
10531
|
mkdirSync7(outDir, { recursive: true });
|
|
10330
10532
|
}
|
|
10331
10533
|
writeFileSync7(outPath, rendered + "\n", "utf8");
|
|
@@ -10373,10 +10575,10 @@ function registerDiscloseCommand(program) {
|
|
|
10373
10575
|
}
|
|
10374
10576
|
|
|
10375
10577
|
// packages/cli/src/commands/verify.ts
|
|
10376
|
-
import { mkdirSync as mkdirSync8, mkdtempSync as
|
|
10377
|
-
import { createHash as
|
|
10378
|
-
import { tmpdir as
|
|
10379
|
-
import { join as
|
|
10578
|
+
import { mkdirSync as mkdirSync8, mkdtempSync as mkdtempSync4, readFileSync as readFileSync13, rmSync as rmSync6, statSync as statSync2, writeFileSync as writeFileSync8 } from "node:fs";
|
|
10579
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
10580
|
+
import { tmpdir as tmpdir5 } from "node:os";
|
|
10581
|
+
import { join as join12, resolve as resolve13 } from "node:path";
|
|
10380
10582
|
var EXCERPT_BYTES = 4 * 1024;
|
|
10381
10583
|
function excerpt(text2, max = EXCERPT_BYTES) {
|
|
10382
10584
|
if (!text2) return "";
|
|
@@ -10624,11 +10826,11 @@ function artifactFromPath(kind, path) {
|
|
|
10624
10826
|
try {
|
|
10625
10827
|
const stat3 = statSync2(path);
|
|
10626
10828
|
if (!stat3.isFile()) return null;
|
|
10627
|
-
const body =
|
|
10829
|
+
const body = readFileSync13(path);
|
|
10628
10830
|
return {
|
|
10629
10831
|
kind: kind.replace(/_ref$/, ""),
|
|
10630
10832
|
path,
|
|
10631
|
-
sha256:
|
|
10833
|
+
sha256: createHash5("sha256").update(body).digest("hex"),
|
|
10632
10834
|
bytes: stat3.size
|
|
10633
10835
|
};
|
|
10634
10836
|
} catch {
|
|
@@ -10665,10 +10867,10 @@ function fixtureResultToShared(result) {
|
|
|
10665
10867
|
};
|
|
10666
10868
|
}
|
|
10667
10869
|
function readJson2(path, kind) {
|
|
10668
|
-
const abs =
|
|
10870
|
+
const abs = resolve13(path);
|
|
10669
10871
|
let raw;
|
|
10670
10872
|
try {
|
|
10671
|
-
raw =
|
|
10873
|
+
raw = readFileSync13(abs, "utf8");
|
|
10672
10874
|
} catch (err) {
|
|
10673
10875
|
throw new Error(
|
|
10674
10876
|
`failed to read ${kind} from ${abs}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -10720,7 +10922,7 @@ function parseDurationMs(raw) {
|
|
|
10720
10922
|
}
|
|
10721
10923
|
}
|
|
10722
10924
|
async function runKernelFindingVerify(opts) {
|
|
10723
|
-
const { verifyStaticKernelFinding, applyVerificationToFinding } = await import("./dist-
|
|
10925
|
+
const { verifyStaticKernelFinding, applyVerificationToFinding } = await import("./dist-4YICS2J2.js");
|
|
10724
10926
|
const rawFinding = readJson2(opts.findingPath, "finding");
|
|
10725
10927
|
let finding;
|
|
10726
10928
|
try {
|
|
@@ -10767,12 +10969,12 @@ async function runKernelFindingVerify(opts) {
|
|
|
10767
10969
|
};
|
|
10768
10970
|
}
|
|
10769
10971
|
function allocateIsolatedWorkspace() {
|
|
10770
|
-
const cwd =
|
|
10972
|
+
const cwd = mkdtempSync4(join12(tmpdir5(), "0sec-verify-"));
|
|
10771
10973
|
return {
|
|
10772
10974
|
cwd,
|
|
10773
10975
|
cleanup: () => {
|
|
10774
10976
|
try {
|
|
10775
|
-
|
|
10977
|
+
rmSync6(cwd, { recursive: true, force: true });
|
|
10776
10978
|
} catch {
|
|
10777
10979
|
}
|
|
10778
10980
|
}
|
|
@@ -10877,7 +11079,7 @@ async function runDeterministicReplayCli(args2) {
|
|
|
10877
11079
|
}
|
|
10878
11080
|
let runDir;
|
|
10879
11081
|
if (args2.outDir) {
|
|
10880
|
-
runDir =
|
|
11082
|
+
runDir = resolve13(args2.outDir);
|
|
10881
11083
|
mkdirSync8(runDir, { recursive: true });
|
|
10882
11084
|
}
|
|
10883
11085
|
if (args2.dockerNetwork && args2.runner !== "docker") {
|
|
@@ -10935,7 +11137,7 @@ async function verifyAction(opts, positionalFinding) {
|
|
|
10935
11137
|
2
|
|
10936
11138
|
);
|
|
10937
11139
|
if (opts.output) {
|
|
10938
|
-
writeFileSync8(
|
|
11140
|
+
writeFileSync8(resolve13(opts.output), result + "\n", "utf8");
|
|
10939
11141
|
} else {
|
|
10940
11142
|
process.stdout.write(result + "\n");
|
|
10941
11143
|
}
|
|
@@ -10970,7 +11172,7 @@ async function verifyAction(opts, positionalFinding) {
|
|
|
10970
11172
|
});
|
|
10971
11173
|
const kernelJson = JSON.stringify(kernelOutcome.result, null, 2);
|
|
10972
11174
|
if (opts.output) {
|
|
10973
|
-
writeFileSync8(
|
|
11175
|
+
writeFileSync8(resolve13(opts.output), kernelJson + "\n", "utf8");
|
|
10974
11176
|
} else {
|
|
10975
11177
|
process.stdout.write(kernelJson + "\n");
|
|
10976
11178
|
}
|
|
@@ -11002,7 +11204,7 @@ async function verifyAction(opts, positionalFinding) {
|
|
|
11002
11204
|
});
|
|
11003
11205
|
const json3 = JSON.stringify(result, null, 2);
|
|
11004
11206
|
if (opts.output) {
|
|
11005
|
-
writeFileSync8(
|
|
11207
|
+
writeFileSync8(resolve13(opts.output), json3 + "\n", "utf8");
|
|
11006
11208
|
} else {
|
|
11007
11209
|
process.stdout.write(json3 + "\n");
|
|
11008
11210
|
}
|
|
@@ -11030,7 +11232,7 @@ async function verifyAction(opts, positionalFinding) {
|
|
|
11030
11232
|
});
|
|
11031
11233
|
const json3 = JSON.stringify(bundleResult, null, 2);
|
|
11032
11234
|
if (opts.output) {
|
|
11033
|
-
writeFileSync8(
|
|
11235
|
+
writeFileSync8(resolve13(opts.output), json3 + "\n", "utf8");
|
|
11034
11236
|
} else {
|
|
11035
11237
|
process.stdout.write(json3 + "\n");
|
|
11036
11238
|
}
|
|
@@ -11067,7 +11269,7 @@ async function verifyAction(opts, positionalFinding) {
|
|
|
11067
11269
|
});
|
|
11068
11270
|
const json2 = JSON.stringify(outcome.result, null, 2);
|
|
11069
11271
|
if (opts.output) {
|
|
11070
|
-
writeFileSync8(
|
|
11272
|
+
writeFileSync8(resolve13(opts.output), json2 + "\n", "utf8");
|
|
11071
11273
|
} else {
|
|
11072
11274
|
process.stdout.write(json2 + "\n");
|
|
11073
11275
|
}
|
|
@@ -11162,7 +11364,7 @@ function registerVerifyCommand(program) {
|
|
|
11162
11364
|
const json2 = JSON.stringify(result, null, 2);
|
|
11163
11365
|
if (opts.output) {
|
|
11164
11366
|
try {
|
|
11165
|
-
writeFileSync8(
|
|
11367
|
+
writeFileSync8(resolve13(opts.output), json2 + "\n", "utf8");
|
|
11166
11368
|
} catch {
|
|
11167
11369
|
process.stderr.write(json2 + "\n");
|
|
11168
11370
|
}
|
|
@@ -11175,8 +11377,8 @@ function registerVerifyCommand(program) {
|
|
|
11175
11377
|
}
|
|
11176
11378
|
|
|
11177
11379
|
// packages/cli/src/commands/exploit.ts
|
|
11178
|
-
import { readFileSync as
|
|
11179
|
-
import { resolve as
|
|
11380
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "node:fs";
|
|
11381
|
+
import { resolve as resolve14 } from "node:path";
|
|
11180
11382
|
var CATEGORY_TO_CRASH_TYPE = {
|
|
11181
11383
|
"use-after-free": "kasan-uaf",
|
|
11182
11384
|
"heap-overflow": "kasan-oob",
|
|
@@ -11187,10 +11389,10 @@ var CATEGORY_TO_CRASH_TYPE = {
|
|
|
11187
11389
|
"null-pointer-deref": "kasan-null"
|
|
11188
11390
|
};
|
|
11189
11391
|
function readJson3(path, kind) {
|
|
11190
|
-
const abs =
|
|
11392
|
+
const abs = resolve14(path);
|
|
11191
11393
|
let raw;
|
|
11192
11394
|
try {
|
|
11193
|
-
raw =
|
|
11395
|
+
raw = readFileSync14(abs, "utf8");
|
|
11194
11396
|
} catch (err) {
|
|
11195
11397
|
throw new Error(
|
|
11196
11398
|
`failed to read ${kind} from ${abs}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -11212,7 +11414,7 @@ async function runExploit(opts) {
|
|
|
11212
11414
|
classifyPrimitiveFromDmesg,
|
|
11213
11415
|
describeKernelPrimitive,
|
|
11214
11416
|
runWeaponization
|
|
11215
|
-
} = await import("./dist-
|
|
11417
|
+
} = await import("./dist-4YICS2J2.js");
|
|
11216
11418
|
const rawFinding = readJson3(opts.findingPath, "finding");
|
|
11217
11419
|
let finding;
|
|
11218
11420
|
try {
|
|
@@ -11223,7 +11425,7 @@ async function runExploit(opts) {
|
|
|
11223
11425
|
}
|
|
11224
11426
|
throw err;
|
|
11225
11427
|
}
|
|
11226
|
-
const reproducer = opts.reproducerPath ?
|
|
11428
|
+
const reproducer = opts.reproducerPath ? readFileSync14(resolve14(opts.reproducerPath), "utf8") : void 0;
|
|
11227
11429
|
const primitive = classifyPrimitiveFromDmesg(
|
|
11228
11430
|
dmesgFromFinding(finding),
|
|
11229
11431
|
CATEGORY_TO_CRASH_TYPE[finding.category]
|
|
@@ -11275,7 +11477,7 @@ async function runExploit(opts) {
|
|
|
11275
11477
|
}
|
|
11276
11478
|
async function exploitAction(opts) {
|
|
11277
11479
|
if (opts.agent) {
|
|
11278
|
-
const { agentFromExploitOpts } = await import("./exploit-agent-
|
|
11480
|
+
const { agentFromExploitOpts } = await import("./exploit-agent-45YQOHPJ.js");
|
|
11279
11481
|
process.exitCode = await agentFromExploitOpts({
|
|
11280
11482
|
...opts.task ? { task: opts.task } : {},
|
|
11281
11483
|
...opts.flagPath ? { flagPath: opts.flagPath } : {},
|
|
@@ -11290,7 +11492,7 @@ async function exploitAction(opts) {
|
|
|
11290
11492
|
return;
|
|
11291
11493
|
}
|
|
11292
11494
|
if (opts.autoclimb) {
|
|
11293
|
-
const { autoclimbFromExploitOpts } = await import("./exploit-autoclimb-
|
|
11495
|
+
const { autoclimbFromExploitOpts } = await import("./exploit-autoclimb-UZGEMGYT.js");
|
|
11294
11496
|
process.exitCode = await autoclimbFromExploitOpts({
|
|
11295
11497
|
...opts.bugSpec ? { bugSpec: opts.bugSpec } : {},
|
|
11296
11498
|
...opts.bootScript ? { bootScript: opts.bootScript } : {},
|
|
@@ -11304,7 +11506,7 @@ async function exploitAction(opts) {
|
|
|
11304
11506
|
throw new Error("missing required flag: --finding <path>");
|
|
11305
11507
|
}
|
|
11306
11508
|
if (opts.climb) {
|
|
11307
|
-
const { runClimb } = await import("./exploit-climb-
|
|
11509
|
+
const { runClimb } = await import("./exploit-climb-SG23KB2G.js");
|
|
11308
11510
|
let loopBoots = 8;
|
|
11309
11511
|
if (opts.loopBoots !== void 0) {
|
|
11310
11512
|
loopBoots = parseInt(opts.loopBoots, 10);
|
|
@@ -11323,7 +11525,7 @@ async function exploitAction(opts) {
|
|
|
11323
11525
|
});
|
|
11324
11526
|
const json3 = JSON.stringify(outcome2.result, null, 2);
|
|
11325
11527
|
if (opts.output) {
|
|
11326
|
-
writeFileSync9(
|
|
11528
|
+
writeFileSync9(resolve14(opts.output), json3 + "\n", "utf8");
|
|
11327
11529
|
} else {
|
|
11328
11530
|
process.stdout.write(json3 + "\n");
|
|
11329
11531
|
}
|
|
@@ -11344,7 +11546,7 @@ async function exploitAction(opts) {
|
|
|
11344
11546
|
});
|
|
11345
11547
|
const json2 = JSON.stringify(outcome.result, null, 2);
|
|
11346
11548
|
if (opts.output) {
|
|
11347
|
-
writeFileSync9(
|
|
11549
|
+
writeFileSync9(resolve14(opts.output), json2 + "\n", "utf8");
|
|
11348
11550
|
} else {
|
|
11349
11551
|
process.stdout.write(json2 + "\n");
|
|
11350
11552
|
}
|
|
@@ -11419,7 +11621,7 @@ function registerExploitCommand(program) {
|
|
|
11419
11621
|
const json2 = JSON.stringify(result, null, 2);
|
|
11420
11622
|
if (opts.output) {
|
|
11421
11623
|
try {
|
|
11422
|
-
writeFileSync9(
|
|
11624
|
+
writeFileSync9(resolve14(opts.output), json2 + "\n", "utf8");
|
|
11423
11625
|
} catch {
|
|
11424
11626
|
process.stderr.write(json2 + "\n");
|
|
11425
11627
|
}
|
|
@@ -11433,7 +11635,7 @@ function registerExploitCommand(program) {
|
|
|
11433
11635
|
|
|
11434
11636
|
// packages/cli/src/commands/recency-hunt.ts
|
|
11435
11637
|
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync10 } from "node:fs";
|
|
11436
|
-
import { join as
|
|
11638
|
+
import { join as join13, resolve as resolve15 } from "node:path";
|
|
11437
11639
|
function parseDetectors(raw) {
|
|
11438
11640
|
if (!raw) return void 0;
|
|
11439
11641
|
const valid = /* @__PURE__ */ new Set(["dataflow", "refcount", "race", "dual-view"]);
|
|
@@ -11458,10 +11660,10 @@ function parseWitnessMode(raw) {
|
|
|
11458
11660
|
}
|
|
11459
11661
|
async function recencyAction(opts) {
|
|
11460
11662
|
if (!opts.tree) throw new Error("missing required flag: --tree <kernel source tree>");
|
|
11461
|
-
const { runRecencyHunt, renderRecencyReportMarkdown } = await import("./dist-
|
|
11462
|
-
const tree =
|
|
11663
|
+
const { runRecencyHunt, renderRecencyReportMarkdown } = await import("./dist-4YICS2J2.js");
|
|
11664
|
+
const tree = resolve15(opts.tree);
|
|
11463
11665
|
const runtime = opts.runtime ?? "api";
|
|
11464
|
-
const modelDir = opts.modelDir ?
|
|
11666
|
+
const modelDir = opts.modelDir ? resolve15(opts.modelDir) : join13(tree, ".recency-models");
|
|
11465
11667
|
mkdirSync9(modelDir, { recursive: true });
|
|
11466
11668
|
const report = await runRecencyHunt({
|
|
11467
11669
|
tree,
|
|
@@ -11495,22 +11697,22 @@ async function recencyAction(opts) {
|
|
|
11495
11697
|
const json2 = JSON.stringify(report, null, 2);
|
|
11496
11698
|
const md = renderRecencyReportMarkdown(report);
|
|
11497
11699
|
if (opts.reportDir) {
|
|
11498
|
-
const dir =
|
|
11700
|
+
const dir = resolve15(opts.reportDir);
|
|
11499
11701
|
mkdirSync9(dir, { recursive: true });
|
|
11500
11702
|
const day = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
11501
|
-
writeFileSync10(
|
|
11502
|
-
writeFileSync10(
|
|
11703
|
+
writeFileSync10(join13(dir, `${day}.json`), json2 + "\n", "utf8");
|
|
11704
|
+
writeFileSync10(join13(dir, `${day}.md`), md + "\n", "utf8");
|
|
11503
11705
|
const f = report.funnel;
|
|
11504
11706
|
const cbd = f.candidatesByDetector;
|
|
11505
11707
|
const dv = report.detectors.includes("dual-view") ? `, dual-view: ${cbd.dualView} (\u2192${f.dualViewWitnessAttempted} witnessed-attempted \u2192${f.survivorsByDetector.dualView} WITNESSED)` : "";
|
|
11506
11708
|
process.stdout.write(
|
|
11507
|
-
`recency-flywheel ${day}: ${f.commits} commits \u2192 ${f.changedFiles} files \u2192 ${f.inScope} in-scope \u2192 ${f.semantic} semantic \u2192 ${f.candidates} candidates {dataflow: ${cbd.dataflow}, refcount: ${cbd.refcount}, race: ${cbd.race}${dv}} \u2192 ${f.survivors} survivor(s). detectors: ${report.detectors.join("+")}. reports: ${
|
|
11709
|
+
`recency-flywheel ${day}: ${f.commits} commits \u2192 ${f.changedFiles} files \u2192 ${f.inScope} in-scope \u2192 ${f.semantic} semantic \u2192 ${f.candidates} candidates {dataflow: ${cbd.dataflow}, refcount: ${cbd.refcount}, race: ${cbd.race}${dv}} \u2192 ${f.survivors} survivor(s). detectors: ${report.detectors.join("+")}. reports: ${join13(dir, day)}.{json,md}
|
|
11508
11710
|
`
|
|
11509
11711
|
);
|
|
11510
11712
|
} else {
|
|
11511
|
-
if (opts.output) writeFileSync10(
|
|
11713
|
+
if (opts.output) writeFileSync10(resolve15(opts.output), json2 + "\n", "utf8");
|
|
11512
11714
|
else process.stdout.write(json2 + "\n");
|
|
11513
|
-
if (opts.md) writeFileSync10(
|
|
11715
|
+
if (opts.md) writeFileSync10(resolve15(opts.md), md + "\n", "utf8");
|
|
11514
11716
|
}
|
|
11515
11717
|
process.exitCode = report.range === "(empty window)" ? 2 : report.survivors.length > 0 ? 0 : 1;
|
|
11516
11718
|
}
|
|
@@ -11525,7 +11727,7 @@ function registerRecencyHuntCommand(program) {
|
|
|
11525
11727
|
const json2 = JSON.stringify({ mode: "recency-hunt", error: reason }, null, 2);
|
|
11526
11728
|
if (opts.output) {
|
|
11527
11729
|
try {
|
|
11528
|
-
writeFileSync10(
|
|
11730
|
+
writeFileSync10(resolve15(opts.output), json2 + "\n", "utf8");
|
|
11529
11731
|
} catch {
|
|
11530
11732
|
process.stderr.write(json2 + "\n");
|
|
11531
11733
|
}
|
|
@@ -11536,8 +11738,8 @@ function registerRecencyHuntCommand(program) {
|
|
|
11536
11738
|
}
|
|
11537
11739
|
|
|
11538
11740
|
// packages/cli/src/commands/memsafety.ts
|
|
11539
|
-
import { existsSync as
|
|
11540
|
-
import { resolve as
|
|
11741
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync10, realpathSync, writeFileSync as writeFileSync11 } from "node:fs";
|
|
11742
|
+
import { resolve as resolve16, join as join14, sep as sep2 } from "node:path";
|
|
11541
11743
|
var VALID_LANGUAGES = /* @__PURE__ */ new Set(["c", "cpp", "rust"]);
|
|
11542
11744
|
var VALID_BUILD_SYSTEMS3 = /* @__PURE__ */ new Set([
|
|
11543
11745
|
"cargo",
|
|
@@ -11546,8 +11748,8 @@ var VALID_BUILD_SYSTEMS3 = /* @__PURE__ */ new Set([
|
|
|
11546
11748
|
"meson",
|
|
11547
11749
|
"make"
|
|
11548
11750
|
]);
|
|
11549
|
-
function detectMemSafetyBuild(sourceRoot, exists =
|
|
11550
|
-
const has = (rel) => exists(
|
|
11751
|
+
function detectMemSafetyBuild(sourceRoot, exists = existsSync14) {
|
|
11752
|
+
const has = (rel) => exists(join14(sourceRoot, rel));
|
|
11551
11753
|
if (has("Cargo.toml")) return { language: "rust", buildSystem: "cargo" };
|
|
11552
11754
|
if (has("CMakeLists.txt")) return { language: "cpp", buildSystem: "cmake" };
|
|
11553
11755
|
if (has("meson.build")) return { language: "c", buildSystem: "meson" };
|
|
@@ -11562,7 +11764,7 @@ function detectMemSafetyBuild(sourceRoot, exists = existsSync13) {
|
|
|
11562
11764
|
function resolveArtifactDir(value, sourceRoot) {
|
|
11563
11765
|
const raw = value?.trim();
|
|
11564
11766
|
if (!raw) return void 0;
|
|
11565
|
-
const artifactDir =
|
|
11767
|
+
const artifactDir = resolve16(raw);
|
|
11566
11768
|
const preparedRoot = realpathSync(sourceRoot);
|
|
11567
11769
|
mkdirSync10(artifactDir, { recursive: true, mode: 448 });
|
|
11568
11770
|
const canonicalArtifactDir = realpathSync(artifactDir);
|
|
@@ -11574,7 +11776,7 @@ function resolveArtifactDir(value, sourceRoot) {
|
|
|
11574
11776
|
return canonicalArtifactDir;
|
|
11575
11777
|
}
|
|
11576
11778
|
async function runMemSafety(opts) {
|
|
11577
|
-
const { prepare: prepare2, runMemSafetyScan, getCloudSinkConfig, postFinding } = await import("./dist-
|
|
11779
|
+
const { prepare: prepare2, runMemSafetyScan, getCloudSinkConfig, postFinding } = await import("./dist-4YICS2J2.js");
|
|
11578
11780
|
const log = opts.log ?? (() => {
|
|
11579
11781
|
});
|
|
11580
11782
|
const prepared = await prepare2(
|
|
@@ -11585,11 +11787,11 @@ async function runMemSafety(opts) {
|
|
|
11585
11787
|
if (e.message) log(`[memsafety:source] ${e.message}`);
|
|
11586
11788
|
}
|
|
11587
11789
|
);
|
|
11588
|
-
const sourceRoot =
|
|
11790
|
+
const sourceRoot = resolve16(prepared.resolvedTarget);
|
|
11589
11791
|
try {
|
|
11590
11792
|
let scopeRoot = sourceRoot;
|
|
11591
11793
|
if (opts.subsystem && opts.subsystem.trim() !== "") {
|
|
11592
|
-
const scoped =
|
|
11794
|
+
const scoped = resolve16(join14(sourceRoot, opts.subsystem));
|
|
11593
11795
|
if (scoped !== sourceRoot && !scoped.startsWith(sourceRoot + sep2)) {
|
|
11594
11796
|
throw new Error(`--subsystem '${opts.subsystem}' escapes the source tree`);
|
|
11595
11797
|
}
|
|
@@ -11724,7 +11926,7 @@ function parseArtifactOptions(opts) {
|
|
|
11724
11926
|
throw new Error("--artifact-max-bytes must be at least 65536");
|
|
11725
11927
|
}
|
|
11726
11928
|
return {
|
|
11727
|
-
artifactDir:
|
|
11929
|
+
artifactDir: resolve16(artifactDir),
|
|
11728
11930
|
artifactMaxBytes: maxBytes
|
|
11729
11931
|
};
|
|
11730
11932
|
}
|
|
@@ -11748,7 +11950,7 @@ async function memsafetyAction(target, opts) {
|
|
|
11748
11950
|
log: (m) => process.stderr.write(m + "\n")
|
|
11749
11951
|
});
|
|
11750
11952
|
const json2 = JSON.stringify(outcome.result, null, 2);
|
|
11751
|
-
if (opts.output) writeFileSync11(
|
|
11953
|
+
if (opts.output) writeFileSync11(resolve16(opts.output), json2 + "\n", "utf8");
|
|
11752
11954
|
else process.stdout.write(json2 + "\n");
|
|
11753
11955
|
process.exitCode = outcome.exitCode;
|
|
11754
11956
|
}
|
|
@@ -11770,7 +11972,7 @@ function registerMemsafetyCommand(program) {
|
|
|
11770
11972
|
if (opts.output) {
|
|
11771
11973
|
const { writeFileSync: writeFileSync18 } = await import("node:fs");
|
|
11772
11974
|
try {
|
|
11773
|
-
writeFileSync18(
|
|
11975
|
+
writeFileSync18(resolve16(opts.output), json2 + "\n", "utf8");
|
|
11774
11976
|
} catch {
|
|
11775
11977
|
process.stderr.write(json2 + "\n");
|
|
11776
11978
|
}
|
|
@@ -11781,7 +11983,7 @@ function registerMemsafetyCommand(program) {
|
|
|
11781
11983
|
}
|
|
11782
11984
|
|
|
11783
11985
|
// packages/cli/src/commands/assumption-hunt.ts
|
|
11784
|
-
import { resolve as
|
|
11986
|
+
import { resolve as resolve17 } from "node:path";
|
|
11785
11987
|
function parseWitnessMode2(raw) {
|
|
11786
11988
|
if (raw === void 0) return void 0;
|
|
11787
11989
|
const m = raw.trim();
|
|
@@ -11791,16 +11993,16 @@ function parseWitnessMode2(raw) {
|
|
|
11791
11993
|
return m;
|
|
11792
11994
|
}
|
|
11793
11995
|
async function runAssumptionHuntCli(sourceRoot, opts) {
|
|
11794
|
-
const { runAssumptionHunt, makeSkepticVerifier } = await import("./dist-
|
|
11996
|
+
const { runAssumptionHunt, makeSkepticVerifier } = await import("./dist-4YICS2J2.js");
|
|
11795
11997
|
const log = (m) => process.stderr.write(m + "\n");
|
|
11796
11998
|
const runtime = opts.runtime ?? "api";
|
|
11797
|
-
const root =
|
|
11999
|
+
const root = resolve17(sourceRoot);
|
|
11798
12000
|
const subsystem = opts.subsystem?.trim() || "subsystem";
|
|
11799
12001
|
const files = (opts.files ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
11800
12002
|
if (files.length === 0) {
|
|
11801
12003
|
throw new Error("--files is required: a comma-separated list of subsystem source files (repo-relative to <source-root>)");
|
|
11802
12004
|
}
|
|
11803
|
-
const modelPath = opts.modelPath ?
|
|
12005
|
+
const modelPath = opts.modelPath ? resolve17(opts.modelPath) : resolve17(root, `.0sec/assumption-models/${subsystem.replaceAll("/", "_")}.json`);
|
|
11804
12006
|
const models = opts.models ? opts.models.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
11805
12007
|
const verify = opts.skipHunt || opts.noVerify ? void 0 : (
|
|
11806
12008
|
// `finderModels` decorrelates the refute pass from the finder fan-out
|
|
@@ -11826,7 +12028,7 @@ async function runAssumptionHuntCli(sourceRoot, opts) {
|
|
|
11826
12028
|
...models ? { finderModels: models } : {},
|
|
11827
12029
|
...opts.finderTargeting === false ? { finderTargeting: false } : {},
|
|
11828
12030
|
...opts.dualView === false ? { dualView: false } : {},
|
|
11829
|
-
...opts.excerptDir ? { excerptDir:
|
|
12031
|
+
...opts.excerptDir ? { excerptDir: resolve17(opts.excerptDir) } : {},
|
|
11830
12032
|
...opts.dynamicWitness ? {
|
|
11831
12033
|
dynamicWitness: {
|
|
11832
12034
|
runtime,
|
|
@@ -11910,7 +12112,7 @@ function registerAssumptionHuntCommand(program) {
|
|
|
11910
12112
|
const json2 = JSON.stringify(outcome.result, null, 2);
|
|
11911
12113
|
if (opts.output) {
|
|
11912
12114
|
const { writeFileSync: writeFileSync18 } = await import("node:fs");
|
|
11913
|
-
writeFileSync18(
|
|
12115
|
+
writeFileSync18(resolve17(opts.output), json2 + "\n", "utf8");
|
|
11914
12116
|
} else process.stdout.write(json2 + "\n");
|
|
11915
12117
|
process.exitCode = outcome.exitCode;
|
|
11916
12118
|
} catch (err) {
|
|
@@ -11922,8 +12124,8 @@ function registerAssumptionHuntCommand(program) {
|
|
|
11922
12124
|
}
|
|
11923
12125
|
|
|
11924
12126
|
// packages/cli/src/commands/specdrift.ts
|
|
11925
|
-
import { readFileSync as
|
|
11926
|
-
import { basename as basename4, resolve as
|
|
12127
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "node:fs";
|
|
12128
|
+
import { basename as basename4, resolve as resolve18 } from "node:path";
|
|
11927
12129
|
function parsePositive3(flag, raw, dflt) {
|
|
11928
12130
|
if (raw === void 0) return dflt;
|
|
11929
12131
|
const n = parseInt(raw, 10);
|
|
@@ -11933,8 +12135,8 @@ function parsePositive3(flag, raw, dflt) {
|
|
|
11933
12135
|
async function runSpecdriftExtract(opts) {
|
|
11934
12136
|
if (!opts.spec) throw new Error("missing required flag: --spec <path>");
|
|
11935
12137
|
const maxInvariants = parsePositive3("--max-invariants", opts.maxInvariants, 40);
|
|
11936
|
-
const specPath =
|
|
11937
|
-
const specText =
|
|
12138
|
+
const specPath = resolve18(opts.spec);
|
|
12139
|
+
const specText = readFileSync15(specPath, "utf8");
|
|
11938
12140
|
return extractSpecInvariants({
|
|
11939
12141
|
specName: opts.specName ?? basename4(specPath),
|
|
11940
12142
|
specText,
|
|
@@ -11955,8 +12157,8 @@ async function runSpecdriftSourceWorkflow(opts, stage) {
|
|
|
11955
12157
|
const maxCandidatesPerInvariant = parsePositive3("--max-candidates-per-invariant", opts.maxCandidatesPerInvariant, 5);
|
|
11956
12158
|
const maxHypotheses = parsePositive3("--max-hypotheses", opts.maxHypotheses, 20);
|
|
11957
12159
|
const timeout = parsePositive3("--timeout", opts.timeout, 6e5);
|
|
11958
|
-
const specPath =
|
|
11959
|
-
const specText =
|
|
12160
|
+
const specPath = resolve18(opts.spec);
|
|
12161
|
+
const specText = readFileSync15(specPath, "utf8");
|
|
11960
12162
|
const prepared = await prepare(opts.source, "source-code", { timeout }, (e) => {
|
|
11961
12163
|
if (e.message) process.stderr.write(`[specdrift:source] ${e.message}
|
|
11962
12164
|
`);
|
|
@@ -11965,7 +12167,7 @@ async function runSpecdriftSourceWorkflow(opts, stage) {
|
|
|
11965
12167
|
const input = {
|
|
11966
12168
|
specName: opts.specName ?? basename4(specPath),
|
|
11967
12169
|
specText,
|
|
11968
|
-
sourceRoot:
|
|
12170
|
+
sourceRoot: resolve18(prepared.resolvedTarget),
|
|
11969
12171
|
maxInvariants,
|
|
11970
12172
|
maxFiles,
|
|
11971
12173
|
maxCandidatesPerInvariant
|
|
@@ -11979,14 +12181,14 @@ async function writeJsonResult(fn, output, stage = "extract") {
|
|
|
11979
12181
|
try {
|
|
11980
12182
|
const result = await fn();
|
|
11981
12183
|
const json2 = JSON.stringify(result, null, 2);
|
|
11982
|
-
if (output) writeFileSync12(
|
|
12184
|
+
if (output) writeFileSync12(resolve18(output), json2 + "\n", "utf8");
|
|
11983
12185
|
else process.stdout.write(json2 + "\n");
|
|
11984
12186
|
} catch (err) {
|
|
11985
12187
|
const reason = err instanceof Error ? err.message : String(err);
|
|
11986
12188
|
const json2 = JSON.stringify({ mode: "specdrift", stage, error: reason }, null, 2);
|
|
11987
12189
|
if (output) {
|
|
11988
12190
|
try {
|
|
11989
|
-
writeFileSync12(
|
|
12191
|
+
writeFileSync12(resolve18(output), json2 + "\n", "utf8");
|
|
11990
12192
|
} catch {
|
|
11991
12193
|
process.stderr.write(json2 + "\n");
|
|
11992
12194
|
}
|
|
@@ -12008,8 +12210,8 @@ function registerSpecdriftCommand(program) {
|
|
|
12008
12210
|
}
|
|
12009
12211
|
|
|
12010
12212
|
// packages/cli/src/commands/protocol-check.ts
|
|
12011
|
-
import { readFileSync as
|
|
12012
|
-
import { resolve as
|
|
12213
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
12214
|
+
import { resolve as resolve19 } from "node:path";
|
|
12013
12215
|
function resolveNativeRuntime(runtimeFlag) {
|
|
12014
12216
|
const choice = (runtimeFlag ?? "auto").toLowerCase();
|
|
12015
12217
|
const timeout = 6e4;
|
|
@@ -12028,9 +12230,9 @@ function resolveNativeRuntime(runtimeFlag) {
|
|
|
12028
12230
|
return rt;
|
|
12029
12231
|
}
|
|
12030
12232
|
function readExcerpt(path, label) {
|
|
12031
|
-
const abs =
|
|
12233
|
+
const abs = resolve19(path);
|
|
12032
12234
|
try {
|
|
12033
|
-
return
|
|
12235
|
+
return readFileSync16(abs, "utf8");
|
|
12034
12236
|
} catch (err) {
|
|
12035
12237
|
throw new Error(
|
|
12036
12238
|
`failed to read ${label} from ${abs}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -12154,8 +12356,8 @@ function registerProtocolCheckCommand(program) {
|
|
|
12154
12356
|
}
|
|
12155
12357
|
|
|
12156
12358
|
// packages/cli/src/commands/cve.ts
|
|
12157
|
-
import { readFileSync as
|
|
12158
|
-
import { resolve as
|
|
12359
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
12360
|
+
import { resolve as resolve20 } from "node:path";
|
|
12159
12361
|
var VALID_FORMATS2 = ["json", "table"];
|
|
12160
12362
|
var EXIT_OK = 0;
|
|
12161
12363
|
var EXIT_USER_ERROR = 1;
|
|
@@ -12187,10 +12389,10 @@ function parseAttempts(input, fallback = 5) {
|
|
|
12187
12389
|
return parsed;
|
|
12188
12390
|
}
|
|
12189
12391
|
function loadArtifactsFile(path) {
|
|
12190
|
-
const abs =
|
|
12392
|
+
const abs = resolve20(path);
|
|
12191
12393
|
let raw;
|
|
12192
12394
|
try {
|
|
12193
|
-
raw =
|
|
12395
|
+
raw = readFileSync17(abs, "utf-8");
|
|
12194
12396
|
} catch (err) {
|
|
12195
12397
|
throw new Error(`failed to read --artifacts ${abs}: ${err instanceof Error ? err.message : String(err)}`);
|
|
12196
12398
|
}
|
|
@@ -12435,7 +12637,7 @@ function wrapText(input, width) {
|
|
|
12435
12637
|
// packages/cli/src/commands/upgrade.ts
|
|
12436
12638
|
var RELEASES_URL = "https://github.com/0sec-labs/0sec/releases/latest";
|
|
12437
12639
|
function registerUpgradeCommand(program) {
|
|
12438
|
-
program.command("upgrade").description("Fetch and install the latest 0sec binary (re-runs install.sh)").option("--version <tag>", "Pin a specific release tag (e.g. v0.10.0)").option("--install-dir <path>", "Override the install directory (default: ~/.0sec/bin)").action(async (opts) => {
|
|
12640
|
+
program.command("upgrade").alias("update").description("Fetch and install the latest 0sec binary (re-runs install.sh)").option("--version <tag>", "Pin a specific release tag (e.g. v0.10.0)").option("--install-dir <path>", "Override the install directory (default: ~/.0sec/bin)").action(async (opts) => {
|
|
12439
12641
|
if (process.platform === "win32") {
|
|
12440
12642
|
console.log("");
|
|
12441
12643
|
console.log(` ${source_default.bold("0sec upgrade")} doesn't support Windows yet.`);
|
|
@@ -13280,7 +13482,7 @@ function registerConsoleCommand(program) {
|
|
|
13280
13482
|
let resumedTarget;
|
|
13281
13483
|
let openResumePicker = false;
|
|
13282
13484
|
if (opts.continue || opts.resume !== void 0) {
|
|
13283
|
-
const { listSessions, loadSession } = await import("./session-store-
|
|
13485
|
+
const { listSessions, loadSession } = await import("./session-store-GZ4A4KYT.js");
|
|
13284
13486
|
const idArg = typeof opts.resume === "string" ? opts.resume.trim() : "";
|
|
13285
13487
|
if (idArg || opts.continue) {
|
|
13286
13488
|
let stored = idArg ? loadSession(idArg) : null;
|
|
@@ -13361,7 +13563,7 @@ turn failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
|
13361
13563
|
console.log(source_default.dim(`MCP: connected ${mcpHost.serverIds().length} server(s) \u2014 ${mcpHost.registeredTools().length} tool(s)`));
|
|
13362
13564
|
}
|
|
13363
13565
|
if (useOpenTui) {
|
|
13364
|
-
const { showOpenTuiConsole, showOpenTuiResume } = await import("./run-
|
|
13566
|
+
const { showOpenTuiConsole, showOpenTuiResume } = await import("./run-D56MPDKY.js");
|
|
13365
13567
|
const baseOptions = {
|
|
13366
13568
|
target: focusedTarget,
|
|
13367
13569
|
scope,
|
|
@@ -14006,7 +14208,7 @@ function renderIdentity(result) {
|
|
|
14006
14208
|
|
|
14007
14209
|
// packages/cli/src/commands/adgraph.ts
|
|
14008
14210
|
import { readdir, readFile as readFile3, stat } from "node:fs/promises";
|
|
14009
|
-
import { join as
|
|
14211
|
+
import { join as join15 } from "node:path";
|
|
14010
14212
|
var DEFAULT_TIMEOUT_MS2 = "120000";
|
|
14011
14213
|
var SEVERITY_ORDER2 = ["critical", "high", "medium", "low", "info"];
|
|
14012
14214
|
var SEVERITY_COLOR2 = {
|
|
@@ -14113,7 +14315,7 @@ async function resolveInputFiles(input) {
|
|
|
14113
14315
|
} catch (err) {
|
|
14114
14316
|
throw new Error(`--input directory '${input}' could not be listed: ${err instanceof Error ? err.message : String(err)}`);
|
|
14115
14317
|
}
|
|
14116
|
-
const files = entries.filter((name) => name.toLowerCase().endsWith(".json")).sort().map((name) =>
|
|
14318
|
+
const files = entries.filter((name) => name.toLowerCase().endsWith(".json")).sort().map((name) => join15(input, name));
|
|
14117
14319
|
if (files.length === 0) {
|
|
14118
14320
|
throw new Error(`--input directory '${input}' contains no *.json files. Point it at an unzipped BloodHound collection.`);
|
|
14119
14321
|
}
|
|
@@ -14195,7 +14397,7 @@ function renderAdGraph(analysis, readWarnings) {
|
|
|
14195
14397
|
|
|
14196
14398
|
// packages/cli/src/commands/entragraph.ts
|
|
14197
14399
|
import { readdir as readdir2, readFile as readFile4, stat as stat2 } from "node:fs/promises";
|
|
14198
|
-
import { join as
|
|
14400
|
+
import { join as join16 } from "node:path";
|
|
14199
14401
|
var DEFAULT_TIMEOUT_MS3 = "120000";
|
|
14200
14402
|
var SEVERITY_ORDER3 = ["critical", "high", "medium", "low", "info"];
|
|
14201
14403
|
var SEVERITY_COLOR3 = {
|
|
@@ -14319,7 +14521,7 @@ async function resolveInputFiles2(input) {
|
|
|
14319
14521
|
`--input directory '${input}' could not be listed: ${err instanceof Error ? err.message : String(err)}`
|
|
14320
14522
|
);
|
|
14321
14523
|
}
|
|
14322
|
-
const files = entries.filter((name) => name.toLowerCase().endsWith(".json")).sort().map((name) =>
|
|
14524
|
+
const files = entries.filter((name) => name.toLowerCase().endsWith(".json")).sort().map((name) => join16(input, name));
|
|
14323
14525
|
if (files.length === 0) {
|
|
14324
14526
|
throw new Error(
|
|
14325
14527
|
`--input directory '${input}' contains no *.json files. Point it at an unzipped AzureHound collection.`
|
|
@@ -14509,7 +14711,7 @@ function loadScopeOrExit(path) {
|
|
|
14509
14711
|
}
|
|
14510
14712
|
|
|
14511
14713
|
// packages/cli/src/commands/xnu-fuzz.ts
|
|
14512
|
-
import { readFileSync as
|
|
14714
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync13 } from "node:fs";
|
|
14513
14715
|
function enumerateAction(opts) {
|
|
14514
14716
|
const bundle = opts.bundle ?? "com.apple.unknown";
|
|
14515
14717
|
const model = enumerateTargetModelFromKext(opts.kext, { kext: bundle, source: opts.kext });
|
|
@@ -14546,7 +14748,7 @@ function pickClient(model, name) {
|
|
|
14546
14748
|
return model.userClients[0];
|
|
14547
14749
|
}
|
|
14548
14750
|
function genAction(opts) {
|
|
14549
|
-
const model = JSON.parse(
|
|
14751
|
+
const model = JSON.parse(readFileSync18(opts.model, "utf8"));
|
|
14550
14752
|
const uc = pickClient(model, opts.class);
|
|
14551
14753
|
if (!uc) {
|
|
14552
14754
|
process.stderr.write("no user client in model\n");
|
|
@@ -14632,15 +14834,15 @@ function registerXnuFuzzCommand(program) {
|
|
|
14632
14834
|
}
|
|
14633
14835
|
|
|
14634
14836
|
// packages/cli/src/commands/research.ts
|
|
14635
|
-
import { readFileSync as
|
|
14636
|
-
import { resolve as
|
|
14837
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
14838
|
+
import { resolve as resolve21 } from "node:path";
|
|
14637
14839
|
function print(value) {
|
|
14638
14840
|
process.stdout.write(JSON.stringify(value, null, 2) + "\n");
|
|
14639
14841
|
}
|
|
14640
14842
|
function registerResearchCommand(program) {
|
|
14641
14843
|
const research = program.command("research").description("Run target-specific engines through the shared evidence research plane");
|
|
14642
14844
|
research.command("pipeline").description("Run the existing web/AI/source/package pipeline through the shared evidence plane").requiredOption("--target <target>", "URL, local path, repository, package, or image").option("--target-type <type>", "url, web-app, source-code, npm-package, pypi-package, cargo-package, or oci-image").option("--profile <profile>", "Source review profile").option("--depth <depth>", "quick, default, or deep", "default").option("--runtime <runtime>", "auto, api, claude, codex, gemini, or ollama", "auto").option("--artifact-root <path>", "Research artifact root", ".0sec-research").action(async (opts) => {
|
|
14643
|
-
const { UnifiedPipelineResearchAdapter, postFinding, runResearch } = await import("./dist-
|
|
14845
|
+
const { UnifiedPipelineResearchAdapter, postFinding, runResearch } = await import("./dist-4YICS2J2.js");
|
|
14644
14846
|
const allowedTypes = /* @__PURE__ */ new Set(["url", "web-app", "source-code", "npm-package", "pypi-package", "cargo-package", "oci-image"]);
|
|
14645
14847
|
if (opts.targetType && !allowedTypes.has(opts.targetType)) throw new Error(`unsupported --target-type ${opts.targetType}`);
|
|
14646
14848
|
print(await runResearch(
|
|
@@ -14659,35 +14861,35 @@ function registerResearchCommand(program) {
|
|
|
14659
14861
|
}
|
|
14660
14862
|
}
|
|
14661
14863
|
},
|
|
14662
|
-
{ artifactRoot:
|
|
14864
|
+
{ artifactRoot: resolve21(opts.artifactRoot), emitFinding: postFinding, log: (message) => process.stderr.write(message + "\n") }
|
|
14663
14865
|
));
|
|
14664
14866
|
});
|
|
14665
14867
|
research.command("mobile").description("Run passive mobile intake; indicators remain hypotheses and only scoped adapters may hand off targets").requiredOption("--target <path>", "Extracted APK/IPA directory or metadata file").option("--artifact-root <path>", "Research artifact root", ".0sec-research").action(async (opts) => {
|
|
14666
|
-
const { MobileStaticResearchAdapter, postFinding, runResearch } = await import("./dist-
|
|
14667
|
-
const targetPath =
|
|
14868
|
+
const { MobileStaticResearchAdapter, postFinding, runResearch } = await import("./dist-4YICS2J2.js");
|
|
14869
|
+
const targetPath = resolve21(opts.target);
|
|
14668
14870
|
print(await runResearch(
|
|
14669
14871
|
new MobileStaticResearchAdapter(),
|
|
14670
14872
|
{ kind: "mobile.static-intake", id: `mobile:${targetPath}`, location: targetPath, config: {} },
|
|
14671
|
-
{ artifactRoot:
|
|
14873
|
+
{ artifactRoot: resolve21(opts.artifactRoot), emitFinding: postFinding, log: (message) => process.stderr.write(message + "\n") }
|
|
14672
14874
|
));
|
|
14673
14875
|
});
|
|
14674
14876
|
research.command("linux-matrix").description("Import externally executed vulnerable-vs-patched boot logs; 0sec validates and hashes them but does not execute boots").requiredOption("--matrix <path>", "Versioned external boot-matrix manifest JSON").requiredOption("--finding <path>", "Existing Finding JSON to bind the proof to").option("--artifact-root <path>", "Research artifact root", ".0sec-research").action(async (opts) => {
|
|
14675
|
-
const { LinuxBootMatrixImportAdapter, postFinding, runResearch } = await import("./dist-
|
|
14676
|
-
const matrix =
|
|
14677
|
-
const finding = JSON.parse(
|
|
14877
|
+
const { LinuxBootMatrixImportAdapter, postFinding, runResearch } = await import("./dist-4YICS2J2.js");
|
|
14878
|
+
const matrix = resolve21(opts.matrix);
|
|
14879
|
+
const finding = JSON.parse(readFileSync19(resolve21(opts.finding), "utf8"));
|
|
14678
14880
|
const result = await runResearch(
|
|
14679
14881
|
new LinuxBootMatrixImportAdapter(),
|
|
14680
14882
|
{ kind: "linux.kernel-boot-matrix-import", id: `linux-matrix:${finding.id}`, location: matrix, config: { finding } },
|
|
14681
|
-
{ artifactRoot:
|
|
14883
|
+
{ artifactRoot: resolve21(opts.artifactRoot), emitFinding: postFinding, log: (message) => process.stderr.write(message + "\n") }
|
|
14682
14884
|
);
|
|
14683
14885
|
if (result.candidates.length === 0) throw new Error("external boot-matrix manifest failed validation");
|
|
14684
14886
|
print(result);
|
|
14685
14887
|
});
|
|
14686
14888
|
research.command("linux").description("Run a supplied Linux kernel reproducer through the shared N-boot evidence gate").requiredOption("--kernel-tree <path>", "Linux source tree").requiredOption("--reproducer <path>", "C reproducer or syzkaller .syz program").requiredOption("--finding <path>", "Existing Finding JSON to bind the proof to").requiredOption("--expected-signature <literal>", "Literal crash signature that every counted boot must contain").option("--boots <n>", "Fresh boots", "3").option("--min-hits <n>", "Required reproducing boots", "2").option("--artifact-root <path>", "Research artifact root", ".0sec-research").action(async (opts) => {
|
|
14687
|
-
const { LinuxKernelResearchAdapter, postFinding, runResearch } = await import("./dist-
|
|
14688
|
-
const kernelTree =
|
|
14689
|
-
const reproducer =
|
|
14690
|
-
const finding = JSON.parse(
|
|
14889
|
+
const { LinuxKernelResearchAdapter, postFinding, runResearch } = await import("./dist-4YICS2J2.js");
|
|
14890
|
+
const kernelTree = resolve21(opts.kernelTree);
|
|
14891
|
+
const reproducer = resolve21(opts.reproducer);
|
|
14892
|
+
const finding = JSON.parse(readFileSync19(resolve21(opts.finding), "utf8"));
|
|
14691
14893
|
const boots = Number.parseInt(opts.boots, 10);
|
|
14692
14894
|
const minHits = Number.parseInt(opts.minHits, 10);
|
|
14693
14895
|
if (!Number.isFinite(boots) || boots < 1 || !Number.isFinite(minHits) || minHits < 1 || minHits > boots) {
|
|
@@ -14703,7 +14905,7 @@ function registerResearchCommand(program) {
|
|
|
14703
14905
|
location: kernelTree,
|
|
14704
14906
|
config: { finding, verify }
|
|
14705
14907
|
},
|
|
14706
|
-
{ artifactRoot:
|
|
14908
|
+
{ artifactRoot: resolve21(opts.artifactRoot), emitFinding: postFinding, log: (message) => process.stderr.write(message + "\n") }
|
|
14707
14909
|
);
|
|
14708
14910
|
if (result.findings.length === 0) {
|
|
14709
14911
|
throw new Error("kernel N-boot verification did not reproduce the expected signature");
|
|
@@ -14749,7 +14951,7 @@ function registerTimelineCommand(program) {
|
|
|
14749
14951
|
process.exitCode = 2;
|
|
14750
14952
|
return;
|
|
14751
14953
|
}
|
|
14752
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
14954
|
+
const { osecDB: osecDB2 } = await import("./dist-4MAW5X6L.js");
|
|
14753
14955
|
const db = new osecDB2(opts.dbPath);
|
|
14754
14956
|
let scan2;
|
|
14755
14957
|
let rows;
|
|
@@ -15036,7 +15238,7 @@ function strArray(value) {
|
|
|
15036
15238
|
}
|
|
15037
15239
|
|
|
15038
15240
|
// packages/cli/src/commands/file-review.ts
|
|
15039
|
-
import { resolve as
|
|
15241
|
+
import { resolve as resolve22 } from "node:path";
|
|
15040
15242
|
function parseDurationMs2(raw) {
|
|
15041
15243
|
const m = /^(\d+(?:\.\d+)?)(ms|s|m|h)?$/.exec(raw.trim());
|
|
15042
15244
|
if (!m) throw new Error(`invalid duration '${raw}' \u2014 use e.g. 30m, 2h, 500ms`);
|
|
@@ -15067,7 +15269,7 @@ function registerFileReviewCommand(program) {
|
|
|
15067
15269
|
program.command("file-review <target>").description(
|
|
15068
15270
|
"Whole-repo file-level security review: regex scan \u2192 coverage gate \u2192 batched AI investigation (refusal audit, field repair) \u2192 optional static revalidation. Resumable: exit code 3 means a cost/duration limit stopped the run at a checkpoint \u2014 re-run the same command to continue."
|
|
15069
15271
|
).option("--project-id <id>", "Project id (defaults to the target basename)").option("--data-dir <path>", "Record store directory (default <target>/.0sec-review)").option("--runtime <mode>", "Engine runtime: api|claude|codex|gemini|ollama (default api)").option("-m, --model <model>", "Model for the investigation/revalidation agents").option("--timeout <ms>", "Per-invocation timeout in milliseconds", "600000").option("--max-cost-usd <usd>", "Hard USD cap for the whole run (resumable stop)").option("--max-duration <dur>", "Wall-clock cap: 30m / 2h / ms (resumable stop)").option("--batch-size <n>", "Files per investigation batch (default 5)").option("--concurrency <n>", "Batches in flight (default 2)").option("--inventory", "Generate the AI surface inventory + INFO.md first (requires claude, codex, or gemini)").option("--revalidate", "Run the static adversarial revalidation on HIGH+ findings").option("--json", "Emit the pipeline result as JSON").action(async (target, opts) => {
|
|
15070
|
-
const rootPath =
|
|
15272
|
+
const rootPath = resolve22(target);
|
|
15071
15273
|
const rtType = (opts.runtime ?? "api") === "auto" ? "api" : opts.runtime ?? "api";
|
|
15072
15274
|
if (opts.inventory && (rtType === "api" || rtType === "ollama")) {
|
|
15073
15275
|
console.error(
|
|
@@ -15143,12 +15345,12 @@ function registerFileReviewCommand(program) {
|
|
|
15143
15345
|
}
|
|
15144
15346
|
|
|
15145
15347
|
// packages/cli/src/commands/agent-assure.ts
|
|
15146
|
-
import { createHash as
|
|
15147
|
-
import { readFileSync as
|
|
15348
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
15349
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
15148
15350
|
function readScenario(path) {
|
|
15149
15351
|
let raw;
|
|
15150
15352
|
try {
|
|
15151
|
-
raw = JSON.parse(
|
|
15353
|
+
raw = JSON.parse(readFileSync20(path, "utf8"));
|
|
15152
15354
|
} catch (error) {
|
|
15153
15355
|
const message = error instanceof Error ? error.message : String(error);
|
|
15154
15356
|
throw new Error(`agent-assure: failed to read scenario ${path}: ${message}`);
|
|
@@ -15159,7 +15361,7 @@ function readHeaders(path, field) {
|
|
|
15159
15361
|
if (!path) return {};
|
|
15160
15362
|
let raw;
|
|
15161
15363
|
try {
|
|
15162
|
-
raw = JSON.parse(
|
|
15364
|
+
raw = JSON.parse(readFileSync20(path, "utf8"));
|
|
15163
15365
|
} catch (error) {
|
|
15164
15366
|
const message = error instanceof Error ? error.message : String(error);
|
|
15165
15367
|
throw new Error(`agent-assure: failed to read ${field} file ${path}: ${message}`);
|
|
@@ -15206,7 +15408,7 @@ function assertInScope(scope, endpoint, label) {
|
|
|
15206
15408
|
}
|
|
15207
15409
|
}
|
|
15208
15410
|
function readBaseline(path) {
|
|
15209
|
-
const raw =
|
|
15411
|
+
const raw = readFileSync20(path, "utf8");
|
|
15210
15412
|
return {
|
|
15211
15413
|
manifest: parseAgentActionEvidenceManifest(JSON.parse(raw)),
|
|
15212
15414
|
sha256: agentActionManifestSha256(raw)
|
|
@@ -15223,11 +15425,11 @@ function registerAgentAssureCommand(program) {
|
|
|
15223
15425
|
assertInScope(scope, opts.mcpEndpoint, "MCP endpoint");
|
|
15224
15426
|
assertInScope(scope, opts.oracleEndpoint, "oracle endpoint");
|
|
15225
15427
|
const baseline = opts.baseline ? readBaseline(opts.baseline) : void 0;
|
|
15226
|
-
const scenarioPayloadSha256 =
|
|
15428
|
+
const scenarioPayloadSha256 = createHash6("sha256").update(scenario.payload).digest("hex");
|
|
15227
15429
|
if (baseline && (baseline.manifest.scenario.id !== scenario.id || baseline.manifest.scenario.payload_sha256 !== scenarioPayloadSha256)) {
|
|
15228
15430
|
throw new Error("agent-assure: --baseline must describe the same scenario id and payload");
|
|
15229
15431
|
}
|
|
15230
|
-
const scopeRaw =
|
|
15432
|
+
const scopeRaw = readFileSync20(opts.scope, "utf8");
|
|
15231
15433
|
const timeoutMs = parsePositiveMilliseconds(opts.timeout, "--timeout");
|
|
15232
15434
|
const oracleTimeoutMs = parsePositiveMilliseconds(opts.oracleTimeout, "--oracle-timeout");
|
|
15233
15435
|
const run = await runAgentActionAssurance({
|
|
@@ -15247,7 +15449,7 @@ function registerAgentAssureCommand(program) {
|
|
|
15247
15449
|
}),
|
|
15248
15450
|
scenario,
|
|
15249
15451
|
targetConfig: {
|
|
15250
|
-
scopeSha256:
|
|
15452
|
+
scopeSha256: createHash6("sha256").update(scopeRaw).digest("hex"),
|
|
15251
15453
|
environment: opts.environment,
|
|
15252
15454
|
agentEndpoint: opts.agentEndpoint,
|
|
15253
15455
|
mcpEndpoint: opts.mcpEndpoint,
|
|
@@ -15290,15 +15492,15 @@ function registerAgentAssureCommand(program) {
|
|
|
15290
15492
|
|
|
15291
15493
|
// packages/cli/src/commands/binary.ts
|
|
15292
15494
|
import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
|
|
15293
|
-
import { existsSync as
|
|
15294
|
-
import { dirname as dirname7, join as
|
|
15495
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
15496
|
+
import { dirname as dirname7, join as join17, resolve as resolve23 } from "node:path";
|
|
15295
15497
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
15296
15498
|
var BINARY_MODES = ["triage", "run", "scan"];
|
|
15297
15499
|
function locateOverseDir(startDir) {
|
|
15298
15500
|
let dir = startDir ?? dirname7(fileURLToPath5(import.meta.url));
|
|
15299
15501
|
for (let i = 0; i < 12; i++) {
|
|
15300
|
-
const candidate =
|
|
15301
|
-
if (
|
|
15502
|
+
const candidate = join17(dir, "0verse");
|
|
15503
|
+
if (existsSync15(join17(candidate, "pyproject.toml"))) {
|
|
15302
15504
|
return candidate;
|
|
15303
15505
|
}
|
|
15304
15506
|
const parent = dirname7(dir);
|
|
@@ -15391,7 +15593,7 @@ function registerBinaryCommand(program) {
|
|
|
15391
15593
|
const overseDir = resolution.overseDir;
|
|
15392
15594
|
const argv = ["run", "--frozen", "0verse", ...resolution.argv ?? []];
|
|
15393
15595
|
const child = spawn2("uv", argv, {
|
|
15394
|
-
cwd:
|
|
15596
|
+
cwd: resolve23(overseDir),
|
|
15395
15597
|
stdio: "inherit",
|
|
15396
15598
|
shell: false
|
|
15397
15599
|
});
|
|
@@ -15413,17 +15615,17 @@ function registerBinaryCommand(program) {
|
|
|
15413
15615
|
|
|
15414
15616
|
// packages/cli/src/commands/plugin.ts
|
|
15415
15617
|
import { chmodSync, mkdirSync as mkdirSync11, writeFileSync as writeFileSync14 } from "node:fs";
|
|
15416
|
-
import { join as
|
|
15618
|
+
import { join as join18 } from "node:path";
|
|
15417
15619
|
var cachedCore;
|
|
15418
15620
|
async function defaultCorePort() {
|
|
15419
15621
|
if (cachedCore) return cachedCore;
|
|
15420
|
-
const mod = await import("./dist-
|
|
15622
|
+
const mod = await import("./dist-4YICS2J2.js");
|
|
15421
15623
|
cachedCore = mod;
|
|
15422
15624
|
return mod;
|
|
15423
15625
|
}
|
|
15424
15626
|
var EXIT_OK4 = 0;
|
|
15425
15627
|
var EXIT_USER_ERROR4 = 1;
|
|
15426
|
-
function
|
|
15628
|
+
function resolve24(deps) {
|
|
15427
15629
|
return {
|
|
15428
15630
|
core: deps.core,
|
|
15429
15631
|
fetchImpl: deps.fetchImpl ?? fetch,
|
|
@@ -15455,7 +15657,7 @@ function installedViews(d) {
|
|
|
15455
15657
|
return out;
|
|
15456
15658
|
}
|
|
15457
15659
|
function runList(deps) {
|
|
15458
|
-
const d =
|
|
15660
|
+
const d = resolve24(deps);
|
|
15459
15661
|
const installed = installedViews(d);
|
|
15460
15662
|
const record2 = d.core.readEnablement(d.projectPath, d.homeDir);
|
|
15461
15663
|
const reconciled = d.core.reconcile(record2, installed);
|
|
@@ -15485,7 +15687,7 @@ function runList(deps) {
|
|
|
15485
15687
|
process.exitCode = EXIT_OK4;
|
|
15486
15688
|
}
|
|
15487
15689
|
async function runSearch(query, deps) {
|
|
15488
|
-
const d =
|
|
15690
|
+
const d = resolve24(deps);
|
|
15489
15691
|
if (d.registryUrl.trim().length === 0) {
|
|
15490
15692
|
d.out("The Hackstore is disabled (registry URL is empty), so there is nothing to search.");
|
|
15491
15693
|
d.out(" The default community Hackstore lives at github.com/0sec-labs/hackstore.");
|
|
@@ -15522,7 +15724,7 @@ async function runSearch(query, deps) {
|
|
|
15522
15724
|
process.exitCode = EXIT_OK4;
|
|
15523
15725
|
}
|
|
15524
15726
|
async function runInstall(id, deps) {
|
|
15525
|
-
const d =
|
|
15727
|
+
const d = resolve24(deps);
|
|
15526
15728
|
if (!d.core.isSafePluginId(id)) {
|
|
15527
15729
|
d.err(source_default.red(`"${id}" is not a valid plugin id; refused before any filesystem access.`));
|
|
15528
15730
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -15574,17 +15776,17 @@ function writePluginFiles(d, root, entry) {
|
|
|
15574
15776
|
if (!d.core.ensurePluginsRoot(root)) {
|
|
15575
15777
|
return { ok: false, error: `could not create the plugins root at ${root}` };
|
|
15576
15778
|
}
|
|
15577
|
-
const dir =
|
|
15779
|
+
const dir = join18(root, entry.id);
|
|
15578
15780
|
try {
|
|
15579
15781
|
mkdirSync11(dir, { recursive: true, mode: d.core.PLUGIN_DIR_MODE });
|
|
15580
15782
|
chmodSync(dir, d.core.PLUGIN_DIR_MODE);
|
|
15581
|
-
const manifestPath =
|
|
15783
|
+
const manifestPath = join18(dir, d.core.PLUGIN_MANIFEST_FILE);
|
|
15582
15784
|
writeFileSync14(manifestPath, `${JSON.stringify(entry.manifest, null, 2)}
|
|
15583
15785
|
`, {
|
|
15584
15786
|
mode: d.core.PLUGIN_FILE_MODE
|
|
15585
15787
|
});
|
|
15586
15788
|
chmodSync(manifestPath, d.core.PLUGIN_FILE_MODE);
|
|
15587
|
-
const entryPath =
|
|
15789
|
+
const entryPath = join18(dir, d.core.PLUGIN_ENTRY_FILE);
|
|
15588
15790
|
writeFileSync14(entryPath, entryBody, { mode: d.core.PLUGIN_FILE_MODE });
|
|
15589
15791
|
chmodSync(entryPath, d.core.PLUGIN_FILE_MODE);
|
|
15590
15792
|
return { ok: true, dir };
|
|
@@ -15593,7 +15795,7 @@ function writePluginFiles(d, root, entry) {
|
|
|
15593
15795
|
}
|
|
15594
15796
|
}
|
|
15595
15797
|
function runEnable(id, deps) {
|
|
15596
|
-
const d =
|
|
15798
|
+
const d = resolve24(deps);
|
|
15597
15799
|
if (!d.core.isSafePluginId(id)) {
|
|
15598
15800
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
15599
15801
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -15637,7 +15839,7 @@ function runEnable(id, deps) {
|
|
|
15637
15839
|
process.exitCode = EXIT_OK4;
|
|
15638
15840
|
}
|
|
15639
15841
|
function runDisable(id, deps) {
|
|
15640
|
-
const d =
|
|
15842
|
+
const d = resolve24(deps);
|
|
15641
15843
|
if (!d.core.isSafePluginId(id)) {
|
|
15642
15844
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
15643
15845
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -15661,7 +15863,7 @@ function runDisable(id, deps) {
|
|
|
15661
15863
|
process.exitCode = EXIT_OK4;
|
|
15662
15864
|
}
|
|
15663
15865
|
function runInfo(id, deps) {
|
|
15664
|
-
const d =
|
|
15866
|
+
const d = resolve24(deps);
|
|
15665
15867
|
if (!d.core.isSafePluginId(id)) {
|
|
15666
15868
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
15667
15869
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -15680,7 +15882,7 @@ function runInfo(id, deps) {
|
|
|
15680
15882
|
const enabled = d.core.isEnabled(record2, id);
|
|
15681
15883
|
d.out(source_default.bold(`${m.name} (${m.id}@${m.version})`));
|
|
15682
15884
|
if (m.minCoreVersion) d.out(` Requires @0sec/core >= ${m.minCoreVersion}`);
|
|
15683
|
-
d.out(` Source: ${
|
|
15885
|
+
d.out(` Source: ${join18(root, id)}`);
|
|
15684
15886
|
d.out(` Enabled for this project: ${enabled ? source_default.green("yes") : source_default.dim("no")}`);
|
|
15685
15887
|
d.out(` Aggregated capabilities: ${capSummary(d.core.aggregateCapabilities(m))}`);
|
|
15686
15888
|
d.out(source_default.dim(" Signature: not re-verified after install (verification happens at fetch time)."));
|
|
@@ -15717,7 +15919,7 @@ function parseRunArgs(pairs, jsonArgs) {
|
|
|
15717
15919
|
return { ok: true, args: args2 };
|
|
15718
15920
|
}
|
|
15719
15921
|
async function runRun(id, tool, pairs, deps) {
|
|
15720
|
-
const d =
|
|
15922
|
+
const d = resolve24(deps);
|
|
15721
15923
|
if (!d.core.isSafePluginId(id)) {
|
|
15722
15924
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
15723
15925
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -15868,7 +16070,7 @@ var EXIT_USER_ERROR5 = 1;
|
|
|
15868
16070
|
var cachedCore2;
|
|
15869
16071
|
async function defaultThemeCorePort() {
|
|
15870
16072
|
if (cachedCore2) return cachedCore2;
|
|
15871
|
-
const mod = await import("./dist-
|
|
16073
|
+
const mod = await import("./dist-4YICS2J2.js");
|
|
15872
16074
|
cachedCore2 = mod;
|
|
15873
16075
|
return mod;
|
|
15874
16076
|
}
|
|
@@ -16073,8 +16275,8 @@ function registerThemeCommand(program) {
|
|
|
16073
16275
|
}
|
|
16074
16276
|
|
|
16075
16277
|
// packages/cli/src/commands/evolve.ts
|
|
16076
|
-
import { readFileSync as
|
|
16077
|
-
import { resolve as
|
|
16278
|
+
import { readFileSync as readFileSync21, existsSync as existsSync16 } from "node:fs";
|
|
16279
|
+
import { resolve as resolve25 } from "node:path";
|
|
16078
16280
|
var EXIT_OK6 = 0;
|
|
16079
16281
|
var EXIT_USER_ERROR6 = 1;
|
|
16080
16282
|
var EXIT_RUNTIME_ERROR = 2;
|
|
@@ -16221,13 +16423,13 @@ function registerEvolveCommand(program) {
|
|
|
16221
16423
|
});
|
|
16222
16424
|
evolve.command("status").description("Show active and canary versions, snapshot identities, and registry events").option("--store <path>", "Required path to evolution store directory").option("--json", "Output structured JSON").action(async (opts) => {
|
|
16223
16425
|
try {
|
|
16224
|
-
const storePath = opts.store ?
|
|
16426
|
+
const storePath = opts.store ? resolve25(opts.store) : void 0;
|
|
16225
16427
|
if (!storePath) {
|
|
16226
16428
|
console.error(source_default.red("--store <path> is required. Point it to the evolution store directory containing registry.json."));
|
|
16227
16429
|
process.exitCode = EXIT_USER_ERROR6;
|
|
16228
16430
|
return;
|
|
16229
16431
|
}
|
|
16230
|
-
if (!
|
|
16432
|
+
if (!existsSync16(storePath)) {
|
|
16231
16433
|
console.error(source_default.red(`store directory not found: ${storePath}`));
|
|
16232
16434
|
process.exitCode = EXIT_USER_ERROR6;
|
|
16233
16435
|
return;
|
|
@@ -16250,7 +16452,7 @@ function registerEvolveCommand(program) {
|
|
|
16250
16452
|
const interrupt = () => controller.abort();
|
|
16251
16453
|
process.once("SIGINT", interrupt);
|
|
16252
16454
|
try {
|
|
16253
|
-
const result = await approveEvolutionCandidate(
|
|
16455
|
+
const result = await approveEvolutionCandidate(resolve25(opts.store), opts.version, { signal: controller.signal });
|
|
16254
16456
|
if (opts.json) console.log(JSON.stringify(result));
|
|
16255
16457
|
else console.log(`Promoted ${result.versionId}; canary cost $${result.evaluationCostUsd.toFixed(4)}`);
|
|
16256
16458
|
process.exitCode = EXIT_OK6;
|
|
@@ -16265,8 +16467,8 @@ function registerEvolveCommand(program) {
|
|
|
16265
16467
|
});
|
|
16266
16468
|
evolve.command("rollback").description("Retire an active or canary evolution version and restore its parent").requiredOption("--store <path>", "Path to evolution store directory").requiredOption("--version <id>", "Active or canary version ID to retire").option("--reason <text>", "Reason for rollback", "operator rollback").action(async (opts) => {
|
|
16267
16469
|
try {
|
|
16268
|
-
const storePath =
|
|
16269
|
-
if (!
|
|
16470
|
+
const storePath = resolve25(opts.store);
|
|
16471
|
+
if (!existsSync16(storePath)) {
|
|
16270
16472
|
console.error(source_default.red(`store directory not found: ${storePath}`));
|
|
16271
16473
|
process.exitCode = EXIT_USER_ERROR6;
|
|
16272
16474
|
return;
|
|
@@ -16333,9 +16535,9 @@ function registerEvolveCommand(program) {
|
|
|
16333
16535
|
const feedback = evolve.command("feedback").description("Capture, approve, and inspect evolution feedback candidates");
|
|
16334
16536
|
feedback.command("capture").description("Capture an evidence-backed observation from a JSON file; does not confirm a finding").requiredOption("--input <path>", "Observation JSON file with source revision and evidence references").option("--store <path>", "Feedback queue JSON file").option("--allow-source-access", "Explicitly consent to source use for this observation").action((opts) => {
|
|
16335
16537
|
try {
|
|
16336
|
-
const input = parseObservationInput(JSON.parse(
|
|
16538
|
+
const input = parseObservationInput(JSON.parse(readFileSync21(resolve25(opts.input), "utf8")));
|
|
16337
16539
|
const result = captureObservation({ ...input, consent: opts.allowSourceAccess === true }, {
|
|
16338
|
-
...opts.store ? { storePath:
|
|
16540
|
+
...opts.store ? { storePath: resolve25(opts.store) } : {}
|
|
16339
16541
|
});
|
|
16340
16542
|
console.log(JSON.stringify(result, null, 2));
|
|
16341
16543
|
process.exitCode = EXIT_OK6;
|
|
@@ -16346,9 +16548,9 @@ function registerEvolveCommand(program) {
|
|
|
16346
16548
|
});
|
|
16347
16549
|
feedback.command("approve").description("Approve independent positive, held-out, and negative fixtures for an observation").requiredOption("--id <feedback-id>", "Full observation ID").requiredOption("--fixtures <path>", "Curation JSON containing positives, heldOut, and negativeControls").option("--store <path>", "Feedback queue JSON file").option("--allow-source-access", "Explicitly consent to source use for synthesis").action((opts) => {
|
|
16348
16550
|
try {
|
|
16349
|
-
const shape = parseApprovedObservationShape(JSON.parse(
|
|
16551
|
+
const shape = parseApprovedObservationShape(JSON.parse(readFileSync21(resolve25(opts.fixtures), "utf8")));
|
|
16350
16552
|
const result = approveObservation(opts.id, shape, {
|
|
16351
|
-
...opts.store ? { storePath:
|
|
16553
|
+
...opts.store ? { storePath: resolve25(opts.store) } : {},
|
|
16352
16554
|
...opts.allowSourceAccess === true ? { allowModelSourceAccess: true } : {}
|
|
16353
16555
|
});
|
|
16354
16556
|
if (!result) throw new Error("observation was not found or is not pending");
|
|
@@ -16361,7 +16563,7 @@ function registerEvolveCommand(program) {
|
|
|
16361
16563
|
});
|
|
16362
16564
|
feedback.command("release").description("Release a stale processing claim after its worker has stopped").requiredOption("--id <feedback-id>", "Full observation ID").requiredOption("--claim-token <token>", "Exact claim token shown by feedback status --json").option("--store <path>", "Feedback queue JSON file").action((opts) => {
|
|
16363
16565
|
try {
|
|
16364
|
-
if (!releaseClaim(opts.id, opts.claimToken, opts.store ? { storePath:
|
|
16566
|
+
if (!releaseClaim(opts.id, opts.claimToken, opts.store ? { storePath: resolve25(opts.store) } : {})) {
|
|
16365
16567
|
throw new Error("observation or processing claim no longer matches");
|
|
16366
16568
|
}
|
|
16367
16569
|
console.log(`Released feedback claim ${opts.id}`);
|
|
@@ -16373,7 +16575,7 @@ function registerEvolveCommand(program) {
|
|
|
16373
16575
|
});
|
|
16374
16576
|
feedback.command("status").description("Show retained observations and their approval/processing status").option("--store <path>", "Feedback queue JSON file").option("--json", "Output structured JSON").action((opts) => {
|
|
16375
16577
|
try {
|
|
16376
|
-
const observations = listObservations(void 0, { ...opts.store ? { storePath:
|
|
16578
|
+
const observations = listObservations(void 0, { ...opts.store ? { storePath: resolve25(opts.store) } : {} });
|
|
16377
16579
|
if (opts.json) console.log(JSON.stringify(observations, null, 2));
|
|
16378
16580
|
else if (observations.length === 0) console.log("No feedback observations.");
|
|
16379
16581
|
else for (const observation of observations) console.log(`${observation.id} ${observation.status} ${observation.classHint}`);
|
|
@@ -16386,7 +16588,7 @@ function registerEvolveCommand(program) {
|
|
|
16386
16588
|
}
|
|
16387
16589
|
|
|
16388
16590
|
// packages/cli/src/commands/config.ts
|
|
16389
|
-
import { readFileSync as
|
|
16591
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync16 } from "node:fs";
|
|
16390
16592
|
var EXIT_OK7 = 0;
|
|
16391
16593
|
var EXIT_USER_ERROR7 = 1;
|
|
16392
16594
|
var SECURITY_KEYS = SETTING_DEFS.filter(
|
|
@@ -16454,7 +16656,7 @@ function runConfigImport(file, deps = {}) {
|
|
|
16454
16656
|
const scope = deps.scope ?? "global";
|
|
16455
16657
|
let parsed;
|
|
16456
16658
|
try {
|
|
16457
|
-
parsed = JSON.parse(
|
|
16659
|
+
parsed = JSON.parse(readFileSync22(file, "utf8"));
|
|
16458
16660
|
} catch (e) {
|
|
16459
16661
|
err(source_default.red(`Could not read ${file}: ${e instanceof Error ? e.message : String(e)}`));
|
|
16460
16662
|
process.exitCode = EXIT_USER_ERROR7;
|
|
@@ -16519,8 +16721,8 @@ function registerConfigCommand(program) {
|
|
|
16519
16721
|
}
|
|
16520
16722
|
|
|
16521
16723
|
// packages/cli/src/commands/hackstore.ts
|
|
16522
|
-
import { existsSync as
|
|
16523
|
-
import { join as
|
|
16724
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync12, readdirSync as readdirSync2, readFileSync as readFileSync23, statSync as statSync3, writeFileSync as writeFileSync17 } from "node:fs";
|
|
16725
|
+
import { join as join19, resolve as resolve26 } from "node:path";
|
|
16524
16726
|
var HACKSTORE_REGISTRY_REPO = "github.com/0sec-labs/hackstore";
|
|
16525
16727
|
var HACKSTORE_SCHEMA_ID = "https://raw.githubusercontent.com/0sec-labs/hackstore/main/hackstore-manifest.schema.json";
|
|
16526
16728
|
var MANIFEST_FILE = "manifest.json";
|
|
@@ -16529,18 +16731,18 @@ var EXIT_USER_ERROR8 = 1;
|
|
|
16529
16731
|
var cachedCore3;
|
|
16530
16732
|
async function defaultCorePort2() {
|
|
16531
16733
|
if (cachedCore3) return cachedCore3;
|
|
16532
|
-
const mod = await import("./dist-
|
|
16734
|
+
const mod = await import("./dist-4YICS2J2.js");
|
|
16533
16735
|
cachedCore3 = { validatePluginManifest: mod.validatePluginManifest };
|
|
16534
16736
|
return cachedCore3;
|
|
16535
16737
|
}
|
|
16536
16738
|
function resolveManifestPath2(pathArg) {
|
|
16537
|
-
const target =
|
|
16538
|
-
if (!
|
|
16739
|
+
const target = resolve26(pathArg);
|
|
16740
|
+
if (!existsSync17(target)) {
|
|
16539
16741
|
return { ok: false, error: `path does not exist: ${target}` };
|
|
16540
16742
|
}
|
|
16541
16743
|
const stat3 = statSync3(target);
|
|
16542
|
-
const file = stat3.isDirectory() ?
|
|
16543
|
-
if (!
|
|
16744
|
+
const file = stat3.isDirectory() ? join19(target, MANIFEST_FILE) : target;
|
|
16745
|
+
if (!existsSync17(file)) {
|
|
16544
16746
|
return { ok: false, error: `no ${MANIFEST_FILE} found at: ${file}` };
|
|
16545
16747
|
}
|
|
16546
16748
|
return { ok: true, file };
|
|
@@ -16563,7 +16765,7 @@ function runValidate(pathArg, deps) {
|
|
|
16563
16765
|
}
|
|
16564
16766
|
let raw;
|
|
16565
16767
|
try {
|
|
16566
|
-
raw = JSON.parse(
|
|
16768
|
+
raw = JSON.parse(readFileSync23(located.file, "utf8"));
|
|
16567
16769
|
} catch (err) {
|
|
16568
16770
|
fail2([`${MANIFEST_FILE} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`]);
|
|
16569
16771
|
return;
|
|
@@ -16686,15 +16888,15 @@ input.on("line", (line) => {
|
|
|
16686
16888
|
`;
|
|
16687
16889
|
}
|
|
16688
16890
|
function isNonEmptyDir(dir) {
|
|
16689
|
-
if (!
|
|
16891
|
+
if (!existsSync17(dir)) return false;
|
|
16690
16892
|
const stat3 = statSync3(dir);
|
|
16691
16893
|
if (!stat3.isDirectory()) return true;
|
|
16692
16894
|
return readdirSync2(dir).length > 0;
|
|
16693
16895
|
}
|
|
16694
16896
|
function runInit(name, deps) {
|
|
16695
|
-
const base = deps.dir ?
|
|
16696
|
-
const targetDir =
|
|
16697
|
-
if (
|
|
16897
|
+
const base = deps.dir ? resolve26(deps.dir) : process.cwd();
|
|
16898
|
+
const targetDir = join19(base, name);
|
|
16899
|
+
if (existsSync17(targetDir) && statSync3(targetDir).isFile()) {
|
|
16698
16900
|
console.error(source_default.red(`Cannot scaffold: a file already exists at ${targetDir}`));
|
|
16699
16901
|
process.exitCode = EXIT_USER_ERROR8;
|
|
16700
16902
|
return;
|
|
@@ -16709,10 +16911,10 @@ function runInit(name, deps) {
|
|
|
16709
16911
|
const manifest = scaffoldManifest(name);
|
|
16710
16912
|
const id = manifest.id;
|
|
16711
16913
|
mkdirSync12(targetDir, { recursive: true });
|
|
16712
|
-
writeFileSync17(
|
|
16914
|
+
writeFileSync17(join19(targetDir, MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
|
|
16713
16915
|
`, "utf8");
|
|
16714
|
-
writeFileSync17(
|
|
16715
|
-
writeFileSync17(
|
|
16916
|
+
writeFileSync17(join19(targetDir, "README.md"), scaffoldReadme(name, id), "utf8");
|
|
16917
|
+
writeFileSync17(join19(targetDir, "plugin.js"), scaffoldPluginSource(), "utf8");
|
|
16716
16918
|
console.log(source_default.green(`Scaffolded Hackstore extension ${source_default.bold(id)} in ${targetDir}`));
|
|
16717
16919
|
console.log("");
|
|
16718
16920
|
console.log(source_default.bold(" Files:"));
|
|
@@ -16721,7 +16923,7 @@ function runInit(name, deps) {
|
|
|
16721
16923
|
console.log(` plugin.js self-contained plugin (NDJSON protocol over stdio)`);
|
|
16722
16924
|
console.log("");
|
|
16723
16925
|
console.log(source_default.bold(" Next steps:"));
|
|
16724
|
-
console.log(` 1. Edit ${
|
|
16926
|
+
console.log(` 1. Edit ${join19(name, MANIFEST_FILE)} \u2014 declare your tools + capabilities`);
|
|
16725
16927
|
console.log(` 2. Validate: ${source_default.cyan(`0sec hackstore validate ${name}`)}`);
|
|
16726
16928
|
console.log(` 3. Test locally and submit: https://${HACKSTORE_REGISTRY_REPO}/blob/main/CONTRIBUTING.md`);
|
|
16727
16929
|
process.exitCode = EXIT_OK8;
|
|
@@ -16745,6 +16947,7 @@ export {
|
|
|
16745
16947
|
registerBinaryCommand,
|
|
16746
16948
|
registerCloudCommand,
|
|
16747
16949
|
registerConfigCommand,
|
|
16950
|
+
registerConnectCommand,
|
|
16748
16951
|
registerConsoleCommand,
|
|
16749
16952
|
registerCveCommand,
|
|
16750
16953
|
registerDashboardCommand,
|
|
@@ -16783,6 +16986,7 @@ export {
|
|
|
16783
16986
|
registerResumeCommand,
|
|
16784
16987
|
registerReviewCommand,
|
|
16785
16988
|
registerScanCommand,
|
|
16989
|
+
registerSecureCommand,
|
|
16786
16990
|
registerSpecdriftCommand,
|
|
16787
16991
|
registerThemeCommand,
|
|
16788
16992
|
registerTimelineCommand,
|