mirror of
https://github.com/Gitlawb/openclaude.git
synced 2026-08-24 10:14:19 -05:00
23bc49a01df40308bb2e863b74be57363dd36f2b
12
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
650fae952d |
fix(sdk): make stub-leak detection TDZ-safe + defer to next microtask (#1287) (#1398)
* fix(sdk): make stub-leak detection TDZ-safe + defer to next microtask (#1287) `bun run scripts/start-grpc.ts` crashed at startup with: ReferenceError: Cannot access 'QueryEngine' before initialization. at detectStubLeaks (src/entrypoints/sdk/index.ts:29:33) at src/entrypoints/sdk/index.ts:47:1 The detector ran at module-load time and read each critical import directly. When the start script's circular-import chain reached the SDK barrel before `QueryEngine.js` had finished initializing its own export bindings, the QueryEngine reference at line 29 hit the temporal dead zone and threw. Stub-leak detection is meant to catch `__stub: true` markers from the esbuild plugin — TDZ is a different bug class (an uninitialized binding can't carry `__stub`), so the detector should treat the access failure as 'nothing to check here' rather than crashing the entire SDK entry. Two changes: 1. Wrap each import read in safelyAccess(() => binding) so a TDZ ReferenceError on one returns undefined and the loop continues. Real stub markers still surface as the explicit SDK init error. 2. Defer detectStubLeaks() from module-load to queueMicrotask, so every same-tick init in the circular chain (start-grpc.ts → SDK index → QueryEngine → ... → SDK index) completes before we read bindings. Microtask runs before any actual SDK usage, so a real stub leak still surfaces well before the first query() call. Tests (3): SDK barrel imports without throwing, anti-regression on real __stub: true bindings, TDZ-shaped access returns undefined. * test(sdk): exercise the real stub-leak detector with stubbed fixtures (#1287) The regression test asserted only that a local object literal had __stub === true and re-implemented safelyAccess inline, so it never ran the real detector: removing queueMicrotask(detectStubLeaks), dropping the loop, or swallowing the __stub case would all still pass. Split the detection primitives (safelyAccess + the critical-import scan) into src/entrypoints/sdk/stubLeakDetection.ts and have the SDK entry point import them. The test now feeds stub-shaped fixtures through the real checkCriticalImportsForStubs / safelyAccess and asserts: a real __stub: true binding throws the explicit SDK init error; non-stub modules pass; a TDZ ReferenceError is tolerated (skipped) without crashing; a stub behind a skipped TDZ access is still caught; and the SDK barrel import never throws on its own load. Detector runtime behavior is unchanged. |
||
|
|
9755550137 |
Typecheck/zero tsc errors (#1597)
* ci(typecheck): add error-count ratchet toward zero tsc errors tsc --noEmit currently reports 697 pre-existing errors (issue #473), so PRs cannot be gated on a clean typecheck yet. This adds scripts/typecheck-ratchet.ts and a per-file baseline: CI fails when the count rises above the baseline (listing exactly which files regressed), passes at or below it, and --update lowers the baseline to lock in gains. Wired into pr-checks as its own step; once the baseline reaches zero the step becomes a plain `bun run typecheck`. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> * fix(typecheck): mechanical sweep — 697 → 624 tsc errors Type-only fixes with no runtime behavior change, except the deliberate NODE_ENV restorations: - Restore process.env.NODE_ENV comparisons that the source snapshot had baked into the literal "production", making the conditions constant (AutoUpdater dev/test skip, useTypeahead, ink devtools injection, interactiveHelpers onboarding skip, TestingPermissionTool.isEnabled — the last now correctly enables under bun test, +3 tests run green) - Type stream read helpers in openaiShim/codexShim as Bun.ReadableStreamDefaultReadResult<Uint8Array<ArrayBuffer>> and annotate throwClassifiedTransportError as never-returning, clearing the reader/response undefined cascades (29 errors) - Delete 14 stale @ts-expect-error directives - Widen useState/useRef/array generics inferred from null/[] literals - as-const notification priority/color literals to match Priority - Accept readonly Tool[] in checkLocalModelContextLoad/getCombinedTools Baseline lowered via typecheck:ratchet --update; full suite green (3690 tests), smoke + bundle guard green. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> * fix(typecheck): recreate missing modules — 624 → 415 tsc errors The open snapshot never mirrored ~60 modules; the bundler noop-stubs them at build time (() => null named exports), so every recreated module here is runtime-inert by construction: no import-time side effects, gated features stay off (isAssistantMode/isSkillSearchEnabled → false, tools isEnabled → false, dialogs render null), lookups return empty, telemetry no-ops. Types are honest and derived from importer usage — no any. Highlights: - sdk: runtimeTypes re-exports/aliases, sdkUtilityTypes (NonNullableUsage), settingsTypes.generated; coreTypes.generated usage fields regenerated as a self-contained structural type (the consumer package ships without sdkUtilityTypes/@anthropic-ai/sdk, so the generated file must stay dependency-free — generator override updated to match, package-consumer-types tests green) - services: contextCollapse operations/persist/stats, compact cachedMicrocompact state/types + reactiveCompact, skillSearch (7 modules), oauth/types, lsp/types, sessionTranscript - cli/server/daemon: Transport interface, parseConnectUrl, server/* (7), daemon/*, bg/templateJobs/runners; assistant/* (KAIROS), ssh/* - tools/components: WorkflowTool trio, ReviewArtifact pair, OverflowTest/TerminalCapture/VerifyPlanExecution/DiscoverSkills, WebBrowserPanel, task dialogs, message variants, ink events/cursor - types: statusLine, fileSuggestion, notebook, messageQueueTypes; SerializedMessage rebuilt as distributed Omit-union so transcript guards narrow again; vitest-compat.d.ts mirrors Bun's runtime 'vitest' → 'bun:test' aliasing - TS2304 names: ant-model helpers imported from existing antModels.ts, inert Ultraplan/Gates/LogoV2 stubs, PromiseWithResolvers local type - build.ts: ACCEPTABLE_RUNTIME_STUBS emptied — both grandfathered bundle-reaching stubs (MonitorMcpDetailDialog, VerifyPlanExecutionTool/constants) are now real typed modules, so the degrade-on-use debt the guard tracked is retired Validation: full suite 3690 green, smoke + bundle guard green, typecheck:type-tests green, sdk package-consumer tests green; baseline lowered via typecheck:ratchet --update. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> * fix(typecheck): reconstruct Message discriminated union — 415 → 342 tsc errors src/types/message.ts was a stub where all ~40 message type aliases were 'export type X = any'. Bare-any aliases break the one thing the union is for: narrowing. Type predicates like isHookAttachmentMessage collapsed to 'never' in guard chains, cascading TS2339/TS2345 through utils/messages.ts, messageFilters.ts, groupToolUses.ts, collapseReadSearch.ts, REPL.tsx, compact.ts, stopHooks.ts and the message components. Envelope design (permissive-body discriminated union): - Each variant declares its literal discriminant(s) — message.type for the envelope union (user/assistant/attachment/progress/system), subtype for the 17-variant System family — plus the properties constructor functions in utils/messages.ts actually populate, with '[key: string]: any' as an escape hatch so unreconstructed properties never error. - UserMessage<C> / AssistantMessage<T> are generic over content shape so NormalizedUserMessage / NormalizedAssistantMessage<T> reuse the envelope without Omit (Omit over an index-signature type collapses keyof to string and silently drops the discriminant, breaking narrowing). - AssistantMessage.message is a structural AssistantMessageContent<T>, not the SDK's BetaMessage: synthetic constructors don't populate every SDK-required field (stop_details), and SDK-facing consumers need assignability to Record<string, unknown>-style bodies. - AttachmentMessage<T = Attachment> / ProgressMessage<T = Progress> stay generic over their payloads (utils/attachments.ts and Tool.ts types). - UI wrappers (GroupedToolUseMessage, CollapsedReadSearchGroup, CollapsibleMessage, RenderableMessage) and stream/control envelopes (StreamEvent over BetaRawMessageStreamEvent, RequestStartEvent, TombstoneMessage, ToolUseSummaryMessage) reconstructed from call sites. - logs.ts SerializedMessage switched from the Omit<Message, never> trick (only sound against an any stub) to an Extract-based distributed union, keeping TranscriptMessage assignable to Message. All other touched files are type-level-only adjustments (annotations on evolving arrays that inferred never[], predicate types, casts in SDK wire adapters and test fixtures) — no runtime logic changed anywhere; the full bun test suite passes 3690/0 before and after. Result: 415 → 342 tsc errors, every never-cascade in the message pipeline resolved, no file above its per-file baseline (ratchet updated). Part of issue #473. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> * fix(typecheck): narrow unknowns and fix signature drift — 342 → 94 tsc errors Clears every remaining non-test error. Honest fixes dominate: evolving array/let/useState/useRef annotations (the repo's noImplicitAny:false disables evolving types), real type guards over unknown wire payloads, hoisted react-compiler-style params annotated with their components' real Props, and callee signature corrections (useRegisterOverlay optional param, generic useVoiceState<T>, growthbook shim's accepted refresh-interval param) that each cleared several call sites. Targeted reason-commented casts only at SDK/stub/wire boundaries; no any, no new suppressions. Runtime deviations are confined to already-broken paths: benchmark.ts imported a function name that never existed (module-load crash), caches.ts called stub methods unguarded (TypeError for ant-gated users), messageActions returned undefined from a string function; CACHE_EDITING_BETA_HEADER is a best-effort reconstruction of a squash-lost constant, reachable only behind feature-gated first-party paths (flagged for review). Also: ConnectorTextBlock gains its wire-proven optional signature field; MCP server factory ambient types gain close(); ink render-node-to-output's nodeType cast fixed (intersection was collapsing the intended widening); upstreamproxy relay normalizes the socket data union. Validation: full suite 3690 green, smoke + bundle guard green; remaining 94 errors are all in test files (PR 5). Baseline lowered via typecheck:ratchet --update. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> * fix(typecheck): clean test typing, gate CI on zero tsc errors — 94 → 0 Closes the typecheck burn-down (issue #473): bun run typecheck now exits 0 across the whole repo and CI fails on any new error. Test typing: new src/test/typedMocks.ts centralizes the two bun:test gaps (asMockFetch — Mock<T> lacks fetch.preconnect; callArgs — argless-signature mocks collapse mock.calls to []). Beyond the helpers, fixes are honest: discriminated-union narrowing before member access, fixture typing with boundary casts, assertion-type corrections, and two tests realigned to production signatures they had drifted from (requestLogging logApiCallEnd args, incrementalTokenCounter tokenBudget rename) with identical assert outcomes. No assertion semantics changed; all touched suites pass. CI: the ratchet served its purpose and is retired — pr-checks now runs a plain `bun run typecheck` step; ratchet script and baseline deleted. Burn-down summary across the series: 697 → 624 (mechanical sweep) → 415 (recreate ~60 missing modules) → 342 (Message discriminated union) → 94 (narrowing + signature drift) → 0 (this PR). Validation: tsc --noEmit exit 0, full suite 3690 green, smoke + bundle guard green. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> * fix(typecheck): reconcile with upstream parallel typecheck fixes Upstream landed #1591/#1592/#1595 while this series was in flight, fixing some of the same errors differently. Rebase resolutions prefer upstream where it is authoritative: their CACHE_EDITING_BETA_HEADER value ('cache-editing-2025-12-01', unconditional) replaces this series' feature-gated reconstruction; their cachedMicrocompact stub shapes (with their new test file) replace ours, with boundary casts in claude.ts where the stub's unknown[] edits meet the local pinned delete-edit shape; their reader/ReadResult stream typing in openaiShim replaces ours. MessageWithoutProgress now matches its name (Exclude<NormalizedMessage, ProgressMessage>), reconciling upstream's RenderableMessage GroupingResult with this series' message union; the @ts-expect-error upstream added for settingsTypes.generated is removed since the module now exists. tsc exit 0; full suite 3697 green (incl. upstream's new cachedMicrocompact tests); smoke + bundle guard green. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> * fix(sdk): keep result usage counters required, fix assistant stub exports Addresses jatmn's and chioarub's review on the typecheck PR: 1. SDK usage contract restored: the generated result types' usage now keeps input_tokens, output_tokens, cache_creation_input_tokens, and cache_read_input_tokens as REQUIRED numbers — result messages are populated from QueryEngine.totalUsage (initialized from EMPTY_USAGE), so they are always present at runtime and strict consumers may sum them without undefined guards. The richer nested metadata (cache_creation, server_tool_use, service_tier) is modeled explicitly instead of hiding behind the index signature; the nested objects carry no index signature so the SDK's interface types stay assignable. Generator override updated and artifacts regenerated; a new package-consumer type test sums the counters and reads the nested fields so this contract cannot silently regress. The sessionHistory test fixture now carries all four counters, matching runtime shape. 2. Assistant install wizard stub mismatch fixed: dialogLaunchers imported NewInstallWizard/computeDefaultInstallDir through a module shape cast, but the assistant stub only exported default — a guaranteed runtime crash if the gated path lit up. The stub now provides real typed exports: a wizard that cancels immediately (so the launcher resolves null/user-cancelled instead of hanging on an empty dialog) and an inert computeDefaultInstallDir; the unsafe cast in dialogLaunchers is gone. Validation: tsc exit 0; full suite 3698 green (incl. the new consumer counters test); smoke + bundle guard green. Co-Authored-By: OpenClaude <openclaude@gitlawb.com> --------- Co-authored-by: OpenClaude <openclaude@gitlawb.com> |
||
|
|
3a308c11d4 |
fix(typecheck): restore control protocol type exports (#1497)
* fix(typecheck): restore control protocol type exports * fix(sdk): align control initialize contract * fix(sdk): expose control initialize response types |
||
|
|
4a4f379b8c |
Add full access mode and fix bypass commit prompts (Issue 1097) (#1110)
* Add full access permission mode Introduce a Full Access mode as a second-level dangerous permission option that bypasses normal confirmation prompts and hard safety-check prompts while still preserving deny decisions. Wire fullAccess through permission mode types, SDK schemas/types, CLI and REPL control paths, settings, mode cycling, spawned teammate inheritance, prompt speculation, and setup safety checks. Update permission handling so Full Access skips ask rules, requiresUserInteraction prompts, content-specific ask results, safety-check asks, and hook-forced asks while preserving updatedInput from tool permission checks. Add a separate Full Access warning acknowledgement and render Full Access selections in red to make the higher-risk mode visually distinct. Allow the project-local .git/OPENCLAUDE_COMMIT_MSG helper file in dangerous modes for /commit while keeping default mode and other .git paths protected by safety prompts. Add focused regression tests for Full Access prompt bypass behavior, hook ask handling, commit message file permissions, mode cycling, spawned teammate propagation, and SDK permission mappings. * fix: restore sdk permission fail-closed behavior Preserve host canUseTool and onPermissionRequest enforcement in fullAccess instead of short-circuiting around SDK policy callbacks. Keep the default SDK permission path fail-closed when no host callback is configured, while still allowing interactive tools to surface guidance prompts under fullAccess. Add focused regression coverage for SDK permission routing and fullAccess user-interaction behavior, plus filesystem coverage for the project-local OPENCLAUDE_COMMIT_MSG path. * fix: complete full access permission mode integrations - keep Full Access out of persisted default permission mode settings - sync Full Access to Claude in Chrome skip-all permission mode - restore Full Access correctly when exiting plan mode - add regression coverage for settings, Chrome sync, and plan-mode exit * test: harden dangerous mode startup flow * feat: add permission mode management tab Add a dedicated permission mode tab for switching session modes from the permissions UI. Keep dangerous modes visible when currently active, route dangerous mode changes through the confirmation dialog without exiting settings, and surface availability errors for auto or bypass modes. Also add focused tests for permission mode option visibility. * feat: add full access approval flows Add fullAccess as an approval option across file, shell, skill, monitor, web fetch, fallback, and plan-exit permission prompts. Introduce a shared dangerous-mode confirmation hook, wire fullAccess session mode updates through the permission handlers, and gate the new option on dangerous-mode availability. Also fix the plan-exit follow-up review findings by preserving hook order around the dangerous-mode dialog and restoring Shift+Tab to the explicit accept-edits approval path. Verified with focused permission tests and Bun module import smoke checks. * Harden dangerous permission mode boundaries Tighten fullAccess and bypassPermissions entry paths so elevated mode always respects explicit local confirmation and authoritative org policy gates. This hardens SDK and bridge activation, Chrome integration, session resume and rewind restoration, team and plan mode transitions, and shared permission update handling. It also keeps session dangerous-mode state in sync and adds focused regression coverage for permission setup, killswitch behavior, conversation recovery, and SDK permission flows. * refactor: centralize permission mode transitions Route permission mode changes through shared decision and live-transition helpers so dangerous/full-access confirmation, plan/auto side effects, and mode application stay aligned across CLI, REPL, prompts, and swarm surfaces. Add a shared UI request hook for resolved dangerous-mode confirmations, persist in-session dangerous-mode acceptance, and remove duplicated request/confirm/apply flows from prompt input, teams, plan exit, and permission settings. Also fix follow-up correctness issues by validating all setMode updates consistently, applying live permission updates before persisting them, and rebasing those live updates on the latest permission context to avoid partial commits or stale-state overwrites. * refactor: simplify permission request flows Centralize permission mode changes behind requestPermissionModeChange and reuse it from the CLI, REPL bridge, inbox poller, and UI callers. Consolidate duplicated permission request behavior by introducing shared shell and simple permission helpers, routing file permission actions through a shared executor, and unifying remote permission queue-item construction. Add a shared PermissionScaffold for the common dialog frame, remove redundant shell option/helper modules, and keep focused permission mode transition coverage in permissionSetup tests. * Enable full access from the permissions UI Expose bypass/full-access modes in the /permissions picker so dangerous modes can be enabled in-session instead of only via launch flags. Propagate a session-only bypass-enable signal through the permission mode change flow, preserve the existing dangerous-mode confirmation and policy checks, and keep the session marked as bypass-capable after the user enables one of the dangerous modes. Also add targeted tests covering picker visibility, local session unlock behavior, and the post-enable session state. * Refine bypass permissions warning copy * fix(powershell): anchor commit message .git exception to project root Align the PowerShell .git write safety exception for .git/OPENCLAUDE_COMMIT_MSG with the shared filesystem permission rule. The PowerShell helper was resolving the path from the mutable shell cwd, which made the bypassPermissions and fullAccess cases order-sensitive in the full test suite. Resolve the exception from getOriginalCwd() instead so the temp commit message file is only exempted inside the project root .git directory while other .git writes still require a safety prompt. Verified with: - bun test src/tools/PowerShellTool/powershellPermissions.test.ts --max-concurrency=1 - bun test src/utils/permissions/filesystem.test.ts --max-concurrency=1 - bun test src/tools/PowerShellTool src/utils/permissions --max-concurrency=1 * test: fix dangerous mode prompt suite hang * Fix monitor permission test isolation * Harden monitor permission state selector --------- Co-authored-by: JATMN <12479882+jatmn@users.noreply.github.com> Co-authored-by: TechBrewBoss <dash@hicap.ai> |
||
|
|
9190bd0c50 |
Harden test isolation and smoke checks (#1440)
* fix(test): isolate provider-related attribution and preconnect tests
Remove process-global provider mocks from apiPreconnect tests and exercise real env-based provider resolution with hermetic first-party setup.
Reset bootstrap/settings state around attribution tests and reload the attribution module per test so provider and client state cannot leak across suites.
Verification: bun test --max-concurrency=1 src/utils/apiPreconnect.test.ts src/utils/attribution.test.ts
* Fix full local check failures
Add a check script that runs smoke plus the full single-concurrency Bun test suite, and wire it into CONTRIBUTING, the PR template, and PR checks.
Fix Windows/full-suite failures by preferring Git Bash over the WSL bash launcher, normalizing settings paths before source matching, making path and warning-glyph tests platform-aware, and restoring persistent Bun module mocks for AgentTool and hook-chain tests.
Verified with bun test src\tools\BashTool\BashTool.errorOutput.test.ts --max-concurrency=1 and bun run check.
* fix(test): eliminate mock.module() leaks and platform-specific test failures
## Problem
The full test suite (bun test --max-concurrency=1) had 10 failing tests on
Windows. Investigation revealed 4 distinct root causes, all stemming from
bun's mock.module() not being fully reversible by mock.restore(). When a
test file replaces a shared module via mock.module(), stale bindings persist
in already-imported modules even after mock.restore() is called. This is a
known bun limitation.
The CI (Ubuntu) only showed 1 consistent failure (the attribution test),
but the Windows-local failures exposed real bugs that could surface in CI
under different test ordering.
## Changes
### src/utils/hookChains.integration.test.ts (root polluter)
This file was the biggest source of test pollution with 9 mock.module()
calls replacing shared modules (analytics, growthbook, policyLimits,
teammateMailbox, teammate, AgentTool, replBridge, etc.) with partial
surfaces. For example, the teammateMailbox mock only exported writeToMailbox
but the real module has 20+ exports including isIdleNotification,
createIdleNotification, readMailbox, etc. When mock.restore() didn't fully
undo these mocks, downstream tests got undefined for missing exports.
Fix: Import real modules via cache-busted dynamic imports before setting up
mocks, then spread the real module surface into each mock.module() call.
This way even if the mock leaks, downstream tests see the full module
surface with only the intended overrides. All 9 mock.module calls now
spread their real module counterparts.
Also fixed: the test was failing in isolation with SyntaxError because
attachments.ts transitively imports isIdleNotification from
teammateMailbox.js, which was missing from the partial mock.
### src/utils/settings/changeDetector.test.ts (Windows path normalization)
4 tests failed because getSourceForPath() normalizes paths using
path.normalize() which converts forward slashes to backslashes on Windows.
The test hardcoded Unix-style paths (/tmp/openclaude/user/settings.json)
but path.normalize produces \tmp\openclaude\user\settings.json on
Windows. The path comparison always failed, so handleChange() returned
early without triggering any callbacks or debounce timers.
Fix: Import normalize from 'path' and apply it to all test path constants
(pathsBySource, getManagedSettingsDropInDir). This matches what the
production code does.
### src/utils/exportFormats.test.ts (Windows path separator)
resolveExportFilepath() uses path.join() which produces backslash-separated
paths on Windows. The test expected forward-slash paths.
Fix: Import join from 'path' and use it in the expected value so the
assertion is platform-agnostic.
### src/utils/file.test.ts (growthbook mock leak)
importFileModuleWithKillswitchEnabled() mocked growthbook.js with only
getFeatureValue_CACHED_MAY_BE_STALE: () => killswitchEnabled. When
killswitchEnabled was false, this poisoned isAgentSwarmsEnabled() for all
downstream tests because agentSwarmsEnabled.ts has a static import of
getFeatureValue_CACHED_MAY_BE_STALE that captured the mock binding.
Fix: Import the real growthbook module and spread it into the mock, so
all exports remain available even if the mock leaks.
### src/utils/plugins/officialMarketplaceStartupCheck.test.ts (same pattern)
Same growthbook mock leak pattern. Top-level mock.module with only
getFeatureValue_CACHED_MAY_BE_STALE: () => true.
Fix: Import real growthbook module and spread into mock.
### src/tools/AgentTool/AgentTool.teammateModel.test.ts (transitive mock binding)
4 tests failed with 'Agent Teams is not yet available on your plan' because
isAgentSwarmsEnabled() returned false. The function checks
getFeatureValue_CACHED_MAY_BE_STALE('tengu_amber_flint', true) from
growthbook.js, but the static import binding in agentSwarmsEnabled.ts was
captured from a leaked mock that returned false.
Cache-busting the AgentTool.js import doesn't help because
agentSwarmsEnabled.ts is a transitive dependency that keeps its
already-loaded (mocked) growthbook binding.
Fix: Add mock.module for agentSwarmsEnabled.js in importAgentToolWithSpawnMock()
to pin isAgentSwarmsEnabled to true, matching the test's intent (it sets
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1).
## Verification
- bun run smoke: passes
- bun test --max-concurrency=1: 3019 pass, 0 fail (verified twice)
- No skipped tests (test.skip/it.skip/describe.skip), no test.todo,
no flaky markers, no test exclusions in config
## Known remaining risks
6 test files still have partial mock.module() calls on providers.js
(withRetry, officialRegistry, domainCheck, conversationRecovery, fastMode)
that don't spread the real module. These don't cause failures under current
test ordering but are latent risks if bun changes file execution order.
* Fix remaining provider mock leak risks
Address the known remaining risks from
|
||
|
|
f12eb1c9e8 |
Harden test isolation for smoke stability (#1192)
* Fix flaky smoke build checks Replace feature-flag build preprocessing with a Bun onLoad transform so smoke/build no longer rewrites tracked src files while tests may be reading them. Keep telemetry stubs ahead of the feature transform in both CLI and SDK builds, preserve non-empty text token counts in hybrid context splitting, and make the corrupted Orama stress test assert against the actual project directory used by the test. Verified with bun run smoke, bun test src/utils/hybridContextStrategy.test.ts, bun test src/utils/knowledgeGraph.stress.test.ts --rerun-each 3, and bun test --max-concurrency=1. * Harden KnowledgeGraph smoke stress isolation Give each KnowledgeGraph stress test its own temporary config directory and remove it during teardown so Orama, SQLite, and corrupted-file state cannot bleed between stress cases or later PR test runs. Reviewed at least 20 open PRs and found the recurring smoke-and-tests failure cluster is the full unit suite, especially KnowledgeGraph corrupted Orama recovery. Verified with bun test src/utils/knowledgeGraph.stress.test.ts --rerun-each 5, bun test --max-concurrency=1, and bun run smoke. * Harden smoke test isolation Audit and harden broad smoke-adjacent test suites for process-global leaks, including env/config restoration, shared registry/module mock cleanup, fetch/axios/mock restoration, and global MACRO/platform/sandbox mutations. Replace fragile render sleeps in interactive tests with output-driven waits, and isolate provider/model/profile tests behind the shared mutation lock so unrelated PRs do not inherit stale process state. Make SQLite knowledge graph cleanup clear closed on-disk databases before best-effort file cleanup, with coverage for the stale database reset path. Verified: bun run smoke; bun test --max-concurrency=1; python -m pytest -q python/tests; bun run security:pr-scan -- --base origin/main; bun run test:provider; npm run test:provider-recommendation. * Harden test isolation across smoke suite Guard process-global test mutations with the shared mutation lock across env, module mock, config cache, and storage tests.\n\nDeep-copy global config snapshots, restore transient globals precisely, and make plugin/LSP mocks expose compatible export surfaces so concurrent test loading does not poison unrelated suites.\n\nReplace fixed SDK cleanup sleeps with call polling to remove timing sensitivity.\n\nVerification:\n- bun test --max-concurrency=1\n- bun run smoke\n- python -m pytest -q python/tests\n- bun run test:provider\n- npm run test:provider-recommendation\n- bun run security:pr-scan -- --base origin/main\n- git diff --check * Close remaining test global-state leaks Guard remaining cache, plugin, console, and VS Code module-mock tests with the shared mutation lock.\n\nThis follow-up audit covers non-env process-global state that can leak across test files: tool schema cache, cache stats tracker state, plugin loader caches, console.error replacement, and VS Code mock.module usage.\n\nVerification:\n- leak-surface scans for env/global/mock.module/cache outliers\n- duplicate top-level mock collision cluster\n- affected tests cluster\n- bun test --max-concurrency=1\n- bun run smoke\n- git diff --check * Guard remaining mock restore cleanup Lock tests that call bun:test mock.restore without installing module mocks themselves.\n\nmock.restore is process-global, so these cleanup hooks can still tear down another test file's active module mocks when files run concurrently.\n\nVerification:\n- expanded leak scans for env, globals, module mocks, mock.restore, timers, argv, and caches\n- bun test src/components/useCodexOAuthFlow.test.tsx src/services/github/deviceFlow.test.ts\n- bun test --max-concurrency=1\n- bun run smoke\n- git diff --check * Harden test isolation for smoke stability Serialize tests that mutate process-global state behind the shared mutation lock, including process.env, transient globals, global config/cache state, storage mocks, and Bun module mocks. Add isolated env mutex instances for SDK mutex tests so timeout coverage no longer manipulates the live process-global mutex. Move top-level mock.module setup behind lock acquisition and restore mocks before releasing locks to prevent cross-file leakage under parallel smoke runs. Verified with: bun test --max-concurrency=1; bun test; bun run smoke. |
||
|
|
94e8ff3941 |
chore: centralize Bun version and refresh CI tool pins (#1171)
* chore: centralize Bun version and refresh CI tool pins - add .bun-version as the shared Bun source of truth for workflows and Docker builds - update PR and release workflows to read Bun from bun-version-file - refresh pinned GitHub Actions and Docker action SHAs to newer low-risk releases - align contributor docs with Bun 1.3.13 guidance * test: stabilize reset and provider profile persistence Harden knowledge graph reset behavior across Windows file-lock scenarios by improving SQLite and JSON reset signaling, preserving a safe JSON source of truth when SQLite cannot be cleared, and adding direct storage regression coverage. Also centralize deterministic config-home handling for tests, tighten provider profile persistence path resolution and cleanup semantics, isolate environment-sensitive suites with the env mutex, and remove flaky external npx dependency from the SDK consumer type test. * test: fix Codex OAuth callback flake Investigate the real provider smoke failure from GitHub Actions and fix the root cause instead of patching the symptom. - make Codex OAuth callback host explicit and consistent across redirect URI generation and listener binding - allow safe loopback host overrides for localhost, 127.0.0.1, and ::1 - harden Codex OAuth tests with env/fetch isolation so they do not poison neighboring provider suites - pin the OAuth callback tests to 127.0.0.1 to avoid localhost IPv4/IPv6 family mismatch flakes in CI Validated with bun test src/services/api/codexOAuth.test.ts, bun test src/services/api/providerConfig.codexSecureStorage.test.ts, and bun run test:provider. * test: harden Codex OAuth callback tests Investigate the recurring provider-smoke OAuth failures across multiple PR runs and fix the flaky callback test design at the root. - remove the free-port reservation race from Codex OAuth tests - add bounded callback retry only for loopback listener warm-up during the in-process OAuth test flow - move ephemeral callback port support into an explicit CodexOAuthService test seam instead of widening production env parsing - keep runtime callback-port semantics unchanged while adding regression coverage for callback host and port parsing Validated with targeted Codex OAuth tests and repeated provider-bucket reruns to check for recurring flake. * test: serialize provider shared-state suites Fix the recurring provider smoke flake at the root cause by serializing test suites that mutate process.env or globalThis.fetch. Add a shared test mutation lock and wire it into the provider bucket so Codex OAuth no longer races with unrelated provider/config/openai shim tests under Bun's parallel test execution. Cleanup now releases the lock in finally blocks, and the shared lock waits indefinitely by default to avoid timeout-based CI flakes. * test: fix smoke root causes and noisy suites Replace the Codex OAuth test's live loopback listener dependency with an injected listener seam, avoid module-mock leakage across provider suites, and clean up the auth-code listener test setup. Also harden noisy storage and search tests by asserting expected log output, isolating SQLite masterpiece persistence per test cwd, and removing routine benchmark/stress logging from passing runs. * build: harden Bun version install in Docker Validate the repo-tracked .bun-version value before using it in the Docker build stage, strip line endings, and install Bun through a quoted semver-only variable instead of raw shell expansion. * test: replace flaky conversation arc benchmark Fix the recurring smoke failure caused by an absolute wall-clock assertion in the normal unit suite. Replace the CI-speed-sensitive conversation arc benchmark with deterministic regression coverage that verifies repeated fact extraction, expected entity shapes, bounded graph growth, and populated-summary behavior. * test: isolate shared-state smoke suites * test: restore codex credential mocks between suites * test: fix shared-state and provider init-order flakes * test: isolate remaining shared-state smoke suites Serialize the remaining smoke-sensitive suites that mutate process env, CLAUDE_CONFIG_DIR, fetch, or SDK session globals. Add shared lock coverage to discovery, agent/skills loading, platform storage, and SDK lifecycle/preserved-segment tests. Restore session and cwd state inside the lock boundary so parallel files cannot leak bootstrap state into knowledge graph and SDK isolation tests. Validated with repeated smoke and full-suite passes: - bun run smoke (2x) - bun test - bun test --max-concurrency=1 - bun run test:provider - python -m pytest -q python/tests - npm run test:provider-recommendation |
||
|
|
d19f4d335d | fix flaky test (#1021) | ||
|
|
1f66d322ad | fix flaky tests in full test run (#1020) | ||
|
|
60c76b6599 |
feat: SDK Runtime — Query Engine, Sessions, and Build Pipeline (#984)
* feat(sdk): add SDK foundation — type declarations, errors, and utilities Adds standalone SDK building blocks with no SDK source dependencies: - sdk.d.ts: ambient type declarations for SDK bundle - coreSchemas.ts + coreTypes.generated.ts: Zod schemas and generated types - errors.ts: SDK-specific error classes - validation.ts: input validation utilities - messageFilters.ts: extracted message filter logic - handlePromptSubmit.ts: imports from messageFilters - 16 generated-types tests * fix(sdk): narrow assertFunction type from broad Function to callable signature Code review finding: assertFunction used `asserts value is Function` which accepts any function-like value without narrowing. Changed to `(...args: any[]) => any` for better type safety. * fix(sdk): update sdk.d.ts header — manually maintained, not generated Reviewer noted the header said "Generated from index.ts" but no generator produces this file. Updated to "Manually maintained — keep in sync with index.ts". Drift detection added in validate-externals.ts (PR 3). * fix(sdk): align sdk.d.ts types with canonical coreTypes.generated.ts Tighten SDK public type contract to resolve reviewer blockers: - PermissionResult: unknown[] → precise 6-shape discriminated union (addRules/replaceRules/removeRules/setMode/addDirectories/removeDirectories) - SDKSessionInfo: snake_case → camelCase (sessionId, lastModified, etc.) - ForkSessionResult: session_id → sessionId - SDKPermissionRequestMessage: uuid + session_id now required - SDKPermissionTimeoutMessage: added uuid + session_id - SessionMessage: parent_uuid → parentUuid - SDKMessage/SDKUserMessage/SDKResultMessage: replaced loose inline definitions with re-exports from coreTypes.generated.ts * feat(sdk): wire existing code modules + SDK shared utilities Modifies core modules for SDK integration: - QueryEngine, tools, state, commands: SDK type hooks - SDK shared utilities (shared.ts, permissions.ts) - 21 SDK tests (shared-utils, permissions) Stack: main ← pr1-foundation ← pr2-sdk-core * feat(sdk): add snake_case ↔ camelCase key mapping utilities casing.ts provides recursive key transformation for the SDK boundary layer. Internal runtime uses snake_case; public API exposes camelCase. Will be used by shared.ts, sessions.ts, query.ts at export boundaries. * test(sdk): add tests for snake_case ↔ camelCase mapping utilities Covers snakeToCamel, camelToSnake, mapKeysToCamel, mapKeysToSnake including nested objects, arrays, null/undefined, and round-trips. * feat(sdk): add SDK runtime — query engine, sessions, build pipeline Completes the SDK implementation: - SDK build target (dist/sdk.mjs) with TUI dependency stubbing - External dependency lists (scripts/externals.ts) - SDK type generation from Zod schemas (scripts/generate-sdk-types.ts) - External validation (scripts/validate-externals.ts) - SDK source: index, query, v2, sessions modules - agentSdkTypes: re-exports SDK functions (query, createSession, etc.) - 136 SDK tests + 7 build scanner tests Stack: main ← pr1-foundation ← pr2-sdk-core ← pr3-sdk-runtime * fix(sdk): align internal SDK types with camelCase public contract shared.ts: SDKSessionInfo, ForkSessionResult, SessionMessage fields now use camelCase matching sdk.d.ts. SDKPermissionRequestMessage and SDKPermissionTimeoutMessage gain required uuid + session_id fields. permissions.ts: onPermissionRequest/onTimeout callbacks now include uuid and session_id in emitted messages. * fix(sdk): update runtime modules to use camelCase field names sessions.ts: toSDKSessionInfo outputs camelCase keys, entryToSessionMessage uses parentUuid, forkSession returns sessionId. query.ts: reads sessionId from listSessions/forkSession results instead of snake_case session_id. * fix(test): update session tests to use camelCase field names session_id → sessionId in forkSession result assertions and getSessionMessages calls. * fix(sdk): prevent permission timeout race condition with once-only resolve wrapper Add createOnceOnlyResolve utility to prevent double-resolution of promises when timeout and host response happen simultaneously. This ensures deterministic behavior in the permission handling flow. * fix(sdk): improve race condition test robustness * fix(sdk): handle consecutive underscores in snakeToCamel conversion Changes: - Use _+([a-z]) regex to match multiple consecutive underscores before letters - Add lookahead (?=. ) to preserve underscore-letter pairs at string end - Handle dunder names (__proto__, __typename) by stripping wrapper and capitalizing - Add tests for consecutive underscores and trailing underscore preservation * fix(sdk): include original error message in permission callback denial When a canUseTool callback throws an error, the catch block now includes the original error message in the denial message, making debugging easier for SDK consumers. * feat(sdk): add optional timeout to env mutex for deadlock prevention Add timeout parameter to acquireEnvMutex() to prevent infinite waits in deadlock scenarios. The timeout is optional and defaults to no timeout (wait forever) for backward compatibility. Returns a MutexAcquireResult object with acquired status and optional timeout reason for failed acquisitions. * fix(sdk): remove timed-out callback from mutex queue to prevent deadlock * test(sdk): add missing error path and timeout scenario tests Add tests for timeout scenarios when host doesn't respond to permission requests, fallback behavior when no onPermissionRequest callback, and MCP connection edge cases for undefined/empty config. * fix(sdk): address code review issues - race conditions, validation, error handling - Add createPermissionTarget() factory that applies onceOnlyResolve at registration time, fixing race condition where timeout and host response could both try to resolve the same promise - Add try-catch to releaseEnvMutex() to prevent permanent lock if callback throws - Extract DEFAULT_PERMISSION_TIMEOUT_MS constant (30 seconds) - Add MCP config validation rejecting null, non-objects, and arrays - Preserve error stack traces in MCP connection failures - Add runtime validation to mapMessageToSDK for null/non-object/invalid type - Update tests to use createPermissionTarget and add validation tests * fix(sdk): syntax fixes and MCP connection error handling - Remove extra closing parenthesis in permissions.ts - Remove extra closing braces in shared.ts type definitions - Wrap MCP connection in try/catch to continue without MCP tools on failure * fix(sdk): syntax fixes, MCP error handling, and logic clarity - Remove extra closing parenthesis in permissions.ts - Remove extra closing braces in shared.ts type definitions - Wrap MCP connection in try/catch to continue without MCP tools on failure - Clarify thinkingConfig logic: use ?? true instead of !== false - Add explanatory comment about thinkingEnabled default behavior - Apply createOnceOnlyResolve wrapper in QueryImpl.registerPendingPermission * fix(sdk): comprehensive error handling and resource cleanup - Add try-catch around injectAgents() to gracefully handle plugin agent tool validation failures (prevents test crashes from unknown 'LS' tool) - Add console.warn logging to agent loading/injection catch blocks for debugging visibility (matches v2.ts pattern) - Add pendingPermissionPrompts.clear() to close() and interrupt() methods in both query.ts and v2.ts to prevent memory accumulation - Add close() method to SDKSession interface and SDKSessionImpl - Wrap MCP connection in query.ts with try-catch (matches v2.ts behavior) - Add timeoutQueue cleanup in finally blocks (query.ts + v2.ts) - Remove error.stack from MCP error messages to prevent internal path leak All 208 SDK tests pass. TypeScript errors are pre-existing. * fix(sdk): address code review non-blocking issues - Add SDKAgentLoadFailureMessage type for agent load failure events - Emit agent definition/injection failures to SDK message stream - Add tool name to permission timeout denial message - Replace 'as any' casts with proper typed state access - Fix supportedCommands to use correct mcp.commands/plugins.commands paths - Update test for correct AppState structure * fix(sdk): address code review blocking and non-blocking issues Blocking Issues Fixed: - MCP cleanup missing on session/query close - now disconnects MCP clients to prevent resource leaks in long-running processes with multiple sessions - Engine reference not cleared on close - now sets _engine = null to prevent memory leaks - Added MCP cleanup tests (9 new tests covering cleanup scenarios) Non-Blocking Issues Fixed: - Removed redundant catch block that just rethrew errors (query.ts) - Fixed inconsistent timeout denial message format (permissions.ts) - Fixed hardcoded tool name 'Bash' in test (permissions.test.ts) - Exported PermissionResolveDecision type for SDK consumers (index.ts) All 217 SDK tests pass. * fix(sdk): address code review type consistency issues - Add close() method to SDKSession interface (documented but missing from type) - Fix SDKSessionInfo, ForkSessionResult, SessionMessage field naming: snake_case → camelCase to match sdk.d.ts public contract and implementation - Add uuid and session_id to SDKPermissionTimeoutMessage for correlation - Fix JSDoc comment in forkSession to use sessionId (not session_id) These changes align internal types (shared.ts) with the public SDK contract (sdk.d.ts) and actual implementation output. The merge from origin/main introduced snake_case types that mismatched camelCase implementation and tests. * fix: restore openclaude.json comment in REPL.tsx Merge |
||
|
|
a46b31c3ec |
feat: SDK Core — Permission System, Async Context, and Engine Extensions (#951)
* feat(sdk): add SDK foundation — type declarations, errors, and utilities
Adds standalone SDK building blocks with no SDK source dependencies:
- sdk.d.ts: ambient type declarations for SDK bundle
- coreSchemas.ts + coreTypes.generated.ts: Zod schemas and generated types
- errors.ts: SDK-specific error classes
- validation.ts: input validation utilities
- messageFilters.ts: extracted message filter logic
- handlePromptSubmit.ts: imports from messageFilters
- 16 generated-types tests
* fix(sdk): narrow assertFunction type from broad Function to callable signature
Code review finding: assertFunction used `asserts value is Function` which
accepts any function-like value without narrowing. Changed to
`(...args: any[]) => any` for better type safety.
* fix(sdk): update sdk.d.ts header — manually maintained, not generated
Reviewer noted the header said "Generated from index.ts" but no generator
produces this file. Updated to "Manually maintained — keep in sync with
index.ts". Drift detection added in validate-externals.ts (PR 3).
* fix(sdk): align sdk.d.ts types with canonical coreTypes.generated.ts
Tighten SDK public type contract to resolve reviewer blockers:
- PermissionResult: unknown[] → precise 6-shape discriminated union
(addRules/replaceRules/removeRules/setMode/addDirectories/removeDirectories)
- SDKSessionInfo: snake_case → camelCase (sessionId, lastModified, etc.)
- ForkSessionResult: session_id → sessionId
- SDKPermissionRequestMessage: uuid + session_id now required
- SDKPermissionTimeoutMessage: added uuid + session_id
- SessionMessage: parent_uuid → parentUuid
- SDKMessage/SDKUserMessage/SDKResultMessage: replaced loose inline
definitions with re-exports from coreTypes.generated.ts
* feat(sdk): wire existing code modules + SDK shared utilities
Modifies core modules for SDK integration:
- QueryEngine, tools, state, commands: SDK type hooks
- SDK shared utilities (shared.ts, permissions.ts)
- 21 SDK tests (shared-utils, permissions)
Stack: main ← pr1-foundation ← pr2-sdk-core
* feat(sdk): add snake_case ↔ camelCase key mapping utilities
casing.ts provides recursive key transformation for the SDK boundary
layer. Internal runtime uses snake_case; public API exposes camelCase.
Will be used by shared.ts, sessions.ts, query.ts at export boundaries.
* test(sdk): add tests for snake_case ↔ camelCase mapping utilities
Covers snakeToCamel, camelToSnake, mapKeysToCamel, mapKeysToSnake
including nested objects, arrays, null/undefined, and round-trips.
* fix(sdk): prevent permission timeout race condition with once-only resolve wrapper
Add createOnceOnlyResolve utility to prevent double-resolution of promises
when timeout and host response happen simultaneously. This ensures
deterministic behavior in the permission handling flow.
* fix(sdk): improve race condition test robustness
* fix(sdk): handle consecutive underscores in snakeToCamel conversion
Changes:
- Use _+([a-z]) regex to match multiple consecutive underscores before letters
- Add lookahead (?=. ) to preserve underscore-letter pairs at string end
- Handle dunder names (__proto__, __typename) by stripping wrapper and capitalizing
- Add tests for consecutive underscores and trailing underscore preservation
* fix(sdk): include original error message in permission callback denial
When a canUseTool callback throws an error, the catch block now
includes the original error message in the denial message, making
debugging easier for SDK consumers.
* feat(sdk): add optional timeout to env mutex for deadlock prevention
Add timeout parameter to acquireEnvMutex() to prevent infinite waits
in deadlock scenarios. The timeout is optional and defaults to no timeout
(wait forever) for backward compatibility.
Returns a MutexAcquireResult object with acquired status and optional
timeout reason for failed acquisitions.
* fix(sdk): remove timed-out callback from mutex queue to prevent deadlock
* test(sdk): add missing error path and timeout scenario tests
Add tests for timeout scenarios when host doesn't respond to permission
requests, fallback behavior when no onPermissionRequest callback, and
MCP connection edge cases for undefined/empty config.
* fix(sdk): address code review issues - race conditions, validation, error handling
- Add createPermissionTarget() factory that applies onceOnlyResolve at
registration time, fixing race condition where timeout and host response
could both try to resolve the same promise
- Add try-catch to releaseEnvMutex() to prevent permanent lock if callback throws
- Extract DEFAULT_PERMISSION_TIMEOUT_MS constant (30 seconds)
- Add MCP config validation rejecting null, non-objects, and arrays
- Preserve error stack traces in MCP connection failures
- Add runtime validation to mapMessageToSDK for null/non-object/invalid type
- Update tests to use createPermissionTarget and add validation tests
* test(sdk): add sequential timeout-then-host-response race condition tests
Adds two tests addressing reviewer request for proof that host response
after SDK timeout is safely handled with no double-resolve or leaked listener:
1. Integration test: stale host resolve called after timeout deny —
verifies no error, no mutation, map cleanup
2. Unit test: raw resolve called exactly once when timeout wins —
directly proves createOnceOnlyResolve prevents second execution
* fix: restore openclaude.json comment in REPL.tsx
Reviewer caught that the comment was incorrectly changed to
~/.claude.json during merge — project has already migrated to
~/.openclaude.json.
* fix(sdk): register pending permission before emitting onPermissionRequest
The previous code emitted onPermissionRequest before calling
registerPendingPermission, so a host responding synchronously from
the callback would find an empty map and its response was lost.
Swap the order so registration happens first.
Adds a regression test for the synchronous host response path.
* fix(sdk): make state setters context-aware for SDK isolation
When running inside runWithSdkContext(), setter functions (regenerateSessionId,
switchSession, setCwdState, setOriginalCwd) now write to the AsyncLocalStorage
context instead of global STATE. This prevents cross-session state leakage in
multi-session SDK scenarios.
Reads were already context-aware; this completes the isolation by making writes
consistent. Outside of SDK context, behavior is unchanged — all writes go to
global STATE as before.
* test(sdk): add context-aware state isolation tests
Tests verify that setters within runWithSdkContext() write to the SDK
context (not global STATE) and that parallel async contexts do not leak
state between sessions. Covers setCwdState, setOriginalCwd,
regenerateSessionId, switchSession, and an end-to-end parallel session
scenario.
* fix(sdk): selective tool schema cache invalidation for multi-engine isolation
Replace global clearToolSchemaCache() in QueryEngine.updateTools() with
selective invalidation that only removes cache entries for tools no longer
in the tool set. This preserves cached schemas for tools that remain,
avoiding unnecessary recomputation for concurrent QueryEngine instances
in multi-session SDK scenarios.
New function invalidateRemovedToolSchemas() handles both simple tool name
keys and schema-variant keys (format: "toolName:{...schemaJSON...}").
* docs(sdk): address PR2 non-blocking documentation and logging issues
- Document request_id vs tool_use_id relationship in shared.ts
(request_id for response correlation, tool_use_id for tracking)
- Add injectable SDKLogger interface to permissions.ts, replacing
direct console.warn calls with logger.warn (hosts can control noise)
- Document Node.js-only AsyncLocalStorage requirement in state.ts
(requires Node.js 12.17.0+ or 14.0.0+)
- Clarify env-mutex is host utility (SDK doesn't mutate process.env)
* fix(sdk): handle throwing onPermissionRequest and fix permission request shape
- Wrap onPermissionRequest in try-catch to clean up pending resolver on throw
- Add uuid and session_id to permission_request message to match SDK schema
- Add regression tests for throwing callback and message shape validation
* fix(sdk): use explicit no-session placeholder for standalone permission prompts
- Add NO_SESSION_PLACEHOLDER constant ('no-session') for permission requests
- Update SDKPermissionRequestMessage doc to explain session_id semantics
- Replace empty string fallback with explicit placeholder
- Add test verifying placeholder behavior when sessionId omitted
* docs(sdk): add example code to permission denial warning
Include canUseTool example in warning message to improve developer
experience and make SDK usage more discoverable for new users.
* fix(sdk): scope parentSessionId to SDK context for parallel isolation
regenerateSessionId({ setCurrentAsParent: true }) was writing to the
process-global STATE.parentSessionId even inside runWithSdkContext(),
allowing one SDK context to overwrite another's parent-session metadata.
Add parentSessionId to the SdkContext type and update both
regenerateSessionId and getParentSessionId to read/write from the
active context when one exists, using an explicit if-else pattern
rather than ?? to avoid undefined fallback leaking across contexts.
The non-SDK CLI path (no active context) continues to use STATE
directly, preserving existing behavior.
---------
Co-authored-by: Ali Alakbarli <ali.alakbarli@users.noreply.github.com>
|
||
|
|
91f93ce615 |
feat: SDK Foundation — Type Declarations, Errors, and Utilities (#866)
* feat(sdk): add SDK foundation — type declarations, errors, and utilities Adds standalone SDK building blocks with no SDK source dependencies: - sdk.d.ts: ambient type declarations for SDK bundle - coreSchemas.ts + coreTypes.generated.ts: Zod schemas and generated types - errors.ts: SDK-specific error classes - validation.ts: input validation utilities - messageFilters.ts: extracted message filter logic - handlePromptSubmit.ts: imports from messageFilters - 16 generated-types tests * fix(sdk): narrow assertFunction type from broad Function to callable signature Code review finding: assertFunction used `asserts value is Function` which accepts any function-like value without narrowing. Changed to `(...args: any[]) => any` for better type safety. * fix(sdk): update sdk.d.ts header — manually maintained, not generated Reviewer noted the header said "Generated from index.ts" but no generator produces this file. Updated to "Manually maintained — keep in sync with index.ts". Drift detection added in validate-externals.ts (PR 3). * fix(sdk): align sdk.d.ts types with canonical coreTypes.generated.ts Tighten SDK public type contract to resolve reviewer blockers: - PermissionResult: unknown[] → precise 6-shape discriminated union (addRules/replaceRules/removeRules/setMode/addDirectories/removeDirectories) - SDKSessionInfo: snake_case → camelCase (sessionId, lastModified, etc.) - ForkSessionResult: session_id → sessionId - SDKPermissionRequestMessage: uuid + session_id now required - SDKPermissionTimeoutMessage: added uuid + session_id - SessionMessage: parent_uuid → parentUuid - SDKMessage/SDKUserMessage/SDKResultMessage: replaced loose inline definitions with re-exports from coreTypes.generated.ts --------- Co-authored-by: Ali Alakbarli <ali.alakbarli@users.noreply.github.com> |