fix: keep only source-map extracted node_modules, exclude pnpm artifacts
Restore node_modules to exact state from cli.js.map extraction: - Move .ignored/ and .ignored_* files back to original package paths - Remove pnpm symlinks (replaced by real source-map directories) - Update .gitignore: only exclude /dist/, .pnpm/, .bin/, .ignored* dirs - All package dist/ folders are now preserved as part of source-map files After clone, run `pnpm install` to get pnpm-managed symlinks for building. The committed node_modules contains the original TypeScript/JS source files as bundled in cli.js.
This commit is contained in:
12
claude-code-source/node_modules/@inquirer/core/dist/esm/index.mjs
generated
vendored
Normal file
12
claude-code-source/node_modules/@inquirer/core/dist/esm/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export * from './lib/key.mjs';
|
||||
export * from './lib/errors.mjs';
|
||||
export { usePrefix } from './lib/use-prefix.mjs';
|
||||
export { useState } from './lib/use-state.mjs';
|
||||
export { useEffect } from './lib/use-effect.mjs';
|
||||
export { useMemo } from './lib/use-memo.mjs';
|
||||
export { useRef } from './lib/use-ref.mjs';
|
||||
export { useKeypress } from './lib/use-keypress.mjs';
|
||||
export { makeTheme } from './lib/make-theme.mjs';
|
||||
export { usePagination } from './lib/pagination/use-pagination.mjs';
|
||||
export { createPrompt } from './lib/create-prompt.mjs';
|
||||
export { Separator } from './lib/Separator.mjs';
|
||||
21
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/Separator.mjs
generated
vendored
Normal file
21
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/Separator.mjs
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import colors from 'yoctocolors-cjs';
|
||||
import figures from '@inquirer/figures';
|
||||
/**
|
||||
* Separator object
|
||||
* Used to space/separate choices group
|
||||
*/
|
||||
export class Separator {
|
||||
separator = colors.dim(Array.from({ length: 15 }).join(figures.line));
|
||||
type = 'separator';
|
||||
constructor(separator) {
|
||||
if (separator) {
|
||||
this.separator = separator;
|
||||
}
|
||||
}
|
||||
static isSeparator(choice) {
|
||||
return Boolean(choice &&
|
||||
typeof choice === 'object' &&
|
||||
'type' in choice &&
|
||||
choice.type === 'separator');
|
||||
}
|
||||
}
|
||||
84
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/create-prompt.mjs
generated
vendored
Normal file
84
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/create-prompt.mjs
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
import * as readline from 'node:readline';
|
||||
import { AsyncResource } from 'node:async_hooks';
|
||||
import MuteStream from 'mute-stream';
|
||||
import { onExit as onSignalExit } from 'signal-exit';
|
||||
import ScreenManager from './screen-manager.mjs';
|
||||
import { PromisePolyfill } from './promise-polyfill.mjs';
|
||||
import { withHooks, effectScheduler } from './hook-engine.mjs';
|
||||
import { AbortPromptError, CancelPromptError, ExitPromptError } from './errors.mjs';
|
||||
export function createPrompt(view) {
|
||||
const prompt = (config, context = {}) => {
|
||||
// Default `input` to stdin
|
||||
const { input = process.stdin, signal } = context;
|
||||
const cleanups = new Set();
|
||||
// Add mute capabilities to the output
|
||||
const output = new MuteStream();
|
||||
output.pipe(context.output ?? process.stdout);
|
||||
const rl = readline.createInterface({
|
||||
terminal: true,
|
||||
input,
|
||||
output,
|
||||
});
|
||||
const screen = new ScreenManager(rl);
|
||||
const { promise, resolve, reject } = PromisePolyfill.withResolver();
|
||||
/** @deprecated pass an AbortSignal in the context options instead. See {@link https://github.com/SBoudrias/Inquirer.js#canceling-prompt} */
|
||||
const cancel = () => reject(new CancelPromptError());
|
||||
if (signal) {
|
||||
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
||||
if (signal.aborted) {
|
||||
abort();
|
||||
return Object.assign(promise, { cancel });
|
||||
}
|
||||
signal.addEventListener('abort', abort);
|
||||
cleanups.add(() => signal.removeEventListener('abort', abort));
|
||||
}
|
||||
cleanups.add(onSignalExit((code, signal) => {
|
||||
reject(new ExitPromptError(`User force closed the prompt with ${code} ${signal}`));
|
||||
}));
|
||||
// Re-renders only happen when the state change; but the readline cursor could change position
|
||||
// and that also requires a re-render (and a manual one because we mute the streams).
|
||||
// We set the listener after the initial workLoop to avoid a double render if render triggered
|
||||
// by a state change sets the cursor to the right position.
|
||||
const checkCursorPos = () => screen.checkCursorPos();
|
||||
rl.input.on('keypress', checkCursorPos);
|
||||
cleanups.add(() => rl.input.removeListener('keypress', checkCursorPos));
|
||||
return withHooks(rl, (cycle) => {
|
||||
// The close event triggers immediately when the user press ctrl+c. SignalExit on the other hand
|
||||
// triggers after the process is done (which happens after timeouts are done triggering.)
|
||||
// We triggers the hooks cleanup phase on rl `close` so active timeouts can be cleared.
|
||||
const hooksCleanup = AsyncResource.bind(() => effectScheduler.clearAll());
|
||||
rl.on('close', hooksCleanup);
|
||||
cleanups.add(() => rl.removeListener('close', hooksCleanup));
|
||||
cycle(() => {
|
||||
try {
|
||||
const nextView = view(config, (value) => {
|
||||
setImmediate(() => resolve(value));
|
||||
});
|
||||
const [content, bottomContent] = typeof nextView === 'string' ? [nextView] : nextView;
|
||||
screen.render(content, bottomContent);
|
||||
effectScheduler.run();
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return Object.assign(promise
|
||||
.then((answer) => {
|
||||
effectScheduler.clearAll();
|
||||
return answer;
|
||||
}, (error) => {
|
||||
effectScheduler.clearAll();
|
||||
throw error;
|
||||
})
|
||||
// Wait for the promise to settle, then cleanup.
|
||||
.finally(() => {
|
||||
cleanups.forEach((cleanup) => cleanup());
|
||||
screen.done({ clearContent: Boolean(context?.clearPromptOnDone) });
|
||||
output.end();
|
||||
})
|
||||
// Once cleanup is done, let the expose promise resolve/reject to the internal one.
|
||||
.then(() => promise), { cancel });
|
||||
});
|
||||
};
|
||||
return prompt;
|
||||
}
|
||||
21
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/errors.mjs
generated
vendored
Normal file
21
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/errors.mjs
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
export class AbortPromptError extends Error {
|
||||
name = 'AbortPromptError';
|
||||
message = 'Prompt was aborted';
|
||||
constructor(options) {
|
||||
super();
|
||||
this.cause = options?.cause;
|
||||
}
|
||||
}
|
||||
export class CancelPromptError extends Error {
|
||||
name = 'CancelPromptError';
|
||||
message = 'Prompt was canceled';
|
||||
}
|
||||
export class ExitPromptError extends Error {
|
||||
name = 'ExitPromptError';
|
||||
}
|
||||
export class HookError extends Error {
|
||||
name = 'HookError';
|
||||
}
|
||||
export class ValidationError extends Error {
|
||||
name = 'ValidationError';
|
||||
}
|
||||
110
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/hook-engine.mjs
generated
vendored
Normal file
110
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/hook-engine.mjs
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/* eslint @typescript-eslint/no-explicit-any: ["off"] */
|
||||
import { AsyncLocalStorage, AsyncResource } from 'node:async_hooks';
|
||||
import { HookError, ValidationError } from './errors.mjs';
|
||||
const hookStorage = new AsyncLocalStorage();
|
||||
function createStore(rl) {
|
||||
const store = {
|
||||
rl,
|
||||
hooks: [],
|
||||
hooksCleanup: [],
|
||||
hooksEffect: [],
|
||||
index: 0,
|
||||
handleChange() { },
|
||||
};
|
||||
return store;
|
||||
}
|
||||
// Run callback in with the hook engine setup.
|
||||
export function withHooks(rl, cb) {
|
||||
const store = createStore(rl);
|
||||
return hookStorage.run(store, () => {
|
||||
function cycle(render) {
|
||||
store.handleChange = () => {
|
||||
store.index = 0;
|
||||
render();
|
||||
};
|
||||
store.handleChange();
|
||||
}
|
||||
return cb(cycle);
|
||||
});
|
||||
}
|
||||
// Safe getStore utility that'll return the store or throw if undefined.
|
||||
function getStore() {
|
||||
const store = hookStorage.getStore();
|
||||
if (!store) {
|
||||
throw new HookError('[Inquirer] Hook functions can only be called from within a prompt');
|
||||
}
|
||||
return store;
|
||||
}
|
||||
export function readline() {
|
||||
return getStore().rl;
|
||||
}
|
||||
// Merge state updates happening within the callback function to avoid multiple renders.
|
||||
export function withUpdates(fn) {
|
||||
const wrapped = (...args) => {
|
||||
const store = getStore();
|
||||
let shouldUpdate = false;
|
||||
const oldHandleChange = store.handleChange;
|
||||
store.handleChange = () => {
|
||||
shouldUpdate = true;
|
||||
};
|
||||
const returnValue = fn(...args);
|
||||
if (shouldUpdate) {
|
||||
oldHandleChange();
|
||||
}
|
||||
store.handleChange = oldHandleChange;
|
||||
return returnValue;
|
||||
};
|
||||
return AsyncResource.bind(wrapped);
|
||||
}
|
||||
export function withPointer(cb) {
|
||||
const store = getStore();
|
||||
const { index } = store;
|
||||
const pointer = {
|
||||
get() {
|
||||
return store.hooks[index];
|
||||
},
|
||||
set(value) {
|
||||
store.hooks[index] = value;
|
||||
},
|
||||
initialized: index in store.hooks,
|
||||
};
|
||||
const returnValue = cb(pointer);
|
||||
store.index++;
|
||||
return returnValue;
|
||||
}
|
||||
export function handleChange() {
|
||||
getStore().handleChange();
|
||||
}
|
||||
export const effectScheduler = {
|
||||
queue(cb) {
|
||||
const store = getStore();
|
||||
const { index } = store;
|
||||
store.hooksEffect.push(() => {
|
||||
store.hooksCleanup[index]?.();
|
||||
const cleanFn = cb(readline());
|
||||
if (cleanFn != null && typeof cleanFn !== 'function') {
|
||||
throw new ValidationError('useEffect return value must be a cleanup function or nothing.');
|
||||
}
|
||||
store.hooksCleanup[index] = cleanFn;
|
||||
});
|
||||
},
|
||||
run() {
|
||||
const store = getStore();
|
||||
withUpdates(() => {
|
||||
store.hooksEffect.forEach((effect) => {
|
||||
effect();
|
||||
});
|
||||
// Warning: Clean the hooks before exiting the `withUpdates` block.
|
||||
// Failure to do so means an updates would hit the same effects again.
|
||||
store.hooksEffect.length = 0;
|
||||
})();
|
||||
},
|
||||
clearAll() {
|
||||
const store = getStore();
|
||||
store.hooksCleanup.forEach((cleanFn) => {
|
||||
cleanFn?.();
|
||||
});
|
||||
store.hooksEffect.length = 0;
|
||||
store.hooksCleanup.length = 0;
|
||||
},
|
||||
};
|
||||
18
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/key.mjs
generated
vendored
Normal file
18
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/key.mjs
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
export const isUpKey = (key) =>
|
||||
// The up key
|
||||
key.name === 'up' ||
|
||||
// Vim keybinding
|
||||
key.name === 'k' ||
|
||||
// Emacs keybinding
|
||||
(key.ctrl && key.name === 'p');
|
||||
export const isDownKey = (key) =>
|
||||
// The down key
|
||||
key.name === 'down' ||
|
||||
// Vim keybinding
|
||||
key.name === 'j' ||
|
||||
// Emacs keybinding
|
||||
(key.ctrl && key.name === 'n');
|
||||
export const isSpaceKey = (key) => key.name === 'space';
|
||||
export const isBackspaceKey = (key) => key.name === 'backspace';
|
||||
export const isNumberKey = (key) => '123456789'.includes(key.name);
|
||||
export const isEnterKey = (key) => key.name === 'enter' || key.name === 'return';
|
||||
30
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/make-theme.mjs
generated
vendored
Normal file
30
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/make-theme.mjs
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { defaultTheme } from './theme.mjs';
|
||||
function isPlainObject(value) {
|
||||
if (typeof value !== 'object' || value === null)
|
||||
return false;
|
||||
let proto = value;
|
||||
while (Object.getPrototypeOf(proto) !== null) {
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
return Object.getPrototypeOf(value) === proto;
|
||||
}
|
||||
function deepMerge(...objects) {
|
||||
const output = {};
|
||||
for (const obj of objects) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
const prevValue = output[key];
|
||||
output[key] =
|
||||
isPlainObject(prevValue) && isPlainObject(value)
|
||||
? deepMerge(prevValue, value)
|
||||
: value;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
export function makeTheme(...themes) {
|
||||
const themesToMerge = [
|
||||
defaultTheme,
|
||||
...themes.filter((theme) => theme != null),
|
||||
];
|
||||
return deepMerge(...themesToMerge);
|
||||
}
|
||||
59
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/pagination/lines.mjs
generated
vendored
Normal file
59
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/pagination/lines.mjs
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
import { breakLines } from '../utils.mjs';
|
||||
function split(content, width) {
|
||||
return breakLines(content, width).split('\n');
|
||||
}
|
||||
/**
|
||||
* Rotates an array of items by an integer number of positions.
|
||||
* @param {number} count The number of positions to rotate by
|
||||
* @param {T[]} items The items to rotate
|
||||
*/
|
||||
function rotate(count, items) {
|
||||
const max = items.length;
|
||||
const offset = ((count % max) + max) % max;
|
||||
return [...items.slice(offset), ...items.slice(0, offset)];
|
||||
}
|
||||
/**
|
||||
* Renders a page of items as lines that fit within the given width ensuring
|
||||
* that the number of lines is not greater than the page size, and the active
|
||||
* item renders at the provided position, while prioritizing that as many lines
|
||||
* of the active item get rendered as possible.
|
||||
*/
|
||||
export function lines({ items, width, renderItem, active, position: requested, pageSize, }) {
|
||||
const layouts = items.map((item, index) => ({
|
||||
item,
|
||||
index,
|
||||
isActive: index === active,
|
||||
}));
|
||||
const layoutsInPage = rotate(active - requested, layouts).slice(0, pageSize);
|
||||
const renderItemAt = (index) => layoutsInPage[index] == null ? [] : split(renderItem(layoutsInPage[index]), width);
|
||||
// Create a blank array of lines for the page
|
||||
const pageBuffer = Array.from({ length: pageSize });
|
||||
// Render the active item to decide the position
|
||||
const activeItem = renderItemAt(requested).slice(0, pageSize);
|
||||
const position = requested + activeItem.length <= pageSize ? requested : pageSize - activeItem.length;
|
||||
// Add the lines of the active item into the page
|
||||
pageBuffer.splice(position, activeItem.length, ...activeItem);
|
||||
// Fill the page under the active item
|
||||
let bufferPointer = position + activeItem.length;
|
||||
let layoutPointer = requested + 1;
|
||||
while (bufferPointer < pageSize && layoutPointer < layoutsInPage.length) {
|
||||
for (const line of renderItemAt(layoutPointer)) {
|
||||
pageBuffer[bufferPointer++] = line;
|
||||
if (bufferPointer >= pageSize)
|
||||
break;
|
||||
}
|
||||
layoutPointer++;
|
||||
}
|
||||
// Fill the page over the active item
|
||||
bufferPointer = position - 1;
|
||||
layoutPointer = requested - 1;
|
||||
while (bufferPointer >= 0 && layoutPointer >= 0) {
|
||||
for (const line of renderItemAt(layoutPointer).reverse()) {
|
||||
pageBuffer[bufferPointer--] = line;
|
||||
if (bufferPointer < 0)
|
||||
break;
|
||||
}
|
||||
layoutPointer--;
|
||||
}
|
||||
return pageBuffer.filter((line) => typeof line === 'string');
|
||||
}
|
||||
27
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/pagination/position.mjs
generated
vendored
Normal file
27
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/pagination/position.mjs
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Creates the next position for the active item considering a finite list of
|
||||
* items to be rendered on a page.
|
||||
*/
|
||||
export function finite({ active, pageSize, total, }) {
|
||||
const middle = Math.floor(pageSize / 2);
|
||||
if (total <= pageSize || active < middle)
|
||||
return active;
|
||||
if (active >= total - middle)
|
||||
return active + pageSize - total;
|
||||
return middle;
|
||||
}
|
||||
/**
|
||||
* Creates the next position for the active item considering an infinitely
|
||||
* looping list of items to be rendered on the page.
|
||||
*/
|
||||
export function infinite({ active, lastActive, total, pageSize, pointer, }) {
|
||||
if (total <= pageSize)
|
||||
return active;
|
||||
// Move the position only when the user moves down, and when the
|
||||
// navigation fits within a single page
|
||||
if (lastActive < active && active - lastActive < pageSize) {
|
||||
// Limit it to the middle of the list
|
||||
return Math.min(Math.floor(pageSize / 2), pointer + active - lastActive);
|
||||
}
|
||||
return pointer;
|
||||
}
|
||||
30
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.mjs
generated
vendored
Normal file
30
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.mjs
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { useRef } from '../use-ref.mjs';
|
||||
import { readlineWidth } from '../utils.mjs';
|
||||
import { lines } from './lines.mjs';
|
||||
import { finite, infinite } from './position.mjs';
|
||||
export function usePagination({ items, active, renderItem, pageSize, loop = true, }) {
|
||||
const state = useRef({ position: 0, lastActive: 0 });
|
||||
const position = loop
|
||||
? infinite({
|
||||
active,
|
||||
lastActive: state.current.lastActive,
|
||||
total: items.length,
|
||||
pageSize,
|
||||
pointer: state.current.position,
|
||||
})
|
||||
: finite({
|
||||
active,
|
||||
total: items.length,
|
||||
pageSize,
|
||||
});
|
||||
state.current.position = position;
|
||||
state.current.lastActive = active;
|
||||
return lines({
|
||||
items,
|
||||
width: readlineWidth(),
|
||||
renderItem,
|
||||
active,
|
||||
position,
|
||||
pageSize,
|
||||
}).join('\n');
|
||||
}
|
||||
14
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.mjs
generated
vendored
Normal file
14
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.mjs
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// TODO: Remove this class once Node 22 becomes the minimum supported version.
|
||||
export class PromisePolyfill extends Promise {
|
||||
// Available starting from Node 22
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
||||
static withResolver() {
|
||||
let resolve;
|
||||
let reject;
|
||||
const promise = new Promise((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
return { promise, resolve: resolve, reject: reject };
|
||||
}
|
||||
}
|
||||
85
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/screen-manager.mjs
generated
vendored
Normal file
85
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/screen-manager.mjs
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
import stripAnsi from 'strip-ansi';
|
||||
import ansiEscapes from 'ansi-escapes';
|
||||
import { breakLines, readlineWidth } from './utils.mjs';
|
||||
const height = (content) => content.split('\n').length;
|
||||
const lastLine = (content) => content.split('\n').pop() ?? '';
|
||||
function cursorDown(n) {
|
||||
return n > 0 ? ansiEscapes.cursorDown(n) : '';
|
||||
}
|
||||
export default class ScreenManager {
|
||||
rl;
|
||||
// These variables are keeping information to allow correct prompt re-rendering
|
||||
height = 0;
|
||||
extraLinesUnderPrompt = 0;
|
||||
cursorPos;
|
||||
constructor(rl) {
|
||||
this.rl = rl;
|
||||
this.rl = rl;
|
||||
this.cursorPos = rl.getCursorPos();
|
||||
}
|
||||
write(content) {
|
||||
this.rl.output.unmute();
|
||||
this.rl.output.write(content);
|
||||
this.rl.output.mute();
|
||||
}
|
||||
render(content, bottomContent = '') {
|
||||
// Write message to screen and setPrompt to control backspace
|
||||
const promptLine = lastLine(content);
|
||||
const rawPromptLine = stripAnsi(promptLine);
|
||||
// Remove the rl.line from our prompt. We can't rely on the content of
|
||||
// rl.line (mainly because of the password prompt), so just rely on it's
|
||||
// length.
|
||||
let prompt = rawPromptLine;
|
||||
if (this.rl.line.length > 0) {
|
||||
prompt = prompt.slice(0, -this.rl.line.length);
|
||||
}
|
||||
this.rl.setPrompt(prompt);
|
||||
// SetPrompt will change cursor position, now we can get correct value
|
||||
this.cursorPos = this.rl.getCursorPos();
|
||||
const width = readlineWidth();
|
||||
content = breakLines(content, width);
|
||||
bottomContent = breakLines(bottomContent, width);
|
||||
// Manually insert an extra line if we're at the end of the line.
|
||||
// This prevent the cursor from appearing at the beginning of the
|
||||
// current line.
|
||||
if (rawPromptLine.length % width === 0) {
|
||||
content += '\n';
|
||||
}
|
||||
let output = content + (bottomContent ? '\n' + bottomContent : '');
|
||||
/**
|
||||
* Re-adjust the cursor at the correct position.
|
||||
*/
|
||||
// We need to consider parts of the prompt under the cursor as part of the bottom
|
||||
// content in order to correctly cleanup and re-render.
|
||||
const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
|
||||
const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
|
||||
// Return cursor to the input position (on top of the bottomContent)
|
||||
if (bottomContentHeight > 0)
|
||||
output += ansiEscapes.cursorUp(bottomContentHeight);
|
||||
// Return cursor to the initial left offset.
|
||||
output += ansiEscapes.cursorTo(this.cursorPos.cols);
|
||||
/**
|
||||
* Render and store state for future re-rendering
|
||||
*/
|
||||
this.write(cursorDown(this.extraLinesUnderPrompt) +
|
||||
ansiEscapes.eraseLines(this.height) +
|
||||
output);
|
||||
this.extraLinesUnderPrompt = bottomContentHeight;
|
||||
this.height = height(output);
|
||||
}
|
||||
checkCursorPos() {
|
||||
const cursorPos = this.rl.getCursorPos();
|
||||
if (cursorPos.cols !== this.cursorPos.cols) {
|
||||
this.write(ansiEscapes.cursorTo(cursorPos.cols));
|
||||
this.cursorPos = cursorPos;
|
||||
}
|
||||
}
|
||||
done({ clearContent }) {
|
||||
this.rl.setPrompt('');
|
||||
let output = cursorDown(this.extraLinesUnderPrompt);
|
||||
output += clearContent ? ansiEscapes.eraseLines(this.height) : '\n';
|
||||
output += ansiEscapes.cursorShow;
|
||||
this.write(output);
|
||||
this.rl.close();
|
||||
}
|
||||
}
|
||||
22
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/theme.mjs
generated
vendored
Normal file
22
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/theme.mjs
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import colors from 'yoctocolors-cjs';
|
||||
import figures from '@inquirer/figures';
|
||||
export const defaultTheme = {
|
||||
prefix: {
|
||||
idle: colors.blue('?'),
|
||||
// TODO: use figure
|
||||
done: colors.green(figures.tick),
|
||||
},
|
||||
spinner: {
|
||||
interval: 80,
|
||||
frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'].map((frame) => colors.yellow(frame)),
|
||||
},
|
||||
style: {
|
||||
answer: colors.cyan,
|
||||
message: colors.bold,
|
||||
error: (text) => colors.red(`> ${text}`),
|
||||
defaultAnswer: (text) => colors.dim(`(${text})`),
|
||||
help: colors.dim,
|
||||
highlight: colors.cyan,
|
||||
key: (text) => colors.cyan(colors.bold(`<${text}>`)),
|
||||
},
|
||||
};
|
||||
11
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-effect.mjs
generated
vendored
Normal file
11
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-effect.mjs
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { withPointer, effectScheduler } from './hook-engine.mjs';
|
||||
export function useEffect(cb, depArray) {
|
||||
withPointer((pointer) => {
|
||||
const oldDeps = pointer.get();
|
||||
const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
|
||||
if (hasChanged) {
|
||||
effectScheduler.queue(cb);
|
||||
}
|
||||
pointer.set(depArray);
|
||||
});
|
||||
}
|
||||
20
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-keypress.mjs
generated
vendored
Normal file
20
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-keypress.mjs
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { useRef } from './use-ref.mjs';
|
||||
import { useEffect } from './use-effect.mjs';
|
||||
import { withUpdates } from './hook-engine.mjs';
|
||||
export function useKeypress(userHandler) {
|
||||
const signal = useRef(userHandler);
|
||||
signal.current = userHandler;
|
||||
useEffect((rl) => {
|
||||
let ignore = false;
|
||||
const handler = withUpdates((_input, event) => {
|
||||
if (ignore)
|
||||
return;
|
||||
void signal.current(event, rl);
|
||||
});
|
||||
rl.input.on('keypress', handler);
|
||||
return () => {
|
||||
ignore = true;
|
||||
rl.input.removeListener('keypress', handler);
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
14
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-memo.mjs
generated
vendored
Normal file
14
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-memo.mjs
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import { withPointer } from './hook-engine.mjs';
|
||||
export function useMemo(fn, dependencies) {
|
||||
return withPointer((pointer) => {
|
||||
const prev = pointer.get();
|
||||
if (!prev ||
|
||||
prev.dependencies.length !== dependencies.length ||
|
||||
prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
|
||||
const value = fn();
|
||||
pointer.set({ value, dependencies });
|
||||
return value;
|
||||
}
|
||||
return prev.value;
|
||||
});
|
||||
}
|
||||
36
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-prefix.mjs
generated
vendored
Normal file
36
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-prefix.mjs
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import { AsyncResource } from 'node:async_hooks';
|
||||
import { useState } from './use-state.mjs';
|
||||
import { useEffect } from './use-effect.mjs';
|
||||
import { makeTheme } from './make-theme.mjs';
|
||||
export function usePrefix({ status = 'idle', theme, }) {
|
||||
const [showLoader, setShowLoader] = useState(false);
|
||||
const [tick, setTick] = useState(0);
|
||||
const { prefix, spinner } = makeTheme(theme);
|
||||
useEffect(() => {
|
||||
if (status === 'loading') {
|
||||
let tickInterval;
|
||||
let inc = -1;
|
||||
// Delay displaying spinner by 300ms, to avoid flickering
|
||||
const delayTimeout = setTimeout(AsyncResource.bind(() => {
|
||||
setShowLoader(true);
|
||||
tickInterval = setInterval(AsyncResource.bind(() => {
|
||||
inc = inc + 1;
|
||||
setTick(inc % spinner.frames.length);
|
||||
}), spinner.interval);
|
||||
}), 300);
|
||||
return () => {
|
||||
clearTimeout(delayTimeout);
|
||||
clearInterval(tickInterval);
|
||||
};
|
||||
}
|
||||
else {
|
||||
setShowLoader(false);
|
||||
}
|
||||
}, [status]);
|
||||
if (showLoader) {
|
||||
return spinner.frames[tick];
|
||||
}
|
||||
// There's a delay before we show the loader. So we want to ignore `loading` here, and pass idle instead.
|
||||
const iconName = status === 'loading' ? 'idle' : status;
|
||||
return typeof prefix === 'string' ? prefix : prefix[iconName];
|
||||
}
|
||||
4
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-ref.mjs
generated
vendored
Normal file
4
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-ref.mjs
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { useState } from './use-state.mjs';
|
||||
export function useRef(val) {
|
||||
return useState({ current: val })[0];
|
||||
}
|
||||
19
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-state.mjs
generated
vendored
Normal file
19
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/use-state.mjs
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import { withPointer, handleChange } from './hook-engine.mjs';
|
||||
export function useState(defaultValue) {
|
||||
return withPointer((pointer) => {
|
||||
const setFn = (newValue) => {
|
||||
// Noop if the value is still the same.
|
||||
if (pointer.get() !== newValue) {
|
||||
pointer.set(newValue);
|
||||
// Trigger re-render
|
||||
handleChange();
|
||||
}
|
||||
};
|
||||
if (pointer.initialized) {
|
||||
return [pointer.get(), setFn];
|
||||
}
|
||||
const value = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
||||
pointer.set(value);
|
||||
return [value, setFn];
|
||||
});
|
||||
}
|
||||
25
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/utils.mjs
generated
vendored
Normal file
25
claude-code-source/node_modules/@inquirer/core/dist/esm/lib/utils.mjs
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import cliWidth from 'cli-width';
|
||||
import wrapAnsi from 'wrap-ansi';
|
||||
import { readline } from './hook-engine.mjs';
|
||||
/**
|
||||
* Force line returns at specific width. This function is ANSI code friendly and it'll
|
||||
* ignore invisible codes during width calculation.
|
||||
* @param {string} content
|
||||
* @param {number} width
|
||||
* @return {string}
|
||||
*/
|
||||
export function breakLines(content, width) {
|
||||
return content
|
||||
.split('\n')
|
||||
.flatMap((line) => wrapAnsi(line, width, { trim: false, hard: true })
|
||||
.split('\n')
|
||||
.map((str) => str.trimEnd()))
|
||||
.join('\n');
|
||||
}
|
||||
/**
|
||||
* Returns the width of the active readline, or 80 as default value.
|
||||
* @returns {number}
|
||||
*/
|
||||
export function readlineWidth() {
|
||||
return cliWidth({ defaultWidth: 80, output: readline().output });
|
||||
}
|
||||
Reference in New Issue
Block a user