claude-code/commands/plan/plan.tsx

122 lines
14 KiB
TypeScript
Raw Normal View History

import { c as _c } from "react/compiler-runtime";
import * as React from 'react';
import { handlePlanModeTransition } from '../../bootstrap/state.js';
import type { LocalJSXCommandContext } from '../../commands.js';
import { Box, Text } from '../../ink.js';
import type { LocalJSXCommandOnDone } from '../../types/command.js';
import { getExternalEditor } from '../../utils/editor.js';
import { toIDEDisplayName } from '../../utils/ide.js';
import { applyPermissionUpdate } from '../../utils/permissions/PermissionUpdate.js';
import { prepareContextForPlanMode } from '../../utils/permissions/permissionSetup.js';
import { getPlan, getPlanFilePath } from '../../utils/plans.js';
import { editFileInEditor } from '../../utils/promptEditor.js';
import { renderToString } from '../../utils/staticRender.js';
function PlanDisplay(t0) {
const $ = _c(11);
const {
planContent,
planPath,
editorName
} = t0;
let t1;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t1 = <Text bold={true}>Current Plan</Text>;
$[0] = t1;
} else {
t1 = $[0];
}
let t2;
if ($[1] !== planPath) {
t2 = <Text dimColor={true}>{planPath}</Text>;
$[1] = planPath;
$[2] = t2;
} else {
t2 = $[2];
}
let t3;
if ($[3] !== planContent) {
t3 = <Box marginTop={1}><Text>{planContent}</Text></Box>;
$[3] = planContent;
$[4] = t3;
} else {
t3 = $[4];
}
let t4;
if ($[5] !== editorName) {
t4 = editorName && <Box marginTop={1}><Text dimColor={true}>"/plan open"</Text><Text dimColor={true}> to edit this plan in </Text><Text bold={true} dimColor={true}>{editorName}</Text></Box>;
$[5] = editorName;
$[6] = t4;
} else {
t4 = $[6];
}
let t5;
if ($[7] !== t2 || $[8] !== t3 || $[9] !== t4) {
t5 = <Box flexDirection="column">{t1}{t2}{t3}{t4}</Box>;
$[7] = t2;
$[8] = t3;
$[9] = t4;
$[10] = t5;
} else {
t5 = $[10];
}
return t5;
}
export async function call(onDone: LocalJSXCommandOnDone, context: LocalJSXCommandContext, args: string): Promise<React.ReactNode> {
const {
getAppState,
setAppState
} = context;
const appState = getAppState();
const currentMode = appState.toolPermissionContext.mode;
// If not in plan mode, enable it
if (currentMode !== 'plan') {
handlePlanModeTransition(currentMode, 'plan');
setAppState(prev => ({
...prev,
toolPermissionContext: applyPermissionUpdate(prepareContextForPlanMode(prev.toolPermissionContext), {
type: 'setMode',
mode: 'plan',
destination: 'session'
})
}));
const description = args.trim();
if (description && description !== 'open') {
onDone('Enabled plan mode', {
shouldQuery: true
});
} else {
onDone('Enabled plan mode');
}
return null;
}
// Already in plan mode - show the current plan
const planContent = getPlan();
const planPath = getPlanFilePath();
if (!planContent) {
onDone('Already in plan mode. No plan written yet.');
return null;
}
// If user typed "/plan open", open in editor
const argList = args.trim().split(/\s+/);
if (argList[0] === 'open') {
const result = await editFileInEditor(planPath);
if (result.error) {
onDone(`Failed to open plan in editor: ${result.error}`);
} else {
onDone(`Opened plan in editor: ${planPath}`);
}
return null;
}
const editor = getExternalEditor();
const editorName = editor ? toIDEDisplayName(editor) : undefined;
const display = <PlanDisplay planContent={planContent} planPath={planPath} editorName={editorName} />;
// Render to string and pass to onDone like local commands do
const output = await renderToString(display);
onDone(output);
return null;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsImhhbmRsZVBsYW5Nb2RlVHJhbnNpdGlvbiIsIkxvY2FsSlNYQ29tbWFuZENvbnRleHQiLCJCb3giLCJUZXh0IiwiTG9jYWxKU1hDb21tYW5kT25Eb25lIiwiZ2V0RXh0ZXJuYWxFZGl0b3IiLCJ0b0lERURpc3BsYXlOYW1lIiwiYXBwbHlQZXJtaXNzaW9uVXBkYXRlIiwicHJlcGFyZUNvbnRleHRGb3JQbGFuTW9kZSIsImdldFBsYW4iLCJnZXRQbGFuRmlsZVBhdGgiLCJlZGl0RmlsZUluRWRpdG9yIiwicmVuZGVyVG9TdHJpbmciLCJQbGFuRGlzcGxheSIsInQwIiwiJCIsIl9jIiwicGxhbkNvbnRlbnQiLCJwbGFuUGF0aCIsImVkaXRvck5hbWUiLCJ0MSIsIlN5bWJvbCIsImZvciIsInQyIiwidDMiLCJ0NCIsInQ1IiwiY2FsbCIsIm9uRG9uZSIsImNvbnRleHQiLCJhcmdzIiwiUHJvbWlzZSIsIlJlYWN0Tm9kZSIsImdldEFwcFN0YXRlIiwic2V0QXBwU3RhdGUiLCJhcHBTdGF0ZSIsImN1cnJlbnRNb2RlIiwidG9vbFBlcm1pc3Npb25Db250ZXh0IiwibW9kZSIsInByZXYiLCJ0eXBlIiwiZGVzdGluYXRpb24iLCJkZXNjcmlwdGlvbiIsInRyaW0iLCJzaG91bGRRdWVyeSIsImFyZ0xpc3QiLCJzcGxpdCIsInJlc3VsdCIsImVycm9yIiwiZWRpdG9yIiwidW5kZWZpbmVkIiwiZGlzcGxheSIsIm91dHB1dCJdLCJzb3VyY2VzIjpbInBsYW4udHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgaGFuZGxlUGxhbk1vZGVUcmFuc2l0aW9uIH0gZnJvbSAnLi4vLi4vYm9vdHN0cmFwL3N0YXRlLmpzJ1xuaW1wb3J0IHR5cGUgeyBMb2NhbEpTWENvbW1hbmRDb250ZXh0IH0gZnJvbSAnLi4vLi4vY29tbWFuZHMuanMnXG5pbXBvcnQgeyBCb3gsIFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZE9uRG9uZSB9IGZyb20gJy4uLy4uL3R5cGVzL2NvbW1hbmQuanMnXG5pbXBvcnQgeyBnZXRFeHRlcm5hbEVkaXRvciB9IGZyb20gJy4uLy4uL3V0aWxzL2VkaXRvci5qcydcbmltcG9ydCB7IHRvSURFRGlzcGxheU5hbWUgfSBmcm9tICcuLi8uLi91dGlscy9pZGUuanMnXG5pbXBvcnQgeyBhcHBseVBlcm1pc3Npb25VcGRhdGUgfSBmcm9tICcuLi8uLi91dGlscy9wZXJtaXNzaW9ucy9QZXJtaXNzaW9uVXBkYXRlLmpzJ1xuaW1wb3J0IHsgcHJlcGFyZUNvbnRleHRGb3JQbGFuTW9kZSB9IGZyb20gJy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL3Blcm1pc3Npb25TZXR1cC5qcydcbmltcG9ydCB7IGdldFBsYW4sIGdldFBsYW5GaWxlUGF0aCB9IGZyb20gJy4uLy4uL3V0aWxzL3BsYW5zLmpzJ1xuaW1wb3J0IHsgZWRpdEZpbGVJbkVkaXRvciB9IGZyb20gJy4uLy4uL3V0aWxzL3Byb21wdEVkaXRvci5qcydcbmltcG9ydCB7IHJlbmRlclRvU3RyaW5nIH0gZnJvbSAnLi4vLi4vdXRpbHMvc3RhdGljUmVuZGVyLmpzJ1xuXG5mdW5jdGlvbiBQbGFuRGlzcGxheSh7XG4gIHBsYW5Db250ZW50LFxuICBwbGFuUGF0aCxcbiAgZWRpdG9yTmFtZSxcbn06IHtcbiAgcGxhbkNvbnRlbnQ6IHN0cmluZ1xuICBwbGFuUGF0aDogc3RyaW5nXG4gIGVkaXRvck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZFxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIHJldHVybiAoXG4gICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCI+XG4gICAgICA8VGV4dCBib2xkPkN1cnJlbnQgUGxhbjwvVGV4dD5cbiAgICAgIDxUZXh0IGRpbUNvbG9yPntwbGFuUGF0aH08L1RleHQ+XG4gICAgICA8Qm94IG1hcmdpblRvcD17MX0+XG4gICAgICAgIDxUZXh0PntwbGFuQ29udGVudH08L1RleHQ+XG4gICAgICA8L0JveD5cbiAgICAgIHtlZGl0b3JOYW1lICYmIChcbiAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiZxdW90Oy9wbGFuIG9wZW4mcXVvdDs8L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+IHRvIGVkaXQgdGhpcyBwbGFuIGluIDwvVGV4dD5cbiAgICAgICAgICA8VGV4dCBib2xkIGRpbUNvbG9yPlxuICAgICAgICAgICAge2VkaXRvck5hbWV9XG4gICAgICAgICAgPC9UZXh0PlxuICAgICAgICA8L0JveD5cbiAgICAgICl9XG4gICAgPC9Cb3g+XG4gIClcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhbGwoXG4gIG9uRG9uZTogTG9jYWxKU1hDb21tYW5kT25Eb25lLFxuICBjb250ZXh0OiBMb2NhbEpTWENvbW1hbmRDb250ZXh0LFxuICBhcmdzOiBzdHJpbmcsXG4pOiBQcm9taXNlPFJlYWN0LlJlYWN0Tm9kZT4ge1xuICBjb25zdCB7IGdldEFwcFN0YXRlLCBzZXRBcHBTdGF0ZSB9ID0gY29udGV4dFxuICBjb25zdCBhcHBTdGF0ZSA9IGdldEFwcFN0YXRlKClcbiAgY29uc3QgY3VycmVudE1vZGUgPSBhcHBTdGF0ZS50b29sUGVybWlzc2lvbkNvbnRleHQubW9kZVxuXG4gIC8vIElmIG5vdCBpbiBwbGFuIG1vZGUsIGVuYWJsZSBpdFxuICBpZiAoY3VycmVudE1vZGUgIT09ICdwbGFuJykge1xuICAgIGhhbmRsZVBsYW5Nb2RlVHJhbnNpdGlvbihjdXJyZW50TW9kZSwgJ3BsYW4nKVxuICAgIHNldEFwcFN0YXRlKHByZXYgPT4gKHtcbiAgICAgIC4uLnByZXYsXG4gICAgICB0b29sUGVybWlzc2lvbkNvbnRleHQ6IGFwcGx5UGVybWlzc2lvblVwZGF0ZShcbiAgICAgICAgcHJlcGFyZUNvbnRleHRGb3JQbGFuTW9kZShwcmV2LnRvb2xQZXJtaXNzaW9uQ29udGV4dCksXG4gICAgICAgIHsgdHlwZTogJ3NldE1vZGUnLCBtb2RlOiAncGxhbicsIGRlc3RpbmF0aW9uOiAnc2Vzc2lvbicgfSxcbiAgICAgICksXG4gICAgfSkpXG4gICAgY29uc3QgZGVzY3JpcHRpb24gPSBhcmdzLnRyaW0oKVxuICAgIGlmIChkZXNjcmlwdGlvbiAmJiBkZXNjcmlwdGlvbiAhPT0gJ29wZW4nKSB7XG4gICAgICBvbkRvbmUoJ0VuYWJsZWQgcGxhbiBtb2RlJywgeyBzaG91bGRRdWVyeTogdHJ1ZSB9KVxuICAgIH0gZWxzZSB7XG4gICAgICBvbkRvbmUoJ0VuYWJsZWQgcGxhbiBtb2RlJylcbiAgICB9XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8vIEFscmVhZHkgaW4