Download src/context.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 6.45 kB
-
https://huggingface.co/chenbhao/codev/resolve/main/src/context.ts
- Command line
-
hf download hf://chenbhao/codev/src/context.ts
-
curl -L -o context.ts https://huggingface.co/chenbhao/codev/resolve/main/src/context.ts
6.45 kB
| import { feature } from 'bun:bundle' | |
| import memoize from 'lodash-es/memoize.js' | |
| import { | |
| getAdditionalDirectoriesForClaudeMd, | |
| setCachedClaudeMdContent, | |
| } from './bootstrap/state.js' | |
| import { getLocalISODate } from './constants/common.js' | |
| import { | |
| filterInjectedMemoryFiles, | |
| getClaudeMds, | |
| getMemoryFiles, | |
| } from './utils/claudemd.js' | |
| import { logForDiagnosticsNoPII } from './utils/diagLogs.js' | |
| import { isBareMode, isEnvTruthy } from './utils/envUtils.js' | |
| import { execFileNoThrow } from './utils/execFileNoThrow.js' | |
| import { getBranch, getDefaultBranch, getIsGit, gitExe } from './utils/git.js' | |
| import { shouldIncludeGitInstructions } from './utils/gitSettings.js' | |
| import { logError } from './utils/log.js' | |
| const MAX_STATUS_CHARS = 2000 | |
| // System prompt injection for cache breaking (ant-only, ephemeral debugging state) | |
| let systemPromptInjection: string | null = null | |
| export function getSystemPromptInjection(): string | null { | |
| return systemPromptInjection | |
| } | |
| export function setSystemPromptInjection(value: string | null): void { | |
| systemPromptInjection = value | |
| // Clear context caches immediately when injection changes | |
| getUserContext.cache.clear?.() | |
| getSystemContext.cache.clear?.() | |
| } | |
| export const getGitStatus = memoize(async (): Promise<string | null> => { | |
| if (process.env.NODE_ENV === 'test') { | |
| // Avoid cycles in tests | |
| return null | |
| } | |
| const startTime = Date.now() | |
| logForDiagnosticsNoPII('info', 'git_status_started') | |
| const isGitStart = Date.now() | |
| const isGit = await getIsGit() | |
| logForDiagnosticsNoPII('info', 'git_is_git_check_completed', { | |
| duration_ms: Date.now() - isGitStart, | |
| is_git: isGit, | |
| }) | |
| if (!isGit) { | |
| logForDiagnosticsNoPII('info', 'git_status_skipped_not_git', { | |
| duration_ms: Date.now() - startTime, | |
| }) | |
| return null | |
| } | |
| try { | |
| const gitCmdsStart = Date.now() | |
| const [branch, mainBranch, status, log, userName] = await Promise.all([ | |
| getBranch(), | |
| getDefaultBranch(), | |
| execFileNoThrow(gitExe(), ['--no-optional-locks', 'status', '--short'], { | |
| preserveOutputOnError: false, | |
| }).then(({ stdout }) => stdout.trim()), | |
| execFileNoThrow( | |
| gitExe(), | |
| ['--no-optional-locks', 'log', '--oneline', '-n', '5'], | |
| { | |
| preserveOutputOnError: false, | |
| }, | |
| ).then(({ stdout }) => stdout.trim()), | |
| execFileNoThrow(gitExe(), ['config', 'user.name'], { | |
| preserveOutputOnError: false, | |
| }).then(({ stdout }) => stdout.trim()), | |
| ]) | |
| logForDiagnosticsNoPII('info', 'git_commands_completed', { | |
| duration_ms: Date.now() - gitCmdsStart, | |
| status_length: status.length, | |
| }) | |
| // Check if status exceeds character limit | |
| const truncatedStatus = | |
| status.length > MAX_STATUS_CHARS | |
| ? status.substring(0, MAX_STATUS_CHARS) + | |
| '\n... (truncated because it exceeds 2k characters. If you need more information, run "git status" using BashTool)' | |
| : status | |
| logForDiagnosticsNoPII('info', 'git_status_completed', { | |
| duration_ms: Date.now() - startTime, | |
| truncated: status.length > MAX_STATUS_CHARS, | |
| }) | |
| return [ | |
| `This is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation.`, | |
| `Current branch: ${branch}`, | |
| `Main branch (you will usually use this for PRs): ${mainBranch}`, | |
| ...(userName ? [`Git user: ${userName}`] : []), | |
| `Status:\n${truncatedStatus || '(clean)'}`, | |
| `Recent commits:\n${log}`, | |
| ].join('\n\n') | |
| } catch (error) { | |
| logForDiagnosticsNoPII('error', 'git_status_failed', { | |
| duration_ms: Date.now() - startTime, | |
| }) | |
| logError(error) | |
| return null | |
| } | |
| }) | |
| /** | |
| * This context is prepended to each conversation, and cached for the duration of the conversation. | |
| */ | |
| export const getSystemContext = memoize( | |
| async (): Promise<{ | |
| [k: string]: string | |
| }> => { | |
| const startTime = Date.now() | |
| logForDiagnosticsNoPII('info', 'system_context_started') | |
| // Skip git status in CCR (unnecessary overhead on resume) or when git instructions are disabled | |
| const gitStatus = | |
| isEnvTruthy(process.env.CLAUDE_CODE_REMOTE) || | |
| !shouldIncludeGitInstructions() | |
| ? null | |
| : await getGitStatus() | |
| // Include system prompt injection if set (for cache breaking, ant-only) | |
| const injection = feature('BREAK_CACHE_COMMAND') | |
| ? getSystemPromptInjection() | |
| : null | |
| logForDiagnosticsNoPII('info', 'system_context_completed', { | |
| duration_ms: Date.now() - startTime, | |
| has_git_status: gitStatus !== null, | |
| has_injection: injection !== null, | |
| }) | |
| return { | |
| ...(gitStatus && { gitStatus }), | |
| ...(feature('BREAK_CACHE_COMMAND') && injection | |
| ? { | |
| cacheBreaker: `[CACHE_BREAKER: ${injection}]`, | |
| } | |
| : {}), | |
| } | |
| }, | |
| ) | |
| /** | |
| * This context is prepended to each conversation, and cached for the duration of the conversation. | |
| */ | |
| export const getUserContext = memoize( | |
| async (): Promise<{ | |
| [k: string]: string | |
| }> => { | |
| const startTime = Date.now() | |
| logForDiagnosticsNoPII('info', 'user_context_started') | |
| // CLAUDE_CODE_DISABLE_CLAUDE_MDS: hard off, always. | |
| // --bare: skip auto-discovery (cwd walk), BUT honor explicit --add-dir. | |
| // --bare means "skip what I didn't ask for", not "ignore what I asked for". | |
| const shouldDisableClaudeMd = | |
| isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_CLAUDE_MDS) || | |
| (isBareMode() && getAdditionalDirectoriesForClaudeMd().length === 0) | |
| // Await the async I/O (readFile/readdir directory walk) so the event | |
| // loop yields naturally at the first fs.readFile. | |
| const claudeMd = shouldDisableClaudeMd | |
| ? null | |
| : getClaudeMds(filterInjectedMemoryFiles(await getMemoryFiles())) | |
| // Cache for the auto-mode classifier (yoloClassifier.ts reads this | |
| // instead of importing claudemd.ts directly, which would create a | |
| // cycle through permissions/filesystem → permissions → yoloClassifier). | |
| setCachedClaudeMdContent(claudeMd || null) | |
| logForDiagnosticsNoPII('info', 'user_context_completed', { | |
| duration_ms: Date.now() - startTime, | |
| claudemd_length: claudeMd?.length ?? 0, | |
| claudemd_disabled: Boolean(shouldDisableClaudeMd), | |
| }) | |
| return { | |
| ...(claudeMd && { claudeMd }), | |
| currentDate: `Today's date is ${getLocalISODate()}.`, | |
| } | |
| }, | |
| ) | |