mirror of
http://10.0.2.1:3031/sauer/claude-code.git
synced 2026-06-30 18:26:58 +10:00
116 lines
15 KiB
TypeScript
116 lines
15 KiB
TypeScript
|
|
import figures from 'figures';
|
||
|
|
import React, { useEffect, useState } from 'react';
|
||
|
|
import { Box, Text } from '../ink.js';
|
||
|
|
import { logForDebugging } from '../utils/debug.js';
|
||
|
|
import type { GitFileStatus } from '../utils/git.js';
|
||
|
|
import { getFileStatus, stashToCleanState } from '../utils/git.js';
|
||
|
|
import { Select } from './CustomSelect/index.js';
|
||
|
|
import { Dialog } from './design-system/Dialog.js';
|
||
|
|
import { Spinner } from './Spinner.js';
|
||
|
|
type TeleportStashProps = {
|
||
|
|
onStashAndContinue: () => void;
|
||
|
|
onCancel: () => void;
|
||
|
|
};
|
||
|
|
export function TeleportStash({
|
||
|
|
onStashAndContinue,
|
||
|
|
onCancel
|
||
|
|
}: TeleportStashProps): React.ReactNode {
|
||
|
|
const [gitFileStatus, setGitFileStatus] = useState<GitFileStatus | null>(null);
|
||
|
|
const changedFiles = gitFileStatus !== null ? [...gitFileStatus.tracked, ...gitFileStatus.untracked] : [];
|
||
|
|
const [loading, setLoading] = useState(true);
|
||
|
|
const [stashing, setStashing] = useState(false);
|
||
|
|
const [error, setError] = useState<string | null>(null);
|
||
|
|
|
||
|
|
// Load changed files on mount
|
||
|
|
useEffect(() => {
|
||
|
|
const loadChangedFiles = async () => {
|
||
|
|
try {
|
||
|
|
const fileStatus = await getFileStatus();
|
||
|
|
setGitFileStatus(fileStatus);
|
||
|
|
} catch (err) {
|
||
|
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
||
|
|
logForDebugging(`Error getting changed files: ${errorMessage}`, {
|
||
|
|
level: 'error'
|
||
|
|
});
|
||
|
|
setError('Failed to get changed files');
|
||
|
|
} finally {
|
||
|
|
setLoading(false);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
void loadChangedFiles();
|
||
|
|
}, []);
|
||
|
|
const handleStash = async () => {
|
||
|
|
setStashing(true);
|
||
|
|
try {
|
||
|
|
logForDebugging('Stashing changes before teleport...');
|
||
|
|
const success = await stashToCleanState('Teleport auto-stash');
|
||
|
|
if (success) {
|
||
|
|
logForDebugging('Successfully stashed changes');
|
||
|
|
onStashAndContinue();
|
||
|
|
} else {
|
||
|
|
setError('Failed to stash changes');
|
||
|
|
}
|
||
|
|
} catch (err_0) {
|
||
|
|
const errorMessage_0 = err_0 instanceof Error ? err_0.message : String(err_0);
|
||
|
|
logForDebugging(`Error stashing changes: ${errorMessage_0}`, {
|
||
|
|
level: 'error'
|
||
|
|
});
|
||
|
|
setError('Failed to stash changes');
|
||
|
|
} finally {
|
||
|
|
setStashing(false);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
const handleSelectChange = (value: string) => {
|
||
|
|
if (value === 'stash') {
|
||
|
|
void handleStash();
|
||
|
|
} else {
|
||
|
|
onCancel();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
if (loading) {
|
||
|
|
return <Box flexDirection="column" padding={1}>
|
||
|
|
<Box marginBottom={1}>
|
||
|
|
<Spinner />
|
||
|
|
<Text> Checking git status{figures.ellipsis}</Text>
|
||
|
|
</Box>
|
||
|
|
</Box>;
|
||
|
|
}
|
||
|
|
if (error) {
|
||
|
|
return <Box flexDirection="column" padding={1}>
|
||
|
|
<Text bold color="error">
|
||
|
|
Error: {error}
|
||
|
|
</Text>
|
||
|
|
<Box marginTop={1}>
|
||
|
|
<Text dimColor>Press </Text>
|
||
|
|
<Text bold>Escape</Text>
|
||
|
|
<Text dimColor> to cancel</Text>
|
||
|
|
</Box>
|
||
|
|
</Box>;
|
||
|
|
}
|
||
|
|
const showFileCount = changedFiles.length > 8;
|
||
|
|
return <Dialog title="Working Directory Has Changes" onCancel={onCancel}>
|
||
|
|
<Text>
|
||
|
|
Teleport will switch git branches. The following changes were found:
|
||
|
|
</Text>
|
||
|
|
|
||
|
|
<Box flexDirection="column" paddingLeft={2}>
|
||
|
|
{changedFiles.length > 0 ? showFileCount ? <Text>{changedFiles.length} files changed</Text> : changedFiles.map((file: string, index: number) => <Text key={index}>{file}</Text>) : <Text dimColor>No changes detected</Text>}
|
||
|
|
</Box>
|
||
|
|
|
||
|
|
<Text>
|
||
|
|
Would you like to stash these changes and continue with teleport?
|
||
|
|
</Text>
|
||
|
|
|
||
|
|
{stashing ? <Box>
|
||
|
|
<Spinner />
|
||
|
|
<Text> Stashing changes...</Text>
|
||
|
|
</Box> : <Select options={[{
|
||
|
|
label: 'Stash changes and continue',
|
||
|
|
value: 'stash'
|
||
|
|
}, {
|
||
|
|
label: 'Exit',
|
||
|
|
value: 'exit'
|
||
|
|
}]} onChange={handleSelectChange} />}
|
||
|
|
</Dialog>;
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmaWd1cmVzIiwiUmVhY3QiLCJ1c2VFZmZlY3QiLCJ1c2VTdGF0ZSIsIkJveCIsIlRleHQiLCJsb2dGb3JEZWJ1Z2dpbmciLCJHaXRGaWxlU3RhdHVzIiwiZ2V0RmlsZVN0YXR1cyIsInN0YXNoVG9DbGVhblN0YXRlIiwiU2VsZWN0IiwiRGlhbG9nIiwiU3Bpbm5lciIsIlRlbGVwb3J0U3Rhc2hQcm9wcyIsIm9uU3Rhc2hBbmRDb250aW51ZSIsIm9uQ2FuY2VsIiwiVGVsZXBvcnRTdGFzaCIsIlJlYWN0Tm9kZSIsImdpdEZpbGVTdGF0dXMiLCJzZXRHaXRGaWxlU3RhdHVzIiwiY2hhbmdlZEZpbGVzIiwidHJhY2tlZCIsInVudHJhY2tlZCIsImxvYWRpbmciLCJzZXRMb2FkaW5nIiwic3Rhc2hpbmciLCJzZXRTdGFzaGluZyIsImVycm9yIiwic2V0RXJyb3IiLCJsb2FkQ2hhbmdlZEZpbGVzIiwiZmlsZVN0YXR1cyIsImVyciIsImVycm9yTWVzc2FnZSIsIkVycm9yIiwibWVzc2FnZSIsIlN0cmluZyIsImxldmVsIiwiaGFuZGxlU3Rhc2giLCJzdWNjZXNzIiwiaGFuZGxlU2VsZWN0Q2hhbmdlIiwidmFsdWUiLCJlbGxpcHNpcyIsInNob3dGaWxlQ291bnQiLCJsZW5ndGgiLCJtYXAiLCJmaWxlIiwiaW5kZXgiLCJsYWJlbCJdLCJzb3VyY2VzIjpbIlRlbGVwb3J0U3Rhc2gudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmaWd1cmVzIGZyb20gJ2ZpZ3VyZXMnXG5pbXBvcnQgUmVhY3QsIHsgdXNlRWZmZWN0LCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgQm94LCBUZXh0IH0gZnJvbSAnLi4vaW5rLmpzJ1xuaW1wb3J0IHsgbG9nRm9yRGVidWdnaW5nIH0gZnJvbSAnLi4vdXRpbHMvZGVidWcuanMnXG5pbXBvcnQgdHlwZSB7IEdpdEZpbGVTdGF0dXMgfSBmcm9tICcuLi91dGlscy9naXQuanMnXG5pbXBvcnQgeyBnZXRGaWxlU3RhdHVzLCBzdGFzaFRvQ2xlYW5TdGF0ZSB9IGZyb20gJy4uL3V0aWxzL2dpdC5qcydcbmltcG9ydCB7IFNlbGVjdCB9IGZyb20gJy4vQ3VzdG9tU2VsZWN0L2luZGV4LmpzJ1xuaW1wb3J0IHsgRGlhbG9nIH0gZnJvbSAnLi9kZXNpZ24tc3lzdGVtL0RpYWxvZy5qcydcbmltcG9ydCB7IFNwaW5uZXIgfSBmcm9tICcuL1NwaW5uZXIuanMnXG5cbnR5cGUgVGVsZXBvcnRTdGFzaFByb3BzID0ge1xuICBvblN0YXNoQW5kQ29udGludWU6ICgpID0+IHZvaWRcbiAgb25DYW5jZWw6ICgpID0+IHZvaWRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFRlbGVwb3J0U3Rhc2goe1xuICBvblN0YXNoQW5kQ29udGludWUsXG4gIG9uQ2FuY2VsLFxufTogVGVsZXBvcnRTdGFzaFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3QgW2dpdEZpbGVTdGF0dXMsIHNldEdpdEZpbGVTdGF0dXNdID0gdXNlU3RhdGU8R2l0RmlsZVN0YXR1cyB8IG51bGw+KG51bGwpXG4gIGNvbnN0IGNoYW5nZWRGaWxlcyA9XG4gICAgZ2l0RmlsZVN0YXR1cyAhPT0gbnVsbFxuICAgICAgPyBbLi4uZ2l0RmlsZVN0YXR1cy50cmFja2VkLCAuLi5naXRGaWxlU3RhdHVzLnVudHJhY2tlZF1cbiAgICAgIDogW11cbiAgY29uc3QgW2xvYWRpbmcsIHNldExvYWRpbmddID0gdXNlU3RhdGUodHJ1ZSlcbiAgY29uc3QgW3N0YXNoaW5nLCBzZXRTdGFzaGluZ10gPSB1c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgW2Vycm9yLCBzZXRFcnJvcl0gPSB1c2VTdGF0ZTxzdHJpbmcgfCBudWxsPihudWxsKVxuXG4gIC8vIExvYWQgY2hhbmdlZCBmaWxlcyBvbiBtb3VudFxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGxvYWRDaGFuZ2VkRmlsZXMgPSBhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBmaWxlU3RhdHVzID0gYXdhaXQgZ2V0RmlsZVN0YXR1cygpXG4gICAgICAgIHNldEdpdEZpbGVTdGF0dXMoZmlsZVN0YXR1cylcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycilcbiAgICAgICAgbG9nRm9yRGVidWdnaW5nKGBFcnJvciBnZXR0aW5nIGNoYW5nZWQgZmlsZXM6ICR7ZXJyb3JNZXNzYWdlfWAsIHtcbiAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgfSlcbiAgICAgICAgc2V0RXJyb3IoJ0ZhaWxlZCB0byBnZXQgY2hhbmdlZCBmaWxlcycpXG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBzZXRMb2FkaW5nKGZhbHNlKVxuICAgICAgfVxuICAgIH1cblxuICAgIHZvaWQgbG9hZENoYW5nZWRGaWxlcygpXG4gIH0sIFtdKVxuXG4gIGNvbnN0IGhhbmRsZVN0YXNoID0gYXN5bmMgKCkgPT4ge1xuICAgIHNldFN0YXNoaW5nKHRydWUpXG4gICAgdHJ5IHtcbiAgICAgIGxvZ0ZvckRlYnVnZ2luZygnU3Rhc2hpbmcgY2hhbmdlcyBiZWZvcmUgdGVsZXBvcnQuLi4nKVxuICAgICAgY29uc3Qgc3VjY2VzcyA9IGF3YWl0IHN0YXNoVG9DbGVhblN0YXRlKCdUZWxlcG9ydCBhdXRvLXN0YXNoJylcblxuICAgICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgICAgbG9nRm9yRGVidWdnaW5nKCdTdWNjZXNzZnVsbHkgc3Rhc2hlZCBjaGFuZ2VzJylcbiAgICAgICAgb25TdGFzaEFuZENvbnRpbnVlKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEVycm9yKCdGYWlsZWQgdG8gc3Rhc2ggY2hhbmdlcycpXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycilcbiAgICAgIGxvZ0ZvckRlYnVnZ2luZyhgRXJyb3Igc3Rhc2hpbmcgY2hhbmdlczogJHtlcnJvck1lc3NhZ2V9YCwge1xuICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgIH0pXG4gICAgICBzZXRFcnJvcignRmFpbGVkIHRvIHN0YXNoIGNoYW5nZXMnKVxuICAgIH0gZmluYWxseSB7XG4gICAgICBzZXRTdGFzaGluZyhmYWxzZSlcbiAgICB9XG4gIH1cblxuICBjb25zdCBoYW5kbGVTZWxlY3RDaGFuZ2UgPSAodmFsdWU6IHN0cmluZykgPT4ge1xuICAgIGlmICh2YWx1ZSA9PT0gJ3N0YXNoJykge1xuICAgICAgdm9pZCBoYW5kbGVTdGF
|