@seqyuan/annodex 0.1.53 → 0.1.55
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +11 -11
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.js +3 -1
- package/.next/required-server-files.json +3 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/api/internal/runtime/route.js +1 -1
- package/.next/server/app/api/version/route.js +1 -1
- package/.next/server/app/docs/changelog.html +2 -2
- package/.next/server/app/docs/changelog.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/_full.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/_head.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/_index.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/docs/changelog/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/docs/changelog.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/docs.segment.rsc +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +1 -1
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/login.html +1 -1
- package/.next/server/app/login.rsc +1 -1
- package/.next/server/app/login.segments/_full.segment.rsc +1 -1
- package/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/server/app/login.segments/_index.segment.rsc +1 -1
- package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/.next/server/app/workspace/page.js +3 -3
- package/.next/server/app/workspace/page_client-reference-manifest.js +1 -1
- package/.next/server/app/workspace.html +1 -1
- package/.next/server/app/workspace.rsc +2 -2
- package/.next/server/app/workspace.segments/_full.segment.rsc +2 -2
- package/.next/server/app/workspace.segments/_head.segment.rsc +1 -1
- package/.next/server/app/workspace.segments/_index.segment.rsc +1 -1
- package/.next/server/app/workspace.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/workspace.segments/workspace/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/workspace.segments/workspace.segment.rsc +1 -1
- package/.next/server/app-paths-manifest.json +11 -11
- package/.next/server/chunks/6983.js +12 -5
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/app/workspace/{page-d1366e4f9b7a7a15.js → page-249489e08420f59d.js} +3 -3
- package/bin/annodex.js +299 -0
- package/lib/macos-codex-security.js +376 -0
- package/next.config.ts +1 -1
- package/package.json +2 -1
- /package/.next/static/{ZR0UxSLWFSPEwsYD3WfeI → vW2g3YlVaZErFy9-fsfCO}/_buildManifest.js +0 -0
- /package/.next/static/{ZR0UxSLWFSPEwsYD3WfeI → vW2g3YlVaZErFy9-fsfCO}/_ssgManifest.js +0 -0
package/bin/annodex.js
CHANGED
|
@@ -27,6 +27,7 @@ const https = require("https");
|
|
|
27
27
|
const { randomBytes } = require("crypto");
|
|
28
28
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
29
29
|
const { readAppSettings, ensureAppSettings } = require("../lib/app-settings.js");
|
|
30
|
+
const macosCodexSecurity = require("../lib/macos-codex-security.js");
|
|
30
31
|
|
|
31
32
|
const pkgDir = path.join(__dirname, "..");
|
|
32
33
|
const nextDir = path.join(pkgDir, ".next");
|
|
@@ -82,6 +83,7 @@ const { values: cliArgs, positionals } = parseArgs({
|
|
|
82
83
|
hostname: { type: "string", short: "H" },
|
|
83
84
|
json: { type: "boolean" },
|
|
84
85
|
follow: { type: "boolean", short: "f" },
|
|
86
|
+
repair: { type: "boolean" },
|
|
85
87
|
version: { type: "boolean", short: "v" },
|
|
86
88
|
help: { type: "boolean", short: "h" },
|
|
87
89
|
},
|
|
@@ -719,6 +721,298 @@ function spawnDetachedServer(extraEnv = {}, overridePort, overrideHost) {
|
|
|
719
721
|
return child;
|
|
720
722
|
}
|
|
721
723
|
|
|
724
|
+
|
|
725
|
+
function commandOutput(command, args, options = {}) {
|
|
726
|
+
try {
|
|
727
|
+
const result = spawnSync(command, args, {
|
|
728
|
+
encoding: "utf8",
|
|
729
|
+
timeout: options.timeout ?? 5000,
|
|
730
|
+
windowsHide: true,
|
|
731
|
+
...options,
|
|
732
|
+
});
|
|
733
|
+
return {
|
|
734
|
+
ok: result.status === 0,
|
|
735
|
+
status: result.status,
|
|
736
|
+
signal: result.signal,
|
|
737
|
+
stdout: (result.stdout || "").trim(),
|
|
738
|
+
stderr: (result.stderr || "").trim(),
|
|
739
|
+
error: result.error ? result.error.message : null,
|
|
740
|
+
};
|
|
741
|
+
} catch (error) {
|
|
742
|
+
return { ok: false, status: null, signal: null, stdout: "", stderr: "", error: error instanceof Error ? error.message : String(error) };
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
function getNpmPrefix() {
|
|
747
|
+
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
748
|
+
const result = commandOutput(npm, ["prefix", "-g"], { timeout: 3000 });
|
|
749
|
+
return result.ok && result.stdout ? result.stdout.split(/\r?\n/)[0].trim() : null;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
function codexPackageInfo() {
|
|
753
|
+
const platform = process.platform;
|
|
754
|
+
const arch = process.arch;
|
|
755
|
+
let pkgName = null;
|
|
756
|
+
let triple = null;
|
|
757
|
+
if (platform === "darwin") {
|
|
758
|
+
if (arch === "arm64") { pkgName = "codex-darwin-arm64"; triple = "aarch64-apple-darwin"; }
|
|
759
|
+
else if (arch === "x64") { pkgName = "codex-darwin-x64"; triple = "x86_64-apple-darwin"; }
|
|
760
|
+
} else if (platform === "linux") {
|
|
761
|
+
if (arch === "arm64") { pkgName = "codex-linux-arm64"; triple = "aarch64-unknown-linux-musl"; }
|
|
762
|
+
else if (arch === "x64") { pkgName = "codex-linux-x64"; triple = "x86_64-unknown-linux-musl"; }
|
|
763
|
+
} else if (platform === "win32") {
|
|
764
|
+
if (arch === "arm64") { pkgName = "codex-win32-arm64"; triple = "aarch64-pc-windows-msvc"; }
|
|
765
|
+
else if (arch === "x64") { pkgName = "codex-win32-x64"; triple = "x86_64-pc-windows-msvc"; }
|
|
766
|
+
}
|
|
767
|
+
return { pkgName, triple, binaryName: platform === "win32" ? "codex.exe" : "codex" };
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
function resolveCodexNativeCandidates() {
|
|
771
|
+
const { pkgName, triple, binaryName } = codexPackageInfo();
|
|
772
|
+
if (!pkgName || !triple) return [];
|
|
773
|
+
const roots = [
|
|
774
|
+
path.join(process.cwd(), "node_modules"),
|
|
775
|
+
path.join(pkgDir, "node_modules"),
|
|
776
|
+
];
|
|
777
|
+
const npmPrefix = getNpmPrefix();
|
|
778
|
+
if (npmPrefix) roots.push(path.join(npmPrefix, "lib", "node_modules"));
|
|
779
|
+
const installedDir = getInstalledPackageDir();
|
|
780
|
+
roots.push(path.join(installedDir, "node_modules"));
|
|
781
|
+
roots.push(path.join(installedDir, "..", "..", "node_modules"));
|
|
782
|
+
const seen = new Set();
|
|
783
|
+
const out = [];
|
|
784
|
+
const subPaths = [
|
|
785
|
+
path.join("vendor", triple, "bin", binaryName),
|
|
786
|
+
path.join("vendor", triple, "codex", binaryName),
|
|
787
|
+
];
|
|
788
|
+
for (const root of roots) {
|
|
789
|
+
for (const layout of ["flat", "nested"]) {
|
|
790
|
+
const pkgRoot = layout === "flat"
|
|
791
|
+
? path.join(root, "@openai", pkgName)
|
|
792
|
+
: path.join(root, "@openai", "codex", "node_modules", "@openai", pkgName);
|
|
793
|
+
for (const sub of subPaths) {
|
|
794
|
+
const candidate = path.join(pkgRoot, sub);
|
|
795
|
+
if (seen.has(candidate)) continue;
|
|
796
|
+
seen.add(candidate);
|
|
797
|
+
if (fs.existsSync(candidate)) out.push(candidate);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
return out;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
function resolveCodexShimCandidates() {
|
|
805
|
+
const names = process.platform === "win32" ? ["codex.cmd", "codex.exe", "codex"] : ["codex"];
|
|
806
|
+
const dirs = [path.join(process.cwd(), "node_modules", ".bin"), path.join(pkgDir, "node_modules", ".bin")];
|
|
807
|
+
const npmPrefix = getNpmPrefix();
|
|
808
|
+
if (npmPrefix) dirs.push(process.platform === "win32" ? npmPrefix : path.join(npmPrefix, "bin"));
|
|
809
|
+
const installedDir = getInstalledPackageDir();
|
|
810
|
+
dirs.push(path.join(installedDir, "node_modules", ".bin"));
|
|
811
|
+
dirs.push(path.join(installedDir, "..", "..", ".bin"));
|
|
812
|
+
const seen = new Set();
|
|
813
|
+
const out = [];
|
|
814
|
+
for (const dir of dirs) {
|
|
815
|
+
for (const name of names) {
|
|
816
|
+
const candidate = path.join(dir, name);
|
|
817
|
+
if (!seen.has(candidate) && fs.existsSync(candidate)) {
|
|
818
|
+
seen.add(candidate);
|
|
819
|
+
out.push(candidate);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
const which = commandOutput(process.platform === "win32" ? "where" : "which", ["codex"], { timeout: 3000 });
|
|
824
|
+
if (which.ok && which.stdout) {
|
|
825
|
+
for (const line of which.stdout.split(/\r?\n/).map((v) => v.trim()).filter(Boolean)) {
|
|
826
|
+
if (!seen.has(line) && fs.existsSync(line)) {
|
|
827
|
+
seen.add(line);
|
|
828
|
+
out.push(line);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
return out;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
function xattrInfo(target) {
|
|
836
|
+
if (process.platform !== "darwin" || !target) return null;
|
|
837
|
+
const result = commandOutput("xattr", [target], { timeout: 3000 });
|
|
838
|
+
return {
|
|
839
|
+
ok: result.ok,
|
|
840
|
+
hasQuarantine: /com\.apple\.quarantine/.test(result.stdout),
|
|
841
|
+
attributes: result.stdout ? result.stdout.split(/\r?\n/).filter(Boolean) : [],
|
|
842
|
+
error: result.ok ? null : (result.stderr || result.error),
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function spctlAssess(target) {
|
|
847
|
+
if (process.platform !== "darwin" || !target) return null;
|
|
848
|
+
const result = commandOutput("spctl", ["--assess", "--verbose", target], { timeout: 5000 });
|
|
849
|
+
return {
|
|
850
|
+
accepted: result.ok || /accepted/i.test(`${result.stdout}\n${result.stderr}`),
|
|
851
|
+
status: result.status,
|
|
852
|
+
output: `${result.stdout}${result.stderr ? `\n${result.stderr}` : ""}`.trim(),
|
|
853
|
+
error: result.error,
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
function selectedCodexPath(nativeCandidates, shimCandidates) {
|
|
858
|
+
const envPath = process.env.ANNODEX_CODEX_PATH?.trim();
|
|
859
|
+
if (envPath) return { path: envPath, source: "ANNODEX_CODEX_PATH", exists: fs.existsSync(envPath) };
|
|
860
|
+
if (nativeCandidates[0]) return { path: nativeCandidates[0], source: "native-candidate", exists: true };
|
|
861
|
+
if (shimCandidates[0]) return { path: shimCandidates[0], source: "shim-candidate", exists: true };
|
|
862
|
+
return { path: process.platform === "win32" ? "codex.cmd" : "codex", source: "PATH fallback", exists: null };
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
function detectMacOSVersion() {
|
|
866
|
+
if (process.platform !== "darwin") return null;
|
|
867
|
+
const result = commandOutput("sw_vers", ["-productVersion"], { timeout: 3000 });
|
|
868
|
+
return result.ok ? result.stdout : null;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
function macOSProtectedLocationInfo(targetPath) {
|
|
872
|
+
if (process.platform !== "darwin" || !targetPath) return null;
|
|
873
|
+
const real = safeRealpath(targetPath);
|
|
874
|
+
const home = os.homedir();
|
|
875
|
+
const protectedRoots = [
|
|
876
|
+
{ label: "Desktop", path: path.join(home, "Desktop") },
|
|
877
|
+
{ label: "Documents", path: path.join(home, "Documents") },
|
|
878
|
+
{ label: "Downloads", path: path.join(home, "Downloads") },
|
|
879
|
+
{ label: "iCloud Drive", path: path.join(home, "Library", "Mobile Documents") },
|
|
880
|
+
];
|
|
881
|
+
const match = protectedRoots.find((root) => isPathInside(real, root.path));
|
|
882
|
+
return {
|
|
883
|
+
path: real,
|
|
884
|
+
inProtectedLocation: Boolean(match),
|
|
885
|
+
root: match?.label ?? null,
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
function runDoctor(json = false, repair = false) {
|
|
890
|
+
const nativeCandidates = resolveCodexNativeCandidates();
|
|
891
|
+
const shimCandidates = resolveCodexShimCandidates();
|
|
892
|
+
const selected = selectedCodexPath(nativeCandidates, shimCandidates);
|
|
893
|
+
const selectedReal = selected.exists ? safeRealpath(selected.path) : selected.path;
|
|
894
|
+
|
|
895
|
+
let repairResults = null;
|
|
896
|
+
if (repair && process.platform === "darwin") {
|
|
897
|
+
macosCodexSecurity.clearMacOSQuarantine(process.cwd());
|
|
898
|
+
const repairPaths = [...new Set([
|
|
899
|
+
...nativeCandidates,
|
|
900
|
+
selected.exists ? selected.path : null,
|
|
901
|
+
].filter(Boolean))];
|
|
902
|
+
repairResults = macosCodexSecurity.repairMacOSCodexPaths(repairPaths);
|
|
903
|
+
if (!json) {
|
|
904
|
+
console.log("repair:");
|
|
905
|
+
for (const item of repairResults) {
|
|
906
|
+
if (item.skipped) {
|
|
907
|
+
console.log(`- ${item.path}: skipped (no revoked cert)`);
|
|
908
|
+
} else {
|
|
909
|
+
console.log(`- ${item.path}: ${item.repair?.ok ? "repaired" : "failed"}`);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
console.log("");
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
const transport = (process.env.ANNODEX_CODEX_TRANSPORT || "auto").toLowerCase();
|
|
917
|
+
const resolvedTransport = transport === "ws" || transport === "stdio" ? transport : (process.platform === "linux" ? "ws" : "stdio");
|
|
918
|
+
const versionProbe = selected.path
|
|
919
|
+
? commandOutput(selected.path, ["--version"], { timeout: 15000 })
|
|
920
|
+
: null;
|
|
921
|
+
const report = {
|
|
922
|
+
annodex: { version: VERSION, packageName: PKG_NAME, packageDir: pkgDir, installedPackageDir: getInstalledPackageDir() },
|
|
923
|
+
platform: { platform: process.platform, arch: process.arch, macOSVersion: detectMacOSVersion() },
|
|
924
|
+
node: { version: process.version, execPath: process.execPath, cwd: process.cwd() },
|
|
925
|
+
appBundle: { enabled: process.env.ANNODEX_APP_BUNDLE === "1", env: process.env.ANNODEX_APP_BUNDLE || null },
|
|
926
|
+
workspace: {
|
|
927
|
+
packageDir: safeRealpath(pkgDir),
|
|
928
|
+
cwd: safeRealpath(process.cwd()),
|
|
929
|
+
packageDirMacOSProtection: macOSProtectedLocationInfo(pkgDir),
|
|
930
|
+
cwdMacOSProtection: macOSProtectedLocationInfo(process.cwd()),
|
|
931
|
+
},
|
|
932
|
+
config: { configDir: agentDir, logFile, npmPrefix: getNpmPrefix() },
|
|
933
|
+
transport: { requested: process.env.ANNODEX_CODEX_TRANSPORT || "auto", resolved: resolvedTransport },
|
|
934
|
+
codex: {
|
|
935
|
+
envPath: process.env.ANNODEX_CODEX_PATH || null,
|
|
936
|
+
selected: { ...selected, realpath: selectedReal },
|
|
937
|
+
nativeCandidates,
|
|
938
|
+
shimCandidates,
|
|
939
|
+
selectedXattr: xattrInfo(selected.exists ? selected.path : null),
|
|
940
|
+
selectedCodesign: selected.exists
|
|
941
|
+
? macosCodexSecurity.codesignVerify(selected.path)
|
|
942
|
+
: null,
|
|
943
|
+
selectedSpctl: spctlAssess(selected.exists ? selected.path : null),
|
|
944
|
+
versionProbe: versionProbe ? {
|
|
945
|
+
ok: versionProbe.ok,
|
|
946
|
+
status: versionProbe.status,
|
|
947
|
+
signal: versionProbe.signal,
|
|
948
|
+
stdout: versionProbe.stdout,
|
|
949
|
+
stderr: versionProbe.stderr,
|
|
950
|
+
error: versionProbe.error,
|
|
951
|
+
} : null,
|
|
952
|
+
},
|
|
953
|
+
recommendations: [],
|
|
954
|
+
repair: repairResults,
|
|
955
|
+
};
|
|
956
|
+
if (process.platform === "darwin") {
|
|
957
|
+
if (!report.appBundle.enabled) report.recommendations.push("macOS: not launched from Annodex.app; CLI mode is diagnostic/advanced until the launcher PoC is validated.");
|
|
958
|
+
if (report.appBundle.enabled && report.workspace.packageDirMacOSProtection?.inProtectedLocation) {
|
|
959
|
+
report.recommendations.push(`macOS: Annodex.app is reading source/runtime files from ${report.workspace.packageDirMacOSProtection.root}. Finder-launched apps may hit TCC EPERM there. Move the repo/runtime outside protected folders or bundle the runtime into Annodex.app before evaluating launcher viability.`);
|
|
960
|
+
}
|
|
961
|
+
if (report.codex.selectedXattr?.hasQuarantine) report.recommendations.push("macOS: selected codex path has com.apple.quarantine. Run `annodex doctor --repair` or restart annodex (xattr is cleared automatically on codex spawn).");
|
|
962
|
+
if (report.codex.selectedCodesign?.revoked || (report.codex.selectedSpctl?.output && macosCodexSecurity.needsRevokedCertRepair(report.codex.selectedSpctl.output))) {
|
|
963
|
+
report.recommendations.push("macOS: codex binary has a revoked Developer ID signature (CSSMERR_TP_CERT_REVOKED). Run `annodex doctor --repair` to strip and apply ad-hoc signing, then retry codex --version.");
|
|
964
|
+
} else if (report.codex.selectedSpctl && !report.codex.selectedSpctl.accepted && versionProbe && !versionProbe.ok) {
|
|
965
|
+
report.recommendations.push("macOS: spctl assessment did not accept the selected codex binary and codex --version failed. Try `annodex doctor --repair` for ad-hoc signing.");
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
if (report.codex.selected.exists === false) report.recommendations.push("ANNODEX_CODEX_PATH is set but does not exist. Fix or unset it.");
|
|
969
|
+
if (versionProbe && !versionProbe.ok) report.recommendations.push("codex --version probe failed. Check the selected codex path and macOS security dialogs/logs.");
|
|
970
|
+
|
|
971
|
+
if (json) {
|
|
972
|
+
console.log(JSON.stringify(report, null, 2));
|
|
973
|
+
return versionProbe && !versionProbe.ok ? 1 : 0;
|
|
974
|
+
}
|
|
975
|
+
console.log(`annodex doctor v${VERSION}`);
|
|
976
|
+
console.log(`platform: ${process.platform}/${process.arch}${report.platform.macOSVersion ? ` macOS ${report.platform.macOSVersion}` : ""}`);
|
|
977
|
+
console.log(`node: ${process.version} ${process.execPath}`);
|
|
978
|
+
console.log(`app bundle: ${report.appBundle.enabled ? "yes" : "no"}`);
|
|
979
|
+
if (report.workspace.packageDirMacOSProtection?.inProtectedLocation) {
|
|
980
|
+
console.log(`package dir protection: ${report.workspace.packageDirMacOSProtection.root}`);
|
|
981
|
+
}
|
|
982
|
+
if (report.workspace.cwdMacOSProtection?.inProtectedLocation) {
|
|
983
|
+
console.log(`cwd protection: ${report.workspace.cwdMacOSProtection.root}`);
|
|
984
|
+
}
|
|
985
|
+
console.log(`config dir: ${agentDir}`);
|
|
986
|
+
console.log(`transport: requested=${report.transport.requested} resolved=${report.transport.resolved}`);
|
|
987
|
+
console.log(`codex selected: ${selected.path} (${selected.source}, exists=${selected.exists})`);
|
|
988
|
+
if (selectedReal && selectedReal !== selected.path) console.log(`codex realpath: ${selectedReal}`);
|
|
989
|
+
console.log(`native candidates: ${nativeCandidates.length ? nativeCandidates.join("; ") : "none"}`);
|
|
990
|
+
console.log(`shim candidates: ${shimCandidates.length ? shimCandidates.join("; ") : "none"}`);
|
|
991
|
+
if (report.codex.selectedXattr) {
|
|
992
|
+
console.log(`xattr quarantine: ${report.codex.selectedXattr.hasQuarantine ? "yes" : "no"}`);
|
|
993
|
+
if (report.codex.selectedXattr.attributes.length) console.log(`xattr attributes: ${report.codex.selectedXattr.attributes.join(", ")}`);
|
|
994
|
+
}
|
|
995
|
+
if (report.codex.selectedCodesign) {
|
|
996
|
+
console.log(`codesign verify: ${report.codex.selectedCodesign.ok ? "ok" : "failed"}${report.codex.selectedCodesign.revoked ? " (revoked cert)" : ""}`);
|
|
997
|
+
if (report.codex.selectedCodesign.output) console.log(`codesign output: ${report.codex.selectedCodesign.output}`);
|
|
998
|
+
}
|
|
999
|
+
if (report.codex.selectedSpctl) {
|
|
1000
|
+
console.log(`spctl accepted: ${report.codex.selectedSpctl.accepted ? "yes" : "no"}`);
|
|
1001
|
+
if (report.codex.selectedSpctl.output) console.log(`spctl output: ${report.codex.selectedSpctl.output}`);
|
|
1002
|
+
}
|
|
1003
|
+
if (versionProbe) {
|
|
1004
|
+
console.log(`codex --version: ${versionProbe.ok ? "ok" : "failed"}${versionProbe.signal ? ` signal=${versionProbe.signal}` : ""}`);
|
|
1005
|
+
if (versionProbe.stdout) console.log(` stdout: ${versionProbe.stdout}`);
|
|
1006
|
+
if (versionProbe.stderr) console.log(` stderr: ${versionProbe.stderr}`);
|
|
1007
|
+
if (versionProbe.error) console.log(` error: ${versionProbe.error}`);
|
|
1008
|
+
}
|
|
1009
|
+
if (report.recommendations.length) {
|
|
1010
|
+
console.log("recommendations:");
|
|
1011
|
+
for (const item of report.recommendations) console.log(`- ${item}`);
|
|
1012
|
+
}
|
|
1013
|
+
return versionProbe && !versionProbe.ok ? 1 : 0;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
722
1016
|
if (cliArgs.version) {
|
|
723
1017
|
console.log(VERSION);
|
|
724
1018
|
process.exit(0);
|
|
@@ -734,6 +1028,7 @@ Usage:
|
|
|
734
1028
|
annodex stop Stop background annodex
|
|
735
1029
|
annodex status [--json] Show background server status
|
|
736
1030
|
annodex logs [-f] Show background server logs
|
|
1031
|
+
annodex doctor [--json] [--repair] Diagnose local codex/runtime setup
|
|
737
1032
|
annodex passwd Set or change password (empty = disable auth)
|
|
738
1033
|
annodex update Update to the latest version
|
|
739
1034
|
|
|
@@ -749,6 +1044,10 @@ Options:
|
|
|
749
1044
|
}
|
|
750
1045
|
|
|
751
1046
|
const firstPos = positionals[0];
|
|
1047
|
+
if (firstPos === "doctor") {
|
|
1048
|
+
process.exit(runDoctor(cliArgs.json, cliArgs.repair));
|
|
1049
|
+
}
|
|
1050
|
+
|
|
752
1051
|
if (firstPos === "status") {
|
|
753
1052
|
const json = cliArgs.json;
|
|
754
1053
|
staleStateRemoved();
|