mirror of
https://github.com/Gitlawb/openclaude.git
synced 2026-08-24 02:34:15 -05:00
* fix(deps): ship a zero-warning, minimal install
The published package declared 62 runtime `dependencies`, but `dist/cli.mjs`
is a fully-bundled esbuild output that inlines almost all of them. End users
therefore installed ~476 transitive packages — including three subtrees the
bundle never needs at install time, each emitting an install warning:
- node-domexception (deprecated) via google-auth-library
- protobufjs (allow-scripts) via @grpc/* (already bundled into dist)
- sharp (allow-scripts) native image module
The repo's `overrides`/`allowScripts` silence these locally, but those are
root-only npm settings and are ignored when the package is installed as a
dependency — so end users saw the warnings.
Core changes:
- package.json: runtime dependencies trimmed 62 -> 3 (@orama/orama,
@orama/plugin-data-persistence, @vscode/ripgrep). Bundled packages, plus
the optional sharp/google-auth-library, move to devDependencies so they
are built/tested but not shipped.
- package.json: @anthropic-ai/sdk, @modelcontextprotocol/sdk, react and
react-reconciler declared as OPTIONAL peerDependencies — externalized by
the ./sdk bundle but bundled into the CLI. Optional peers keep the CLI
install minimal and warning-free while still resolving for ./sdk consumers.
- externals.ts: sharp, google-auth-library and @anthropic-ai/bedrock-sdk
marked OPTIONAL_RUNTIME_EXTERNALS (loaded on demand, not shipped).
- validate-externals.ts: runtime deps validate against externals; bundled
deps validate against dependencies + devDependencies.
- client.ts: load @anthropic-ai/bedrock-sdk via the runtime importer so
esbuild no longer inlines it and hoists its static @aws-sdk import into
the CLI bundle (that was a startup crash for default installs).
Optional-dependency UX (consistent, actionable errors):
- New src/utils/optionalRuntimeModule.ts exports importRuntimeModule and
importOptionalRuntimeModule. The optional variant translates a missing
package (code === 'ERR_MODULE_NOT_FOUND', specifier present in message)
into "<feature> requires "<pkg>" ... Run `npm i -g <pkg>`". Generic so
typed call sites keep their module types.
- Routed ALL optional-package load sites through it (previously only one
did): google-auth-library (client.ts, auth.ts, geminiAuth.ts),
@anthropic-ai/foundry-sdk + @azure/identity (client.ts), and the
@aws-sdk/* Bedrock paths (model/bedrock.ts, tokenEstimation.ts, aws.ts).
- imageProcessor.ts: sharp-missing error now says `npm i -g sharp`.
- docs/advanced-setup.md: new "Optional provider packages" table and a
Vertex note documenting the on-demand installs.
- Unit test for the helper (friendly error, success path, specifier match,
raw passthrough).
- knip.json: ignore google-auth-library (now loaded via runtime string).
Verified on the current tree:
- tsc, build/validate-externals, knip, and tests all pass.
- npm pack + install --omit=dev adds 8 packages, zero deprecation/
allow-scripts/funding warnings; --version/--help/mcp list run.
- With packages absent, CLAUDE_CODE_USE_BEDROCK and CLAUDE_CODE_USE_VERTEX
print the friendly `npm i -g <pkg>` error (verified end-to-end).
- ./sdk imports once its optional peers are present (24 exports, no warns).
- Bundled ajv + ajv-formats validate with no ajv installed; no unguarded
native runtime requires (fsevents absent in chokidar 4; bun:sqlite Bun-only).
Trade-off: image reads, AWS Bedrock, Azure Foundry and GCP/Vertex now prompt
a one-time `npm i -g <pkg>` instead of being shipped to every user.
Co-Authored-By: OpenClaude <openclaude@gitlawb.com>
Review fixes (CodeRabbit + jatmn):
- validate-externals: the INTENTIONALLY_BUNDLED exemption is now scoped per
bundle. The CLI exempts every bundled package; the SDK does NOT exempt
packages declared as peerDependencies (keyed on package.json, an independent
source of truth) so dropping react/@anthropic-ai/sdk from SDK_EXTERNALS now
fails validation instead of silently passing. Added an explicit minimal-
install contract check: bundled packages must be devDependencies-only — never
in `dependencies`, and only the SDK-external subset may be optional peers.
Validation logic extracted to scripts/externalsValidation.ts + tests.
- FileReadTool oversized-image fallback now loads via the shared
getImageProcessor() (not a raw import('sharp')) and re-throws
ImageProcessorUnavailableError, so a missing processor surfaces the
`npm i -g sharp` install hint instead of returning an over-budget image.
- optionalRuntimeModule: match the missing specifier as a QUOTED token, not a
raw substring, so a missing transitive package whose name contains the
requested one (sharp vs sharp-libvips, @aws-sdk/client-bedrock vs
@aws-sdk/client-bedrock-runtime) no longer triggers the wrong install hint.
Predicate extracted to isMissingSpecifierError() with regression tests.
- docs/advanced-setup.md: the Vertex auth section now shows both documented
paths (gcloud ADC and a GOOGLE_APPLICATION_CREDENTIALS service-account file).
Review fixes (round 2, CodeRabbit):
- validate-externals: assert the optional-peer install contract — every
peerDependency must be { optional: true } in peerDependenciesMeta
(validateOptionalPeers), so losing that flag fails the build instead of
silently reintroducing install warnings.
- validate-externals: hard-check OPTIONAL_RUNTIME_EXTERNALS placement
(validateOptionalRuntimeexternals). Anything esbuild can see statically must
stay external in BOTH bundles (dropping sharp/google-auth-library now fails);
the runtime-indirection-only subset (new RUNTIME_INDIRECTION_ONLY_EXTERNALS)
must stay OUT of externals so esbuild never re-exposes their static imports.
- Deeper-dig fix: @anthropic-ai/foundry-sdk was misclassified as
INTENTIONALLY_BUNDLED, but it is loaded only through the Function indirection
(esbuild never sees it, so it was never actually bundled) — its sole presence
in dist is the specifier string. Per the PR's own "Azure Foundry now prompts"
trade-off it is on-demand, so it now lives in OPTIONAL_RUNTIME_EXTERNALS +
RUNTIME_INDIRECTION_ONLY_EXTERNALS (mirroring bedrock-sdk). sandbox-runtime is
genuinely statically imported, so it stays bundled.
- Provider-routing coverage (scripts/optionalRuntimeSpecifiers.test.ts): a
static scan asserts every importOptionalRuntimeModule specifier is a declared
OPTIONAL_RUNTIME_EXTERNAL and never also INTENTIONALLY_BUNDLED — the
invariant that keeps a provider's optional package loadable on demand.
- All new validators extracted to scripts/externalsValidation.ts with tests.
Review fixes (round 3, CodeRabbit):
- client.ts: gate the Vertex google-auth-library import behind the non-skip
branch. CLAUDE_CODE_SKIP_VERTEX_AUTH (proxy/test) uses a mock GoogleAuth and
must not require the optional package; it was loaded unconditionally before.
- optionalRuntimeModule: drop the hard-coded `npm i -g`. The helper backs both
the global CLI and project-local ./sdk consumers, so the hint is now
context-neutral ("npm install <pkg>" / add -g for the global CLI).
- validate-externals: every SDK_ONLY_EXTERNALS entry must STAY a
peerDependency (a dropped peer leaves runtimeDeps while the SDK still
externalizes it); and OPTIONAL_RUNTIME_EXTERNALS must never be shipped (fail
on overlap with dependencies/peerDependencies). Both with tests + live-verified.
- optionalRuntimeSpecifiers.test: pin the EXACT set of optionally-loaded
specifiers instead of a >=5 count (a count passes even if a provider path
regresses).
- attachments: extract tryReadEditedImageAttachment() — background watched-file
image attachments DEGRADE to null on any failure (incl.
ImageProcessorUnavailableError) so a missing optional package never aborts a
turn, while the explicit FileReadTool path still surfaces the install hint.
Deterministic regression test (bad path -> null).
- docs: Bedrock row notes profile-based auth also needs
@aws-sdk/credential-providers; install-hint wording matches the new message.
Review fixes (round 4, CodeRabbit):
- attachments: stop sending the raw file path through the analytics
bypass-cast (tengu_watched_file_compression_failed). Send only the safe
file extension via getFileExtensionForAnalytics, matching the existing
tengu_file_read_dedup pattern, so no usernames/project paths can leak.
- externals.ts: corrected the OPTIONAL_RUNTIME_EXTERNALS header comment,
which still claimed all entries "remain in COMMON_EXTERNALS" — no longer
true since the indirection-only subset (bedrock/foundry) must stay OUT of
the externals lists.
(Other CodeRabbit comments on this push re-surface items already addressed in
prior commits: the peerDependenciesMeta-optional check (validateOptionalPeers),
the SDK-peers-present and optional-not-shipped validator rules, the
exact-specifier-set test, the attachments degrade contract + test, and the
context-neutral install hint are all present. The "assert every optional
external is a devDependency" suggestion is intentionally NOT applied: @aws-sdk/*
and @azure/identity are transitive devDeps via bedrock-sdk/foundry-sdk, so a
blanket assertion would be incorrect; source resolution is covered by the
build + tests that import these packages.)
Review fixes (round 5, CodeRabbit):
- attachments: stop leaking file paths via logError in the background-image
degrade path. readImageWithTokenBudget can throw path-bearing messages
(e.g. "Image file is empty: <path>") and logError persists message/stack, so
log only the error TYPE name now. (Analytics payload was already sanitized.)
- attachments: tryReadEditedImageAttachment takes an injectable reader so the
degrade contract is tested for the EXACT error types — ImageProcessorUnavailableError
and a path-bearing read error both degrade to null (not just ENOENT) — plus a
success case. No mocking.
- validate-externals: enforce the source-install half of the optional contract.
Non-transitive OPTIONAL_RUNTIME_EXTERNALS must be devDependencies so `bun
install` source builds resolve them. The new TRANSITIVE_OPTIONAL_EXTERNALS
documents the exemption (@aws-sdk/* via @anthropic-ai/bedrock-sdk, @azure/identity
via @anthropic-ai/foundry-sdk — provided transitively, not direct devDeps). A
blanket "all optionals are devDeps" check would have wrongly failed on those.
Tests + live-verified (dropping sharp from devDependencies now fails).
Review fixes (round 6, CodeRabbit + jatmn):
- optionalRuntimeSpecifiers.test: the call-site scan regex missed
generic-annotated calls (importOptionalRuntimeModule<...>(...)) in
model/bedrock.ts and tokenEstimation.ts, so the exact-set assertion was
incomplete. Regex now allows an optional generic; EXPECTED_SPECIFIERS adds
@aws-sdk/client-bedrock and @aws-sdk/client-bedrock-runtime (7 total).
- importOptionalRuntimeModule default generic is now <T = unknown> (was any),
so destructured imports are no longer silently any. Every call site now
supplies its module type — typeof import('<pkg>') where the package is
type-resolvable (bedrock-sdk, foundry-sdk, @aws-sdk/credential-providers,
google-auth-library), and a named minimal-shape alias for @azure/identity
(not a direct devDep, so typeof import can't resolve it). This gives
compile-time verification of each provider's module contract (export names,
shapes) — the structural answer to the "cover the provider branches" ask.
- attachments: tryReadEditedImageAttachment takes injectable {read,log,track};
a new test asserts the sanitized-telemetry contract directly — the logError
payload is path-free and the analytics payload carries only `ext`, never the
edited-image path.
* fix(deps): address optional runtime review findings
* test(deps): isolate optional runtime importer mocks
* fix(deps): clarify AWS optional auth labels
* fix(deps): close optional runtime review gaps
---------
Co-authored-by: jatmn <the@jat.mn>
203 lines
7.2 KiB
JSON
203 lines
7.2 KiB
JSON
{
|
|
"name": "@gitlawb/openclaude",
|
|
"version": "0.22.0",
|
|
"description": "OpenClaude opens coding-agent workflows to any LLM — OpenAI, Gemini, DeepSeek, Ollama, and 200+ models",
|
|
"type": "module",
|
|
"bin": {
|
|
"openclaude": "./bin/openclaude"
|
|
},
|
|
"exports": {
|
|
"./package.json": "./package.json",
|
|
"./dist/cli.mjs": "./dist/cli.mjs",
|
|
"./sdk": {
|
|
"types": "./src/entrypoints/sdk.d.ts",
|
|
"import": "./dist/sdk.mjs"
|
|
}
|
|
},
|
|
"files": [
|
|
"bin/",
|
|
"dist/cli.mjs",
|
|
"dist/sdk.mjs",
|
|
"src/entrypoints/sdk.d.ts",
|
|
"src/entrypoints/sdk/coreTypes.generated.ts",
|
|
"scripts/windows/openclaude-aliases.ps1",
|
|
"vendor/node-domexception-shim/",
|
|
"docs/windows-aliases-and-launchers.md",
|
|
"README.md"
|
|
],
|
|
"scripts": {
|
|
"build": "bun run scripts/build.ts",
|
|
"integrations:generate": "bun run scripts/generate-integrations-artifacts.ts",
|
|
"integrations:check": "bun run scripts/generate-integrations-artifacts.ts --check",
|
|
"dev": "bun run build && node bin/openclaude",
|
|
"dev:profile": "bun run scripts/provider-launch.ts",
|
|
"dev:profile:fast": "bun run scripts/provider-launch.ts auto --fast --bare",
|
|
"dev:codex": "bun run scripts/provider-launch.ts codex",
|
|
"dev:openai": "bun run scripts/provider-launch.ts openai",
|
|
"dev:gemini": "bun run scripts/provider-launch.ts gemini",
|
|
"dev:ollama": "bun run scripts/provider-launch.ts ollama",
|
|
"dev:ollama:fast": "bun run scripts/provider-launch.ts ollama --fast --bare",
|
|
"dev:atomic-chat": "bun run scripts/provider-launch.ts atomic-chat",
|
|
"profile:init": "bun run scripts/provider-bootstrap.ts",
|
|
"profile:recommend": "bun run scripts/provider-recommend.ts",
|
|
"profile:auto": "bun run scripts/provider-recommend.ts --apply",
|
|
"profile:codex": "bun run profile:init -- --provider codex --model codexplan",
|
|
"profile:fast": "bun run profile:init -- --provider ollama --model llama3.2:3b",
|
|
"profile:code": "bun run profile:init -- --provider ollama --model qwen2.5-coder:7b",
|
|
"dev:fast": "bun run profile:fast && bun run dev:ollama:fast",
|
|
"dev:code": "bun run profile:code && bun run dev:profile",
|
|
"dev:grpc": "bun run scripts/start-grpc.ts",
|
|
"dev:grpc:cli": "bun run scripts/grpc-cli.ts",
|
|
"start": "node bin/openclaude",
|
|
"web:dev": "bun run --cwd web dev",
|
|
"web:build": "bun run --cwd web build",
|
|
"web:preview": "bun run --cwd web preview",
|
|
"web:typecheck": "bun run --cwd web typecheck",
|
|
"test": "bun test --feature=UNATTENDED_RETRY",
|
|
"test:full": "bun test --feature=UNATTENDED_RETRY --max-concurrency=1",
|
|
"test:coverage": "bun test --feature=UNATTENDED_RETRY --coverage --coverage-reporter=lcov --coverage-dir=coverage --max-concurrency=1 && bun run scripts/render-coverage-heatmap.ts",
|
|
"test:coverage:ui": "bun run scripts/render-coverage-heatmap.ts",
|
|
"security:pr-scan": "bun run scripts/pr-intent-scan.ts",
|
|
"test:provider-recommendation": "bun test src/utils/providerRecommendation.test.ts src/utils/providerProfile.test.ts",
|
|
"typecheck": "tsc --noEmit",
|
|
"typecheck:type-tests": "bun run scripts/typecheck-type-tests.ts",
|
|
"smoke": "bun run build && node dist/cli.mjs --version",
|
|
"deadcode": "knip --include files,dependencies",
|
|
"check": "bun run smoke && bun run deadcode && bun run test:full",
|
|
"verify:privacy": "bun run scripts/verify-no-phone-home.ts",
|
|
"build:verified": "bun run build && bun run verify:privacy",
|
|
"test:provider": "bun test --feature=UNATTENDED_RETRY --max-concurrency=1 src/services/api/*.test.ts src/utils/context.test.ts",
|
|
"doctor:runtime": "bun run scripts/system-check.ts",
|
|
"doctor:runtime:json": "bun run scripts/system-check.ts --json",
|
|
"doctor:report": "bun run scripts/system-check.ts --out reports/doctor-runtime.json",
|
|
"hardening:check": "bun run smoke && bun run doctor:runtime",
|
|
"hardening:strict": "bun run typecheck && bun run hardening:check",
|
|
"prepack": "npm run build"
|
|
},
|
|
"dependencies": {
|
|
"@orama/orama": "^3.1.18",
|
|
"@orama/plugin-data-persistence": "^3.1.18",
|
|
"@vscode/ripgrep": "^1.17.1"
|
|
},
|
|
"devDependencies": {
|
|
"@alcalzone/ansi-tokenize": "0.3.0",
|
|
"@anthropic-ai/bedrock-sdk": "0.29.1",
|
|
"@anthropic-ai/foundry-sdk": "0.2.3",
|
|
"@anthropic-ai/sandbox-runtime": "0.0.55",
|
|
"@anthropic-ai/sdk": "0.94.0",
|
|
"@aws-sdk/client-bedrock": "3.1047.0",
|
|
"@aws-sdk/client-sts": "3.1047.0",
|
|
"@aws-sdk/credential-provider-node": "3.972.41",
|
|
"@azure/identity": "^4.13.1",
|
|
"@commander-js/extra-typings": "12.1.0",
|
|
"@grpc/grpc-js": "^1.14.3",
|
|
"@grpc/proto-loader": "^0.8.0",
|
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
"@smithy/core": "3.24.3",
|
|
"@smithy/node-http-handler": "4.7.3",
|
|
"@types/bun": "1.3.11",
|
|
"@types/node": "25.5.0",
|
|
"@types/react": "19.2.14",
|
|
"ajv": "8.18.0",
|
|
"auto-bind": "5.0.1",
|
|
"axios": "1.16.0",
|
|
"bidi-js": "1.0.3",
|
|
"chalk": "5.6.2",
|
|
"chokidar": "4.0.3",
|
|
"cli-boxes": "3.0.0",
|
|
"cli-highlight": "2.1.11",
|
|
"commander": "12.1.0",
|
|
"cross-spawn": "7.0.6",
|
|
"diff": "8.0.3",
|
|
"duck-duck-scrape": "^2.2.7",
|
|
"emoji-regex": "10.6.0",
|
|
"env-paths": "3.0.0",
|
|
"execa": "9.6.1",
|
|
"fflate": "0.8.2",
|
|
"figures": "6.1.0",
|
|
"fuse.js": "7.1.0",
|
|
"graphology": "0.26.0",
|
|
"get-east-asian-width": "1.5.0",
|
|
"google-auth-library": "10.6.2",
|
|
"https-proxy-agent": "7.0.6",
|
|
"ignore": "7.0.5",
|
|
"graphology-metrics": "2.4.0",
|
|
"indent-string": "5.0.0",
|
|
"js-tiktoken": "1.0.21",
|
|
"jsonc-parser": "3.3.1",
|
|
"knip": "^6.16.1",
|
|
"lodash-es": "4.18.1",
|
|
"lru-cache": "11.2.7",
|
|
"marked": "15.0.12",
|
|
"p-map": "7.0.4",
|
|
"picomatch": "4.0.4",
|
|
"proper-lockfile": "4.1.2",
|
|
"qrcode": "1.5.4",
|
|
"react": "19.2.4",
|
|
"react-compiler-runtime": "1.0.0",
|
|
"react-reconciler": "0.33.0",
|
|
"semver": "7.7.4",
|
|
"sharp": "^0.34.5",
|
|
"shell-quote": "1.8.4",
|
|
"signal-exit": "4.1.0",
|
|
"supports-hyperlinks": "3.2.0",
|
|
"tree-kill": "1.2.2",
|
|
"tree-sitter-wasms": "0.1.13",
|
|
"turndown": "7.2.2",
|
|
"type-fest": "4.41.0",
|
|
"typescript": "5.9.3",
|
|
"undici": "7.28.0",
|
|
"usehooks-ts": "3.1.1",
|
|
"web-tree-sitter": "0.25.10",
|
|
"vscode-languageserver-protocol": "3.17.5",
|
|
"wrap-ansi": "9.0.2",
|
|
"ws": "8.21.0",
|
|
"xss": "1.0.15",
|
|
"yaml": "2.8.3",
|
|
"zod": "3.25.76"
|
|
},
|
|
"peerDependencies": {
|
|
"@anthropic-ai/sdk": "^0.94.0",
|
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
"react": "^19.0.0",
|
|
"react-reconciler": "^0.33.0"
|
|
},
|
|
"peerDependenciesMeta": {
|
|
"@anthropic-ai/sdk": { "optional": true },
|
|
"@modelcontextprotocol/sdk": { "optional": true },
|
|
"react": { "optional": true },
|
|
"react-reconciler": { "optional": true }
|
|
},
|
|
"engines": {
|
|
"node": ">=22.0.0"
|
|
},
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "https://github.com/Gitlawb/openclaude.git"
|
|
},
|
|
"keywords": [
|
|
"claude-code",
|
|
"openai",
|
|
"llm",
|
|
"cli",
|
|
"agent",
|
|
"deepseek",
|
|
"ollama",
|
|
"gemini"
|
|
],
|
|
"license": "SEE LICENSE FILE",
|
|
"publishConfig": {
|
|
"access": "public"
|
|
},
|
|
"overrides": {
|
|
"ip-address": "10.2.0",
|
|
"google-auth-library": "10.6.2",
|
|
"lodash-es": "4.18.1",
|
|
"node-domexception": "file:vendor/node-domexception-shim"
|
|
},
|
|
"allowScripts": {
|
|
"protobufjs@7.6.4": true,
|
|
"sharp@0.34.5": true
|
|
}
|
|
}
|