@socketsecurity/lib 6.0.6 → 6.0.8
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/CHANGELOG.md +46 -1
- package/README.md +1 -1
- package/dist/ai/agent-context.d.mts +103 -0
- package/dist/ai/agent-context.js +157 -0
- package/dist/ai/backends.d.mts +83 -0
- package/dist/ai/backends.js +173 -0
- package/dist/ai/credentials.d.mts +49 -0
- package/dist/ai/credentials.js +82 -0
- package/dist/ai/discover.d.mts +6 -2
- package/dist/ai/discover.js +4 -3
- package/dist/ai/exec.d.mts +52 -0
- package/dist/ai/exec.js +92 -0
- package/dist/ai/http.d.mts +132 -0
- package/dist/ai/http.js +130 -0
- package/dist/ai/profiles.d.mts +41 -6
- package/dist/ai/profiles.js +52 -10
- package/dist/ai/route.d.mts +69 -0
- package/dist/ai/route.js +156 -0
- package/dist/ai/spawn.d.mts +10 -2
- package/dist/ai/spawn.js +56 -31
- package/dist/ai/subagent-status.d.mts +48 -0
- package/dist/ai/subagent-status.js +57 -0
- package/dist/ai/tier.d.mts +60 -0
- package/dist/ai/tier.js +53 -0
- package/dist/ai/types.d.mts +31 -6
- package/dist/ai/worktree.d.mts +6 -6
- package/dist/ai/worktree.js +5 -1
- package/dist/ansi/strip.d.ts +1 -1
- package/dist/ansi/strip.js +0 -2
- package/dist/archives/_internal.js +7 -9
- package/dist/archives/extract.js +1 -1
- package/dist/archives/tar.js +7 -7
- package/dist/archives/zip.js +5 -7
- package/dist/argv/flag-predicates.d.ts +12 -12
- package/dist/argv/flag-predicates.js +17 -17
- package/dist/argv/flag-types.d.ts +18 -18
- package/dist/argv/flag-types.js +4 -4
- package/dist/argv/parse.d.ts +20 -3
- package/dist/argv/parse.js +1 -1
- package/dist/arrays/_internal.js +11 -12
- package/dist/arrays/chunk.js +0 -1
- package/dist/arrays/join.d.ts +37 -3
- package/dist/arrays/join.js +47 -7
- package/dist/arrays/unique.js +0 -1
- package/dist/bin/_internal.d.ts +1 -1
- package/dist/bin/_internal.js +1 -1
- package/dist/bin/exec.js +2 -3
- package/dist/bin/find.js +17 -17
- package/dist/bin/prim.cjs +36175 -35861
- package/dist/bin/resolve.js +13 -14
- package/dist/bin/which.js +8 -8
- package/dist/cache/ttl/store.js +6 -6
- package/dist/checks/primordials-defaults.d.ts +3 -3
- package/dist/checks/primordials-defaults.js +3 -3
- package/dist/checks/primordials.js +4 -3
- package/dist/{bin → cli}/check-primordials.d.ts +18 -13
- package/dist/{bin → cli}/check-primordials.js +58 -55
- package/dist/{bin → cli}/check.js +3 -3
- package/dist/{bin → cli}/socket-lib.d.ts +1 -1
- package/dist/{bin → cli}/socket-lib.js +4 -4
- package/dist/colors/socket-palette.js +7 -9
- package/dist/compression/_internal.d.ts +12 -12
- package/dist/compression/_internal.js +18 -18
- package/dist/compression/brotli.d.ts +26 -27
- package/dist/compression/brotli.js +39 -35
- package/dist/compression/gzip.d.ts +23 -23
- package/dist/compression/gzip.js +46 -42
- package/dist/constants/agents.d.ts +3 -1
- package/dist/constants/agents.js +15 -11
- package/dist/constants/licenses.js +3 -3
- package/dist/constants/node.d.ts +23 -0
- package/dist/constants/node.js +47 -15
- package/dist/constants/packages.d.ts +3 -0
- package/dist/constants/packages.js +24 -29
- package/dist/constants/platform.d.ts +30 -3
- package/dist/constants/platform.js +72 -12
- package/dist/constants/runtime.d.ts +22 -0
- package/dist/constants/runtime.js +32 -0
- package/dist/constants/socket.d.ts +2 -6
- package/dist/constants/socket.js +12 -14
- package/dist/cover/code.js +10 -10
- package/dist/cover/formatters.js +5 -5
- package/dist/crypto/hash.d.ts +30 -2
- package/dist/crypto/hash.js +47 -13
- package/dist/debug/_internal.js +4 -6
- package/dist/debug/caller-info.js +3 -4
- package/dist/debug/namespace.d.ts +7 -0
- package/dist/debug/namespace.js +21 -12
- package/dist/debug/output.js +21 -24
- package/dist/debug/types.d.ts +4 -4
- package/dist/dlx/arborist.js +18 -8
- package/dist/dlx/binary-cache.js +15 -15
- package/dist/dlx/binary-download.d.ts +1 -1
- package/dist/dlx/binary-download.js +11 -11
- package/dist/dlx/binary-resolution.js +17 -15
- package/dist/dlx/binary-types.d.ts +5 -5
- package/dist/dlx/binary.js +5 -5
- package/dist/dlx/cache.js +1 -1
- package/dist/dlx/detect.d.ts +42 -25
- package/dist/dlx/detect.js +86 -77
- package/dist/dlx/dir.js +2 -2
- package/dist/dlx/firewall.d.ts +9 -1
- package/dist/dlx/firewall.js +1 -1
- package/dist/dlx/lockfile.d.ts +19 -18
- package/dist/dlx/lockfile.js +19 -16
- package/dist/dlx/manifest.d.ts +6 -6
- package/dist/dlx/manifest.js +5 -5
- package/dist/dlx/package.d.ts +10 -10
- package/dist/dlx/package.js +20 -16
- package/dist/dlx/packages.js +4 -4
- package/dist/dlx/paths.js +7 -7
- package/dist/dlx/spec.js +1 -1
- package/dist/dlx/types.d.ts +28 -27
- package/dist/eco/cargo/parse-lockfile.d.ts +2 -3
- package/dist/eco/cargo/parse-lockfile.js +5 -5
- package/dist/eco/manifest/analyze-lockfile.js +2 -2
- package/dist/eco/manifest/detect-format.js +5 -5
- package/dist/eco/manifest/find-packages.js +2 -2
- package/dist/eco/manifest/get-package-versions.js +2 -2
- package/dist/eco/manifest/get-package.js +2 -2
- package/dist/eco/manifest/parse-lockfile.js +2 -2
- package/dist/eco/manifest/parse-manifest.js +2 -2
- package/dist/eco/manifest/parse.js +2 -2
- package/dist/eco/npm/npm/exec.js +2 -2
- package/dist/eco/npm/npm/flags.js +7 -12
- package/dist/eco/npm/npm/parse-lockfile.d.ts +17 -18
- package/dist/eco/npm/npm/parse-lockfile.js +4 -4
- package/dist/eco/npm/parse-package-json.d.ts +11 -0
- package/dist/eco/npm/parse-package-json.js +3 -3
- package/dist/eco/npm/pnpm/exec.d.ts +1 -1
- package/dist/eco/npm/pnpm/exec.js +5 -5
- package/dist/eco/npm/pnpm/flags.js +0 -3
- package/dist/eco/npm/pnpm/parse-lockfile.d.ts +6 -4
- package/dist/eco/npm/pnpm/parse-lockfile.js +7 -7
- package/dist/eco/npm/script.js +9 -6
- package/dist/eco/npm/yarnpkg/yarn/exec.js +4 -4
- package/dist/eco/npm/yarnpkg/yarn/parse-lockfile.d.ts +3 -4
- package/dist/eco/npm/yarnpkg/yarn/parse-lockfile.js +9 -9
- package/dist/effects/pulse-frames.d.ts +3 -1
- package/dist/effects/shimmer-keyframes.d.ts +1 -1
- package/dist/effects/shimmer-terminal.d.ts +1 -1
- package/dist/env/boolean.js +0 -1
- package/dist/env/ci.js +0 -1
- package/dist/env/debug.js +0 -1
- package/dist/env/github-status.d.ts +51 -0
- package/dist/env/github-status.js +90 -0
- package/dist/env/github.js +0 -8
- package/dist/env/home.js +0 -1
- package/dist/env/locale.js +0 -3
- package/dist/env/node-auth-token.js +0 -1
- package/dist/env/node-env.js +0 -1
- package/dist/env/node-version-managers.d.ts +53 -0
- package/dist/env/node-version-managers.js +90 -0
- package/dist/env/npm.js +0 -5
- package/dist/env/number.js +0 -1
- package/dist/env/package-manager.js +3 -6
- package/dist/env/path.js +0 -1
- package/dist/env/pre-commit.js +1 -2
- package/dist/env/proxy.js +1 -1
- package/dist/env/rewire.d.ts +8 -6
- package/dist/env/rewire.js +16 -17
- package/dist/env/shell.js +0 -1
- package/dist/env/socket-cli.js +5 -18
- package/dist/env/socket-mcp.d.ts +114 -0
- package/dist/env/socket-mcp.js +146 -0
- package/dist/env/socket.d.ts +8 -109
- package/dist/env/socket.js +22 -167
- package/dist/env/string.js +0 -1
- package/dist/env/temp-dir.js +0 -3
- package/dist/env/term.js +0 -1
- package/dist/env/test.js +3 -6
- package/dist/env/windows.js +0 -4
- package/dist/env/xdg.js +0 -3
- package/dist/errors/predicates.js +1 -1
- package/dist/events/exit/_internal.d.ts +11 -9
- package/dist/events/exit/_internal.js +31 -35
- package/dist/events/exit/handler.js +3 -4
- package/dist/events/exit/intercept.js +4 -6
- package/dist/events/exit/lifecycle.js +16 -18
- package/dist/events/exit/signals.js +1 -2
- package/dist/events/exit/types.d.ts +6 -5
- package/dist/external/@npmcli/package-json.js +2 -2
- package/dist/external/@npmcli/promise-spawn.js +3 -1
- package/dist/external/npm-pack.js +2 -2
- package/dist/external/pico-pack.js +4 -2
- package/dist/external/which.js +3 -1
- package/dist/external-tools/bazel/asset-names.d.ts +1 -1
- package/dist/external-tools/bazel/asset-names.js +5 -2
- package/dist/external-tools/bazel/from-download.d.ts +1 -1
- package/dist/external-tools/bazel/from-download.js +5 -2
- package/dist/external-tools/bazel/read-bazel-version-file.js +1 -1
- package/dist/external-tools/bazel/resolve-bazel-version.js +4 -0
- package/dist/external-tools/bazel/resolve.d.ts +3 -3
- package/dist/external-tools/bazel/resolve.js +16 -8
- package/dist/external-tools/bazel/types.d.ts +1 -1
- package/dist/external-tools/cdxgen/asset-names.d.ts +1 -1
- package/dist/external-tools/cdxgen/asset-names.js +5 -2
- package/dist/external-tools/cdxgen/from-download.d.ts +1 -1
- package/dist/external-tools/cdxgen/from-download.js +7 -4
- package/dist/external-tools/cdxgen/from-vfs.js +1 -1
- package/dist/external-tools/cdxgen/resolve.d.ts +3 -3
- package/dist/external-tools/cdxgen/resolve.js +16 -8
- package/dist/external-tools/cdxgen/types.d.ts +1 -1
- package/dist/external-tools/from-download.d.ts +3 -3
- package/dist/external-tools/from-download.js +12 -6
- package/dist/external-tools/from-pip-venv.d.ts +1 -1
- package/dist/external-tools/from-pip-venv.js +12 -5
- package/dist/external-tools/janus/asset-names.d.ts +1 -1
- package/dist/external-tools/janus/asset-names.js +5 -2
- package/dist/external-tools/janus/from-download.d.ts +1 -1
- package/dist/external-tools/janus/from-download.js +5 -2
- package/dist/external-tools/janus/from-vfs.js +1 -1
- package/dist/external-tools/janus/resolve.d.ts +3 -3
- package/dist/external-tools/janus/resolve.js +16 -8
- package/dist/external-tools/janus/types.d.ts +1 -1
- package/dist/external-tools/jre/asset-names.d.ts +1 -1
- package/dist/external-tools/jre/asset-names.js +5 -2
- package/dist/external-tools/jre/detect-platform-arch.d.ts +10 -6
- package/dist/external-tools/jre/detect-platform-arch.js +29 -14
- package/dist/external-tools/jre/from-download.d.ts +1 -1
- package/dist/external-tools/jre/from-download.js +7 -4
- package/dist/external-tools/jre/from-java-home.js +2 -2
- package/dist/external-tools/jre/from-vfs.js +3 -3
- package/dist/external-tools/jre/resolve.d.ts +3 -3
- package/dist/external-tools/jre/resolve.js +16 -8
- package/dist/external-tools/jre/types.d.ts +1 -1
- package/dist/external-tools/manifest.d.ts +25 -7
- package/dist/external-tools/manifest.js +13 -13
- package/dist/external-tools/opengrep/asset-names.d.ts +1 -1
- package/dist/external-tools/opengrep/asset-names.js +5 -2
- package/dist/external-tools/opengrep/from-download.d.ts +1 -1
- package/dist/external-tools/opengrep/from-download.js +5 -2
- package/dist/external-tools/opengrep/from-vfs.js +1 -1
- package/dist/external-tools/opengrep/resolve.d.ts +3 -3
- package/dist/external-tools/opengrep/resolve.js +16 -8
- package/dist/external-tools/opengrep/types.d.ts +1 -1
- package/dist/external-tools/python/asset-names.d.ts +76 -0
- package/dist/external-tools/python/asset-names.js +111 -0
- package/dist/external-tools/python/dlx.d.ts +80 -0
- package/dist/external-tools/python/dlx.js +98 -0
- package/dist/external-tools/python/from-download.d.ts +53 -0
- package/dist/external-tools/python/from-download.js +75 -0
- package/dist/external-tools/python/from-path.d.ts +7 -0
- package/dist/external-tools/python/from-path.js +23 -0
- package/dist/external-tools/python/pin.d.ts +121 -0
- package/dist/external-tools/python/pin.js +176 -0
- package/dist/external-tools/python/pip-install.d.ts +75 -0
- package/dist/external-tools/python/pip-install.js +142 -0
- package/dist/external-tools/python/resolve.d.ts +42 -0
- package/dist/external-tools/python/resolve.js +66 -0
- package/dist/external-tools/python/types.d.ts +49 -0
- package/dist/external-tools/sbt/asset-names.d.ts +1 -1
- package/dist/external-tools/sbt/asset-names.js +5 -2
- package/dist/external-tools/sbt/from-download.d.ts +1 -1
- package/dist/external-tools/sbt/from-download.js +5 -2
- package/dist/external-tools/sbt/from-vfs.js +1 -1
- package/dist/external-tools/sbt/resolve.d.ts +3 -3
- package/dist/external-tools/sbt/resolve.js +16 -8
- package/dist/external-tools/sbt/types.d.ts +1 -1
- package/dist/external-tools/skillspector/from-dlx.d.ts +1 -1
- package/dist/external-tools/skillspector/from-dlx.js +10 -3
- package/dist/external-tools/skillspector/from-path.js +3 -5
- package/dist/external-tools/skillspector/from-vfs.js +1 -1
- package/dist/external-tools/skillspector/resolve.d.ts +2 -2
- package/dist/external-tools/skillspector/resolve.js +14 -6
- package/dist/external-tools/synp/asset-names.d.ts +1 -1
- package/dist/external-tools/synp/asset-names.js +6 -2
- package/dist/external-tools/synp/from-download.d.ts +1 -1
- package/dist/external-tools/synp/from-download.js +7 -4
- package/dist/external-tools/synp/from-vfs.js +1 -1
- package/dist/external-tools/synp/resolve.d.ts +3 -3
- package/dist/external-tools/synp/resolve.js +16 -8
- package/dist/external-tools/trivy/asset-names.d.ts +1 -1
- package/dist/external-tools/trivy/asset-names.js +5 -2
- package/dist/external-tools/trivy/from-download.d.ts +1 -1
- package/dist/external-tools/trivy/from-download.js +7 -4
- package/dist/external-tools/trivy/from-vfs.js +1 -1
- package/dist/external-tools/trivy/resolve.d.ts +3 -3
- package/dist/external-tools/trivy/resolve.js +16 -8
- package/dist/external-tools/trivy/types.d.ts +1 -1
- package/dist/external-tools/trufflehog/asset-names.d.ts +1 -1
- package/dist/external-tools/trufflehog/asset-names.js +5 -2
- package/dist/external-tools/trufflehog/from-download.d.ts +1 -1
- package/dist/external-tools/trufflehog/from-download.js +7 -4
- package/dist/external-tools/trufflehog/from-vfs.js +1 -1
- package/dist/external-tools/trufflehog/resolve.d.ts +3 -3
- package/dist/external-tools/trufflehog/resolve.js +16 -8
- package/dist/external-tools/trufflehog/types.d.ts +1 -1
- package/dist/fs/_internal.d.ts +1 -1
- package/dist/fs/_internal.js +7 -7
- package/dist/fs/access.js +5 -9
- package/dist/fs/allowed-dirs-cache.d.ts +47 -0
- package/dist/fs/allowed-dirs-cache.js +69 -0
- package/dist/fs/encoding.js +5 -7
- package/dist/fs/{find-up.js → find.js} +12 -14
- package/dist/fs/inspect.js +7 -13
- package/dist/fs/read-dir.js +7 -10
- package/dist/fs/read-file.js +8 -14
- package/dist/fs/read-json-cache.d.ts +13 -4
- package/dist/fs/read-json-cache.js +9 -6
- package/dist/fs/read-json.js +4 -6
- package/dist/fs/resolve-module.js +7 -3
- package/dist/fs/safe.d.ts +1 -1
- package/dist/fs/safe.js +13 -14
- package/dist/fs/unique.js +4 -5
- package/dist/fs/validate.js +1 -2
- package/dist/fs/write-json.js +4 -5
- package/dist/git/_internal.js +11 -11
- package/dist/git/changed.js +4 -4
- package/dist/git/repo.js +5 -7
- package/dist/git/staged.js +12 -4
- package/dist/git/tracked.d.ts +84 -0
- package/dist/git/tracked.js +163 -0
- package/dist/git/unstaged.js +12 -4
- package/dist/github/ghsa.js +2 -2
- package/dist/github/refs-cache.d.ts +1 -1
- package/dist/github/refs-cache.js +5 -5
- package/dist/github/refs-graphql.js +4 -0
- package/dist/github/refs-rest.js +9 -5
- package/dist/github/refs.js +15 -10
- package/dist/github/{fetch.js → request.js} +13 -2
- package/dist/github/token.js +1 -1
- package/dist/github/types.d.ts +1 -1
- package/dist/globs/_internal.js +8 -10
- package/dist/globs/match.js +13 -7
- package/dist/globs/matcher.d.ts +3 -3
- package/dist/globs/matcher.js +16 -14
- package/dist/globs/stream.js +1 -2
- package/dist/globs/types.d.ts +24 -24
- package/dist/http-request/_internal.d.ts +1 -1
- package/dist/http-request/browser.js +10 -4
- package/dist/http-request/checksum-file.d.ts +55 -0
- package/dist/http-request/checksum-file.js +95 -0
- package/dist/http-request/download-types.d.ts +15 -23
- package/dist/http-request/download.js +3 -3
- package/dist/http-request/{browser-fetch.d.ts → fetch/browser.d.ts} +2 -2
- package/dist/http-request/{browser-fetch.js → fetch/browser.js} +4 -4
- package/dist/http-request/headers.js +1 -2
- package/dist/http-request/request-attempt.js +38 -34
- package/dist/http-request/request-types.d.ts +2 -2
- package/dist/http-request/request.js +1 -1
- package/dist/http-request/user-agent.js +4 -5
- package/dist/integrity.d.ts +92 -18
- package/dist/integrity.js +125 -30
- package/dist/ipc/directory.js +2 -2
- package/dist/ipc/paths.js +1 -1
- package/dist/ipc/write.js +1 -1
- package/dist/ipc-cli/get.js +12 -12
- package/dist/json/edit.js +51 -44
- package/dist/json/format.js +1 -1
- package/dist/json/parse.d.ts +1 -1
- package/dist/json/parse.js +3 -7
- package/dist/logger/_internal.d.ts +4 -4
- package/dist/logger/_internal.js +3 -3
- package/dist/logger/colors.js +4 -3
- package/dist/logger/console-methods.d.ts +132 -0
- package/dist/logger/console-methods.js +169 -0
- package/dist/logger/console.d.ts +12 -0
- package/dist/logger/console.js +42 -11
- package/dist/logger/indentation-methods.d.ts +81 -0
- package/dist/logger/indentation-methods.js +121 -0
- package/dist/logger/node.d.ts +16 -338
- package/dist/logger/node.js +75 -608
- package/dist/logger/options.d.ts +39 -0
- package/dist/logger/options.js +47 -0
- package/dist/logger/semantic-methods.d.ts +63 -0
- package/dist/logger/semantic-methods.js +108 -0
- package/dist/logger/stream-methods.d.ts +63 -0
- package/dist/logger/stream-methods.js +101 -0
- package/dist/logger/stream.d.ts +37 -0
- package/dist/logger/stream.js +42 -0
- package/dist/logger/symbols-builder.js +9 -9
- package/dist/logger/symbols.d.ts +2 -25
- package/dist/logger/symbols.js +53 -74
- package/dist/logger/types.d.ts +1 -1
- package/dist/memo/types.d.ts +6 -6
- package/dist/native-messaging/host.d.ts +20 -0
- package/dist/native-messaging/host.js +120 -0
- package/dist/native-messaging/index.d.ts +5 -0
- package/dist/native-messaging/index.js +22 -0
- package/dist/native-messaging/install.d.ts +60 -0
- package/dist/native-messaging/install.js +144 -0
- package/dist/native-messaging/rate-limit.d.ts +69 -0
- package/dist/native-messaging/rate-limit.js +119 -0
- package/dist/native-messaging/run.d.ts +10 -0
- package/dist/native-messaging/run.js +17 -0
- package/dist/node/async-hooks.js +4 -3
- package/dist/node/child-process.js +4 -3
- package/dist/node/crypto.js +4 -3
- package/dist/node/events.js +4 -3
- package/dist/node/fs-promises.js +4 -3
- package/dist/node/fs.d.ts +22 -6
- package/dist/node/fs.js +17 -3
- package/dist/node/http.js +4 -3
- package/dist/node/https.js +4 -3
- package/dist/node/module.js +10 -6
- package/dist/node/os.d.ts +10 -2
- package/dist/node/os.js +12 -4
- package/dist/node/path.d.ts +11 -2
- package/dist/node/path.js +18 -4
- package/dist/node/timers-promises.js +4 -3
- package/dist/node/url.js +4 -3
- package/dist/node/util.js +4 -3
- package/dist/objects/getters.js +6 -8
- package/dist/objects/inspect.js +1 -4
- package/dist/objects/mutate.js +4 -5
- package/dist/objects/predicates.js +1 -5
- package/dist/objects/sort.js +3 -7
- package/dist/packages/edit-class.d.ts +2 -3
- package/dist/packages/edit-class.js +53 -48
- package/dist/packages/edit.js +12 -14
- package/dist/packages/exports.js +15 -21
- package/dist/packages/fetch.d.ts +16 -0
- package/dist/packages/fetch.js +81 -0
- package/dist/packages/find.d.ts +55 -0
- package/dist/packages/find.js +65 -0
- package/dist/packages/isolation.js +14 -14
- package/dist/packages/licenses.js +18 -18
- package/dist/packages/manifest.js +16 -19
- package/dist/packages/metadata-extensions.d.ts +14 -0
- package/dist/packages/metadata-extensions.js +43 -0
- package/dist/packages/normalize.js +6 -10
- package/dist/packages/provenance.js +17 -19
- package/dist/packages/read.d.ts +29 -0
- package/dist/packages/read.js +66 -0
- package/dist/packages/specs.d.ts +48 -1
- package/dist/packages/specs.js +75 -12
- package/dist/packages/tarball.d.ts +24 -0
- package/dist/packages/tarball.js +81 -0
- package/dist/packages/types.d.ts +22 -22
- package/dist/packages/validation.js +0 -3
- package/dist/paths/_internal.d.ts +2 -1
- package/dist/paths/_internal.js +7 -19
- package/dist/paths/conversion.js +5 -9
- package/dist/paths/dirnames.d.ts +1 -0
- package/dist/paths/dirnames.js +2 -0
- package/dist/paths/filenames.d.ts +0 -1
- package/dist/paths/filenames.js +0 -2
- package/dist/paths/normalize.js +4 -5
- package/dist/paths/packages.js +4 -7
- package/dist/paths/predicates.js +9 -16
- package/dist/paths/resolve.js +17 -25
- package/dist/paths/rewire.d.ts +5 -0
- package/dist/paths/rewire.js +3 -3
- package/dist/paths/socket.d.ts +74 -111
- package/dist/paths/socket.js +106 -139
- package/dist/paths/walk.d.ts +1 -1
- package/dist/paths/walk.js +4 -4
- package/dist/perf/report.js +2 -2
- package/dist/perf/types.d.ts +1 -1
- package/dist/pkg-ext/data.js +1 -1
- package/dist/primordials/array.js +9 -9
- package/dist/primordials/date.js +2 -2
- package/dist/primordials/error.js +3 -3
- package/dist/primordials/headers.d.ts +10 -0
- package/dist/primordials/headers.js +23 -0
- package/dist/primordials/intl.d.ts +13 -0
- package/dist/primordials/intl.js +26 -0
- package/dist/primordials/math.js +33 -33
- package/dist/primordials/number.js +9 -9
- package/dist/primordials/object.js +5 -5
- package/dist/primordials/process.d.ts +88 -0
- package/dist/primordials/process.js +132 -0
- package/dist/primordials/string.d.ts +2 -2
- package/dist/primordials/string.js +6 -6
- package/dist/primordials/symbol.js +3 -3
- package/dist/primordials/uncurry.d.ts +1 -2
- package/dist/primordials/uncurry.js +9 -9
- package/dist/process/abort.js +3 -3
- package/dist/process/lock-manager.js +8 -8
- package/dist/process/spawn/_internal.js +6 -8
- package/dist/process/spawn/child.js +20 -14
- package/dist/process/spawn/errors.js +3 -5
- package/dist/process/spawn/kill-tree.d.ts +53 -0
- package/dist/process/spawn/kill-tree.js +85 -0
- package/dist/process/spawn/stdio.js +0 -1
- package/dist/process/spawn/types.d.ts +5 -5
- package/dist/process/transient.js +2 -2
- package/dist/promises/_internal.d.ts +2 -1
- package/dist/promises/_internal.js +2 -6
- package/dist/promises/iterate.js +11 -15
- package/dist/promises/options.js +3 -6
- package/dist/promises/retry.js +4 -5
- package/dist/promises/timers.d.ts +30 -0
- package/dist/promises/timers.js +48 -0
- package/dist/regexps/spec.js +1 -1
- package/dist/releases/github-archives.d.ts +6 -6
- package/dist/releases/github-archives.js +3 -3
- package/dist/releases/github-asset-url.d.ts +1 -1
- package/dist/releases/github-asset-url.js +5 -5
- package/dist/releases/github-downloads.d.ts +1 -1
- package/dist/releases/github-downloads.js +3 -3
- package/dist/releases/github-listing.d.ts +12 -4
- package/dist/releases/github-listing.js +20 -7
- package/dist/releases/github-retry-config.js +1 -1
- package/dist/releases/github-types.d.ts +6 -6
- package/dist/releases/socket-btm-binary-naming.d.ts +107 -0
- package/dist/releases/socket-btm-binary-naming.js +155 -0
- package/dist/releases/socket-btm.d.ts +8 -115
- package/dist/releases/socket-btm.js +16 -159
- package/dist/schema/types.d.ts +4 -5
- package/dist/schema/validate.js +1 -1
- package/dist/sea/detect.js +6 -6
- package/dist/secrets/_internal.d.ts +2 -2
- package/dist/secrets/_internal.js +2 -2
- package/dist/secrets/compare.d.ts +45 -0
- package/dist/secrets/compare.js +61 -0
- package/dist/secrets/find.d.ts +2 -2
- package/dist/secrets/find.js +10 -4
- package/dist/secrets/keychain.d.ts +1 -1
- package/dist/secrets/keychain.js +6 -4
- package/dist/secrets/linux.js +40 -52
- package/dist/secrets/macos.d.ts +2 -3
- package/dist/secrets/macos.js +24 -33
- package/dist/secrets/rc.d.ts +4 -4
- package/dist/secrets/rc.js +27 -17
- package/dist/secrets/socket-api-token.d.ts +4 -4
- package/dist/secrets/socket-api-token.js +26 -9
- package/dist/secrets/windows.js +32 -37
- package/dist/shadow/skip.js +2 -2
- package/dist/shell/parse.d.ts +32 -0
- package/dist/shell/parse.js +60 -0
- package/dist/smol/detect.js +9 -10
- package/dist/smol/http.js +6 -7
- package/dist/smol/https.js +6 -7
- package/dist/smol/manifest.d.ts +1 -1
- package/dist/smol/manifest.js +6 -7
- package/dist/smol/path.d.ts +1 -1
- package/dist/smol/path.js +7 -8
- package/dist/smol/primordial.d.ts +4 -0
- package/dist/smol/primordial.js +6 -7
- package/dist/smol/purl.d.ts +1 -1
- package/dist/smol/purl.js +7 -8
- package/dist/smol/versions.js +6 -7
- package/dist/smol/vfs.js +6 -7
- package/dist/sorts/_internal.js +6 -8
- package/dist/sorts/natural.js +10 -12
- package/dist/sorts/semver.js +1 -2
- package/dist/sorts/strings.js +0 -1
- package/dist/sorts/types.d.ts +1 -1
- package/dist/spinner/create-spinner-class.d.ts +38 -0
- package/dist/spinner/create-spinner-class.js +302 -0
- package/dist/spinner/default.js +8 -9
- package/dist/spinner/spinner-internals.d.ts +36 -0
- package/dist/spinner/spinner-internals.js +105 -0
- package/dist/spinner/spinner-shimmer-methods.d.ts +54 -0
- package/dist/spinner/spinner-shimmer-methods.js +143 -0
- package/dist/spinner/spinner-status-methods.d.ts +40 -0
- package/dist/spinner/spinner-status-methods.js +133 -0
- package/dist/spinner/spinner.d.ts +8 -5
- package/dist/spinner/spinner.js +19 -706
- package/dist/spinner/types.d.ts +3 -1
- package/dist/spinner/with.d.ts +10 -0
- package/dist/spinner/with.js +16 -2
- package/dist/stdio/divider.js +1 -1
- package/dist/stdio/footer.js +3 -3
- package/dist/stdio/header.js +4 -4
- package/dist/stdio/progress.js +10 -6
- package/dist/stdio/prompts.d.ts +7 -5
- package/dist/stdio/prompts.js +7 -8
- package/dist/stdio/stdout.js +3 -3
- package/dist/streams/parallel.js +3 -5
- package/dist/streams/transform.js +2 -3
- package/dist/strings/format.js +2 -6
- package/dist/strings/predicates.js +0 -2
- package/dist/strings/search.js +1 -2
- package/dist/strings/transform.js +0 -3
- package/dist/strings/width.js +9 -10
- package/dist/tables/bordered.js +4 -3
- package/dist/tables/padding.js +1 -1
- package/dist/tables/simple.js +8 -5
- package/dist/temporal/instant.js +1 -1
- package/dist/temporal/slots.js +6 -6
- package/dist/temporal/system.js +9 -9
- package/dist/themes/context.d.ts +3 -2
- package/dist/themes/context.js +4 -5
- package/dist/themes/themes.js +15 -15
- package/dist/themes/types.d.ts +3 -3
- package/dist/url/assert-safe.d.ts +29 -0
- package/dist/url/assert-safe.js +54 -0
- package/dist/url/parse.js +0 -2
- package/dist/url/predicates.d.ts +31 -1
- package/dist/url/predicates.js +43 -3
- package/dist/url/search-params.js +3 -9
- package/dist/url/types.d.ts +9 -5
- package/dist/versions/_internal.js +3 -3
- package/dist/words/article.js +0 -1
- package/dist/words/capitalize.js +0 -1
- package/dist/words/pluralize.js +15 -5
- package/package.json +419 -216
- package/dist/external-tools/uv/asset-names.d.ts +0 -36
- package/dist/external-tools/uv/asset-names.js +0 -70
- package/dist/external-tools/uv/from-download.d.ts +0 -17
- package/dist/external-tools/uv/from-download.js +0 -47
- package/dist/external-tools/uv/from-path.d.ts +0 -5
- package/dist/external-tools/uv/from-path.js +0 -22
- package/dist/external-tools/uv/from-vfs.d.ts +0 -7
- package/dist/external-tools/uv/from-vfs.js +0 -26
- package/dist/external-tools/uv/resolve.d.ts +0 -25
- package/dist/external-tools/uv/resolve.js +0 -53
- package/dist/external-tools/uv/types.d.ts +0 -24
- package/dist/fs/path-cache.d.ts +0 -21
- package/dist/fs/path-cache.js +0 -34
- package/dist/http-request/checksums.d.ts +0 -69
- package/dist/http-request/checksums.js +0 -108
- package/dist/http-request/http-request.d.ts +0 -12
- package/dist/http-request/http-request.js +0 -11
- package/dist/packages/operations.d.ts +0 -113
- package/dist/packages/operations.js +0 -304
- package/dist/ssri/convert.d.ts +0 -48
- package/dist/ssri/convert.js +0 -69
- package/dist/ssri/parse.d.ts +0 -27
- package/dist/ssri/parse.js +0 -41
- package/dist/ssri/validate.d.ts +0 -41
- package/dist/ssri/validate.js +0 -56
- /package/dist/{bin → cli}/check.d.ts +0 -0
- /package/dist/external-tools/{uv → python}/types.js +0 -0
- /package/dist/fs/{find-up.d.ts → find.d.ts} +0 -0
- /package/dist/github/{fetch.d.ts → request.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,11 +5,56 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [6.0.8](https://github.com/SocketDev/socket-lib/releases/tag/v6.0.8) - 2026-06-11
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`shell/parse`: `detectShellHazards`.** Checks a shell command string for two tricks that hide which program actually runs, so a tool that allows or denies commands by name isn't fooled. First, Zsh `=name` expansion: `=curl evil.com` runs `/usr/bin/curl`, but the command's first word reads as `=curl`, not `curl`. Second, process substitution `<(…)` / `>(…)` / `=(…)`: the command inside the parentheses runs, yet its name never appears as a command word. Returns `{ equalsExpansion, processSubstitution }`, the facts only; the caller decides whether to block.
|
|
13
|
+
- **`url` — `assertSafeHttpUrl`.** SSRF guard for a URL the server did not author (an OAuth issuer, a metadata-advertised introspection endpoint, a webhook target): parses the value, rejects non-`http(s)` schemes, and refuses hosts in loopback / private / link-local ranges (cloud metadata, redis, internal services). Returns the parsed `URL`; throws otherwise. `allowLocalhost` permits `localhost` / `127.0.0.1` / `::1` for local-stack dev; `label` names the subject in the thrown message.
|
|
14
|
+
- **`git/tracked` — tracked-status and submodule-membership probes.** `isTracked(path)` reports whether git tracks an exact path. `getSubmodulePaths()` lists a repo's submodule mount points read from `.gitmodules`, so it covers submodules that are declared but not yet initialized. `isInSubmodule(path)` and the pure `pathIsUnderSubmodule(path, subs)` report whether a path lives inside one. `isUntrackedNonSubmodulePath(path)` composes them into the safe-to-touch condition for cleanup tooling: true only when git does not track the path and it is not inside a submodule (any check error resolves to false).
|
|
15
|
+
- **`primordials/process` — accessors for the `process` global.** `processCwd`, `processPlatform`, `processEnv`, `processArgv`, `processArch`, `processExecPath`, `processPid`, `processVersion`, `processStdout`, `processStderr`, `processEmitWarning`, and `processNextTick`. Each reads through the `process` object captured when the module loads, so reassigning the global cannot redirect it, while still calling the method at access time so test spies keep working.
|
|
16
|
+
- **`ai` — model-selection tiers, balancing, and provider routing.** The model-selection ladder gains a verification tier for check-style passes and a top-capability tier for the hardest work. Requests load-balance across a provider's backends so they spread instead of pinning one. A shared multi-agent backend registry centralizes routing, and a provider-credential resolver reads from environment variables and falls back to the OS keychain.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **`http-request` browser entry — `fetch/browser`.** The browser build of `httpJson` / `httpText` now resolves through `http-request/fetch/browser` (was `http-request/browser-fetch`), and the package's `browser` field maps Node-only builtins to their browser stubs. Bundlers targeting the browser pick the right entry automatically.
|
|
21
|
+
- **Node-builtin accessors are browser-bundler friendly.** The internal Node-builtin accessor layer requires builtins by their bare name so a browser bundler's builtin replacement (the package `browser` field, a consumer's bundler fallback config) resolves them; the `node:`-prefixed form bypasses that replacement in some bundlers. No public API change.
|
|
22
|
+
- **Caller-supplied `options` are prototype-pollution hardened.** Functions that take an `options` argument normalize it before reading, so an object with a tampered prototype cannot leak inherited properties into the library's behavior.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **`ai` — codex reasoning effort.** Setting `effort` on a `spawnAiAgent` call now reaches the codex backend (emitted as codex's reasoning-effort config), where it was previously accepted but silently ignored for every agent except claude. The claude-only `max` level maps to codex's `xhigh` ceiling.
|
|
27
|
+
|
|
28
|
+
## [6.0.7](https://github.com/SocketDev/socket-lib/releases/tag/v6.0.7) - 2026-06-03
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- **`external-tools/python` — zero-host-dependency Python.** `resolvePython` (PATH → python-build-standalone download), `downloadPipPackage` (bundle-safe `pip install --target`), `resolvePipPackagePin` (hash-pinned closure), and the `dlxPipInstall` / `dlxPipPin` one-call wrappers. Removes the unused `external-tools/uv`.
|
|
33
|
+
- **`constants/platform` — `getOs`, `getLibc`, `getTarget`.** OS, libc (`glibc`/`musl`/`undefined`), and the pnpm `pack-app` host token `<os>-<arch>[-<libc>]`.
|
|
34
|
+
- **`http-request` decompresses `gzip` / `br` response bodies.** Buffered requests advertise `Accept-Encoding: gzip, br` and now decode the body by its `Content-Encoding` before resolving. 6.0.6 sent the header but never decompressed, so a compressed response reached callers as raw deflated bytes. Streamed requests (`stream: true`, e.g. `httpDownload`) skip the header so piped-to-disk payloads stay raw and checksum cleanly. Callers can override with `'identity'`.
|
|
35
|
+
- **`crypto/hash` blob content-address helpers.** `blobHashOf(bytes)` returns Socket's content-addressed blob hash (`Q` + base64url(sha256)), and `verifyBlobHash(hash, bytes)` throws when bytes don't hash to the expected address. Both build on the fast one-shot `hash()`; the `S` file-stream discriminator verifies against the same digest body. Lets blob consumers (the SDK, MCP server) verify integrity against one canonical implementation instead of re-deriving the scheme.
|
|
36
|
+
- **`integrity` — unified checksum/integrity surface.** `checksumToIntegrity(hex, algorithm?)` and `integrityToChecksum(sri)` convert between the two named hash flavors and are idempotent on the destination format (pass an SRI to `checksumToIntegrity`, get it back unchanged). `isIntegrity(s)` and `isChecksum(s)` are the predicates. `parseIntegrity(s)` returns `{ algorithm, body }` for the SRI structure. Replaces the `src/ssri/` directory (`hexToSsri`, `ssriToHex`, `isValidHex`, `isValidSsri`, `parseSsri`) — SSRI is just another name for Subresource Integrity, so the duplication confused readers. `isIntegrity` now accepts the full W3C SRI set (`sha256` / `sha384` / `sha512`) — the previous predicate hardcoded `sha512` only, which mismatched the contract `external-tools/manifest.ts` already promised and rejected the fleet's `sha256-<base64>` integrity strings.
|
|
37
|
+
- **`process/spawn/kill-tree` — cross-platform process-tree termination.** `killProcessTree(target, { detached?, signal? })` walks and signals the whole descendant tree of a `pid` or `ChildProcess`: POSIX uses `process.kill(-pid, signal)` against the detached child's process group; Windows shells out to `taskkill /T /F /pid <pid>`. `isProcessAlive(pid)` probes liveness with `process.kill(pid, 0)`. Both helpers are best-effort and never throw — `ESRCH` (process gone) or `EPERM` (not ours) returns `false` so cleanup kills can't mask the caller's control flow.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- **dlx + pin API renamed (breaking).** `downloadPackage` → `downloadNpmPackage`, `generatePackagePin` → `resolveNpmPackagePin`, the `package` option → `spec`. `downloadNpmPackage` gains an optional `hash` for tarball integrity.
|
|
42
|
+
- **`packages/operations` split by concern (breaking).** The grab-bag `@socketsecurity/lib/packages/operations` export is gone; its members move to focused subpaths: `readPackageJson`/`readPackageJsonSync` → `packages/read`, the fetcher + GitHub tarball resolver → `packages/fetch`, `extractPackage`/`packPackage` → `packages/tarball`, the dependency-metadata override lookup → `packages/metadata-extensions`, and the name/spec helpers → `packages/specs`. `findUpPackageJson` now lives at `packages/find` (the `packages/find-up` subpath is removed). The `fs/find-up` subpath is renamed `fs/find`, and `fs/path-cache` is renamed `fs/allowed-dirs-cache` (it caches the safe-delete allowed-directories set, not arbitrary paths).
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **Python downloads now work on Windows and Alpine.** python-build-standalone resolution previously returned no asset on `win32` and musl hosts; both now resolve.
|
|
47
|
+
- **`debug` — namespace `SOCKET_DEBUG` values enable debug output.** `envAsBoolean(getSocketDebug())` returned false for `SOCKET_DEBUG=*` or `SOCKET_DEBUG=socket:foo` — those aren't boolean literals, so debug output was silently suppressed for the common namespace-selection shape. The new `isSocketDebugEnabled()` helper treats any non-empty value other than `0`/`false`/`no` (case-insensitive) as enabled.
|
|
48
|
+
- **`external-tools/skillspector` pipx detection on Windows.** The PATH-tier resolver normalizes the resolved binary path with `normalizePath` and matches a forward-slash-only `pipx/venvs/` pattern, instead of `path.normalize` plus a dual-separator regex. On Windows the old form left backslashes in the path and missed pipx-installed binaries, tagging them `source: 'path'` rather than `source: 'pipx'`.
|
|
49
|
+
|
|
50
|
+
### Removed
|
|
51
|
+
|
|
52
|
+
- **`@socketsecurity/lib/ssri/{convert,parse,validate}` package exports.** Folded into `@socketsecurity/lib/integrity` (see Added). No fleet consumers were using the `ssri` subpath imports — verified by grep across socket-\* fleet repos.
|
|
53
|
+
|
|
8
54
|
## [6.0.6](https://github.com/SocketDev/socket-lib/releases/tag/v6.0.6) - 2026-06-01
|
|
9
55
|
|
|
10
56
|
### Added
|
|
11
57
|
|
|
12
|
-
- **`http-request` now negotiates and decompresses `gzip` / `br` response bodies.** Buffered requests advertise `Accept-Encoding: gzip, br` and transparently decompress responses by `Content-Encoding`. Node's HTTP client does neither, so a compressed Socket API response previously reached callers as raw deflated bytes. Streamed requests (`stream: true`, e.g. `httpDownload`) intentionally skip the `Accept-Encoding` header so piped-to-disk payloads stay raw and checksum cleanly. Callers can override (e.g. `'identity'`).
|
|
13
58
|
- **`http-request/headers` — `basicAuthHeader(token)`.** Builds the Socket API Basic-auth shape (token-as-username, empty password) so call sites stop hand-rolling `Basic ${base64(token + ':')}`.
|
|
14
59
|
- **`http-request` retry instrumentation.** Adds `Retry-Attempt`, `Retry-Max`, and `Retry-After` request headers on retried attempts so server-side logs can correlate a retry chain.
|
|
15
60
|
- **`prim` CLI bin.** `prim` is now published as a `bin` entry (`dist/bin/prim.cjs`); installs from `@socketsecurity/lib` make `npx prim` work. Also new in this release: `prim --diff` for unified line-diffs in dry-run mode, multi-hop cycle detection in `validateRewrites`, and a two-phase apply with cross-batch validation.
|
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ import { httpJson } from '@socketsecurity/lib/http-request'
|
|
|
39
39
|
import { safeDelete } from '@socketsecurity/lib/fs'
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
Start with the [API
|
|
42
|
+
Start with the [API reference](./docs/api.md) — every subpath export with a one-line description.
|
|
43
43
|
|
|
44
44
|
## Development
|
|
45
45
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Agent-awareness for hooks + scripts: WHICH agent is running right now,
|
|
3
|
+
* and WHERE that agent keeps its config / memory on the current platform. Two
|
|
4
|
+
* distinct questions, two functions:
|
|
5
|
+
*
|
|
6
|
+
* - `detectAgent()` — who is invoking this process? Read from the environment
|
|
7
|
+
* the running agent injects, NOT from any stdin payload (a Claude Code hook
|
|
8
|
+
* gets `{tool_name,…}` on stdin but no agent id; Codex/OpenCode use
|
|
9
|
+
* entirely different invocation contracts). The cross-agent signal is
|
|
10
|
+
* `AI_AGENT` (Claude Code sets `AI_AGENT=claude-code_<ver>_agent`);
|
|
11
|
+
* tool-specific flags (`CLAUDECODE`, `CODEX_*`, `OPENCODE`) are the
|
|
12
|
+
* fallback. Returns `undefined` when nothing identifies an agent (a plain
|
|
13
|
+
* shell / CI).
|
|
14
|
+
* - `agentPaths()` — given an agent, the config + memory directories it uses on
|
|
15
|
+
* THIS OS. Built on the cross-platform `getHome()` (HOME → USERPROFILE) and
|
|
16
|
+
* XDG helpers so a Windows path differs from mac/linux correctly. This is
|
|
17
|
+
* the runtime complement to `discoverAiAgents()` (which agents are
|
|
18
|
+
* INSTALLED on PATH); this answers which one is DRIVING + where it lives.
|
|
19
|
+
* Memory caveat baked into the data: only Claude Code maintains an
|
|
20
|
+
* agent-written memory store (`~/.claude/projects/<slug>/memory/`). Codex +
|
|
21
|
+
* OpenCode have NO self-written memory — their only persistent context is
|
|
22
|
+
* the human-authored AGENTS.md. So `agentPaths(...).memoryDir` is defined
|
|
23
|
+
* only for `claude`; for the others it is `undefined` (there is no memory
|
|
24
|
+
* dir to point at), and the shared cross-tool memory surface is the
|
|
25
|
+
* committed AGENTS.md (which the fleet symlinks to CLAUDE.md).
|
|
26
|
+
*/
|
|
27
|
+
import type { AiAgentName } from './types.mts';
|
|
28
|
+
/**
|
|
29
|
+
* The detected running agent + the raw version token from `AI_AGENT`, when
|
|
30
|
+
* present. `agent` is the normalized `AiAgentName`; `raw` is the full env value
|
|
31
|
+
* (e.g. `claude-code_2-1-169_agent`) for callers that want the version.
|
|
32
|
+
*/
|
|
33
|
+
export interface DetectedAgent {
|
|
34
|
+
readonly agent: AiAgentName;
|
|
35
|
+
readonly raw: string | undefined;
|
|
36
|
+
}
|
|
37
|
+
export declare function agentFromAiAgentEnv(value: string): AiAgentName | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* The config + memory directories an agent uses on the current platform.
|
|
40
|
+
*
|
|
41
|
+
* `configDir` is where the agent keeps global config / instructions.
|
|
42
|
+
* `memoryDir` is the agent-written persistent-memory store — defined ONLY for
|
|
43
|
+
* `claude` (Codex/OpenCode have no self-written memory; their durable context
|
|
44
|
+
* is the human-authored AGENTS.md). For non-claude agents `memoryDir` is
|
|
45
|
+
* `undefined`.
|
|
46
|
+
*
|
|
47
|
+
* All paths derive from `getHome()` (HOME → USERPROFILE, cross-platform) so the
|
|
48
|
+
* Windows location differs from mac/linux correctly. Returns `undefined` when
|
|
49
|
+
* the home dir can't be resolved.
|
|
50
|
+
*/
|
|
51
|
+
export interface AgentPaths {
|
|
52
|
+
readonly agent: AiAgentName;
|
|
53
|
+
readonly configDir: string;
|
|
54
|
+
readonly memoryDir: string | undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve an agent's config (and, for Claude, memory) directories on this OS.
|
|
58
|
+
*
|
|
59
|
+
* Per-agent / per-platform (verified against each tool's docs; flagged where a
|
|
60
|
+
* platform path is best-effort):
|
|
61
|
+
*
|
|
62
|
+
* - **claude**: `~/.claude` on every OS. Memory:
|
|
63
|
+
* `~/.claude/projects/<cwd-slug>/memory/` (slug = cwd with `/`→`-`). Pass
|
|
64
|
+
* `options.cwd` to compute the memory dir for a specific project.
|
|
65
|
+
* - **codex**: `$CODEX_HOME` if set, else `~/.codex` (all OSes, incl. Windows
|
|
66
|
+
* `%USERPROFILE%\.codex` — Codex uses a dotdir, not %APPDATA%). No memory.
|
|
67
|
+
* - **opencode**: XDG — `$XDG_CONFIG_HOME/opencode` else `~/.config/opencode` on
|
|
68
|
+
* mac/linux; on Windows `%APPDATA%\opencode` (best-effort: OpenCode's docs
|
|
69
|
+
* don't pin the Windows user-config path; APPDATA is the conventional
|
|
70
|
+
* fallback and is overridable via `$XDG_CONFIG_HOME`). No memory.
|
|
71
|
+
* - **gemini**: `~/.gemini` (all OSes). No memory.
|
|
72
|
+
*
|
|
73
|
+
* @returns The resolved paths, or `undefined` if the home dir is unresolvable.
|
|
74
|
+
*/
|
|
75
|
+
export declare function agentPaths(agent: AiAgentName, options?: {
|
|
76
|
+
cwd?: string | undefined;
|
|
77
|
+
} | undefined): AgentPaths | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Detect which AI agent is invoking the current process, from the environment.
|
|
80
|
+
*
|
|
81
|
+
* Resolution order:
|
|
82
|
+
*
|
|
83
|
+
* 1. `AI_AGENT` — the cross-agent signal (Claude Code sets it). Its leading token
|
|
84
|
+
* names the family.
|
|
85
|
+
* 2. Tool-specific flags as a fallback: `CLAUDECODE=1` / `CLAUDE_CODE_*` → claude;
|
|
86
|
+
* `CODEX_*` → codex; `OPENCODE` → opencode.
|
|
87
|
+
*
|
|
88
|
+
* Returns `undefined` when no agent signal is present (a plain shell, CI, a
|
|
89
|
+
* non-agent subprocess) — callers should treat that as "agent-agnostic", not an
|
|
90
|
+
* error.
|
|
91
|
+
*
|
|
92
|
+
* Note: a hook receives NO agent id in its stdin payload; this env read is the
|
|
93
|
+
* only reliable signal. Different agents also invoke hooks differently (Claude:
|
|
94
|
+
* stdin JSON; Codex: its own hooks; OpenCode: plugin callbacks), so a
|
|
95
|
+
* `.claude/hooks/` script is fundamentally Claude-invoked — `detectAgent()` is
|
|
96
|
+
* most useful for scripts/skills that want to branch on the active agent, or
|
|
97
|
+
* when an agent delegates to another.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* const detected = detectAgent()
|
|
101
|
+
* if (detected?.agent === 'claude') { ... }
|
|
102
|
+
*/
|
|
103
|
+
export declare function detectAgent(): DetectedAgent | undefined;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Socket Lib - Built with rolldown */
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
5
|
+
const require_constants_platform = require('../constants/platform.js');
|
|
6
|
+
const require_env_rewire = require('../env/rewire.js');
|
|
7
|
+
const require_env_home = require('../env/home.js');
|
|
8
|
+
const require_env_xdg = require('../env/xdg.js');
|
|
9
|
+
let node_path = require("node:path");
|
|
10
|
+
node_path = require_runtime.__toESM(node_path, 1);
|
|
11
|
+
|
|
12
|
+
//#region src/ai/agent-context.mts
|
|
13
|
+
/**
|
|
14
|
+
* @file Agent-awareness for hooks + scripts: WHICH agent is running right now,
|
|
15
|
+
* and WHERE that agent keeps its config / memory on the current platform. Two
|
|
16
|
+
* distinct questions, two functions:
|
|
17
|
+
*
|
|
18
|
+
* - `detectAgent()` — who is invoking this process? Read from the environment
|
|
19
|
+
* the running agent injects, NOT from any stdin payload (a Claude Code hook
|
|
20
|
+
* gets `{tool_name,…}` on stdin but no agent id; Codex/OpenCode use
|
|
21
|
+
* entirely different invocation contracts). The cross-agent signal is
|
|
22
|
+
* `AI_AGENT` (Claude Code sets `AI_AGENT=claude-code_<ver>_agent`);
|
|
23
|
+
* tool-specific flags (`CLAUDECODE`, `CODEX_*`, `OPENCODE`) are the
|
|
24
|
+
* fallback. Returns `undefined` when nothing identifies an agent (a plain
|
|
25
|
+
* shell / CI).
|
|
26
|
+
* - `agentPaths()` — given an agent, the config + memory directories it uses on
|
|
27
|
+
* THIS OS. Built on the cross-platform `getHome()` (HOME → USERPROFILE) and
|
|
28
|
+
* XDG helpers so a Windows path differs from mac/linux correctly. This is
|
|
29
|
+
* the runtime complement to `discoverAiAgents()` (which agents are
|
|
30
|
+
* INSTALLED on PATH); this answers which one is DRIVING + where it lives.
|
|
31
|
+
* Memory caveat baked into the data: only Claude Code maintains an
|
|
32
|
+
* agent-written memory store (`~/.claude/projects/<slug>/memory/`). Codex +
|
|
33
|
+
* OpenCode have NO self-written memory — their only persistent context is
|
|
34
|
+
* the human-authored AGENTS.md. So `agentPaths(...).memoryDir` is defined
|
|
35
|
+
* only for `claude`; for the others it is `undefined` (there is no memory
|
|
36
|
+
* dir to point at), and the shared cross-tool memory surface is the
|
|
37
|
+
* committed AGENTS.md (which the fleet symlinks to CLAUDE.md).
|
|
38
|
+
*/
|
|
39
|
+
function agentFromAiAgentEnv(value) {
|
|
40
|
+
const lower = value.toLowerCase();
|
|
41
|
+
if (lower.startsWith("claude")) return "claude";
|
|
42
|
+
if (lower.startsWith("codex")) return "codex";
|
|
43
|
+
if (lower.startsWith("opencode")) return "opencode";
|
|
44
|
+
if (lower.startsWith("gemini")) return "gemini";
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve an agent's config (and, for Claude, memory) directories on this OS.
|
|
48
|
+
*
|
|
49
|
+
* Per-agent / per-platform (verified against each tool's docs; flagged where a
|
|
50
|
+
* platform path is best-effort):
|
|
51
|
+
*
|
|
52
|
+
* - **claude**: `~/.claude` on every OS. Memory:
|
|
53
|
+
* `~/.claude/projects/<cwd-slug>/memory/` (slug = cwd with `/`→`-`). Pass
|
|
54
|
+
* `options.cwd` to compute the memory dir for a specific project.
|
|
55
|
+
* - **codex**: `$CODEX_HOME` if set, else `~/.codex` (all OSes, incl. Windows
|
|
56
|
+
* `%USERPROFILE%\.codex` — Codex uses a dotdir, not %APPDATA%). No memory.
|
|
57
|
+
* - **opencode**: XDG — `$XDG_CONFIG_HOME/opencode` else `~/.config/opencode` on
|
|
58
|
+
* mac/linux; on Windows `%APPDATA%\opencode` (best-effort: OpenCode's docs
|
|
59
|
+
* don't pin the Windows user-config path; APPDATA is the conventional
|
|
60
|
+
* fallback and is overridable via `$XDG_CONFIG_HOME`). No memory.
|
|
61
|
+
* - **gemini**: `~/.gemini` (all OSes). No memory.
|
|
62
|
+
*
|
|
63
|
+
* @returns The resolved paths, or `undefined` if the home dir is unresolvable.
|
|
64
|
+
*/
|
|
65
|
+
function agentPaths(agent, options) {
|
|
66
|
+
const opts = {
|
|
67
|
+
__proto__: null,
|
|
68
|
+
...options
|
|
69
|
+
};
|
|
70
|
+
const home = require_env_home.getHome();
|
|
71
|
+
if (!home) return;
|
|
72
|
+
switch (agent) {
|
|
73
|
+
case "claude": {
|
|
74
|
+
const configDir = node_path.default.join(home, ".claude");
|
|
75
|
+
const cwd = opts.cwd;
|
|
76
|
+
return {
|
|
77
|
+
agent,
|
|
78
|
+
configDir,
|
|
79
|
+
memoryDir: cwd ? node_path.default.join(configDir, "projects", cwd.replace(/[/\\]/g, "-"), "memory") : void 0
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
case "codex": return {
|
|
83
|
+
agent,
|
|
84
|
+
configDir: require_env_rewire.getEnvValue("CODEX_HOME") || node_path.default.join(home, ".codex"),
|
|
85
|
+
memoryDir: void 0
|
|
86
|
+
};
|
|
87
|
+
case "opencode": {
|
|
88
|
+
const xdg = require_env_xdg.getXdgConfigHome();
|
|
89
|
+
let base;
|
|
90
|
+
if (xdg) base = xdg;
|
|
91
|
+
else if (require_constants_platform.WIN32) base = require_env_rewire.getEnvValue("APPDATA") || node_path.default.join(home, ".config");
|
|
92
|
+
else base = node_path.default.join(home, ".config");
|
|
93
|
+
return {
|
|
94
|
+
agent,
|
|
95
|
+
configDir: node_path.default.join(base, "opencode"),
|
|
96
|
+
memoryDir: void 0
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
case "gemini": return {
|
|
100
|
+
agent,
|
|
101
|
+
configDir: node_path.default.join(home, ".gemini"),
|
|
102
|
+
memoryDir: void 0
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Detect which AI agent is invoking the current process, from the environment.
|
|
108
|
+
*
|
|
109
|
+
* Resolution order:
|
|
110
|
+
*
|
|
111
|
+
* 1. `AI_AGENT` — the cross-agent signal (Claude Code sets it). Its leading token
|
|
112
|
+
* names the family.
|
|
113
|
+
* 2. Tool-specific flags as a fallback: `CLAUDECODE=1` / `CLAUDE_CODE_*` → claude;
|
|
114
|
+
* `CODEX_*` → codex; `OPENCODE` → opencode.
|
|
115
|
+
*
|
|
116
|
+
* Returns `undefined` when no agent signal is present (a plain shell, CI, a
|
|
117
|
+
* non-agent subprocess) — callers should treat that as "agent-agnostic", not an
|
|
118
|
+
* error.
|
|
119
|
+
*
|
|
120
|
+
* Note: a hook receives NO agent id in its stdin payload; this env read is the
|
|
121
|
+
* only reliable signal. Different agents also invoke hooks differently (Claude:
|
|
122
|
+
* stdin JSON; Codex: its own hooks; OpenCode: plugin callbacks), so a
|
|
123
|
+
* `.claude/hooks/` script is fundamentally Claude-invoked — `detectAgent()` is
|
|
124
|
+
* most useful for scripts/skills that want to branch on the active agent, or
|
|
125
|
+
* when an agent delegates to another.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* const detected = detectAgent()
|
|
129
|
+
* if (detected?.agent === 'claude') { ... }
|
|
130
|
+
*/
|
|
131
|
+
function detectAgent() {
|
|
132
|
+
const aiAgent = require_env_rewire.getEnvValue("AI_AGENT");
|
|
133
|
+
if (aiAgent) {
|
|
134
|
+
const agent = agentFromAiAgentEnv(aiAgent);
|
|
135
|
+
if (agent) return {
|
|
136
|
+
agent,
|
|
137
|
+
raw: aiAgent
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (require_env_rewire.getEnvValue("CLAUDECODE") || require_env_rewire.getEnvValue("CLAUDE_CODE_ENTRYPOINT")) return {
|
|
141
|
+
agent: "claude",
|
|
142
|
+
raw: aiAgent
|
|
143
|
+
};
|
|
144
|
+
if (require_env_rewire.getEnvValue("OPENCODE")) return {
|
|
145
|
+
agent: "opencode",
|
|
146
|
+
raw: aiAgent
|
|
147
|
+
};
|
|
148
|
+
if (require_env_rewire.getEnvValue("CODEX_SANDBOX") || require_env_rewire.getEnvValue("CODEX_HOME")) return {
|
|
149
|
+
agent: "codex",
|
|
150
|
+
raw: aiAgent
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
exports.agentFromAiAgentEnv = agentFromAiAgentEnv;
|
|
156
|
+
exports.agentPaths = agentPaths;
|
|
157
|
+
exports.detectAgent = detectAgent;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Multi-agent CLI backend registry + role routing. The fleet's review /
|
|
3
|
+
* scan / fix skills delegate work to whichever agent CLIs are installed
|
|
4
|
+
* (`codex`, `claude`, `kimi`, `opencode`), falling back through a per-role
|
|
5
|
+
* preference order and skipping a pass when nothing usable is present. Before
|
|
6
|
+
* this module each skill copied the same registry + detection block inline
|
|
7
|
+
* (the canonical copy lived in
|
|
8
|
+
* `.claude/skills/fleet/reviewing-code/run.mts`); the shared policy doc
|
|
9
|
+
* (`_shared/multi-agent-backends.md`) flagged the extraction. Import
|
|
10
|
+
* `BACKENDS` / `detectAvailableBackends` / `resolveBackendForRole` here
|
|
11
|
+
* instead so a new backend or a routing-policy change is a single edit. The
|
|
12
|
+
* registry is prompt-agnostic: it owns WHICH CLI runs and HOW its argv is
|
|
13
|
+
* built ({ argv, outMode }), not WHAT to ask. A skill keeps its own role
|
|
14
|
+
* table (prompts + per-role `preferenceOrder` + timeouts) and passes the
|
|
15
|
+
* order into `resolveBackendForRole`. Detection uses `which` (cross-platform)
|
|
16
|
+
* rather than `command -v` under `shell: true`, which mangles on Windows. The
|
|
17
|
+
* resolver is pure — it returns a structured result (chosen backend + why)
|
|
18
|
+
* and never logs, so the caller decides how to surface a fallback or a skip.
|
|
19
|
+
* `opencode` is hybrid (it dispatches to whatever provider its own config
|
|
20
|
+
* selects, e.g. Fireworks / Synthetic), so it is NEVER auto-picked from a
|
|
21
|
+
* preference order — only when a caller names it explicitly — to keep model
|
|
22
|
+
* attribution accurate.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* A CLI backend the fleet can delegate a pass to.
|
|
26
|
+
*/
|
|
27
|
+
export type BackendName = 'claude' | 'codex' | 'kimi' | 'opencode';
|
|
28
|
+
/**
|
|
29
|
+
* How a backend's process emits its result.
|
|
30
|
+
*/
|
|
31
|
+
export type BackendOutMode = 'file' | 'stdout';
|
|
32
|
+
export interface BackendRun {
|
|
33
|
+
readonly argv: readonly string[];
|
|
34
|
+
readonly outMode: BackendOutMode;
|
|
35
|
+
}
|
|
36
|
+
export interface BackendDescriptor {
|
|
37
|
+
readonly bin: string;
|
|
38
|
+
readonly hybrid: boolean;
|
|
39
|
+
readonly name: BackendName;
|
|
40
|
+
readonly run: (promptFile: string, outFile: string) => BackendRun;
|
|
41
|
+
}
|
|
42
|
+
export declare const BACKENDS: Readonly<Record<BackendName, BackendDescriptor>>;
|
|
43
|
+
/**
|
|
44
|
+
* The set of backends whose CLI is installed. Fans the `which` lookups out
|
|
45
|
+
* concurrently rather than awaiting one at a time.
|
|
46
|
+
*/
|
|
47
|
+
export declare function detectAvailableBackends(): Promise<ReadonlySet<BackendName>>;
|
|
48
|
+
/**
|
|
49
|
+
* True when `value` names a known backend.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isBackendName(value: string): value is BackendName;
|
|
52
|
+
/**
|
|
53
|
+
* True when the named CLI resolves on PATH (cross-platform via `which`).
|
|
54
|
+
*/
|
|
55
|
+
export declare function isCommandAvailable(bin: string): Promise<boolean>;
|
|
56
|
+
export type BackendResolution = {
|
|
57
|
+
readonly backend: BackendName;
|
|
58
|
+
readonly reason: 'override';
|
|
59
|
+
} | {
|
|
60
|
+
readonly backend: BackendName;
|
|
61
|
+
readonly reason: 'preference';
|
|
62
|
+
} | {
|
|
63
|
+
readonly backend: BackendName;
|
|
64
|
+
readonly reason: 'preference';
|
|
65
|
+
readonly overrideMissing: BackendName;
|
|
66
|
+
} | {
|
|
67
|
+
readonly backend: undefined;
|
|
68
|
+
readonly reason: 'unavailable';
|
|
69
|
+
};
|
|
70
|
+
export interface ResolveBackendOptions {
|
|
71
|
+
readonly preferenceOrder: readonly BackendName[];
|
|
72
|
+
readonly available: ReadonlySet<BackendName>;
|
|
73
|
+
readonly override?: BackendName | undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolve which backend runs a pass, encoding the fleet detection policy
|
|
77
|
+
* (`_shared/multi-agent-backends.md`): an installed explicit override wins;
|
|
78
|
+
* else the first installed non-hybrid entry in the preference order; else
|
|
79
|
+
* nothing (skip the pass). Pure — returns the decision + why, never logs. An
|
|
80
|
+
* override that isn't installed is reported via `overrideMissing` so the caller
|
|
81
|
+
* can warn.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveBackendForRole(options: ResolveBackendOptions): BackendResolution;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Socket Lib - Built with rolldown */
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
const require_bin_which = require('../bin/which.js');
|
|
5
|
+
const require_ai_spawn = require('./spawn.js');
|
|
6
|
+
|
|
7
|
+
//#region src/ai/backends.mts
|
|
8
|
+
/**
|
|
9
|
+
* @file Multi-agent CLI backend registry + role routing. The fleet's review /
|
|
10
|
+
* scan / fix skills delegate work to whichever agent CLIs are installed
|
|
11
|
+
* (`codex`, `claude`, `kimi`, `opencode`), falling back through a per-role
|
|
12
|
+
* preference order and skipping a pass when nothing usable is present. Before
|
|
13
|
+
* this module each skill copied the same registry + detection block inline
|
|
14
|
+
* (the canonical copy lived in
|
|
15
|
+
* `.claude/skills/fleet/reviewing-code/run.mts`); the shared policy doc
|
|
16
|
+
* (`_shared/multi-agent-backends.md`) flagged the extraction. Import
|
|
17
|
+
* `BACKENDS` / `detectAvailableBackends` / `resolveBackendForRole` here
|
|
18
|
+
* instead so a new backend or a routing-policy change is a single edit. The
|
|
19
|
+
* registry is prompt-agnostic: it owns WHICH CLI runs and HOW its argv is
|
|
20
|
+
* built ({ argv, outMode }), not WHAT to ask. A skill keeps its own role
|
|
21
|
+
* table (prompts + per-role `preferenceOrder` + timeouts) and passes the
|
|
22
|
+
* order into `resolveBackendForRole`. Detection uses `which` (cross-platform)
|
|
23
|
+
* rather than `command -v` under `shell: true`, which mangles on Windows. The
|
|
24
|
+
* resolver is pure — it returns a structured result (chosen backend + why)
|
|
25
|
+
* and never logs, so the caller decides how to surface a fallback or a skip.
|
|
26
|
+
* `opencode` is hybrid (it dispatches to whatever provider its own config
|
|
27
|
+
* selects, e.g. Fireworks / Synthetic), so it is NEVER auto-picked from a
|
|
28
|
+
* preference order — only when a caller names it explicitly — to keep model
|
|
29
|
+
* attribution accurate.
|
|
30
|
+
*/
|
|
31
|
+
const BACKENDS = {
|
|
32
|
+
__proto__: null,
|
|
33
|
+
claude: {
|
|
34
|
+
bin: "claude",
|
|
35
|
+
hybrid: false,
|
|
36
|
+
name: "claude",
|
|
37
|
+
run(_promptFile, _outFile) {
|
|
38
|
+
const model = process.env["CLAUDE_MODEL"] ?? "opus";
|
|
39
|
+
const effort = process.env["CLAUDE_EFFORT"] ?? "high";
|
|
40
|
+
return {
|
|
41
|
+
argv: [
|
|
42
|
+
"--print",
|
|
43
|
+
"--model",
|
|
44
|
+
model,
|
|
45
|
+
...require_ai_spawn.isAdaptiveOnlyModel(model) ? [] : ["--effort", effort],
|
|
46
|
+
"--no-session-persistence",
|
|
47
|
+
"--permission-mode",
|
|
48
|
+
"dontAsk"
|
|
49
|
+
],
|
|
50
|
+
outMode: "stdout"
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
codex: {
|
|
55
|
+
bin: "codex",
|
|
56
|
+
hybrid: false,
|
|
57
|
+
name: "codex",
|
|
58
|
+
run(_promptFile, outFile) {
|
|
59
|
+
return {
|
|
60
|
+
argv: [
|
|
61
|
+
"exec",
|
|
62
|
+
"--model",
|
|
63
|
+
process.env["CODEX_MODEL"] ?? "gpt-5.5",
|
|
64
|
+
"-c",
|
|
65
|
+
`model_reasoning_effort=${process.env["CODEX_REASONING"] ?? "xhigh"}`,
|
|
66
|
+
"--full-auto",
|
|
67
|
+
"--ephemeral",
|
|
68
|
+
"-o",
|
|
69
|
+
outFile,
|
|
70
|
+
"-"
|
|
71
|
+
],
|
|
72
|
+
outMode: "file"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
kimi: {
|
|
77
|
+
bin: "kimi",
|
|
78
|
+
hybrid: false,
|
|
79
|
+
name: "kimi",
|
|
80
|
+
run(_promptFile, _outFile) {
|
|
81
|
+
return {
|
|
82
|
+
argv: [
|
|
83
|
+
"chat",
|
|
84
|
+
"--model",
|
|
85
|
+
process.env["KIMI_MODEL"] ?? "kimi-latest",
|
|
86
|
+
"--no-stream"
|
|
87
|
+
],
|
|
88
|
+
outMode: "stdout"
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
opencode: {
|
|
93
|
+
bin: "opencode",
|
|
94
|
+
hybrid: true,
|
|
95
|
+
name: "opencode",
|
|
96
|
+
run(_promptFile, _outFile) {
|
|
97
|
+
const model = process.env["OPENCODE_MODEL"];
|
|
98
|
+
return {
|
|
99
|
+
argv: model ? [
|
|
100
|
+
"run",
|
|
101
|
+
"--model",
|
|
102
|
+
model
|
|
103
|
+
] : ["run"],
|
|
104
|
+
outMode: "stdout"
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* The set of backends whose CLI is installed. Fans the `which` lookups out
|
|
111
|
+
* concurrently rather than awaiting one at a time.
|
|
112
|
+
*/
|
|
113
|
+
async function detectAvailableBackends() {
|
|
114
|
+
const names = Object.keys(BACKENDS);
|
|
115
|
+
const results = await Promise.all(names.map(async (name) => ({
|
|
116
|
+
available: await isCommandAvailable(BACKENDS[name].bin),
|
|
117
|
+
name
|
|
118
|
+
})));
|
|
119
|
+
return new Set(results.filter((r) => r.available).map((r) => r.name));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* True when `value` names a known backend.
|
|
123
|
+
*/
|
|
124
|
+
function isBackendName(value) {
|
|
125
|
+
return value in BACKENDS;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* True when the named CLI resolves on PATH (cross-platform via `which`).
|
|
129
|
+
*/
|
|
130
|
+
async function isCommandAvailable(bin) {
|
|
131
|
+
return await require_bin_which.which(bin) !== null;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Resolve which backend runs a pass, encoding the fleet detection policy
|
|
135
|
+
* (`_shared/multi-agent-backends.md`): an installed explicit override wins;
|
|
136
|
+
* else the first installed non-hybrid entry in the preference order; else
|
|
137
|
+
* nothing (skip the pass). Pure — returns the decision + why, never logs. An
|
|
138
|
+
* override that isn't installed is reported via `overrideMissing` so the caller
|
|
139
|
+
* can warn.
|
|
140
|
+
*/
|
|
141
|
+
function resolveBackendForRole(options) {
|
|
142
|
+
const { available, override, preferenceOrder } = {
|
|
143
|
+
__proto__: null,
|
|
144
|
+
...options
|
|
145
|
+
};
|
|
146
|
+
if (override && available.has(override)) return {
|
|
147
|
+
backend: override,
|
|
148
|
+
reason: "override"
|
|
149
|
+
};
|
|
150
|
+
for (let i = 0, { length } = preferenceOrder; i < length; i += 1) {
|
|
151
|
+
const candidate = preferenceOrder[i];
|
|
152
|
+
if (BACKENDS[candidate]?.hybrid) continue;
|
|
153
|
+
if (available.has(candidate)) return override ? {
|
|
154
|
+
backend: candidate,
|
|
155
|
+
overrideMissing: override,
|
|
156
|
+
reason: "preference"
|
|
157
|
+
} : {
|
|
158
|
+
backend: candidate,
|
|
159
|
+
reason: "preference"
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
backend: void 0,
|
|
164
|
+
reason: "unavailable"
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
//#endregion
|
|
169
|
+
exports.BACKENDS = BACKENDS;
|
|
170
|
+
exports.detectAvailableBackends = detectAvailableBackends;
|
|
171
|
+
exports.isBackendName = isBackendName;
|
|
172
|
+
exports.isCommandAvailable = isCommandAvailable;
|
|
173
|
+
exports.resolveBackendForRole = resolveBackendForRole;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Layered provider-credential resolver for AI backends. One call site,
|
|
3
|
+
* dev and CI: a provider token resolves from an explicit override, then the
|
|
4
|
+
* provider's env var, then the OS keychain — mirroring the
|
|
5
|
+
* `readSocketApiToken` env → keychain precedence
|
|
6
|
+
* (`secrets/socket-api-token.ts`). Why a single resolver: `ai/http.mts` read
|
|
7
|
+
* `process.env[tokenEnv]` inline, so every consumer hard-coded the env-only
|
|
8
|
+
* path and none could reach the keychain. Routing skills also need a uniform
|
|
9
|
+
* way to ask "do I have a credential for provider X?" without knowing its
|
|
10
|
+
* env-var name. This centralizes the provider → { tokenEnv, keychainService }
|
|
11
|
+
* map (the HTTP providers reuse `AI_HTTP_PROVIDERS` so the env var isn't
|
|
12
|
+
* duplicated) and the precedence. CI vs dev: pass `allowEnvOnly: true` (the
|
|
13
|
+
* resolver's existing escape) in headless contexts so a missing token returns
|
|
14
|
+
* `undefined` immediately instead of triggering a keychain auth prompt. CI
|
|
15
|
+
* sets the token as a GH-secret env var (e.g. `ANTHROPIC_API_KEY`); the same
|
|
16
|
+
* `resolveProviderCredential` call reads it there with no keychain. proteus
|
|
17
|
+
* hook-point: the forthcoming biometric credential daemon
|
|
18
|
+
* (`.claude/plans/proteus-credential-broker.md`) slots in as a layer between
|
|
19
|
+
* the env check and the keychain read inside `resolve()`'s implementation —
|
|
20
|
+
* call sites here do not change when it lands (resolver decision #4 in that
|
|
21
|
+
* plan). This module is the stable seam.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* A provider whose credential this module can resolve: the HTTP providers
|
|
25
|
+
* (fireworks, synthetic) plus the CLI/first-party providers (anthropic, openai,
|
|
26
|
+
* xai) for CI env + keychain.
|
|
27
|
+
*/
|
|
28
|
+
export type CredentialProvider = 'anthropic' | 'fireworks' | 'openai' | 'synthetic' | 'xai';
|
|
29
|
+
export interface ProviderCredentialSpec {
|
|
30
|
+
readonly tokenEnv: string;
|
|
31
|
+
readonly keychainService: string;
|
|
32
|
+
}
|
|
33
|
+
export declare const PROVIDER_CREDENTIALS: Readonly<Record<CredentialProvider, ProviderCredentialSpec>>;
|
|
34
|
+
/**
|
|
35
|
+
* True when `value` names a provider with a resolvable credential.
|
|
36
|
+
*/
|
|
37
|
+
export declare function isCredentialProvider(value: string): value is CredentialProvider;
|
|
38
|
+
export interface ResolveProviderCredentialOptions {
|
|
39
|
+
readonly provider: CredentialProvider;
|
|
40
|
+
readonly explicit?: string | undefined;
|
|
41
|
+
readonly allowEnvOnly?: boolean | undefined;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a provider's bearer token: explicit override → env var → keychain →
|
|
45
|
+
* undefined. The token never appears inline or in logs — callers pass the
|
|
46
|
+
* result straight to an `Authorization` header. Returns `undefined` when no
|
|
47
|
+
* source has it (the caller decides whether that's fatal).
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveProviderCredential(options: ResolveProviderCredentialOptions): Promise<string | undefined>;
|