mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 14:25:51 +00:00
更新大量 tsx 原始文件; 已经迁移 login panel; 部分 (#121)
* style(B1-1): 格式化 ink/buddy/cli/context/screens/tasks/services/keybindings/state (43 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 修复了 Box.tsx 和 ScrollBox.tsx 中无效的 global.d.ts import。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-2): 格式化 commands (79 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-3): 格式化 components/messages,permissions,mcp,sandbox,shell (104 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-4): 格式化 components/PromptInput,FeedbackSurvey,tasks,agents,skills,design-system,wizard (73 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-5): 格式化 components其余 + hooks + tools (232 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-6): 格式化 main/entrypoints/utils/moreright (21 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: 更新 README,新增 Run.ps1/TODO.md,删除 V6.md - README.md: 大幅重写,更详细版本历史和配置示例 - Run.ps1: 新增 Windows 启动脚本 - TODO.md: 新增包完成清单 - V6.md: 删除(架构重构规划已不适用) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: 修复以前的问题 * fix: 修复 login 面板的问题 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,180 +1,180 @@
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import type { StructuredPatchHunk } from 'diff';
|
||||
import * as React from 'react';
|
||||
import { Suspense, use, useState } from 'react';
|
||||
import { useTerminalSize } from '../hooks/useTerminalSize.js';
|
||||
import { Box, Text } from '../ink.js';
|
||||
import type { FileEdit } from '../tools/FileEditTool/types.js';
|
||||
import { findActualString, preserveQuoteStyle } from '../tools/FileEditTool/utils.js';
|
||||
import { adjustHunkLineNumbers, CONTEXT_LINES, getPatchForDisplay } from '../utils/diff.js';
|
||||
import { logError } from '../utils/log.js';
|
||||
import { CHUNK_SIZE, openForScan, readCapped, scanForContext } from '../utils/readEditContext.js';
|
||||
import { firstLineOf } from '../utils/stringUtils.js';
|
||||
import { StructuredDiffList } from './StructuredDiffList.js';
|
||||
import type { StructuredPatchHunk } from 'diff'
|
||||
import * as React from 'react'
|
||||
import { Suspense, use, useState } from 'react'
|
||||
import { useTerminalSize } from '../hooks/useTerminalSize.js'
|
||||
import { Box, Text } from '../ink.js'
|
||||
import type { FileEdit } from '../tools/FileEditTool/types.js'
|
||||
import {
|
||||
findActualString,
|
||||
preserveQuoteStyle,
|
||||
} from '../tools/FileEditTool/utils.js'
|
||||
import {
|
||||
adjustHunkLineNumbers,
|
||||
CONTEXT_LINES,
|
||||
getPatchForDisplay,
|
||||
} from '../utils/diff.js'
|
||||
import { logError } from '../utils/log.js'
|
||||
import {
|
||||
CHUNK_SIZE,
|
||||
openForScan,
|
||||
readCapped,
|
||||
scanForContext,
|
||||
} from '../utils/readEditContext.js'
|
||||
import { firstLineOf } from '../utils/stringUtils.js'
|
||||
import { StructuredDiffList } from './StructuredDiffList.js'
|
||||
|
||||
type Props = {
|
||||
file_path: string;
|
||||
edits: FileEdit[];
|
||||
};
|
||||
file_path: string
|
||||
edits: FileEdit[]
|
||||
}
|
||||
|
||||
type DiffData = {
|
||||
patch: StructuredPatchHunk[];
|
||||
firstLine: string | null;
|
||||
fileContent: string | undefined;
|
||||
};
|
||||
export function FileEditToolDiff(props) {
|
||||
const $ = _c(7);
|
||||
let t0;
|
||||
if ($[0] !== props.edits || $[1] !== props.file_path) {
|
||||
t0 = () => loadDiffData(props.file_path, props.edits);
|
||||
$[0] = props.edits;
|
||||
$[1] = props.file_path;
|
||||
$[2] = t0;
|
||||
} else {
|
||||
t0 = $[2];
|
||||
}
|
||||
const [dataPromise] = useState(t0);
|
||||
let t1;
|
||||
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = <DiffFrame placeholder={true} />;
|
||||
$[3] = t1;
|
||||
} else {
|
||||
t1 = $[3];
|
||||
}
|
||||
let t2;
|
||||
if ($[4] !== dataPromise || $[5] !== props.file_path) {
|
||||
t2 = <Suspense fallback={t1}><DiffBody promise={dataPromise} file_path={props.file_path} /></Suspense>;
|
||||
$[4] = dataPromise;
|
||||
$[5] = props.file_path;
|
||||
$[6] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
}
|
||||
return t2;
|
||||
patch: StructuredPatchHunk[]
|
||||
firstLine: string | null
|
||||
fileContent: string | undefined
|
||||
}
|
||||
function DiffBody(t0: { promise: Promise<DiffData>; file_path: string }) {
|
||||
const $ = _c(6);
|
||||
const {
|
||||
promise,
|
||||
file_path
|
||||
} = t0;
|
||||
const {
|
||||
patch,
|
||||
firstLine,
|
||||
fileContent
|
||||
} = use(promise);
|
||||
const {
|
||||
columns
|
||||
} = useTerminalSize();
|
||||
let t1;
|
||||
if ($[0] !== columns || $[1] !== fileContent || $[2] !== file_path || $[3] !== firstLine || $[4] !== patch) {
|
||||
t1 = <DiffFrame><StructuredDiffList hunks={patch} dim={false} width={columns} filePath={file_path} firstLine={firstLine} fileContent={fileContent} /></DiffFrame>;
|
||||
$[0] = columns;
|
||||
$[1] = fileContent;
|
||||
$[2] = file_path;
|
||||
$[3] = firstLine;
|
||||
$[4] = patch;
|
||||
$[5] = t1;
|
||||
} else {
|
||||
t1 = $[5];
|
||||
}
|
||||
return t1;
|
||||
|
||||
export function FileEditToolDiff(props: Props): React.ReactNode {
|
||||
// Snapshot on mount — the diff must stay consistent even if the file changes
|
||||
// while the dialog is open. useMemo on props.edits would re-read the file on
|
||||
// every render because callers pass fresh array literals.
|
||||
const [dataPromise] = useState(() =>
|
||||
loadDiffData(props.file_path, props.edits),
|
||||
)
|
||||
return (
|
||||
<Suspense fallback={<DiffFrame placeholder />}>
|
||||
<DiffBody promise={dataPromise} file_path={props.file_path} />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
function DiffFrame(t0) {
|
||||
const $ = _c(5);
|
||||
const {
|
||||
children,
|
||||
placeholder
|
||||
} = t0;
|
||||
let t1;
|
||||
if ($[0] !== children || $[1] !== placeholder) {
|
||||
t1 = placeholder ? <Text dimColor={true}>…</Text> : children;
|
||||
$[0] = children;
|
||||
$[1] = placeholder;
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[2];
|
||||
}
|
||||
let t2;
|
||||
if ($[3] !== t1) {
|
||||
t2 = <Box flexDirection="column"><Box borderColor="subtle" borderStyle="dashed" flexDirection="column" borderLeft={false} borderRight={false}>{t1}</Box></Box>;
|
||||
$[3] = t1;
|
||||
$[4] = t2;
|
||||
} else {
|
||||
t2 = $[4];
|
||||
}
|
||||
return t2;
|
||||
|
||||
function DiffBody({
|
||||
promise,
|
||||
file_path,
|
||||
}: {
|
||||
promise: Promise<DiffData>
|
||||
file_path: string
|
||||
}): React.ReactNode {
|
||||
const { patch, firstLine, fileContent } = use(promise)
|
||||
const { columns } = useTerminalSize()
|
||||
return (
|
||||
<DiffFrame>
|
||||
<StructuredDiffList
|
||||
hunks={patch}
|
||||
dim={false}
|
||||
width={columns}
|
||||
filePath={file_path}
|
||||
firstLine={firstLine}
|
||||
fileContent={fileContent}
|
||||
/>
|
||||
</DiffFrame>
|
||||
)
|
||||
}
|
||||
async function loadDiffData(file_path: string, edits: FileEdit[]): Promise<DiffData> {
|
||||
const valid = edits.filter(e => e.old_string != null && e.new_string != null);
|
||||
const single = valid.length === 1 ? valid[0]! : undefined;
|
||||
|
||||
function DiffFrame({
|
||||
children,
|
||||
placeholder,
|
||||
}: {
|
||||
children?: React.ReactNode
|
||||
placeholder?: boolean
|
||||
}): React.ReactNode {
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Box
|
||||
borderColor="subtle"
|
||||
borderStyle="dashed"
|
||||
flexDirection="column"
|
||||
borderLeft={false}
|
||||
borderRight={false}
|
||||
>
|
||||
{placeholder ? <Text dimColor>…</Text> : children}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
async function loadDiffData(
|
||||
file_path: string,
|
||||
edits: FileEdit[],
|
||||
): Promise<DiffData> {
|
||||
const valid = edits.filter(e => e.old_string != null && e.new_string != null)
|
||||
const single = valid.length === 1 ? valid[0]! : undefined
|
||||
|
||||
// SedEditPermissionRequest passes the entire file as old_string. Scanning for
|
||||
// a needle ≥ CHUNK_SIZE allocates O(needle) for the overlap buffer — skip the
|
||||
// file read entirely and diff the inputs we already have.
|
||||
if (single && single.old_string.length >= CHUNK_SIZE) {
|
||||
return diffToolInputsOnly(file_path, [single]);
|
||||
return diffToolInputsOnly(file_path, [single])
|
||||
}
|
||||
|
||||
try {
|
||||
const handle = await openForScan(file_path);
|
||||
if (handle === null) return diffToolInputsOnly(file_path, valid);
|
||||
const handle = await openForScan(file_path)
|
||||
if (handle === null) return diffToolInputsOnly(file_path, valid)
|
||||
try {
|
||||
// Multi-edit and empty old_string genuinely need full-file for sequential
|
||||
// replacements — structuredPatch needs before/after strings. replace_all
|
||||
// routes through the chunked path below (shows first-occurrence window;
|
||||
// matches within the slice still replace via edit.replace_all).
|
||||
if (!single || single.old_string === '') {
|
||||
const file = await readCapped(handle);
|
||||
if (file === null) return diffToolInputsOnly(file_path, valid);
|
||||
const normalized = valid.map(e => normalizeEdit(file, e));
|
||||
const file = await readCapped(handle)
|
||||
if (file === null) return diffToolInputsOnly(file_path, valid)
|
||||
const normalized = valid.map(e => normalizeEdit(file, e))
|
||||
return {
|
||||
patch: getPatchForDisplay({
|
||||
filePath: file_path,
|
||||
fileContents: file,
|
||||
edits: normalized
|
||||
edits: normalized,
|
||||
}),
|
||||
firstLine: firstLineOf(file),
|
||||
fileContent: file
|
||||
};
|
||||
fileContent: file,
|
||||
}
|
||||
}
|
||||
const ctx = await scanForContext(handle, single.old_string, CONTEXT_LINES);
|
||||
|
||||
const ctx = await scanForContext(handle, single.old_string, CONTEXT_LINES)
|
||||
if (ctx.truncated || ctx.content === '') {
|
||||
return diffToolInputsOnly(file_path, [single]);
|
||||
return diffToolInputsOnly(file_path, [single])
|
||||
}
|
||||
const normalized = normalizeEdit(ctx.content, single);
|
||||
const normalized = normalizeEdit(ctx.content, single)
|
||||
const hunks = getPatchForDisplay({
|
||||
filePath: file_path,
|
||||
fileContents: ctx.content,
|
||||
edits: [normalized]
|
||||
});
|
||||
edits: [normalized],
|
||||
})
|
||||
return {
|
||||
patch: adjustHunkLineNumbers(hunks, ctx.lineOffset - 1),
|
||||
firstLine: ctx.lineOffset === 1 ? firstLineOf(ctx.content) : null,
|
||||
fileContent: ctx.content
|
||||
};
|
||||
fileContent: ctx.content,
|
||||
}
|
||||
} finally {
|
||||
await handle.close();
|
||||
await handle.close()
|
||||
}
|
||||
} catch (e) {
|
||||
logError(e as Error);
|
||||
return diffToolInputsOnly(file_path, valid);
|
||||
logError(e as Error)
|
||||
return diffToolInputsOnly(file_path, valid)
|
||||
}
|
||||
}
|
||||
|
||||
function diffToolInputsOnly(filePath: string, edits: FileEdit[]): DiffData {
|
||||
return {
|
||||
patch: edits.flatMap(e => getPatchForDisplay({
|
||||
filePath,
|
||||
fileContents: e.old_string,
|
||||
edits: [e]
|
||||
})),
|
||||
patch: edits.flatMap(e =>
|
||||
getPatchForDisplay({
|
||||
filePath,
|
||||
fileContents: e.old_string,
|
||||
edits: [e],
|
||||
}),
|
||||
),
|
||||
firstLine: null,
|
||||
fileContent: undefined
|
||||
};
|
||||
fileContent: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeEdit(fileContent: string, edit: FileEdit): FileEdit {
|
||||
const actualOld = findActualString(fileContent, edit.old_string) || edit.old_string;
|
||||
const actualNew = preserveQuoteStyle(edit.old_string, actualOld, edit.new_string);
|
||||
return {
|
||||
...edit,
|
||||
old_string: actualOld,
|
||||
new_string: actualNew
|
||||
};
|
||||
const actualOld =
|
||||
findActualString(fileContent, edit.old_string) || edit.old_string
|
||||
const actualNew = preserveQuoteStyle(
|
||||
edit.old_string,
|
||||
actualOld,
|
||||
edit.new_string,
|
||||
)
|
||||
return { ...edit, old_string: actualOld, new_string: actualNew }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user