surshar / claude-code
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
Built by Anthropic · github.com/anthropics
| @@ -1,0 +1,5 @@ | ||
| 1 | +/** | |
| 2 | + * The line an ask ends with when its diff was cut to fit the prompt. | |
| 3 | + */ | |
| 4 | +export const ASK_CUT_NOTE = | |
| 5 | + '(The rest of this diff was cut: it did not fit in the prompt.)' |
| @@ -1,0 +1,3 @@ | ||
| 1 | +export * from './ask-cut-note.js' | |
| 2 | + | |
| 3 | +export * as default from '.' |
| @@ -1,5 +1,0 @@ | ||
| 1 | -/** | |
| 2 | - * The line an ask ends with when its diff was cut to fit the prompt. | |
| 3 | - */ | |
| 4 | -export const ASK_CUT_NOTE = | |
| 5 | - '(The rest of this diff was cut: it did not fit in the prompt.)' |
| @@ -1,4 +1,4 @@ | ||
| 1 | -import { ASK_CUT_NOTE } from './ask-cut-note.js' | |
| 1 | +import { ASK_CUT_NOTE } from './ask-cut-note' | |
| 2 | 2 | |
| 3 | 3 | /** |
| 4 | 4 | * An armed ask's text as it fits in the room a prompt's context has left: |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | export * from './armed-ask' |
| 2 | 2 | export * from './armed-ask-of.js' |
| 3 | -export * from './ask-cut-note.js' | |
| 3 | +export * from './ask-cut-note' | |
| 4 | 4 | export * from './fitted-ask-text-of.js' |
| 5 | 5 | |
| 6 | 6 | export * as default from '.' |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | import type Git from '../../../git' |
| 2 | -import type Host from '../../../host' | |
| 2 | +import type { Host } from '../../../host' | |
| 3 | 3 | |
| 4 | 4 | /** |
| 5 | 5 | * What pinning a backend takes from the bound host: its raw process runner, |
| @@ -9,7 +9,7 @@ | ||
| 9 | 9 | * to the runner; the session's start is read as it stands at each fetch |
| 10 | 10 | * (a later `session.start` moves it). |
| 11 | 11 | */ |
| 12 | -export type BackendHost = Pick<Host.Host, 'run' | 'readFile'> & | |
| 12 | +export type BackendHost = Pick<Host, 'run' | 'readFile'> & | |
| 13 | 13 | Pick<Git.GitDeps, 'mtimeOf' | 'entryKindsOf' | 'onBranchBase'> & { |
| 14 | 14 | /** |
| 15 | 15 | * The engine's clock, in milliseconds (`$.clock.now`). |
| @@ -1,0 +1,33 @@ | ||
| 1 | +import Probes from '../probes' | |
| 2 | +import Tiers from '../tiers' | |
| 3 | +import type Types from '../types' | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * One fetch of the session's pinned repository, as the built-in panel | |
| 7 | + * fetches; every git child names it so paths stay root-relative. | |
| 8 | + * | |
| 9 | + * Mid-merge, mid-rebase, mid-cherry-pick or mid-revert, or when git cannot | |
| 10 | + * answer, it is unavailable and the caller keeps what it had. | |
| 11 | + * | |
| 12 | + * @param deps the host: pinned git, the repository, the file probes | |
| 13 | + * @param mode what to compare against | |
| 14 | + * @returns the outcome | |
| 15 | + */ | |
| 16 | +export async function fetchDiff( | |
| 17 | + deps: Types.GitDeps, | |
| 18 | + mode: Types.BaseMode, | |
| 19 | +): Promise<Types.FetchOutcome> { | |
| 20 | + const isBusy = await Probes.isTransient( | |
| 21 | + deps.entryKindsOf, | |
| 22 | + deps.repository.gitDir, | |
| 23 | + ) | |
| 24 | + | |
| 25 | + if (isBusy) { | |
| 26 | + return { kind: 'unavailable' } | |
| 27 | + } | |
| 28 | + | |
| 29 | + const context = Tiers.fetchContextOf(deps, mode) | |
| 30 | + const isBranch = mode === 'branch' | |
| 31 | + | |
| 32 | + return isBranch ? Tiers.branchTier(context) : Tiers.workingTreeTier(context) | |
| 33 | +} |
| @@ -1,0 +1,3 @@ | ||
| 1 | +export * from './fetch-diff.js' | |
| 2 | + | |
| 3 | +export * as default from '.' |
| @@ -1,33 +1,0 @@ | ||
| 1 | -import Probes from './probes' | |
| 2 | -import Tiers from './tiers' | |
| 3 | -import type Types from './types' | |
| 4 | - | |
| 5 | -/** | |
| 6 | - * One fetch of the session's pinned repository, as the built-in panel | |
| 7 | - * fetches; every git child names it so paths stay root-relative. | |
| 8 | - * | |
| 9 | - * Mid-merge, mid-rebase, mid-cherry-pick or mid-revert, or when git cannot | |
| 10 | - * answer, it is unavailable and the caller keeps what it had. | |
| 11 | - * | |
| 12 | - * @param deps the host: pinned git, the repository, the file probes | |
| 13 | - * @param mode what to compare against | |
| 14 | - * @returns the outcome | |
| 15 | - */ | |
| 16 | -export async function fetchDiff( | |
| 17 | - deps: Types.GitDeps, | |
| 18 | - mode: Types.BaseMode, | |
| 19 | -): Promise<Types.FetchOutcome> { | |
| 20 | - const isBusy = await Probes.isTransient( | |
| 21 | - deps.entryKindsOf, | |
| 22 | - deps.repository.gitDir, | |
| 23 | - ) | |
| 24 | - | |
| 25 | - if (isBusy) { | |
| 26 | - return { kind: 'unavailable' } | |
| 27 | - } | |
| 28 | - | |
| 29 | - const context = Tiers.fetchContextOf(deps, mode) | |
| 30 | - const isBranch = mode === 'branch' | |
| 31 | - | |
| 32 | - return isBranch ? Tiers.branchTier(context) : Tiers.workingTreeTier(context) | |
| 33 | -} |
| @@ -1,0 +1,41 @@ | ||
| 1 | +import Argv from '../argv' | |
| 2 | +import { EMPTY_FILE_HUNKS } from '../empty-file-hunks' | |
| 3 | +import Parse from '../parse' | |
| 4 | +import type Types from '../types' | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * One file's hunks against the base its row was read against, so body and | |
| 8 | + * counts agree, by literal pathspec, as the built-in panel reads hunks. | |
| 9 | + * | |
| 10 | + * A rename passes both its paths so git pairs them; an untracked or binary | |
| 11 | + * row, or on an unborn HEAD a file edited after staging, has no honest | |
| 12 | + * body and answers no hunks. | |
| 13 | + * | |
| 14 | + * @param run runs git against the pinned repository | |
| 15 | + * @param data the fetch the row belongs to | |
| 16 | + * @param file the row | |
| 17 | + * @returns the parsed body, or null when git failed | |
| 18 | + */ | |
| 19 | +export async function fetchFileHunks( | |
| 20 | + run: Types.GitRun, | |
| 21 | + data: Types.DiffData, | |
| 22 | + file: Types.FileStat, | |
| 23 | +): Promise<Types.FileHunks | null> { | |
| 24 | + const hasNoBody = | |
| 25 | + file.isUntracked || file.isBinary || data.stalePaths.includes(file.path) | |
| 26 | + | |
| 27 | + if (hasNoBody) { | |
| 28 | + return EMPTY_FILE_HUNKS | |
| 29 | + } | |
| 30 | + | |
| 31 | + const { exitCode, stdout } = await run([ | |
| 32 | + '--literal-pathspecs', | |
| 33 | + ...Argv.DIFF_LEADING_ARGS, | |
| 34 | + data.baseRef, | |
| 35 | + '--', | |
| 36 | + ...(file.renamedFrom === null ? [] : [file.renamedFrom]), | |
| 37 | + file.path, | |
| 38 | + ]) | |
| 39 | + | |
| 40 | + return exitCode === 0 ? Parse.parseFileDiff(stdout) : null | |
| 41 | +} |
| @@ -1,0 +1,3 @@ | ||
| 1 | +export * from './fetch-file-hunks.js' | |
| 2 | + | |
| 3 | +export * as default from '.' |
| @@ -1,41 +1,0 @@ | ||
| 1 | -import Argv from './argv' | |
| 2 | -import { EMPTY_FILE_HUNKS } from './empty-file-hunks' | |
| 3 | -import GitParse from './parse' | |
| 4 | -import type Types from './types' | |
| 5 | - | |
| 6 | -/** | |
| 7 | - * One file's hunks against the base its row was read against, so body and | |
| 8 | - * counts agree, by literal pathspec, as the built-in panel reads hunks. | |
| 9 | - * | |
| 10 | - * A rename passes both its paths so git pairs them; an untracked or binary | |
| 11 | - * row, or on an unborn HEAD a file edited after staging, has no honest | |
| 12 | - * body and answers no hunks. | |
| 13 | - * | |
| 14 | - * @param run runs git against the pinned repository | |
| 15 | - * @param data the fetch the row belongs to | |
| 16 | - * @param file the row | |
| 17 | - * @returns the parsed body, or null when git failed | |
| 18 | - */ | |
| 19 | -export async function fetchFileHunks( | |
| 20 | - run: Types.GitRun, | |
| 21 | - data: Types.DiffData, | |
| 22 | - file: Types.FileStat, | |
| 23 | -): Promise<Types.FileHunks | null> { | |
| 24 | - const hasNoBody = | |
| 25 | - file.isUntracked || file.isBinary || data.stalePaths.includes(file.path) | |
| 26 | - | |
| 27 | - if (hasNoBody) { | |
| 28 | - return EMPTY_FILE_HUNKS | |
| 29 | - } | |
| 30 | - | |
| 31 | - const { exitCode, stdout } = await run([ | |
| 32 | - '--literal-pathspecs', | |
| 33 | - ...Argv.DIFF_LEADING_ARGS, | |
| 34 | - data.baseRef, | |
| 35 | - '--', | |
| 36 | - ...(file.renamedFrom === null ? [] : [file.renamedFrom]), | |
| 37 | - file.path, | |
| 38 | - ]) | |
| 39 | - | |
| 40 | - return exitCode === 0 ? GitParse.parseFileDiff(stdout) : null | |
| 41 | -} |
| @@ -2,8 +2,8 @@ | ||
| 2 | 2 | import Limits from '../limits' |
| 3 | 3 | import Argv from './argv' |
| 4 | 4 | import { FAILED_RUN } from './failed-run' |
| 5 | -import { fetchDiff } from './fetch-diff.js' | |
| 6 | -import { fetchFileHunks } from './fetch-file-hunks.js' | |
| 5 | +import { fetchDiff } from './fetch-diff' | |
| 6 | +import { fetchFileHunks } from './fetch-file-hunks' | |
| 7 | 7 | import { GIT_BASE_MODES } from './git-base-modes' |
| 8 | 8 | import { GIT_WORDS } from './git-words' |
| 9 | 9 | import Probes from './probes' |
| @@ -2,8 +2,8 @@ | ||
| 2 | 2 | export * from './cut-hunks' |
| 3 | 3 | export * from './empty-file-hunks' |
| 4 | 4 | export * from './failed-run' |
| 5 | -export * from './fetch-diff.js' | |
| 6 | -export * from './fetch-file-hunks.js' | |
| 5 | +export * from './fetch-diff' | |
| 6 | +export * from './fetch-file-hunks' | |
| 7 | 7 | export * from './git-backend-of.js' |
| 8 | 8 | export * from './git-base-modes' |
| 9 | 9 | export * from './git-words' |
| @@ -22,7 +22,7 @@ | ||
| 22 | 22 | export * from './transient-state-files' |
| 23 | 23 | export * from './unstaged-numstat.js' |
| 24 | 24 | export * from './untracked-files' |
| 25 | -export * from './untracked-rows-of' | |
| 26 | 25 | export * from './untracked-place' |
| 26 | +export * from './untracked-rows-of' | |
| 27 | 27 | |
| 28 | 28 | export * as default from '.' |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | import Limits from '../../limits' |
| 2 | 2 | import Argv from '../argv' |
| 3 | -import GitParse from '../parse' | |
| 3 | +import Parse from '../parse' | |
| 4 | 4 | import type Types from '../types' |
| 5 | 5 | |
| 6 | 6 | /** |
| @@ -22,7 +22,7 @@ | ||
| 22 | 22 | |
| 23 | 23 | const shortstat = await run([...Argv.DIFF_LEADING_ARGS, base, '--shortstat']) |
| 24 | 24 | const totals = |
| 25 | - shortstat.exitCode === 0 ? GitParse.parseShortstat(shortstat.stdout) : null | |
| 25 | + shortstat.exitCode === 0 ? Parse.parseShortstat(shortstat.stdout) : null | |
| 26 | 26 | const isPastDetails = |
| 27 | 27 | totals !== null && totals.filesCount > Limits.MAX_FILES_FOR_DETAILS |
| 28 | 28 | |
| @@ -36,7 +36,7 @@ | ||
| 36 | 36 | '--numstat', |
| 37 | 37 | '-z', |
| 38 | 38 | ]) |
| 39 | - const isRead = GitParse.isWholeAnswer(numstat) | |
| 39 | + const isRead = Parse.isWholeAnswer(numstat) | |
| 40 | 40 | |
| 41 | - return isRead ? GitParse.parseNumstat(numstat.stdout, Limits.MAX_FILES) : null | |
| 41 | + return isRead ? Parse.parseNumstat(numstat.stdout, Limits.MAX_FILES) : null | |
| 42 | 42 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | import Argv from '../argv' |
| 2 | -import GitParse from '../parse' | |
| 2 | +import Parse from '../parse' | |
| 3 | 3 | import type Types from '../types' |
| 4 | 4 | |
| 5 | 5 | /** |
| @@ -15,9 +15,9 @@ | ||
| 15 | 15 | run: Types.GitRun, |
| 16 | 16 | ): Promise<Types.NumstatResult | null> { |
| 17 | 17 | const numstat = await run([...Argv.DIFF_LEADING_ARGS, '--numstat', '-z']) |
| 18 | - const isRead = GitParse.isWholeAnswer(numstat) | |
| 18 | + const isRead = Parse.isWholeAnswer(numstat) | |
| 19 | 19 | |
| 20 | 20 | return isRead |
| 21 | - ? GitParse.parseNumstat(numstat.stdout, Number.POSITIVE_INFINITY) | |
| 21 | + ? Parse.parseNumstat(numstat.stdout, Number.POSITIVE_INFINITY) | |
| 22 | 22 | : null |
| 23 | 23 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | import Argv from '../../argv' |
| 2 | -import GitParse from '../../parse' | |
| 2 | +import Parse from '../../parse' | |
| 3 | 3 | import type Types from '../../types' |
| 4 | 4 | import type { UntrackedPlace } from '../untracked-place' |
| 5 | 5 | import { untrackedRowsOf } from '../untracked-rows-of' |
| @@ -30,7 +30,7 @@ | ||
| 30 | 30 | '--full-name', |
| 31 | 31 | ]) |
| 32 | 32 | |
| 33 | - if (!GitParse.isWholeAnswer(listing)) { | |
| 33 | + if (!Parse.isWholeAnswer(listing)) { | |
| 34 | 34 | return null |
| 35 | 35 | } |
| 36 | 36 |
| @@ -1,0 +1,5 @@ | ||
| 1 | +/** | |
| 2 | + * The most of a child's stdout `$.process.run` hands back, in bytes | |
| 3 | + * (process-host OUTPUT_LIMIT); a listing that long was cut, silently. | |
| 4 | + */ | |
| 5 | +export const HOST_OUTPUT_CAP_BYTES = 4 * 1024 * 1024 |
| @@ -1,0 +1,4 @@ | ||
| 1 | +export * from './host-output-cap-bytes.js' | |
| 2 | +export * from './max-diff-bytes.js' | |
| 3 | + | |
| 4 | +export * as default from '.' |
| @@ -1,0 +1,5 @@ | ||
| 1 | +/** | |
| 2 | + * A file whose unified diff text is longer than this is a "large file": its | |
| 3 | + * hunks are not parsed (the built-in panel's size cap). | |
| 4 | + */ | |
| 5 | +export const MAX_DIFF_BYTES = 1_000_000 |
| @@ -1,5 +1,0 @@ | ||
| 1 | -/** | |
| 2 | - * The most of a child's stdout `$.process.run` hands back, in bytes | |
| 3 | - * (process-host OUTPUT_LIMIT); a listing that long was cut, silently. | |
| 4 | - */ | |
| 5 | -export const HOST_OUTPUT_CAP_BYTES = 4 * 1024 * 1024 |
| @@ -1,5 +1,4 @@ | ||
| 1 | -export * from './host-output-cap-bytes.js' | |
| 2 | -export * from './max-diff-bytes.js' | |
| 1 | +export * from './bytes' | |
| 3 | 2 | export * from './max-files.js' |
| 4 | 3 | export * from './max-files-for-details.js' |
| 5 | 4 | export * from './max-lines-per-file.js' |
| @@ -1,5 +1,0 @@ | ||
| 1 | -/** | |
| 2 | - * A file whose unified diff text is longer than this is a "large file": its | |
| 3 | - * hunks are not parsed (the built-in panel's size cap). | |
| 4 | - */ | |
| 5 | -export const MAX_DIFF_BYTES = 1_000_000 |
| @@ -3,6 +3,6 @@ | ||
| 3 | 3 | export * from './not-in-repository-text.js' |
| 4 | 4 | export * from './register-failed-text-of.js' |
| 5 | 5 | export * from './resize-terminal-text.js' |
| 6 | -export * from './untracked-withheld-text.js' | |
| 6 | +export * from './untracked-withheld-text-of.js' | |
| 7 | 7 | |
| 8 | 8 | export * as default from '.' |
| @@ -1,0 +1,9 @@ | ||
| 1 | +/** | |
| 2 | + * The pane's word for a fetch whose untracked listing the backend did not | |
| 3 | + * give whole: the tracked rows stand, the new files are not counted. | |
| 4 | + * | |
| 5 | + * @param lister the program that lists untracked files (BackendWords) | |
| 6 | + * @returns the note | |
| 7 | + */ | |
| 8 | +export const untrackedWithheldTextOf = (lister: string) => | |
| 9 | + `Untracked files unavailable (${lister} could not list them); not counted` |
| @@ -1,9 +1,0 @@ | ||
| 1 | -/** | |
| 2 | - * The pane's word for a fetch whose untracked listing the backend did not | |
| 3 | - * give whole: the tracked rows stand, the new files are not counted. | |
| 4 | - * | |
| 5 | - * @param lister the program that lists untracked files (BackendWords) | |
| 6 | - * @returns the note | |
| 7 | - */ | |
| 8 | -export const untrackedWithheldTextOf = (lister: string) => | |
| 9 | - `Untracked files unavailable (${lister} could not list them); not counted` |