chore: migrate formatting to Oxfmt (#615)

This commit is contained in:
morluto authored and GitHub committed 2026-10-06 01:59:19 +08:00
1 parent f557207887
commit 5daaa453ff
25 files changed
+514 -139

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"printWidth": 80,
"sortImports": false,
"sortPackageJson": false,
"ignorePatterns": [
"dist/**",
"build/**",
"docs/api/**",
"node_modules/**",
"CHANGELOG.md",
"package-lock.json",
"_reference/**"
]
}
-8
View File
@@ -1,8 +0,0 @@
dist
docs/api
node_modules
CHANGELOG.md
package-lock.json
# Local reference sources and analysis artifacts
/_reference/
+1 -1
View File
@@ -47,7 +47,7 @@ Configuration is parsed and validated by `src/config.ts` and `src/config/`. Keep
## Coding Style & Naming Conventions ## Coding Style & Naming Conventions
Use ESM TypeScript, two-space indentation, and Prettier defaults. Keep compiler strictness intact (`strict`, `exactOptionalPropertyTypes`, `noUncheckedIndexedAccess`, `verbatimModuleSyntax`). Use `camelCase` for values/functions, `PascalCase` for classes/types, and `UPPER_SNAKE_CASE` for constants. Parse unknown values at every MCP, environment, and subprocess boundary. Avoid `any`, unchecked casts, non-null assertions, import-time I/O, and floating promises. Exported APIs require concise JSDoc. Model expected failures with the tagged error algebra and `Result`, not broad exception wrappers. Use ESM TypeScript, two-space indentation, and the committed Oxfmt configuration. Keep compiler strictness intact (`strict`, `exactOptionalPropertyTypes`, `noUncheckedIndexedAccess`, `verbatimModuleSyntax`). Use `camelCase` for values/functions, `PascalCase` for classes/types, and `UPPER_SNAKE_CASE` for constants. Parse unknown values at every MCP, environment, and subprocess boundary. Avoid `any`, unchecked casts, non-null assertions, import-time I/O, and floating promises. Exported APIs require concise JSDoc. Model expected failures with the tagged error algebra and `Result`, not broad exception wrappers.
## Boundary Contracts ## Boundary Contracts
+3 -1
View File
@@ -49,7 +49,9 @@ require the matching real-provider `verify:*` lane.
`check:fast` runs cached typecheck and lint, reporting diagnostics on failure. `check:fast` runs cached typecheck and lint, reporting diagnostics on failure.
`check` adds formatting, dead-code, and package-metadata freshness checks. `check` adds formatting, dead-code, and package-metadata freshness checks.
Pre-commit formats and lints staged files; pre-push runs `check:fast`. Formatting uses Oxfmt and the committed `.oxfmtrc.json`; generated sources use
the same configuration. Pre-commit formats and lints staged files; pre-push runs
`check:fast`.
`docs:check` checks committed generated metadata without rendering API HTML. `docs:check` checks committed generated metadata without rendering API HTML.
`docs:generate` regenerates those files; render API HTML separately with `docs:generate` regenerates those files; render API HTML separately with
`npm run docs:api:cached`. PR CI renders and uploads the `api-docs` artifact. `npm run docs:api:cached`. PR CI renders and uploads the `api-docs` artifact.
+19 -19
View File
@@ -59,22 +59,22 @@
## من الملف التنفيذي إلى السلوك ## من الملف التنفيذي إلى السلوك
| فك الترجمة | الفهم | إعادة الإنشاء | | فك الترجمة | الفهم | إعادة الإنشاء |
| ----------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------- | | ---------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------ |
| استخرج الشيفرة شبه المصدرية، والتعليمات، والسلاسل النصية، والرموز | تتبع تدفق التحكم والمراجع المتبادلة والاستدعاءات والأنواع | حوّل ما تعلمه الوكيل إلى ميزة تناسب تقنياتك وواجهتك ومتطلباتك | | استخرج الشيفرة شبه المصدرية، والتعليمات، والسلاسل النصية، والرموز | تتبع تدفق التحكم والمراجع المتبادلة والاستدعاءات والأنواع | حوّل ما تعلمه الوكيل إلى ميزة تناسب تقنياتك وواجهتك ومتطلباتك |
يوضح REA كيف وصل إلى نتائجه. وهو لا يدّعي استعادة الشيفرة المصدرية الأصلية أو استنساخ التطبيق تلقائيًا. يوضح REA كيف وصل إلى نتائجه. وهو لا يدّعي استعادة الشيفرة المصدرية الأصلية أو استنساخ التطبيق تلقائيًا.
## لماذا REA؟ ## لماذا REA؟
| | | | | |
| -------------------- | ----------------------------------------------------------------------------------------- | | -------------------- | ------------------------------------------------------------------------------------- |
| **مصمم للوكلاء** | اسأل عما يفعله تطبيق مترجم ودع الوكيل يجمع الأدلة بدلًا من التخمين. | | **مصمم للوكلاء** | اسأل عما يفعله تطبيق مترجم ودع الوكيل يجمع الأدلة بدلًا من التخمين. |
| **CLI وMCP** | استخدم قدرات الهندسة العكسية نفسها من الطرفية أو وكيل البرمجة. | | **CLI وMCP** | استخدم قدرات الهندسة العكسية نفسها من الطرفية أو وكيل البرمجة. |
| **يتولى التعقيد** | يدير REA إعداد الأدوات وفتح التطبيق واستمرار الاستقصاء والتنظيف بعد الانتهاء. | | **يتولى التعقيد** | يدير REA إعداد الأدوات وفتح التطبيق واستمرار الاستقصاء والتنظيف بعد الانتهاء. |
| **سير عمل كامل** | انتقل من النظرة الأولى إلى الشيفرة شبه المصدرية وعلاقات الاستدعاء والأنواع وأدلة التنفيذ. | | **سير عمل كامل** | انتقل من النظرة الأولى إلى الشيفرة شبه المصدرية وعلاقات الاستدعاء والأنواع وأدلة التنفيذ. |
| **محلي حسب التصميم** | يجري التحليل على جهازك المدعوم ولا يرفع REA الملف التنفيذي إلى خدمة تحليل مستضافة. | | **محلي حسب التصميم** | يجري التحليل على جهازك المدعوم ولا يرفع REA الملف التنفيذي إلى خدمة تحليل مستضافة. |
| **يحافظ على السياق** | استقصِ عدة ملفات تنفيذية من دون بدء التحليل من جديد عند كل سؤال. | | **يحافظ على السياق** | استقصِ عدة ملفات تنفيذية من دون بدء التحليل من جديد عند كل سؤال. |
## البدء السريع ## البدء السريع
@@ -200,18 +200,18 @@ rea setup
## منصة أدوات التحقيق ## منصة أدوات التحقيق
| عائلة الأدوات | العدد | الاستخدام | | عائلة الأدوات | العدد | الاستخدام |
| --------------------- | ----: | ---------------------------------------------------------------------------------------- | | --------------------- | ----: | -------------------------------------------------------------------------------------- |
| فحص الملفات التنفيذية | 39 | الدوال والشيفرة شبه المصدرية والتعليمات والسلاسل والرموز والمراجع والتعليقات | | فحص الملفات التنفيذية | 39 | الدوال والشيفرة شبه المصدرية والتعليمات والسلاسل والرموز والمراجع والتعليقات |
| التحليل المركب | 14 | النظرة العامة وتحليل الدوال وفك الترجمة الدفعي ومخطط الاستدعاء وفحص Swift وObjC | | التحليل المركب | 14 | النظرة العامة وتحليل الدوال وفك الترجمة الدفعي ومخطط الاستدعاء وفحص Swift وObjC |
| أدوات macOS الأصلية | 7 | بيانات Mach-O والتوقيعات وplist والمعماريات واستعادة أسماء Swift | | أدوات macOS الأصلية | 7 | بيانات Mach-O والتوقيعات وplist والمعماريات واستعادة أسماء Swift |
| الملفات والحزم | 5 | فحص الدلائل والحزم وInterface Builder وموارد Apple والاستخراج | | الملفات والحزم | 5 | فحص الدلائل والحزم وInterface Builder وموارد Apple والاستخراج |
| .NET PE/CLI | 7 | هوية التجميع والبيانات الوصفية وCIL والاستدعاءات الأصلية والمقارنة واستيراد إعادة البناء | | .NET PE/CLI | 7 | هوية التجميع والبيانات الوصفية وCIL والاستدعاءات الأصلية والمقارنة واستيراد إعادة البناء |
| مراقبة المتصفح | 9 | الصفحات والبرامج النصية وخرائط المصدر وWebMCP والصور ومقارنة الالتقاط | | مراقبة المتصفح | 9 | الصفحات والبرامج النصية وخرائط المصدر وWebMCP والصور ومقارنة الالتقاط |
| تحليل Electron | 5 | مراقبة الصفحات وبنية التطبيق وربط النتائج الثابتة بنتائج التشغيل | | تحليل Electron | 5 | مراقبة الصفحات وبنية التطبيق وربط النتائج الثابتة بنتائج التشغيل |
| وقت تشغيل JavaScript | 2 | الاتصال بهدف Node/Electron Inspector موجود لمراقبة البرامج وسياقات التنفيذ | | وقت تشغيل JavaScript | 2 | الاتصال بهدف Node/Electron Inspector موجود لمراقبة البرامج وسياقات التنفيذ |
| سير عمل التطبيقات | 7 | تتبع الميزات ومقارنة الإصدارات وبنية قيم الإرجاع والتحقق من إعادة الإنشاء | | سير عمل التطبيقات | 7 | تتبع الميزات ومقارنة الإصدارات وبنية قيم الإرجاع والتحقق من إعادة الإنشاء |
| جلسة الملف التنفيذي | 21 | تبديل الأهداف وحفظ الأدلة ومقارنة العمليات والدوال وتسجيل الأسئلة غير المحسومة | | جلسة الملف التنفيذي | 21 | تبديل الأهداف وحفظ الأدلة ومقارنة العمليات والدوال وتسجيل الأسئلة غير المحسومة |
## خطة العمل ## خطة العمل
@@ -11,7 +11,7 @@
metadata, signatures, method bodies, raw CIL hashes, limited metadata, signatures, method bodies, raw CIL hashes, limited
decoded-instruction-tuple v1 hashes, exception regions, call edges, and decoded-instruction-tuple v1 hashes, exception regions, call edges, and
field-access anchors are shipped through `inspect_managed_members`; `rea field-access anchors are shipped through `inspect_managed_members`; `rea
inspect-managed-members` provides CLI parity. Static member comparison and build-local inspect-managed-members` provides CLI parity. Static member comparison and build-local
token remapping are shipped through `compare_managed_members` / token remapping are shipped through `compare_managed_members` /
`rea compare-managed-members`. Declaration-only managed/native boundary `rea compare-managed-members`. Declaration-only managed/native boundary
inventory for ModuleRef, ImplMap/PInvoke, ReadyToRun indicators, and non-IL inventory for ModuleRef, ImplMap/PInvoke, ReadyToRun indicators, and non-IL
+1 -1
View File
@@ -25,7 +25,7 @@ coverage and unknowns. The CLI and MCP use the same application workflows.
a source-owned AppKit XIB with `ibtool`. Storyboards require an installed a source-owned AppKit XIB with `ibtool`. Storyboards require an installed
iOS platform; unsupported archive forms remain explicit. iOS platform; unsupported archive forms remain explicit.
- `inspect_native_dispatch_metadata` / `rea inspect-native-dispatch-metadata - `inspect_native_dispatch_metadata` / `rea inspect-native-dispatch-metadata
<app-or-binary>` prefers a validated macOS Mach-O byte reader. It decodes <app-or-binary>` prefers a validated macOS Mach-O byte reader. It decodes
64-bit little-endian Objective-C class/metaclass records, superclass pointers, 64-bit little-endian Objective-C class/metaclass records, superclass pointers,
absolute/relative method entries, ivar offsets/sizes/alignment and protocol absolute/relative method entries, ivar offsets/sizes/alignment and protocol
declarations. It also decodes simple Swift conformances, static synchronous declarations. It also decodes simple Swift conformances, static synchronous
+386 -17
View File
@@ -55,8 +55,8 @@
"jscpd": "5.0.12", "jscpd": "5.0.12",
"knip": "6.26.0", "knip": "6.26.0",
"lint-staged": "16.4.0", "lint-staged": "16.4.0",
"oxfmt": "0.72.0",
"oxlint": "1.73.0", "oxlint": "1.73.0",
"prettier": "3.6.2",
"turbo": "2.10.5", "turbo": "2.10.5",
"typedoc": "0.28.20", "typedoc": "0.28.20",
"typescript": "5.9.3", "typescript": "5.9.3",
@@ -1104,6 +1104,329 @@
"win32" "win32"
] ]
}, },
"node_modules/@oxfmt/binding-android-arm-eabi": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.72.0.tgz",
"integrity": "sha512-u4U1uaDOVBuorGNC/07NLm48nECHOiJJka002YGML16Md2DRvf38RGBt01lH60EOGvNlFVmbLoksQedNBoZHKw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-android-arm64": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.72.0.tgz",
"integrity": "sha512-GCnM+Ae2mWOKC+92y3FOb6eZJeVnBAVz82e3lITUUg+kxukYKzBNAvJ/hhHIfa2A0md55SYYhdWPddSSy3KPVA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-darwin-arm64": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.72.0.tgz",
"integrity": "sha512-LjQ8tlevdtwraFlWC6AnQ1Forzde0clRmnsP3QmK+ydSElDt/J+5Jc+m+//Ly1G97aP7WCNUw110QMIUw2K7xA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-darwin-x64": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.72.0.tgz",
"integrity": "sha512-+ZbcxhB1C34RQR5IldSyY6Z/yalJIxHXhP36PGE4sEq0f/lgL5jCLmOKoDeVm8dqd9gFGDsd1bNWHSGCAwdSkw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-freebsd-x64": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.72.0.tgz",
"integrity": "sha512-yGPhA8sePEBFV9iGcprhyOk3Bz3fZshswMH3DpYIPZFLT1DG5LjiZ0j6AJQpSueaL6bUK0av1K+5+fe+ldy5EQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-arm-gnueabihf": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.72.0.tgz",
"integrity": "sha512-/g5axuqFMcAtoQrFLR5EJEMDjR5Ea4GuzpdDmMpPWAgrF1DmL4kD1NPNVlpXEOxpFJnD6lPvLKYj1lzdlrfifA==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-arm-musleabihf": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.72.0.tgz",
"integrity": "sha512-InVitdHbS09PM+w+WinIiyX37rC9R3L7lUP9mKy9uKTEDSUFaLjWsLoreRIxKivnv7Ndqc6Trvi+K+b6ZzhiJg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-arm64-gnu": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.72.0.tgz",
"integrity": "sha512-WKjlyRAxpPjXoqeuwFBim5LscgvY+RNEiZ971C9JlRQZONhJTsXDki/oHFYQE+fzzRpzXh3owZvOdT3kNL2g+g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-arm64-musl": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.72.0.tgz",
"integrity": "sha512-poafnbsPpJhR+5Mbwpf8CscugTyiRAzjTOxRVn8ra3X2jnURs2xL5Du2xl5g2iW85lICMglpmLf8jDjZEbNgzQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-ppc64-gnu": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.72.0.tgz",
"integrity": "sha512-zNUi0gKRsO7S3IfPzsTbnm88OedPuX32hmZFWZRWHvWJlAoZRwVbeO6Nb3hng4vDgL7qUKp4TGqzPz1mhsycYg==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-riscv64-gnu": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.72.0.tgz",
"integrity": "sha512-qTY7z/iyF/rWI2HWwWMevXqZW5PZUOofUy2afK7v6rseXnpld3yjgyIk6pCux3DqWQ0lB+f5atvLJNBwzLvFsw==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-riscv64-musl": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.72.0.tgz",
"integrity": "sha512-w18qfo8vEMD6EKEHtzTvjc6jH8yCyXIT1Bn7PFWJd0PpZyzH/VQDx4xvjCh0LGz6GRzqiezbisTdG9AoXtpkZQ==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-s390x-gnu": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.72.0.tgz",
"integrity": "sha512-grW8HwEir+vK7fCcq1ZgL3NHQCfZ1PidiERE9Hbf+24xGys+DoDaoqTht4ccfn0PcBwbViLkwkda/KNpJu2KRQ==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-x64-gnu": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.72.0.tgz",
"integrity": "sha512-wQJRQfWBRIn88Pkr449EUViwRayrYUScg7ty+Ihiem21mQ9BUA6S9e/4RAgyNk9lMag0KBouyKskjq61rOC0WQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-x64-musl": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.72.0.tgz",
"integrity": "sha512-T1B0uQzafxuGPjjaPrZJ497nxoi1BiI65JfsYc56nNpmev3msfb/iaTmH2kQuNFqa8PKxpMlf3GhWrWBvBPORQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-openharmony-arm64": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.72.0.tgz",
"integrity": "sha512-OKxxgTurl7+hypVplO8QRAbbQlwEs0j1Y6FZv+ZN2qNbdxQk2muMlzuJNBGTCWwxQ0rkkOD1uK/DW1fvzoUSJA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-win32-arm64-msvc": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.72.0.tgz",
"integrity": "sha512-L78TKzURqvjuZOCo88ixMbPXf/RP7u31Y0cmjJ/KEmrHmfYhmhEvsDaTYPiyTRne64jUgCbADfY0YeoQk4/Xyw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-win32-ia32-msvc": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.72.0.tgz",
"integrity": "sha512-gQtFW+Ii8BWgtJTAD17TY/WsdNS5gUfAPov8iI1jeq4r9lRRYImmxPL08UU00/RLaCfBJwh2UgINnDY0iOiZ+A==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-win32-x64-msvc": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.72.0.tgz",
"integrity": "sha512-uhooIN+DCzWX5uH7mQkSVCsODqsGluGJ4n3ch4+mITtWKpESMDjUJUSDBAVFuYQDwqY2McPDKdKJbM0oZVW/Qw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-android-arm-eabi": { "node_modules/@oxlint/binding-android-arm-eabi": {
"version": "1.73.0", "version": "1.73.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.73.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.73.0.tgz",
@@ -4219,6 +4542,58 @@
"@oxc-resolver/binding-win32-x64-msvc": "11.21.3" "@oxc-resolver/binding-win32-x64-msvc": "11.21.3"
} }
}, },
"node_modules/oxfmt": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.72.0.tgz",
"integrity": "sha512-16OQeL0uhPZbfmT9S9WWM0Nv9+BmVi8Ra1uTYaSKj/qSCs6FB30KOhz9JoNYw6thT+K5bVxsk/tSEOu497i34g==",
"dev": true,
"license": "MIT",
"dependencies": {
"tinypool": "2.2.0"
},
"bin": {
"oxfmt": "bin/oxfmt"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"funding": {
"url": "https://github.com/sponsors/oxc-project"
},
"optionalDependencies": {
"@oxfmt/binding-android-arm-eabi": "0.72.0",
"@oxfmt/binding-android-arm64": "0.72.0",
"@oxfmt/binding-darwin-arm64": "0.72.0",
"@oxfmt/binding-darwin-x64": "0.72.0",
"@oxfmt/binding-freebsd-x64": "0.72.0",
"@oxfmt/binding-linux-arm-gnueabihf": "0.72.0",
"@oxfmt/binding-linux-arm-musleabihf": "0.72.0",
"@oxfmt/binding-linux-arm64-gnu": "0.72.0",
"@oxfmt/binding-linux-arm64-musl": "0.72.0",
"@oxfmt/binding-linux-ppc64-gnu": "0.72.0",
"@oxfmt/binding-linux-riscv64-gnu": "0.72.0",
"@oxfmt/binding-linux-riscv64-musl": "0.72.0",
"@oxfmt/binding-linux-s390x-gnu": "0.72.0",
"@oxfmt/binding-linux-x64-gnu": "0.72.0",
"@oxfmt/binding-linux-x64-musl": "0.72.0",
"@oxfmt/binding-openharmony-arm64": "0.72.0",
"@oxfmt/binding-win32-arm64-msvc": "0.72.0",
"@oxfmt/binding-win32-ia32-msvc": "0.72.0",
"@oxfmt/binding-win32-x64-msvc": "0.72.0"
},
"peerDependencies": {
"svelte": "^5.0.0",
"vite-plus": "*"
},
"peerDependenciesMeta": {
"svelte": {
"optional": true
},
"vite-plus": {
"optional": true
}
}
},
"node_modules/oxlint": { "node_modules/oxlint": {
"version": "1.73.0", "version": "1.73.0",
"resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.73.0.tgz", "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.73.0.tgz",
@@ -4444,22 +4819,6 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/prettier": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/process": { "node_modules/process": {
"version": "0.11.10", "version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -4982,6 +5341,16 @@
"url": "https://github.com/sponsors/SuperchupuDev" "url": "https://github.com/sponsors/SuperchupuDev"
} }
}, },
"node_modules/tinypool": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.2.0.tgz",
"integrity": "sha512-jBrmx4lYmaC9k/mgPbylxs7kBUxHtD8256up+HjLaDFfXScKJQyil+SWXSvhAtT7XHo+yTVlpB81PGmHP8oLSQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^20.0.0 || >=22.0.0"
}
},
"node_modules/tinyrainbow": { "node_modules/tinyrainbow": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz",
+5 -5
View File
@@ -77,8 +77,8 @@
"precheck:ci": "npm run deps:check", "precheck:ci": "npm run deps:check",
"check:ci": "turbo run typecheck lint format:check knip metadata:check jscpd scan:todos", "check:ci": "turbo run typecheck lint format:check knip metadata:check jscpd scan:todos",
"build:cached": "turbo run build", "build:cached": "turbo run build",
"format": "prettier --write .", "format": "oxfmt .",
"format:check": "prettier --check .", "format:check": "oxfmt --check .",
"lint": "oxlint", "lint": "oxlint",
"lint:fix": "oxlint --fix", "lint:fix": "oxlint --fix",
"knip": "knip", "knip": "knip",
@@ -160,10 +160,10 @@
}, },
"lint-staged": { "lint-staged": {
"*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}": [ "*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}": [
"prettier --write", "oxfmt",
"oxlint --fix" "oxlint --fix"
], ],
"*.{json,md,yml,yaml}": "prettier --write" "*.{json,md,yml,yaml}": "oxfmt"
}, },
"dependencies": { "dependencies": {
"@babel/parser": "8.0.4", "@babel/parser": "8.0.4",
@@ -208,8 +208,8 @@
"jscpd": "5.0.12", "jscpd": "5.0.12",
"knip": "6.26.0", "knip": "6.26.0",
"lint-staged": "16.4.0", "lint-staged": "16.4.0",
"oxfmt": "0.72.0",
"oxlint": "1.73.0", "oxlint": "1.73.0",
"prettier": "3.6.2",
"turbo": "2.10.5", "turbo": "2.10.5",
"typedoc": "0.28.20", "typedoc": "0.28.20",
"typescript": "5.9.3", "typescript": "5.9.3",
+5 -4
View File
@@ -2,7 +2,7 @@ import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { analysisErrorJsonSchema } from "../dist/contracts/errorSchemas.js"; import { analysisErrorJsonSchema } from "../dist/contracts/errorSchemas.js";
import { format } from "prettier"; import { formatGeneratedFile } from "./lib/format-generated-file.mjs";
import { ensureGeneratedFile } from "./lib/generated-file.mjs"; import { ensureGeneratedFile } from "./lib/generated-file.mjs";
const arguments_ = new Set(process.argv.slice(2)); const arguments_ = new Set(process.argv.slice(2));
@@ -13,9 +13,10 @@ for (const argument of arguments_)
const root = join(dirname(fileURLToPath(import.meta.url)), ".."); const root = join(dirname(fileURLToPath(import.meta.url)), "..");
await ensureGeneratedFile({ await ensureGeneratedFile({
path: join(root, "docs/error-contract.schema.json"), path: join(root, "docs/error-contract.schema.json"),
source: await format(JSON.stringify(analysisErrorJsonSchema), { source: await formatGeneratedFile(
parser: "json", "docs/error-contract.schema.json",
}), JSON.stringify(analysisErrorJsonSchema),
),
check: arguments_.has("--check"), check: arguments_.has("--check"),
generateCommand: "npm run docs:generate", generateCommand: "npm run docs:generate",
}); });
+3 -3
View File
@@ -1,6 +1,6 @@
import { dirname, join } from "node:path"; import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { format } from "prettier"; import { formatGeneratedFile } from "./lib/format-generated-file.mjs";
import { Client, InMemoryTransport } from "@modelcontextprotocol/client"; import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
import { Ajv2020 } from "ajv/dist/2020.js"; import { Ajv2020 } from "ajv/dist/2020.js";
import { McpServer } from "@modelcontextprotocol/server"; import { McpServer } from "@modelcontextprotocol/server";
@@ -110,7 +110,8 @@ const canonicalizeJson = (value) => {
const payloadJson = JSON.stringify( const payloadJson = JSON.stringify(
canonicalizeJson({ catalog, auxiliaryProviders }), canonicalizeJson({ catalog, auxiliaryProviders }),
); );
const source = await format( const source = await formatGeneratedFile(
"src/generatedMcpToolCatalog.ts",
`import type { ToolAnnotations } from "@modelcontextprotocol/server"; `import type { ToolAnnotations } from "@modelcontextprotocol/server";
import type { import type {
CapabilityDescriptor, CapabilityDescriptor,
@@ -194,7 +195,6 @@ function isRecord(
return typeof value === "object" && value !== null && !Array.isArray(value); return typeof value === "object" && value !== null && !Array.isArray(value);
} }
`, `,
{ parser: "typescript" },
); );
await ensureGeneratedFile({ await ensureGeneratedFile({
+12
View File
@@ -0,0 +1,12 @@
import { format } from "oxfmt";
import config from "../../.oxfmtrc.json" with { type: "json" };
/** Format generated source with the same options as the repository formatter. */
export const formatGeneratedFile = async (fileName, source) => {
const result = await format(fileName, source, config);
if (result.errors.length > 0)
throw new Error(
`Cannot format ${fileName}: ${result.errors.map(({ message }) => message).join("; ")}`,
);
return result.code;
};
+5 -2
View File
@@ -1,4 +1,4 @@
import { format } from "prettier"; import { formatGeneratedFile } from "./format-generated-file.mjs";
import { assertSameNames, digest, loadSources } from "./catalog-core.mjs"; import { assertSameNames, digest, loadSources } from "./catalog-core.mjs";
import { import {
@@ -67,4 +67,7 @@ export const createProductCatalog = async (root) => {
/** Stable checked-in representation of the product catalog. */ /** Stable checked-in representation of the product catalog. */
export const serializeProductCatalog = (catalog) => export const serializeProductCatalog = (catalog) =>
format(JSON.stringify(catalog, null, 2), { parser: "json" }); formatGeneratedFile(
"docs/product-catalog.json",
JSON.stringify(catalog, null, 2),
);
@@ -47,12 +47,10 @@ export async function verifySwitchEvidenceControls({
workspace, workspace,
runId, runId,
}) { }) {
const { spawnOwnedProviderProcess, ProviderProcessSupervisor } = await import( const { spawnOwnedProviderProcess, ProviderProcessSupervisor } =
"../dist/process/ProviderProcess.js" await import("../dist/process/ProviderProcess.js");
); const { cleanupOwnedProcessGroup } =
const { cleanupOwnedProcessGroup } = await import( await import("../dist/process/ProcessOwnership.js");
"../dist/process/ProcessOwnership.js"
);
const bridge = await realpath( const bridge = await realpath(
join(dirname(entrypoint), "../bridge/ghidra/ReaGhidraBridge.java"), join(dirname(entrypoint), "../bridge/ghidra/ReaGhidraBridge.java"),
); );
+2 -3
View File
@@ -67,9 +67,8 @@ for (const [role, command] of Object.entries(commands)) {
} }
let installation; let installation;
if (!compilerOnly) { if (!compilerOnly) {
const { inspectGhidraInstallation } = await import( const { inspectGhidraInstallation } =
"../dist/ghidra/GhidraInstallation.js" await import("../dist/ghidra/GhidraInstallation.js");
);
assert.ok( assert.ok(
process.env.GHIDRA_INSTALL_DIR, process.env.GHIDRA_INSTALL_DIR,
"Ghidra switch lane prerequisite missing: GHIDRA_INSTALL_DIR (bring your own)", "Ghidra switch lane prerequisite missing: GHIDRA_INSTALL_DIR (bring your own)",
+15 -17
View File
@@ -245,23 +245,21 @@ const setupPlan = (input: {
: []), : []),
...input.clients ...input.clients
.filter(({ client }) => client.format !== "unsupported") .filter(({ client }) => client.format !== "unsupported")
.map( .map(({ client, operation, backupPath }): SetupAction => ({
({ client, operation, backupPath }): SetupAction => ({ id: `configure_client:${client.name}`,
id: `configure_client:${client.name}`, kind: "configure_client",
kind: "configure_client", label: client.displayName ?? client.name,
label: client.displayName ?? client.name, target: client.configPath,
target: client.configPath, detail: clientConfigurationDetail(
detail: clientConfigurationDetail( client.displayName ?? client.name,
client.displayName ?? client.name, input.command,
input.command, input.providerEnvironment,
input.providerEnvironment, input.installHopper,
input.installHopper, ),
), external: false,
external: false, operation,
operation, ...(backupPath === undefined ? {} : { backupPath }),
...(backupPath === undefined ? {} : { backupPath }), })),
}),
),
...(input.installSkill ...(input.installSkill
? [ ? [
{ {
+6 -9
View File
@@ -45,21 +45,18 @@ export const createBinarySession = (
new AnalysisProviderRegistry([hopper, ghidra], config.analysisProvider), new AnalysisProviderRegistry([hopper, ghidra], config.analysisProvider),
[ [
lazyProvider("rea-artifact-graph", async () => { lazyProvider("rea-artifact-graph", async () => {
const { ArtifactProvider } = await import( const { ArtifactProvider } =
"../artifacts/ArtifactProvider.js" await import("../artifacts/ArtifactProvider.js");
);
return new ArtifactProvider(); return new ArtifactProvider();
}), }),
lazyProvider("native-macos", async () => { lazyProvider("native-macos", async () => {
const { NativeMacOSProvider } = await import( const { NativeMacOSProvider } =
"../native/NativeMacOSProvider.js" await import("../native/NativeMacOSProvider.js");
);
return new NativeMacOSProvider(); return new NativeMacOSProvider();
}), }),
lazyProvider("rea-dotnet-static", async () => { lazyProvider("rea-dotnet-static", async () => {
const { ManagedStaticProvider } = await import( const { ManagedStaticProvider } =
"../dotnet/ManagedStaticProvider.js" await import("../dotnet/ManagedStaticProvider.js");
);
return new ManagedStaticProvider(); return new ManagedStaticProvider();
}), }),
], ],
@@ -311,9 +311,7 @@ const runScenario = async (
}; };
/** Controlled Playwright/CDP scenario driver with exact process ownership. */ /** Controlled Playwright/CDP scenario driver with exact process ownership. */
export class PlaywrightBrowserScenarioProvider export class PlaywrightBrowserScenarioProvider implements BrowserScenarioCapturePort {
implements BrowserScenarioCapturePort
{
constructor( constructor(
private readonly factory: BrowserScenarioSessionFactory = lazyPlaywrightFactory, private readonly factory: BrowserScenarioSessionFactory = lazyPlaywrightFactory,
) {} ) {}
@@ -305,13 +305,11 @@ export const readApplicationState = async (
}> => { }> => {
const pages = application.windows(); const pages = application.windows();
const pageSnapshotsPromise: Promise<ElectronPageSnapshot[]> = Promise.all( const pageSnapshotsPromise: Promise<ElectronPageSnapshot[]> = Promise.all(
pages.map( pages.map(async (page: Page, index): Promise<ElectronPageSnapshot> => ({
async (page: Page, index): Promise<ElectronPageSnapshot> => ({ index,
index, url: page.url(),
url: page.url(), title: await page.title(),
title: await page.title(), })),
}),
),
); );
const windowMetadataPromise: Promise<ElectronWindowMetadata[]> = application const windowMetadataPromise: Promise<ElectronWindowMetadata[]> = application
.evaluate(({ BrowserWindow }) => .evaluate(({ BrowserWindow }) =>
@@ -146,9 +146,7 @@ const createCoverage = (hookSnapshot: ElectronHookSnapshot) => {
}; };
/** Launch an owned Electron application through the official Playwright API. */ /** Launch an owned Electron application through the official Playwright API. */
export class PlaywrightElectronActiveProvider export class PlaywrightElectronActiveProvider implements ElectronActiveObservationPort {
implements ElectronActiveObservationPort
{
identity(): ProviderIdentity { identity(): ProviderIdentity {
return PLAYWRIGHT_ELECTRON_ACTIVE_PROVIDER_IDENTITY; return PLAYWRIGHT_ELECTRON_ACTIVE_PROVIDER_IDENTITY;
} }
+1 -3
View File
@@ -274,9 +274,7 @@ export class PlaywrightScenarioSession implements BrowserScenarioSessionPort {
} }
/** Production Playwright/CDP session factory. */ /** Production Playwright/CDP session factory. */
export class PlaywrightScenarioSessionFactory export class PlaywrightScenarioSessionFactory implements BrowserScenarioSessionFactory {
implements BrowserScenarioSessionFactory
{
constructor( constructor(
private readonly environment: Readonly< private readonly environment: Readonly<
Record<string, string | undefined> Record<string, string | undefined>
+16 -18
View File
@@ -102,24 +102,22 @@ export const projectAppleAssetCatalogPage = (input: {
}[]; }[];
}) => { }) => {
const all = input.catalogs.flatMap((catalog) => const all = input.catalogs.flatMap((catalog) =>
catalog.records.map( catalog.records.map((metadata, index): AppleAssetCatalogRecord => ({
(metadata, index): AppleAssetCatalogRecord => ({ catalog_path: catalog.path,
catalog_path: catalog.path, catalog_sha256: catalog.sha256,
catalog_sha256: catalog.sha256, index,
index, kind:
kind: typeof metadata.RenditionName === "string" ||
typeof metadata.RenditionName === "string" || typeof metadata.Name === "string"
typeof metadata.Name === "string" ? "rendition"
? "rendition" : "catalog",
: "catalog", asset_name: typeof metadata.Name === "string" ? metadata.Name : null,
asset_name: typeof metadata.Name === "string" ? metadata.Name : null, rendition_name:
rendition_name: typeof metadata.RenditionName === "string"
typeof metadata.RenditionName === "string" ? metadata.RenditionName
? metadata.RenditionName : null,
: null, metadata,
metadata, })),
}),
),
); );
const records = all.slice(input.offset, input.offset + input.limit); const records = all.slice(input.offset, input.offset + input.limit);
const next = input.offset + records.length; const next = input.offset + records.length;
+3 -2
View File
@@ -478,8 +478,9 @@ export class BinaryTargetError extends AnalysisError {
} }
} }
export interface AnalysisErrorProjection export interface AnalysisErrorProjection extends Readonly<
extends Readonly<Record<string, JsonValue>> { Record<string, JsonValue>
> {
readonly code: readonly code:
| "invalid_request" | "invalid_request"
| "unreadable_output" | "unreadable_output"
@@ -47,8 +47,8 @@ type OneSidedNode =
}; };
type ComparisonItemSemantic< type ComparisonItemSemantic<
Item extends Item extends ApplicationVersionComparisonItem =
ApplicationVersionComparisonItem = ApplicationVersionComparisonItem, ApplicationVersionComparisonItem,
> = Item extends ApplicationVersionComparisonItem > = Item extends ApplicationVersionComparisonItem
? Omit<Item, "item_id"> ? Omit<Item, "item_id">
: never; : never;
+2 -4
View File
@@ -55,8 +55,7 @@ interface GhidraInstallationObservation {
} }
/** Bounded observation of a supported BYO Ghidra installation and JDK. */ /** Bounded observation of a supported BYO Ghidra installation and JDK. */
export interface AvailableGhidraInstallation export interface AvailableGhidraInstallation extends GhidraInstallationObservation {
extends GhidraInstallationObservation {
readonly status: "available"; readonly status: "available";
readonly installDir: string; readonly installDir: string;
readonly analyzeHeadlessPath: string; readonly analyzeHeadlessPath: string;
@@ -67,8 +66,7 @@ export interface AvailableGhidraInstallation
} }
/** Bounded observation explaining why a BYO Ghidra installation is unusable. */ /** Bounded observation explaining why a BYO Ghidra installation is unusable. */
export interface UnavailableGhidraInstallation export interface UnavailableGhidraInstallation extends GhidraInstallationObservation {
extends GhidraInstallationObservation {
readonly status: "unavailable"; readonly status: "unavailable";
readonly installDir: string | null; readonly installDir: string | null;
readonly analyzeHeadlessPath: string | null; readonly analyzeHeadlessPath: string | null;