devlyn-cli 4.2.0 → 4.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +4 -2
  2. package/bin/devlyn.js +184 -147
  3. package/bin/skill-history.json +140 -0
  4. package/bin/skill-ownership.js +67 -0
  5. package/node_modules/@inquirer/ansi/LICENSE +22 -0
  6. package/node_modules/@inquirer/ansi/README.md +121 -0
  7. package/node_modules/@inquirer/ansi/dist/index.d.ts +14 -0
  8. package/node_modules/@inquirer/ansi/dist/index.js +21 -0
  9. package/node_modules/@inquirer/ansi/package.json +79 -0
  10. package/node_modules/@inquirer/checkbox/LICENSE +22 -0
  11. package/node_modules/@inquirer/checkbox/README.md +265 -0
  12. package/node_modules/@inquirer/checkbox/dist/index.d.ts +67 -0
  13. package/node_modules/@inquirer/checkbox/dist/index.js +210 -0
  14. package/node_modules/@inquirer/checkbox/package.json +93 -0
  15. package/node_modules/@inquirer/core/LICENSE +22 -0
  16. package/node_modules/@inquirer/core/README.md +424 -0
  17. package/node_modules/@inquirer/core/dist/index.d.ts +13 -0
  18. package/node_modules/@inquirer/core/dist/index.js +12 -0
  19. package/node_modules/@inquirer/core/dist/lib/Separator.d.ts +10 -0
  20. package/node_modules/@inquirer/core/dist/lib/Separator.js +21 -0
  21. package/node_modules/@inquirer/core/dist/lib/__probe/p1.d.ts +9 -0
  22. package/node_modules/@inquirer/core/dist/lib/__probe/p1.js +4 -0
  23. package/node_modules/@inquirer/core/dist/lib/__probe/p2.d.ts +9 -0
  24. package/node_modules/@inquirer/core/dist/lib/__probe/p2.js +3 -0
  25. package/node_modules/@inquirer/core/dist/lib/__probe/p3.d.ts +9 -0
  26. package/node_modules/@inquirer/core/dist/lib/__probe/p3.js +5 -0
  27. package/node_modules/@inquirer/core/dist/lib/create-prompt.d.ts +11 -0
  28. package/node_modules/@inquirer/core/dist/lib/create-prompt.js +185 -0
  29. package/node_modules/@inquirer/core/dist/lib/errors.d.ts +20 -0
  30. package/node_modules/@inquirer/core/dist/lib/errors.js +21 -0
  31. package/node_modules/@inquirer/core/dist/lib/hook-engine.d.ts +17 -0
  32. package/node_modules/@inquirer/core/dist/lib/hook-engine.js +109 -0
  33. package/node_modules/@inquirer/core/dist/lib/key.d.ts +15 -0
  34. package/node_modules/@inquirer/core/dist/lib/key.js +34 -0
  35. package/node_modules/@inquirer/core/dist/lib/make-theme.d.ts +3 -0
  36. package/node_modules/@inquirer/core/dist/lib/make-theme.js +33 -0
  37. package/node_modules/@inquirer/core/dist/lib/pagination/use-pagination.d.ts +15 -0
  38. package/node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js +121 -0
  39. package/node_modules/@inquirer/core/dist/lib/screen-manager.d.ts +14 -0
  40. package/node_modules/@inquirer/core/dist/lib/screen-manager.js +84 -0
  41. package/node_modules/@inquirer/core/dist/lib/theme.d.ts +166 -0
  42. package/node_modules/@inquirer/core/dist/lib/theme.js +29 -0
  43. package/node_modules/@inquirer/core/dist/lib/use-effect.d.ts +2 -0
  44. package/node_modules/@inquirer/core/dist/lib/use-effect.js +11 -0
  45. package/node_modules/@inquirer/core/dist/lib/use-keypress.d.ts +3 -0
  46. package/node_modules/@inquirer/core/dist/lib/use-keypress.js +20 -0
  47. package/node_modules/@inquirer/core/dist/lib/use-memo.d.ts +1 -0
  48. package/node_modules/@inquirer/core/dist/lib/use-memo.js +14 -0
  49. package/node_modules/@inquirer/core/dist/lib/use-prefix.d.ts +5 -0
  50. package/node_modules/@inquirer/core/dist/lib/use-prefix.js +35 -0
  51. package/node_modules/@inquirer/core/dist/lib/use-ref.d.ts +6 -0
  52. package/node_modules/@inquirer/core/dist/lib/use-ref.js +4 -0
  53. package/node_modules/@inquirer/core/dist/lib/use-state.d.ts +7 -0
  54. package/node_modules/@inquirer/core/dist/lib/use-state.js +28 -0
  55. package/node_modules/@inquirer/core/dist/lib/utils.d.ts +13 -0
  56. package/node_modules/@inquirer/core/dist/lib/utils.js +25 -0
  57. package/node_modules/@inquirer/core/package.json +98 -0
  58. package/node_modules/@inquirer/figures/LICENSE +22 -0
  59. package/node_modules/@inquirer/figures/dist/index.d.ts +275 -0
  60. package/node_modules/@inquirer/figures/dist/index.js +315 -0
  61. package/node_modules/@inquirer/figures/package.json +81 -0
  62. package/node_modules/@inquirer/select/LICENSE +22 -0
  63. package/node_modules/@inquirer/select/README.md +258 -0
  64. package/node_modules/@inquirer/select/dist/index.d.ts +42 -0
  65. package/node_modules/@inquirer/select/dist/index.js +191 -0
  66. package/node_modules/@inquirer/select/package.json +93 -0
  67. package/node_modules/@inquirer/type/LICENSE +22 -0
  68. package/node_modules/@inquirer/type/dist/index.d.ts +2 -0
  69. package/node_modules/@inquirer/type/dist/index.js +2 -0
  70. package/node_modules/@inquirer/type/dist/inquirer.d.ts +35 -0
  71. package/node_modules/@inquirer/type/dist/inquirer.js +1 -0
  72. package/node_modules/@inquirer/type/dist/utils.d.ts +45 -0
  73. package/node_modules/@inquirer/type/dist/utils.js +16 -0
  74. package/node_modules/@inquirer/type/package.json +88 -0
  75. package/node_modules/cli-width/LICENSE +13 -0
  76. package/node_modules/cli-width/README.md +71 -0
  77. package/node_modules/cli-width/index.d.ts +13 -0
  78. package/node_modules/cli-width/index.js +49 -0
  79. package/node_modules/cli-width/package.json +40 -0
  80. package/node_modules/fast-string-truncated-width/dist/index.d.ts +4 -0
  81. package/node_modules/fast-string-truncated-width/dist/index.js +111 -0
  82. package/node_modules/fast-string-truncated-width/dist/types.d.ts +19 -0
  83. package/node_modules/fast-string-truncated-width/dist/types.js +2 -0
  84. package/node_modules/fast-string-truncated-width/dist/utils.d.ts +4 -0
  85. package/node_modules/fast-string-truncated-width/dist/utils.js +20 -0
  86. package/node_modules/fast-string-truncated-width/license +21 -0
  87. package/node_modules/fast-string-truncated-width/package.json +35 -0
  88. package/node_modules/fast-string-truncated-width/readme.md +59 -0
  89. package/node_modules/fast-string-width/dist/index.d.ts +4 -0
  90. package/node_modules/fast-string-width/dist/index.js +14 -0
  91. package/node_modules/fast-string-width/license +21 -0
  92. package/node_modules/fast-string-width/package.json +34 -0
  93. package/node_modules/fast-string-width/readme.md +42 -0
  94. package/node_modules/fast-wrap-ansi/LICENSE +23 -0
  95. package/node_modules/fast-wrap-ansi/README.md +26 -0
  96. package/node_modules/fast-wrap-ansi/lib/main.d.ts +6 -0
  97. package/node_modules/fast-wrap-ansi/lib/main.js +218 -0
  98. package/node_modules/fast-wrap-ansi/package.json +51 -0
  99. package/node_modules/mute-stream/LICENSE +15 -0
  100. package/node_modules/mute-stream/README.md +68 -0
  101. package/node_modules/mute-stream/lib/index.js +142 -0
  102. package/node_modules/mute-stream/package.json +54 -0
  103. package/node_modules/signal-exit/LICENSE.txt +16 -0
  104. package/node_modules/signal-exit/README.md +74 -0
  105. package/node_modules/signal-exit/dist/cjs/browser.d.ts +12 -0
  106. package/node_modules/signal-exit/dist/cjs/browser.d.ts.map +1 -0
  107. package/node_modules/signal-exit/dist/cjs/browser.js +10 -0
  108. package/node_modules/signal-exit/dist/cjs/browser.js.map +1 -0
  109. package/node_modules/signal-exit/dist/cjs/index.d.ts +48 -0
  110. package/node_modules/signal-exit/dist/cjs/index.d.ts.map +1 -0
  111. package/node_modules/signal-exit/dist/cjs/index.js +279 -0
  112. package/node_modules/signal-exit/dist/cjs/index.js.map +1 -0
  113. package/node_modules/signal-exit/dist/cjs/package.json +3 -0
  114. package/node_modules/signal-exit/dist/cjs/signals.d.ts +29 -0
  115. package/node_modules/signal-exit/dist/cjs/signals.d.ts.map +1 -0
  116. package/node_modules/signal-exit/dist/cjs/signals.js +42 -0
  117. package/node_modules/signal-exit/dist/cjs/signals.js.map +1 -0
  118. package/node_modules/signal-exit/dist/mjs/browser.d.ts +12 -0
  119. package/node_modules/signal-exit/dist/mjs/browser.d.ts.map +1 -0
  120. package/node_modules/signal-exit/dist/mjs/browser.js +4 -0
  121. package/node_modules/signal-exit/dist/mjs/browser.js.map +1 -0
  122. package/node_modules/signal-exit/dist/mjs/index.d.ts +48 -0
  123. package/node_modules/signal-exit/dist/mjs/index.d.ts.map +1 -0
  124. package/node_modules/signal-exit/dist/mjs/index.js +275 -0
  125. package/node_modules/signal-exit/dist/mjs/index.js.map +1 -0
  126. package/node_modules/signal-exit/dist/mjs/package.json +3 -0
  127. package/node_modules/signal-exit/dist/mjs/signals.d.ts +29 -0
  128. package/node_modules/signal-exit/dist/mjs/signals.d.ts.map +1 -0
  129. package/node_modules/signal-exit/dist/mjs/signals.js +39 -0
  130. package/node_modules/signal-exit/dist/mjs/signals.js.map +1 -0
  131. package/node_modules/signal-exit/package.json +106 -0
  132. package/package.json +16 -2
@@ -0,0 +1,84 @@
1
+ import { stripVTControlCharacters } from 'node:util';
2
+ import { breakLines, readlineWidth } from "./utils.js";
3
+ import { cursorDown, cursorLeft, cursorUp, cursorTo, cursorShow, eraseLines, } from '@inquirer/ansi';
4
+ const height = (content) => content.split('\n').length;
5
+ const lastLine = (content) => content.split('\n').pop() ?? '';
6
+ export default class ScreenManager {
7
+ // These variables are keeping information to allow correct prompt re-rendering
8
+ height = 0;
9
+ extraLinesUnderPrompt = 0;
10
+ cursorPos;
11
+ rl;
12
+ constructor(rl) {
13
+ this.rl = rl;
14
+ this.cursorPos = rl.getCursorPos();
15
+ }
16
+ write(content) {
17
+ this.rl.output.unmute();
18
+ this.rl.output.write(content);
19
+ this.rl.output.mute();
20
+ }
21
+ render(content, bottomContent = '') {
22
+ // Write message to screen and setPrompt to control backspace
23
+ const promptLine = lastLine(content);
24
+ const rawPromptLine = stripVTControlCharacters(promptLine);
25
+ // Remove the rl.line from our prompt. We can't rely on the content of
26
+ // rl.line (mainly because of the password prompt), so just rely on it's
27
+ // length.
28
+ let prompt = rawPromptLine;
29
+ if (this.rl.line.length > 0) {
30
+ prompt = prompt.slice(0, -this.rl.line.length);
31
+ }
32
+ this.rl.setPrompt(prompt);
33
+ // SetPrompt will change cursor position, now we can get correct value
34
+ this.cursorPos = this.rl.getCursorPos();
35
+ const width = readlineWidth();
36
+ content = breakLines(content, width);
37
+ bottomContent = breakLines(bottomContent, width);
38
+ // Manually insert an extra line if we're at the end of the line.
39
+ // This prevent the cursor from appearing at the beginning of the
40
+ // current line.
41
+ if (rawPromptLine.length % width === 0) {
42
+ content += '\n';
43
+ }
44
+ let output = content + (bottomContent ? '\n' + bottomContent : '');
45
+ /**
46
+ * Re-adjust the cursor at the correct position.
47
+ */
48
+ // We need to consider parts of the prompt under the cursor as part of the bottom
49
+ // content in order to correctly cleanup and re-render.
50
+ const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
51
+ const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
52
+ // Return cursor to the input position (on top of the bottomContent)
53
+ if (bottomContentHeight > 0)
54
+ output += cursorUp(bottomContentHeight);
55
+ // Return cursor to the initial left offset.
56
+ output += cursorTo(this.cursorPos.cols);
57
+ /**
58
+ * Render and store state for future re-rendering
59
+ */
60
+ this.write(cursorDown(this.extraLinesUnderPrompt) + eraseLines(this.height) + output);
61
+ this.extraLinesUnderPrompt = bottomContentHeight;
62
+ this.height = height(output);
63
+ }
64
+ checkCursorPos() {
65
+ const cursorPos = this.rl.getCursorPos();
66
+ if (cursorPos.cols !== this.cursorPos.cols) {
67
+ this.write(cursorTo(cursorPos.cols));
68
+ this.cursorPos = cursorPos;
69
+ }
70
+ }
71
+ done({ clearContent }) {
72
+ this.rl.setPrompt('');
73
+ let output = cursorDown(this.extraLinesUnderPrompt);
74
+ output += clearContent ? eraseLines(this.height) : '\n';
75
+ // Reset cursor to column 0. On Windows terminals, \n moves the cursor
76
+ // down without resetting the column when the rendered prompt+answer
77
+ // wraps past the terminal width. Without this, all subsequent output
78
+ // starts at the wrong horizontal offset.
79
+ output += cursorLeft;
80
+ output += cursorShow;
81
+ this.write(output);
82
+ this.rl.close();
83
+ }
84
+ }
@@ -0,0 +1,166 @@
1
+ import type { Prettify } from '@inquirer/type';
2
+ import { type Keybinding } from './key.ts';
3
+ /**
4
+ * Union type representing the possible statuses of a prompt.
5
+ *
6
+ * - `'loading'`: The prompt is currently loading.
7
+ * - `'idle'`: The prompt is loaded and currently waiting for the user to
8
+ * submit an answer.
9
+ * - `'done'`: The user has submitted an answer and the prompt is finished.
10
+ * - `string`: Any other string: The prompt is in a custom state.
11
+ */
12
+ export type Status = 'loading' | 'idle' | 'done' | (string & {});
13
+ type DefaultTheme = {
14
+ /**
15
+ * Prefix to prepend to the message. If a function is provided, it will be
16
+ * called with the current status of the prompt, and the return value will be
17
+ * used as the prefix.
18
+ *
19
+ * @remarks
20
+ * If `status === 'loading'`, this property is ignored and the spinner (styled
21
+ * by the `spinner` property) will be displayed instead.
22
+ *
23
+ * @defaultValue
24
+ * ```ts
25
+ * // import { styleText } from 'node:util';
26
+ * (status) => status === 'done' ? styleText('green', '✔') : styleText('blue', '?')
27
+ * ```
28
+ */
29
+ prefix: string | Prettify<Omit<Record<Status, string>, 'loading'>>;
30
+ /**
31
+ * Configuration for the spinner that is displayed when the prompt is in the
32
+ * `'loading'` state.
33
+ *
34
+ * We recommend the use of {@link https://github.com/sindresorhus/cli-spinners|cli-spinners} for a list of available spinners.
35
+ */
36
+ spinner: {
37
+ /**
38
+ * The time interval between frames, in milliseconds.
39
+ *
40
+ * @defaultValue
41
+ * ```ts
42
+ * 80
43
+ * ```
44
+ */
45
+ interval: number;
46
+ /**
47
+ * A list of frames to show for the spinner.
48
+ *
49
+ * @defaultValue
50
+ * ```ts
51
+ * ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
52
+ * ```
53
+ */
54
+ frames: string[];
55
+ };
56
+ /**
57
+ * Alternative keybindings enabled for prompt navigation.
58
+ *
59
+ * @defaultValue
60
+ * ```ts
61
+ * process.env['INQUIRER_KEYBINDINGS']
62
+ * ```
63
+ */
64
+ keybindings: ReadonlyArray<Keybinding>;
65
+ /**
66
+ * Object containing functions to style different parts of the prompt.
67
+ */
68
+ style: {
69
+ /**
70
+ * Style to apply to the user's answer once it has been submitted.
71
+ *
72
+ * @param text - The user's answer.
73
+ * @returns The styled answer.
74
+ *
75
+ * @defaultValue
76
+ * ```ts
77
+ * // import { styleText } from 'node:util';
78
+ * (text) => styleText('cyan', text)
79
+ * ```
80
+ */
81
+ answer: (text: string) => string;
82
+ /**
83
+ * Style to apply to the message displayed to the user.
84
+ *
85
+ * @param text - The message to style.
86
+ * @param status - The current status of the prompt.
87
+ * @returns The styled message.
88
+ *
89
+ * @defaultValue
90
+ * ```ts
91
+ * // import { styleText } from 'node:util';
92
+ * (text, status) => styleText('bold', text)
93
+ * ```
94
+ */
95
+ message: (text: string, status: Status) => string;
96
+ /**
97
+ * Style to apply to error messages.
98
+ *
99
+ * @param text - The error message.
100
+ * @returns The styled error message.
101
+ *
102
+ * @defaultValue
103
+ * ```ts
104
+ * // import { styleText } from 'node:util';
105
+ * (text) => styleText('red', `> ${text}`)
106
+ * ```
107
+ */
108
+ error: (text: string) => string;
109
+ /**
110
+ * Style to apply to the default answer when one is provided.
111
+ *
112
+ * @param text - The default answer.
113
+ * @returns The styled default answer.
114
+ *
115
+ * @defaultValue
116
+ * ```ts
117
+ * // import { styleText } from 'node:util';
118
+ * (text) => styleText('dim', `(${text})`)
119
+ * ```
120
+ */
121
+ defaultAnswer: (text: string) => string;
122
+ /**
123
+ * Style to apply to help text.
124
+ *
125
+ * @param text - The help text.
126
+ * @returns The styled help text.
127
+ *
128
+ * @defaultValue
129
+ * ```ts
130
+ * // import { styleText } from 'node:util';
131
+ * (text) => styleText('dim', text)
132
+ * ```
133
+ */
134
+ help: (text: string) => string;
135
+ /**
136
+ * Style to apply to highlighted text.
137
+ *
138
+ * @param text - The text to highlight.
139
+ * @returns The highlighted text.
140
+ *
141
+ * @defaultValue
142
+ * ```ts
143
+ * // import { styleText } from 'node:util';
144
+ * (text) => styleText('cyan', text)
145
+ * ```
146
+ */
147
+ highlight: (text: string) => string;
148
+ /**
149
+ * Style to apply to keyboard keys referred to in help texts.
150
+ *
151
+ * @param text - The key to style.
152
+ * @returns The styled key.
153
+ *
154
+ * @defaultValue
155
+ * ```ts
156
+ * // import { styleText } from 'node:util';
157
+ * (text) => styleText('cyan', styleText('bold', `<${text}>`))
158
+ * ```
159
+ */
160
+ key: (text: string) => string;
161
+ };
162
+ };
163
+ export type Theme<Extension extends object = object> = Extension & DefaultTheme;
164
+ export declare const defaultTheme: DefaultTheme;
165
+ export declare function getDefaultTheme(): DefaultTheme;
166
+ export {};
@@ -0,0 +1,29 @@
1
+ import { styleText } from 'node:util';
2
+ import figures from '@inquirer/figures';
3
+ import { getDefaultKeybindings } from "./key.js";
4
+ export const defaultTheme = {
5
+ prefix: {
6
+ idle: styleText('blue', '?'),
7
+ done: styleText('green', figures.tick),
8
+ },
9
+ spinner: {
10
+ interval: 80,
11
+ frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'].map((frame) => styleText('yellow', frame)),
12
+ },
13
+ keybindings: [],
14
+ style: {
15
+ answer: (text) => styleText('cyan', text),
16
+ message: (text) => styleText('bold', text),
17
+ error: (text) => styleText('red', `> ${text}`),
18
+ defaultAnswer: (text) => styleText('dim', `(${text})`),
19
+ help: (text) => styleText('dim', text),
20
+ highlight: (text) => styleText('cyan', text),
21
+ key: (text) => styleText('cyan', styleText('bold', `<${text}>`)),
22
+ },
23
+ };
24
+ export function getDefaultTheme() {
25
+ return {
26
+ ...defaultTheme,
27
+ keybindings: getDefaultKeybindings(),
28
+ };
29
+ }
@@ -0,0 +1,2 @@
1
+ import type { InquirerReadline } from '@inquirer/type';
2
+ export declare function useEffect(cb: (rl: InquirerReadline) => void | (() => void), depArray: ReadonlyArray<unknown>): void;
@@ -0,0 +1,11 @@
1
+ import { withPointer, effectScheduler } from "./hook-engine.js";
2
+ export function useEffect(cb, depArray) {
3
+ withPointer((pointer) => {
4
+ const oldDeps = pointer.get();
5
+ const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
6
+ if (hasChanged) {
7
+ effectScheduler.queue(cb);
8
+ }
9
+ pointer.set(depArray);
10
+ });
11
+ }
@@ -0,0 +1,3 @@
1
+ import { type InquirerReadline } from '@inquirer/type';
2
+ import { type KeypressEvent } from './key.ts';
3
+ export declare function useKeypress(userHandler: (event: KeypressEvent, rl: InquirerReadline) => void | Promise<void>): void;
@@ -0,0 +1,20 @@
1
+ import { useRef } from "./use-ref.js";
2
+ import { useEffect } from "./use-effect.js";
3
+ import { withUpdates } from "./hook-engine.js";
4
+ export function useKeypress(userHandler) {
5
+ const signal = useRef(userHandler);
6
+ signal.current = userHandler;
7
+ useEffect((rl) => {
8
+ let ignore = false;
9
+ const handler = withUpdates((_input, event) => {
10
+ if (ignore)
11
+ return;
12
+ void signal.current(event, rl);
13
+ });
14
+ rl.input.on('keypress', handler);
15
+ return () => {
16
+ ignore = true;
17
+ rl.input.removeListener('keypress', handler);
18
+ };
19
+ }, []);
20
+ }
@@ -0,0 +1 @@
1
+ export declare function useMemo<Value>(fn: () => Value, dependencies: ReadonlyArray<unknown>): Value;
@@ -0,0 +1,14 @@
1
+ import { withPointer } from "./hook-engine.js";
2
+ export function useMemo(fn, dependencies) {
3
+ return withPointer((pointer) => {
4
+ const prev = pointer.get();
5
+ if (!pointer.initialized ||
6
+ prev.dependencies.length !== dependencies.length ||
7
+ prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
8
+ const value = fn();
9
+ pointer.set({ value, dependencies });
10
+ return value;
11
+ }
12
+ return prev.value;
13
+ });
14
+ }
@@ -0,0 +1,5 @@
1
+ import type { Theme, Status } from './theme.ts';
2
+ export declare function usePrefix({ status, theme, }: {
3
+ status?: Status;
4
+ theme?: Theme;
5
+ }): string;
@@ -0,0 +1,35 @@
1
+ import { useState } from "./use-state.js";
2
+ import { useEffect } from "./use-effect.js";
3
+ import { makeTheme } from "./make-theme.js";
4
+ export function usePrefix({ status = 'idle', theme, }) {
5
+ const [showLoader, setShowLoader] = useState(false);
6
+ const [tick, setTick] = useState(0);
7
+ const { prefix, spinner } = makeTheme(theme);
8
+ useEffect(() => {
9
+ if (status === 'loading') {
10
+ let tickInterval;
11
+ let inc = -1;
12
+ // Delay displaying spinner by 300ms, to avoid flickering
13
+ const delayTimeout = setTimeout(() => {
14
+ setShowLoader(true);
15
+ tickInterval = setInterval(() => {
16
+ inc = inc + 1;
17
+ setTick(inc % spinner.frames.length);
18
+ }, spinner.interval);
19
+ }, 300);
20
+ return () => {
21
+ clearTimeout(delayTimeout);
22
+ clearInterval(tickInterval);
23
+ };
24
+ }
25
+ else {
26
+ setShowLoader(false);
27
+ }
28
+ }, [status]);
29
+ if (showLoader) {
30
+ return spinner.frames[tick];
31
+ }
32
+ // There's a delay before we show the loader. So we want to ignore `loading` here, and pass idle instead.
33
+ const iconName = status === 'loading' ? 'idle' : status;
34
+ return typeof prefix === 'string' ? prefix : (prefix[iconName] ?? prefix['idle']);
35
+ }
@@ -0,0 +1,6 @@
1
+ export declare function useRef<Value>(val: Value): {
2
+ current: Value;
3
+ };
4
+ export declare function useRef<Value>(val?: Value): {
5
+ current: Value | undefined;
6
+ };
@@ -0,0 +1,4 @@
1
+ import { useState } from "./use-state.js";
2
+ export function useRef(val) {
3
+ return useState({ current: val })[0];
4
+ }
@@ -0,0 +1,7 @@
1
+ type NotFunction<T> = T extends (...args: never) => unknown ? never : T;
2
+ type Reducer<Value> = (currentValue: Value) => Value;
3
+ type SetState<Value> = (newValue: NotFunction<Value> | Reducer<Value>) => void;
4
+ type OptionalSetState<Value> = (newValue?: NotFunction<Value> | Reducer<Value>) => void;
5
+ export declare function useState<Value>(defaultValue: NotFunction<Value> | (() => Value)): [Value, SetState<Value>];
6
+ export declare function useState<Value>(defaultValue?: NotFunction<Value> | (() => Value)): [Value | undefined, OptionalSetState<Value | undefined>];
7
+ export {};
@@ -0,0 +1,28 @@
1
+ import { AsyncResource } from 'node:async_hooks';
2
+ import { withPointer, handleChange } from "./hook-engine.js";
3
+ function isFactory(value) {
4
+ return typeof value === 'function';
5
+ }
6
+ function isReducer(value) {
7
+ return typeof value === 'function';
8
+ }
9
+ export function useState(defaultValue) {
10
+ return withPointer((pointer) => {
11
+ const setState = AsyncResource.bind(function setState(newValue) {
12
+ const currentValue = pointer.get();
13
+ const nextValue = isReducer(newValue) ? newValue(currentValue) : newValue;
14
+ // Noop if the value is still the same.
15
+ if (!Object.is(currentValue, nextValue)) {
16
+ pointer.set(nextValue);
17
+ // Trigger re-render
18
+ handleChange();
19
+ }
20
+ });
21
+ if (pointer.initialized) {
22
+ return [pointer.get(), setState];
23
+ }
24
+ const value = isFactory(defaultValue) ? defaultValue() : defaultValue;
25
+ pointer.set(value);
26
+ return [value, setState];
27
+ });
28
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Force line returns at specific width. This function is ANSI code friendly and it'll
3
+ * ignore invisible codes during width calculation.
4
+ * @param {string} content
5
+ * @param {number} width
6
+ * @return {string}
7
+ */
8
+ export declare function breakLines(content: string, width: number): string;
9
+ /**
10
+ * Returns the width of the active readline, or 80 as default value.
11
+ * @returns {number}
12
+ */
13
+ export declare function readlineWidth(): number;
@@ -0,0 +1,25 @@
1
+ import cliWidth from 'cli-width';
2
+ import { wrapAnsi } from 'fast-wrap-ansi';
3
+ import { readline } from "./hook-engine.js";
4
+ /**
5
+ * Force line returns at specific width. This function is ANSI code friendly and it'll
6
+ * ignore invisible codes during width calculation.
7
+ * @param {string} content
8
+ * @param {number} width
9
+ * @return {string}
10
+ */
11
+ export function breakLines(content, width) {
12
+ return content
13
+ .split('\n')
14
+ .flatMap((line) => wrapAnsi(line, width, { trim: false, wordWrap: false })
15
+ .split('\n')
16
+ .map((str) => str.trimEnd()))
17
+ .join('\n');
18
+ }
19
+ /**
20
+ * Returns the width of the active readline, or 80 as default value.
21
+ * @returns {number}
22
+ */
23
+ export function readlineWidth() {
24
+ return cliWidth({ defaultWidth: 80, output: readline().output });
25
+ }
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "@inquirer/core",
3
+ "version": "12.0.4",
4
+ "description": "Core Inquirer prompt API",
5
+ "keywords": [
6
+ "answer",
7
+ "answers",
8
+ "ask",
9
+ "base",
10
+ "cli",
11
+ "command",
12
+ "command-line",
13
+ "confirm",
14
+ "enquirer",
15
+ "generate",
16
+ "generator",
17
+ "hyper",
18
+ "input",
19
+ "inquire",
20
+ "inquirer",
21
+ "interface",
22
+ "iterm",
23
+ "javascript",
24
+ "menu",
25
+ "node",
26
+ "nodejs",
27
+ "prompt",
28
+ "promptly",
29
+ "prompts",
30
+ "question",
31
+ "readline",
32
+ "scaffold",
33
+ "scaffolder",
34
+ "scaffolding",
35
+ "stdin",
36
+ "stdout",
37
+ "terminal",
38
+ "tty",
39
+ "ui",
40
+ "yeoman",
41
+ "yo",
42
+ "zsh"
43
+ ],
44
+ "homepage": "https://github.com/SBoudrias/Inquirer.js/blob/main/packages/core/README.md",
45
+ "license": "MIT",
46
+ "author": "Simon Boudrias <admin@simonboudrias.com>",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/SBoudrias/Inquirer.js.git"
50
+ },
51
+ "files": [
52
+ "dist"
53
+ ],
54
+ "type": "module",
55
+ "sideEffects": false,
56
+ "exports": {
57
+ ".": {
58
+ "types": "./dist/index.d.ts",
59
+ "default": "./dist/index.js"
60
+ },
61
+ "./package.json": "./package.json"
62
+ },
63
+ "publishConfig": {
64
+ "access": "public"
65
+ },
66
+ "scripts": {
67
+ "tsc": "tsc"
68
+ },
69
+ "dependencies": {
70
+ "@inquirer/ansi": "^2.0.9",
71
+ "@inquirer/figures": "^2.0.9",
72
+ "@inquirer/type": "4.2.0",
73
+ "cli-width": "^4.1.0",
74
+ "fast-wrap-ansi": "^0.2.0",
75
+ "mute-stream": "^3.0.0",
76
+ "signal-exit": "^4.1.0"
77
+ },
78
+ "devDependencies": {
79
+ "@repo/tsconfig": "0.0.0",
80
+ "@types/mute-stream": "^0.0.4",
81
+ "@types/node": "^26.1.1",
82
+ "typescript": "^6.0.2"
83
+ },
84
+ "peerDependencies": {
85
+ "@types/node": ">=18"
86
+ },
87
+ "peerDependenciesMeta": {
88
+ "@types/node": {
89
+ "optional": true
90
+ }
91
+ },
92
+ "engines": {
93
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
94
+ },
95
+ "main": "./dist/index.js",
96
+ "types": "./dist/index.d.ts",
97
+ "gitHead": "a9436bd94d55a439df308f50e77a7cd0b2078e98"
98
+ }
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2025 Simon Boudrias
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.