Commit Graph
26 Commits
Author SHA1 Message Date
479b0e8226 fix(sandbox): guard annotateStderrWithSandboxFailures against missing runtime method (fixes Bash on builds without sandbox-runtime) (#1452)
* fix(sandbox): guard annotateStderrWithSandboxFailures against missing runtime method

Fall back to a passthrough when BaseSandboxManager.annotateStderrWithSandboxFailures
is absent, so BashTool no longer throws "is not a function" on every command when the
underlying sandbox-runtime build doesn't provide the method. No behavior change when it
is present.

* fix(sandbox): complete the SDK SandboxManager stubs so they match the CLI's Proxy-noop

The SDK build stubs @anthropic-ai/sandbox-runtime two ways: the native-stub
namespace uses `new Proxy({}, { get: () => noop })` (every access is safe), but
defaultExportOverrides replaces SandboxManager/BaseSandboxManager with hollow
classes that omit annotateStderrWithSandboxFailures. The class form wins in the
SDK bundle, so SDK embedders crash on every Bash command
(`SandboxManager.annotateStderrWithSandboxFailures is not a function`) while the
CLI build — which keeps the Proxy-noop and ships the real native runtime — is
unaffected.

Add a passthrough `annotateStderrWithSandboxFailures` to both stub classes so
they behave like the Proxy form (return stderr unchanged when no real runtime is
present). Combined with the call-site `?? passthrough` guard, the SDK now
degrades gracefully on builds without sandbox-runtime instead of throwing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 05:58:05 +08:00
beardthelionandGitHub f111eaa1b3 feat: enable MCP_SKILLS — discover skill:// resources as invocable skills (#1408)
* feat(mcp-skills): implement MCP skill discovery via skill:// resources

- mcpSkills.ts: fetchMcpSkillsForClient — lists MCP resources, filters skill://
  URIs, reads each via resources/read, parses frontmatter, builds skill commands
  with loadedFrom/source: 'mcp'. Memoized per server name (LRU, size 20).
- isSkillResource: pure helper to detect skill:// URI scheme
- deriveMcpSkillName: namespaced name builder (mcp__<server>__<name>)
- Enable MCP_SKILLS: true in scripts/build.ts

All call sites, cache-invalidation paths, and consumers were already wired
behind feature('MCP_SKILLS'). Only the module itself was missing. Fixes the
"fetchMcpSkillsForClient is not a function" crash (#856) when the flag was
force-enabled without the module present.

* fix(mcp-skills): discard hooks frontmatter from remote MCP skills

A skill:// resource's hooks frontmatter was carried through the
parseSkillFrontmatterFields spread into the Command, and the slash-command
path registered command.hooks as session hooks on invocation. This let any
connected MCP server install local command hooks that later run shell in the
user's workspace, bypassing the loadedFrom === 'mcp' inline-shell guard by
moving the payload into frontmatter hooks instead of the markdown body.

Discard hooks at the MCP construction site so untrusted remote skills can
never become registrable session hooks.

* fix(mcp-skills): discard allowed-tools frontmatter from remote MCP skills

Like hooks, a skill:// resource's allowed-tools frontmatter flowed through
the parseSkillFrontmatterFields spread into the Command. On the user-typed
slash path (/mcp__server__skill) those tools are written into
alwaysAllowRules.command, so a remote MCP server could auto-approve tool
calls (e.g. Bash) that its own skill body then drives the model to make —
with no permission prompt. The inline-shell guard for loadedFrom === 'mcp'
does not cover this.

Discard allowed-tools at the MCP construction site so remote skills can't
auto-grant tools; the model still prompts on each tool use. The model-invoked
SkillTool path already gates non-empty allowedTools via
skillHasOnlySafeProperties, but the slash path bypasses checkPermissions.

* fix(mcp-skills): skip @-mention attachment scanning for remote MCP skill bodies

A skill:// resource's markdown body flows through getMessagesForPromptSlashCommand
into getAttachmentMessages, which scans for @-mentions and MCP resource refs and
reads them before the model continues. skipSkillDiscovery only gates skill
discovery, not @-mention file reads, so a remote skill could embed @~/.ssh/config
or @.env and exfiltrate local file contents into the conversation with no tool
permission prompt — the same class as the already-stripped hooks/allowed-tools.

Gate the scan input on loadedFrom === 'mcp' (new attachmentScanInputForCommand
helper): the body still reaches the model verbatim, but its @-mentions are no
longer auto-read. Thread-level attachments are unaffected (input=null only gates
the user-input branch in getAttachments).
2026-05-31 10:15:07 +08:00
chioarubandGitHub 132539ff79 fix(build): restore /dream slash command in bundled CLI (#1399)
Scope missing-module stubs for relative imports to the importer file so the unmirrored KAIROS dream skill stub no longer replaces the real /dream command module during bundling.
2026-05-31 06:37:05 +08:00
JATMNandGitHub 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.
2026-05-16 15:18:42 +08:00
2c71e09394 chore(build): clean up external dependency validation warnings (#1124)
* chore(build): clean up external dependency validation warnings

Remove 2 unused externals (@opentelemetry/sdk-trace-node, ink) and add
12 missing packages to package.json that are dynamically imported at
runtime but weren't declared as dependencies. Also remove the unused
@opentelemetry/sdk-trace-node dependency.

This eliminates all 13 build validation warnings:
- 8 missing OTel exporter deps (http, proto, grpc variants + prometheus)
- 4 missing AWS SDK deps (bedrock, bedrock-runtime, sts, credential-providers)
- 1 missing Azure dep (@azure/identity)
- ink external pointed to local reimplementation, not npm package
- sdk-trace-node was declared external but never imported

Build validation now passes cleanly with 0 warnings.

Co-Authored-By: OpenClaude <openclaude@gitlawb.com>

* chore(build): eliminate external validation warnings

Remove unused @opentelemetry/sdk-trace-node from externals and package.json
(it's not imported anywhere in src/). Remove ink from SDK_ONLY_EXTERNALS
(the project reimplements ink locally at src/ink/). Add OPTIONAL_RUNTIME_EXTERNALS
list for packages that are dynamically imported but intentionally not direct
deps — OTel protocol exporters and cloud provider SDKs are resolved from
transitive deps or installed by users who need them.

Validation now passes with 0 warnings instead of 13.

Co-Authored-By: OpenClaude <openclaude@gitlawb.com>

* feat(telemetry): full OpenTelemetry purge — remove all tracking dependencies

Replace all @opentelemetry/* runtime dependencies with no-op stubs,
delete OTel-only source modules, and remove 10 @opentelemetry packages
from package.json plus @growthbook/growthbook.

Key changes:
- Delete 5 OTel-only modules (instrumentation, betaSessionTracing,
  bigqueryExporter, logger, firstPartyEventLoggingExporter)
- Replace 9 modules with no-op stubs (sessionTracing, events,
  telemetryAttributes, firstPartyEventLogger, growthbook, index,
  sink, datadog, sinkKillswitch, perfettoTracing)
- Remove all @opentelemetry/* imports from bootstrap/state.ts,
  entrypoints/init.ts, and ~20 caller files
- Remove all OTel counter types, meter/provider state from state.ts
- Clean externals.ts: remove 27 @opentelemetry/* entries
- Clean build.ts: remove OTel native-stub namespace exports
- Simplify no-telemetry-plugin.ts: remove redundant source-level stubs
- Remove 10 @opentelemetry/* + @growthbook/growthbook from package.json
- GrowthBook stub reads local ~/.claude/feature-flags.json for overrides

Co-Authored-By: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>

* fix format

* chore: regenerate lockfile after OTel dependency removal

Co-Authored-By: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>

* fix(growthbook): route gate helpers through local flag overrides

checkStatsigFeatureGate_CACHED_MAY_BE_STALE() and
checkGate_CACHED_OR_BLOCKING() now resolve from
~/.claude/feature-flags.json like getFeatureValue_* does,
so gates like tengu_thinkback, tengu_ccr_bridge, and
VS Code upsells can be flipped on locally. Security gates
(checkSecurityRestrictionGate) remain hard-false.

Also adds 5 tests covering gate helper override behavior
and unifies JSDoc wording for _getFlagValue-routed functions.

Co-Authored-By: OpenClaude (zai-org-glm-5-1) <openclaude@gitlawb.com>

---------

Co-authored-by: OpenClaude <openclaude@gitlawb.com>
2026-05-13 17:07:45 +08:00
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 0f3aa7a incorrectly took main's side for this comment, reverting
PR2 fix c725c48. Project has migrated to ~/.openclaude.json, not ~/.claude.json.

This is the only PR2 fix lost during merge - all other PR2 fixes
(permissions.ts race conditions, state.ts parentSessionId, etc.)
are preserved in PR3 via subsequent fix commits.

* fix(sdk): add missing type declarations to sdk.d.ts

Add SDKAgentLoadFailureMessage and PermissionResolveDecision to sdk.d.ts
to resolve type declaration drift detected by build validation.

- SDKAgentLoadFailureMessage: Agent loading failure notification
  (stage: definitions/injection, error_message)
- PermissionResolveDecision: SDK-specific permission resolution result
  (allow with updatedInput, deny with message + decisionReason)

Build validation now passes: 56 exports match between index.ts and sdk.d.ts.

* fix(sdk): resource leak and null safety in close/interrupt paths

- unstable_v2_prompt: wrap session in try/finally to guarantee
  session.close() on both success and error paths, preventing
  MCP connection and engine resource leaks
- QueryImpl.interrupt(): add null guard on _engine so calling
  interrupt() after close() is a safe no-op instead of throwing
- SDKSessionImpl.interrupt(): add matching null guard for v2
  sessions, consistent with the Query fix
- QueryImpl.close(): call this.interrupt() before cleanup to
  properly stop in-flight engine operations, matching v2's close()
  pattern and ensuring engine.interrupt() runs before nulling

* fix(sdk): abort AbortController in SDKSessionImpl.close() to prevent resource leak

SDKSessionImpl.close() was not aborting the AbortController, unlike
QueryImpl.close() which does. This meant in-flight HTTP requests and
async operations could continue running after session closure.

- Store AbortController reference via _abortController field + late-bind setter
- Abort and null the controller in close(), mirroring QueryImpl pattern
- Also null _appStateStore in close() to release state snapshots
- Wire abortController through createEngineFromOptions return value

* fix(sdk): index ALL entries in byUuid for compact preserved segment

The byUuid map must index system compact_boundary entries, not just
user/assistant. When anchorUuid === boundary.uuid, the relink walk
needs to find the boundary in byUuid.

Changes:
- query.ts: Index ALL non-sidechain entries (user, assistant, system)
- v2.ts: Same fix — index ALL entries, leaf selection user/assistant only
- Add regression test: boundary.uuid as anchorUuid scenario

Test verifies preserved messages kept, stale pre-compact dropped,
post-boundary chain intact when anchorUuid points to boundary itself.

* fix(sdk): complete preserved segment handling for compact resumes

Multiple fixes for compact-aware transcript loading:

1. Index ALL entries in byUuid (including system compact_boundary)
   - Needed when anchorUuid === boundary.uuid

2. Keep anchorUuid when pruning preserved segment entries
   - The anchor is the parent of preserved head after relink
   - Deleting it breaks the conversation chain

3. Filter system entries from final messages
   - compact_boundary is metadata, shouldn't pass to engine

4. Fix test timestamp format (ISO 8601 requires 2-digit hours)
   - '2025-01-04T0:00:00Z' → '2025-01-04T00:00:00Z'

5. Update test expectations for anchor inclusion
   - When anchor is a stale entry, it appears in messages
   - preserved(4) + anchor(1) + post(4) = 9 max

All 224 SDK tests pass.

* fix(sdk): MCP type:sdk tools properly convert SdkMcpToolDefinition to Tool

- Import MCPTool base from tools/MCPTool/MCPTool.js
- Spread MCPTool properties for proper Tool interface compliance
- Add tools field to SdkMcpSdkConfig type declaration
- Add regression tests for type:sdk tools wiring

Fix ensures in-process SDK tools match Tool interface expected
by QueryEngine and permission handlers.

* test(sdk): strengthen preserved segment and MCP tools tests

Preserved segment test improvements:
- Fix content extraction (access message.content, not message)
- Add exact count assert: messages.length === 6
- Add exact content asserts: preserved turn 1/2, post-boundary present
- Assert no stale, no system entries in final messages

MCP tools test additions:
- Direct test of connectSdkMcpServers() function
- Assert clients.length === 0 (in-process, no MCP connections)
- Assert tools.length === 1 with proper name/description
- Verify handler works via direct call (not via Tool.call which needs context)

* fix(sdk): published types complete, init errors fatal, permission session IDs

Three fixes for SDK production readiness:

1. HIGH: Published SDK types incomplete
   - Add coreTypes.generated.d.ts to package.json "files" array
   - sdk.d.ts re-exports from ./sdk/coreTypes.generated.js which was missing
   - TypeScript consumers would get module resolution errors

2. MEDIUM: query() swallows real init() failures
   - Add _engineWasInjected field to track pre-injected vs fresh engine
   - Check _engineWasInjected, not _engine !== null (always true after setEngine)
   - Auth/config/init errors now properly fatal for normal query() calls

3. MEDIUM: SDK permission events lose real session id
   - Pass sessionId to createExternalCanUseTool() in both query.ts and v2.ts
   - Permission_request/timeout messages now have correct session_id
   - Hosts can correlate permission callbacks to sessions

Test result: 225 pass, 0 fail

* fix(sdk): complete package types + dynamic permission session_id

Two fixes for SDK production readiness:

1. Published SDK types now include actual definitions
   - Replace 215-byte wrapper with 63KB coreTypes.generated.ts
   - TypeScript consumers get full type definitions (SDKMessage, etc.)
   - npm pack now includes real generated types

2. Permission event session_id dynamic for all query() paths
   - createExternalCanUseTool accepts string | (() => string | undefined)
   - query.ts passes () => queryImpl.sessionId getter
   - Fresh/fork/continue queries emit correct session_id at event time
   - V2 passes static sessionId (stable at creation/resume)
   - Add 4 tests: static sessionId, getter resolution, undefined fallback, timeout

Test result: 229 pass, 0 fail

* fix(sdk): fix sdk.d.ts for real TypeScript consumer compilation

Two issues prevented external consumers from compiling against packed SDK types:

1. SDKRateLimitError used constructor parameter properties (readonly resetsAt,
   readonly rateLimitType) which are invalid in .d.ts declarations — moved to
   class properties with separate constructor signature.

2. Re-exported SDKMessage/SDKUserMessage/SDKResultMessage were not imported
   into local scope — added import type alongside export type so TypeScript
   can resolve them for use in other declarations within the same file.

Added package-consumer-types.test.ts that compiles a real temp project against
the SDK types with skipLibCheck:false, catching both regressions.

* fix(sdk): eliminate React/Ink imports from SDK bundle

SDK bundle leaked React/Ink imports via tool UI modules, keybindings,
react-compiler-runtime, and spawnMultiAgent's static React import.

Changes:
- Stub root ink.js barrel, tool UI.js, keybindings/, react-compiler-runtime,
  It2SetupPrompt, and React hook files in SDK build
- Add local no-op stub for react/jsx-dev-runtime (jsxDEV returns null)
- Convert spawnMultiAgent's static React/It2SetupPrompt imports to dynamic
  await import() — spawnTeammate logic stays fully intact
- Add post-build leakage validation (fails on from "react"/"ink"/jsx-dev-runtime)
- Remove react/jsx-dev-runtime from SDK externals (now handled by build plugin)

* fix(sdk): wire disallowedTools through permission context

QueryOptions.disallowedTools was declared but never used. buildPermissionContext()
now passes it to alwaysDenyRules.cliArg so getTools() filters denied tools from
the model-visible list. Also added to V2 SDKSessionOptions for API consistency.

* fix(sdk): defer permission warning to execution time

createDefaultCanUseTool() warned at construction time even when the caller
provided canUseTool/onPermissionRequest. Move warning to first actual default
denial so valid SDK consumers never see false warnings. Add tests for
disallowedTools filtering, tool exclusion, and warning timing.

* refactor(sdk): extract transcript helpers + fix permission typing

- Extract shared transcript utilities to transcript.ts
  (parseJsonlEntries, findLastCompactBoundary, applyPreservedSegmentRelinks,
  buildConversationChain, stripExtraFields) deduplicating query.ts and v2.ts

- Add PermissionTarget interface to hide internal pendingPermissionPrompts
  map from createExternalCanUseTool, with deletePendingPermission and
  denyPendingPermission methods on QueryImpl and SDKSessionImpl

- Fix sessionId stability: preserve constructor UUID for fresh queries
  when continue:true finds no existing sessions, and when explicit
  sessionId does not resolve to a valid transcript file

- Add getMcpClients/setMcpClients to QueryEngine for SDK cleanup access

* fix(sdk): resolve remaining TypeScript errors in SDK modules

- Fix PermissionDecision type compatibility: import from types/permissions
  and cast PermissionResolveDecision to PermissionDecision properly

- Fix AsyncIterator/AsyncGenerator: async generators must return
  AsyncGenerator (which implements AsyncIterable), not AsyncIterator

- Fix Map method callable errors: cast additionalWorkingDirectories
  to Map<string, unknown> before calling .set() and .keys()

- Fix ApiKeySource type: map internal ApiKeySource to SDK's narrower
  type using conversion function, spread info before apiKeySource
  to avoid override

- Fix MCP config scope type: cast 'session' scope to ScopedMcpServerConfig
  for connectToServer compatibility

- Add PermissionMode import and cast for decisionReason.mode

- Deny pending permissions in interrupt(): resolve all pending promises
  with deny before clearing the map (both query.ts and v2.ts)

* fix(sdk): correct init skip logic and test mocks

- query.ts: skip init() entirely for injected engines (mocks, SDK host
  overrides) instead of calling init() and swallowing errors. Pass
  { injected: false } from query() factory to distinguish real engine
  from test mocks.
- mock-engine.ts: add getMcpClients() and setMcpClients() methods to
  match QueryEngine API added in this PR.
- permissions.test.ts: use filterToolsByDenyRules instead of getTools
  for disallowedTools tests, with proper base tool fixtures.

* fix: address code review feedback for exports and build script

package.json exports (Breaking Change Mitigation):
- Add "./package.json": "./package.json" for tool compatibility
- Add "./dist/cli.mjs": "./dist/cli.mjs" for CLI bundle access
- Keep ./sdk as sole library entrypoint
- Root import intentionally blocked (CLI-first package, no main field)

build.ts (Bug Fix):
- Add | undefined to result/sdkResult type declarations
- Add optional chaining: result?.success, sdkResult?.success
- Prevents TypeError masking actual build errors when Bun.build throws

tests/sdk/package-consumer-types.test.ts:
- Update simulated exports to match real package.json
- Add tests verifying exports map structure and file existence

---------

Co-authored-by: Ali Alakbarli <ali.alakbarli@users.noreply.github.com>
2026-05-04 20:56:30 +08:00
JATMNandGitHub 3d791bf07f Disable feedback/mobile commands and refresh OpenClaude branding (#980)
- disable /feedback and /mobile from command availability while keeping implementation code in place
- remove or rewrite lingering user guidance that pointed to /feedback or /mobile
- switch HelpV2 to a public build version helper and fix the help dialog wrapper regression
- update OpenClaude-facing links and prompt copy for issue reporting and branding consistency
2026-05-04 16:18:17 +08:00
KRATOSandGitHub ee0d930093 fix(ripgrep): use @vscode/ripgrep package as the builtin source (#911) (#932)
The vendored-binary lookup at vendor/ripgrep/<arch>-<platform>/rg never
resolved in this fork — that directory does not ship — so users without
a system rg had no working fallback. Switch to the @vscode/ripgrep
package so Microsoft maintains the platform/arch matrix and the binary
is delivered via npm.

- src/utils/ripgrep.ts: replace hand-rolled vendor-path resolution with
  rgPath from @vscode/ripgrep. Lazy require so a missing package falls
  through to the system rg branch instead of throwing at import.
  Drop builtinExists from the config args; builtinCommand is now a
  string-or-null. The system override (USE_BUILTIN_RIPGREP=0), the
  Bun-compiled standalone embedded mode, the macOS codesign hook, and
  all retry/timeout/error logic are preserved untouched.
- scripts/build.ts: mark @vscode/ripgrep as external. The package
  resolves rgPath via __dirname at runtime, so bundling would freeze
  the build host's absolute path into dist/cli.mjs.
- src/utils/ripgrep.test.ts: update for the new config shape and add
  tests covering USE_BUILTIN_RIPGREP=0, embedded mode, last-resort
  fallback, and null builtin path.

Tested locally on Linux (Bun 1.3.13). macOS (codesign hook) and
Windows (rg.exe extension) need contributor verification.
2026-04-30 00:58:46 +08:00
KRATOSandGitHub dcbe29558a fix(mcp): disable MCP_SKILLS feature flag — source not mirrored (#872)
Closes #856.

MCP servers that expose resources (e.g. RepoPrompt) failed to load
their tools in the open build with:

    Error fetching tools/commands/resources:
    fetchMcpSkillsForClient is not a function

Root cause: scripts/build.ts set MCP_SKILLS: true, which made
feature('MCP_SKILLS') evaluate to true at build time. The guards
around the dynamic skill discovery path therefore stayed live. The
underlying source file src/skills/mcpSkills.ts is not mirrored into
the open tree, so the bundler fell back to its generic missing-module
stub — which only exports `default` for require()-style imports, not
the named `fetchMcpSkillsForClient` binding. At runtime the require
returned an object without that property, and calling it threw.

`openclaude mcp doctor` reported RepoPrompt as healthy because doctor
does not exercise the skills-fetch path.

Fix: flip MCP_SKILLS to false and move it into the "Disabled: missing
source" group. With the flag off, every `if (feature('MCP_SKILLS'))`
guard becomes a no-op at build time, the require() branch is dead
code, and MCP servers with resources load normally via the existing
`Promise.resolve([])` fallbacks already present at each call site.

Also adds scripts/feature-flags-source-guard.test.ts to fail fast if
MCP_SKILLS (or any future flag in the same category) is re-enabled
without the corresponding source file being mirrored first.

Verification:
  - Test fails on main, passes with this fix
  - `bun run build` produces a bundle with no
    `missing-module-stub:../../skills/mcpSkills.js` reference
  - Full `bun test` — 1222 pass / 12 fail (same pre-existing 12 as
    main; new test adds the +1 pass)
2026-04-24 11:35:59 +08:00
Nourrisse FlorianandGitHub 6a62e3ff76 feat: enable 15 additional feature flags in open build (#667)
* feat: enable 16 additional feature flags in open build

Activate features whose source is fully available in the mirror and
that have no Anthropic-internal infrastructure dependencies:

UI/UX: MESSAGE_ACTIONS, HISTORY_PICKER, QUICK_SEARCH, HOOK_PROMPTS
Reasoning: ULTRATHINK, TOKEN_BUDGET, SHOT_STATS
Agents: FORK_SUBAGENT, VERIFICATION_AGENT, MCP_SKILLS
Memory: EXTRACT_MEMORIES, AWAY_SUMMARY
Optimization: CACHED_MICROCOMPACT, PROMPT_CACHE_BREAK_DETECTION
Safety: TRANSCRIPT_CLASSIFIER
Debug: DUMP_SYSTEM_PROMPT

Also reorganize featureFlags into documented sections (disabled/upstream/new)
with inline comments explaining each flag's purpose.

* feat: add centralized GrowthBook defaults map for open build

Add _openBuildDefaults in the GrowthBook stub (no-telemetry-plugin.ts)
with all 66 runtime feature keys, organized by category with inline
comments describing each flag's purpose.

Override tengu_sedge_lantern (AWAY_SUMMARY) and tengu_hive_evidence
(VERIFICATION_AGENT) to true so these features work out of the box
without requiring manual ~/.claude/feature-flags.json setup.

Priority: feature-flags.json > _openBuildDefaults > upstream default

* feat: replace refusal language with positive security guidance

Remove refusal instructions from CYBER_RISK_INSTRUCTION since they are
redundant for Anthropic models (applied server-side) and useless for
uncensored models in multi-provider setups. Keep positive guidance for
security testing contexts and add red teaming support.

* Revert "feat: replace refusal language with positive security guidance"

This reverts commit 0463676a8f.

* fix: add EXTRACT_MEMORIES runtime gate overrides to open-build defaults

EXTRACT_MEMORIES was enabled at build-time but its runtime GrowthBook
gates (tengu_passport_quail, tengu_coral_fern) still defaulted to false,
preventing the feature from activating. Add both keys to
_openBuildDefaults so memory extraction works out of the box.

Also adds test coverage for _openBuildDefaults precedence behavior.

* docs: update GrowthBook runtime keys catalog to 88 keys

Expand the reference catalog in no-telemetry-plugin.ts from ~62 to 88
unique keys, covering all tengu_* call sites found in src/. Adds 27
previously undocumented keys including VSCode gates, dynamic configs
(auto-mode, cron, bridge), security gates, and KAIROS cron keys.

Adds "not exhaustive" disclaimer as suggested by Copilot reviewer.
Reorganizes categories with section dividers for readability.
2026-04-21 18:34:51 +08:00
Nourrisse FlorianandGitHub a00b7928de fix: strip comments before scanning for missing imports (#676)
* fix: strip comments before scanning for missing imports

The scanForMissingImports regex matched require() and import() patterns
inside JSDoc comments, causing false-positive missing module detection.
A documented path like `require('./commands/proactive.js')` in a comment
was resolved from the wrong directory, marked as missing, then the global
onResolve handler intercepted ALL imports of that specifier — including
valid ones — replacing them with truthy noop stubs that broke runtime.

Strip block (/* */) and line (//) comments from source before scanning.

* fix: repair 10 pre-existing test failures

- promptIdentity.test.ts: define MACRO global (ISSUES_EXPLAINER etc.)
  for test mode where Bun.define build-time replacements aren't active
- context.test.ts: clear OPENAI_MODEL env var in each test — the user's
  environment (e.g. OPENAI_MODEL=github_copilot/gpt-5.4) polluted the
  provider-qualified lookup, returning wrong context windows
- openclaudePaths.test.ts: set CLAUDE_CONFIG_DIR to force .openclaude
  path when ~/.openclaude doesn't exist on the test machine
2026-04-15 19:42:26 +08:00
Nourrisse FlorianandGitHub 252808bbd0 feat: activate message actions in open build (#632)
Enable the MESSAGE_ACTIONS feature flag so open-build users get the
shift+up keybinding for the message actions panel.

Gate sites: src/keybindings/defaultBindings.ts, src/screens/REPL.tsx
(5 total). Pure UI/keybinding feature with zero external dependencies.
2026-04-13 21:48:29 +08:00
Nourrisse FlorianandGitHub b818dd5958 feat: implement Monitor tool for streaming shell output (#649)
* feat: implement Monitor tool for streaming shell output

Add the Monitor tool that executes shell commands in the background and
streams stdout line-by-line as notifications to the model. This enables
real-time monitoring of logs, builds, and long-running processes.

Implementation:
- MonitorTool (src/tools/MonitorTool/) — spawns LocalShellTask with
  kind='monitor', returns immediately with task ID
- MonitorMcpTask (src/tasks/MonitorMcpTask/) — task lifecycle management
  and agent cleanup via killMonitorMcpTasksForAgent()
- MonitorPermissionRequest — permission dialog component

The codebase already had all integration points wired (tools.ts, tasks.ts,
PermissionRequest.tsx, LocalShellTask kind='monitor', BashTool prompt).
This PR provides the missing implementations.

* fix: command-specific permission rule + architecture docs

- MonitorPermissionRequest: "don't ask again" now creates a
  command-prefix rule (like BashTool) instead of a blanket
  tool-name-only rule that would auto-allow all Monitor commands
- MonitorMcpTask: clarify architecture comments explaining why
  monitor_mcp type exists as a registry stub while actual tasks
  are local_bash with kind='monitor'

* fix: address Copilot review feedback

- Fix permission rule field: expression → ruleContent (Copilot #1)
- Handle empty command prefix: skip rule creation (Copilot #2)
- Remove unused useTheme() import (Copilot #3)
- Save permission rules under 'Bash' toolName so bashToolHasPermission
  can match them — Monitor delegates to Bash permission system (Copilot #4)
- Remove unused logError import from MonitorMcpTask (Copilot #6)
- Copilot #5 (getAppState throws): same pattern as BashTool:915, not a bug
2026-04-13 21:39:07 +08:00
Nourrisse FlorianandGitHub 24d485f42f feat: activate local-only team memory in open build (#648)
* feat: activate local-only team memory in open build

Enable the TEAMMEM feature flag and the isTeamMemoryEnabled() gate so
team memory works in local-only mode for all open-build users.

Team memory is a shared memory system scoped per-project, stored at
~/.claude/projects/<project>/memory/team/. The implementation is
already almost entirely local — extraction, UI, prompts, file
detection, and path validation all work on local files.

The cloud sync overlay (OAuth + API) is cleanly separated: the
watcher does an early return when OAuth is unavailable, so the
feature degrades gracefully to local-only storage with no crashes.

What works locally:
- Memory extraction (auto + team, combined prompts)
- Team MEMORY.md loaded into conversation context
- File selector with team memory folder option
- Collapse tracking (read/search/write counts)
- Secret scanning before persistence
- Path validation + symlink protection

What requires OAuth (not available in open build):
- Cloud sync between team members
- Automatic push/pull via file watcher

* fix: preserve opt-out gate for team memory via feature flag

Change isTeamMemoryEnabled() to read tengu_herring_clock with default
true instead of unconditional return true. This enables team memory by
default while preserving user opt-out via ~/.claude/feature-flags.json.
2026-04-13 21:29:10 +08:00
Nourrisse FlorianandGitHub 99a17144ee feat: activate coordinator mode in open build (#647)
* feat: activate coordinator mode in open build

Enable the COORDINATOR_MODE feature flag and create the missing
src/coordinator/workerAgent.ts module that provides worker agent
definitions for the coordinator.

Coordinator mode is a multi-agent system where a coordinator agent
orchestrates independent workers via AgentTool, SendMessageTool,
and TaskStopTool. The implementation was already 99% complete
(19KB coordinatorMode.ts, 26 gate sites across 15 files) — only
the workerAgent module was missing from the source snapshot.

Workers get the standard built-in agents (general-purpose, explore,
plan). The coordinator system prompt (252 lines) handles all
orchestration logic.

Activate at runtime: CLAUDE_CODE_COORDINATOR_MODE=1
Optional scratchpad: set {"tengu_scratch": true} in
~/.claude/feature-flags.json (#639)

* fix: add worker agent type for coordinator mode

The coordinator system prompt instructs the model to spawn workers with
subagent_type: "worker", but no agent had agentType === 'worker'.
This caused AgentTool to throw "Agent type 'worker' not found" on
every coordinator spawn attempt.

Add a WORKER_AGENT definition that spreads GENERAL_PURPOSE_AGENT with
agentType: 'worker'. Also use the narrower BuiltInAgentDefinition type.

* feat: activate built-in explore and plan agents in open build

Enable BUILTIN_EXPLORE_PLAN_AGENTS so Explore (fast, haiku, read-only)
and Plan (architect, read-only) agents are available to all users in
both normal and coordinator modes.

This resolves the inconsistency flagged in code review: coordinator
workers had access to Explore/Plan agents while normal sessions did not.

The GrowthBook A/B test gate (tengu_amber_stoat) defaults to true via
the no-telemetry stub. Users can disable via feature-flags.json (#639).
2026-04-13 21:19:57 +08:00
Nourrisse FlorianandGitHub adbe391e63 fix: replace broken bun:bundle shim with source pre-processing (#657)
* fix: replace broken bun:bundle shim with source pre-processing

The `onResolve`/`onLoad` plugin shim for `bun:bundle` was silently
ineffective in Bun v1.3.9+ — the `bun:` namespace is resolved by
Bun's native C++ resolver before the JS plugin phase runs. This meant
ALL `feature()` flags evaluated to `false` regardless of the
`featureFlags` map in build.ts (including `MONITOR_TOOL: true`).

Replace the shim with a source pre-processing step that:
1. Strips `import { feature } from 'bun:bundle'` from .ts/.tsx files
2. Replaces `feature('FLAG')` calls with boolean literals
3. Restores original files in a `finally` block after Bun.build()

Also extend the missing-module scanner to detect `require()` and
dynamic `import()` calls — not just static `import ... from` — since
modules behind feature() gates become resolvable when flags are enabled.

* fix: ensure source files are always restored after build

- Add SIGINT/SIGTERM handlers to restore pre-processed source files
  on abrupt termination (Ctrl+C, kill)
- Replace process.exit(1) with process.exitCode = 1 so the finally
  block runs on build failure
2026-04-13 21:07:08 +08:00
Kevin CodexandGitHub d1a2df2f69 feat: activate buddy system in open build (#346) 2026-04-05 05:39:00 +08:00
280c9732f5 feat: fix open-source build and add Ollama model picker (#302)
* feat: fix open-source build and add Ollama model picker

- Fix build failures by stubbing 62+ missing Anthropic-internal modules
  with a catch-all plugin in scripts/build.ts
- Add runtime shim exports (isReplBridgeActive, getReplBridgeHandle) in
  bootstrap/state.ts for feature-gated code references
- Add /model picker support for Ollama: fetches available models from
  Ollama server at startup and displays them in the model selection menu
- Add Ollama model validation against cached server model list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review feedback for Ollama integration

- Move Ollama validation before enterprise allowlist check in validateModel
- Truncate model list in error messages to first 5 entries
- Fix isOllamaProvider() to detect OLLAMA_BASE_URL-only configurations
- Reuse getOllamaApiBaseUrl() from providerDiscovery instead of duplicating
- Reset fetchPromise on failure to allow retry in prefetchOllamaModels
- Include Default option in Ollama model picker, prevent Claude model fallthrough
- Add file existence check for src/tasks/ stubs in build script

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use pre-scanned exact-match resolvers to avoid Bun bundler corruption

Bun's onResolve plugin corrupts the module graph even when returning null
for non-matching imports. This caused lodash-es memoize and zod's util
namespace to be incorrectly tree-shaken, producing runtime ReferenceErrors.

Replace all pattern-based onResolve hooks with a pre-build scan that
identifies missing modules upfront, then registers exact-match resolvers
only for confirmed missing imports. This avoids touching any valid module
resolution paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: move Ollama model prefetch outside startup throttle gate

prefetchOllamaModels() was inside the skipStartupPrefetches condition,
so it would be skipped on subsequent launches due to the bgRefresh
throttle timestamp. Ollama model fetch targets a local/remote server
and is fast & cheap, so it should always run at startup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-04 17:22:18 +08:00
KRATOSandGitHub c52245fc0a fix: restore image paste and image tool-result handling (#308) 2026-04-04 14:10:26 +08:00
Mikey 0746802b6a security: kill GrowthBook phone-home and auto-updater at build time
Adds a Bun build plugin that replaces analytics/telemetry modules with
no-op stubs at compile time.

Primary targets (NOT killed by PR #94 or the feature() shim):

  - GrowthBook: phones home to api.anthropic.com on every launch,
    sending account UUID, org UUID, email, device ID, subscription
    type. Refreshes every 6 hours. Now returns defaults without
    making any network call.

  - Auto-updater: contacts storage.googleapis.com and npm registry
    on launch to check for new versions. Now returns null/no-op.

Defense-in-depth (already gated by PR #94 or feature flags, but
now the code itself is replaced with empty functions):

  - Datadog, 1P event logging, BigQuery metrics, Perfetto tracing,
    session tracing, plugin fetch telemetry, transcript sharing.

Deliberately NOT stubbed:

  - Plugin marketplace (downloads.claude.ai) — needed for /plugin
  - User-configurable OTel (CLAUDE_CODE_ENABLE_TELEMETRY) — opt-in

Implementation: separate plugin file (scripts/no-telemetry-plugin.ts)
with a 2-line hook in build.ts. The plugin file does not exist
upstream so it cannot cause merge conflicts.
2026-04-01 21:57:15 -07:00
Juan Camilo dda553e281 fix: define MACRO.PACKAGE_URL and MACRO.NATIVE_PACKAGE_URL in build
These macros are used in ~10 files (autoUpdater, localInstaller,
nativeInstaller, update CLI) but were not defined in the build script's
`define` block. At runtime, they resolve to `undefined`, causing
commands like `npm install undefined` and `npm view undefined` to fail
silently during auto-update checks.

Sets MACRO.PACKAGE_URL to the published npm package name and
MACRO.NATIVE_PACKAGE_URL to undefined (no native binary distribution).

Relates to #29

Co-Authored-By: Juan Camilo <juancamilo.auriti@gmail.com>
2026-04-01 15:35:10 +02:00
Vasanthdev2004 5175dba6da fix: stub internal-only modules in open build 2026-04-01 15:26:55 +05:30
Kevin Codex 2d7aa9c841 feat: rebrand as Open Claude and harden OpenAI REPL 2026-04-01 13:31:18 +08:00
Kevin 747be9c2f3 fix: restore interactive OpenAI REPL startup 2026-04-01 05:16:40 +08:00
did:key:z6MkqDnb7Siv3Cwj7pGJq4T5EsUisECqR8KpnDLwcaZq5TPrandClaude Opus 4.6 db04c3e0c0 fix: bypass version gate by setting MACRO.VERSION to 99.0.0
The original code checks GrowthBook for a minimum version and blocks
startup if the build version is too low. Setting to 99.0.0 ensures
OpenClaude always passes the check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 02:48:10 +08:00
did:key:z6MkqDnb7Siv3Cwj7pGJq4T5EsUisECqR8KpnDLwcaZq5TPrandClaude Opus 4.6 3e652cafdf feat: add build system, stubs, and npm packaging — openclaude is now runnable
- package.json with all 70+ dependencies
- Bun build script with feature flag shims, native module stubs, otel externals
- Stubs for ~15 missing source files (snapshot gaps)
- tsconfig.json for TypeScript
- bin/openclaude entry point
- Builds to single 19MB dist/cli.mjs
- Verified: --version and --help work

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 02:36:07 +08:00