myshell-tools 2.7.0 → 2.10.0
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.
- package/CHANGELOG.md +32 -0
- package/README.md +36 -5
- package/dist/cli.js +28 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/login.d.ts +8 -5
- package/dist/commands/login.js +143 -44
- package/dist/commands/login.js.map +1 -1
- package/dist/core/classify.d.ts +20 -4
- package/dist/core/classify.js +241 -43
- package/dist/core/classify.js.map +1 -1
- package/dist/core/orchestrate.js +57 -84
- package/dist/core/orchestrate.js.map +1 -1
- package/dist/infra/config.d.ts +6 -0
- package/dist/infra/config.js.map +1 -1
- package/dist/infra/credentials.d.ts +28 -0
- package/dist/infra/credentials.js +52 -1
- package/dist/infra/credentials.js.map +1 -1
- package/dist/infra/update-check.d.ts +67 -0
- package/dist/infra/update-check.js +181 -0
- package/dist/infra/update-check.js.map +1 -0
- package/dist/interface/menu.d.ts +42 -0
- package/dist/interface/menu.js +159 -26
- package/dist/interface/menu.js.map +1 -1
- package/package.json +1 -1
|
@@ -56,3 +56,31 @@ export declare function applyStoredCredentials(env: NodeJS.ProcessEnv, homeDir?:
|
|
|
56
56
|
* extractClaudeToken('no token here') // → null
|
|
57
57
|
*/
|
|
58
58
|
export declare function extractClaudeToken(text: string): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* Strip surrounding whitespace and enclosing `"` or `'` quotes from a pasted
|
|
61
|
+
* string. Useful for normalising user-pasted tokens before extraction.
|
|
62
|
+
*
|
|
63
|
+
* Pure / never throws.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* stripPastedSecretWrapper('" sk-ant-oat01-abc "') // → 'sk-ant-oat01-abc'
|
|
67
|
+
* stripPastedSecretWrapper("'token'") // → 'token'
|
|
68
|
+
* stripPastedSecretWrapper(' plain ') // → 'plain'
|
|
69
|
+
*/
|
|
70
|
+
export declare function stripPastedSecretWrapper(raw: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Classify a pasted secret string into one of three categories:
|
|
73
|
+
*
|
|
74
|
+
* - `'oauth-token'` — starts with `sk-ant-oat` (the expected setup-token output).
|
|
75
|
+
* - `'api-key'` — starts with `sk-ant-api` (a raw Anthropic API key, NOT what we want).
|
|
76
|
+
* - `'none'` — neither; blank or unrecognised.
|
|
77
|
+
*
|
|
78
|
+
* Input is pre-normalised (trimmed, quotes stripped) by the caller.
|
|
79
|
+
* Pure / never throws.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* classifyPastedSecret('sk-ant-oat01-abc-XYZ') // → 'oauth-token'
|
|
83
|
+
* classifyPastedSecret('sk-ant-api03-abc-XYZ') // → 'api-key'
|
|
84
|
+
* classifyPastedSecret('not-a-token') // → 'none'
|
|
85
|
+
*/
|
|
86
|
+
export declare function classifyPastedSecret(s: string): 'oauth-token' | 'api-key' | 'none';
|
|
@@ -146,7 +146,7 @@ export async function applyStoredCredentials(env, homeDir) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
// ---------------------------------------------------------------------------
|
|
149
|
-
// Pure token extraction
|
|
149
|
+
// Pure token extraction and classification helpers
|
|
150
150
|
// ---------------------------------------------------------------------------
|
|
151
151
|
/**
|
|
152
152
|
* Extract the first Claude long-lived OAuth token from `text`.
|
|
@@ -169,4 +169,55 @@ export function extractClaudeToken(text) {
|
|
|
169
169
|
return null;
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Strip surrounding whitespace and enclosing `"` or `'` quotes from a pasted
|
|
174
|
+
* string. Useful for normalising user-pasted tokens before extraction.
|
|
175
|
+
*
|
|
176
|
+
* Pure / never throws.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* stripPastedSecretWrapper('" sk-ant-oat01-abc "') // → 'sk-ant-oat01-abc'
|
|
180
|
+
* stripPastedSecretWrapper("'token'") // → 'token'
|
|
181
|
+
* stripPastedSecretWrapper(' plain ') // → 'plain'
|
|
182
|
+
*/
|
|
183
|
+
export function stripPastedSecretWrapper(raw) {
|
|
184
|
+
try {
|
|
185
|
+
let s = raw.trim();
|
|
186
|
+
if ((s.startsWith('"') && s.endsWith('"')) ||
|
|
187
|
+
(s.startsWith("'") && s.endsWith("'"))) {
|
|
188
|
+
s = s.slice(1, -1).trim();
|
|
189
|
+
}
|
|
190
|
+
return s;
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return raw;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Classify a pasted secret string into one of three categories:
|
|
198
|
+
*
|
|
199
|
+
* - `'oauth-token'` — starts with `sk-ant-oat` (the expected setup-token output).
|
|
200
|
+
* - `'api-key'` — starts with `sk-ant-api` (a raw Anthropic API key, NOT what we want).
|
|
201
|
+
* - `'none'` — neither; blank or unrecognised.
|
|
202
|
+
*
|
|
203
|
+
* Input is pre-normalised (trimmed, quotes stripped) by the caller.
|
|
204
|
+
* Pure / never throws.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* classifyPastedSecret('sk-ant-oat01-abc-XYZ') // → 'oauth-token'
|
|
208
|
+
* classifyPastedSecret('sk-ant-api03-abc-XYZ') // → 'api-key'
|
|
209
|
+
* classifyPastedSecret('not-a-token') // → 'none'
|
|
210
|
+
*/
|
|
211
|
+
export function classifyPastedSecret(s) {
|
|
212
|
+
try {
|
|
213
|
+
if (s.includes('sk-ant-oat'))
|
|
214
|
+
return 'oauth-token';
|
|
215
|
+
if (s.includes('sk-ant-api'))
|
|
216
|
+
return 'api-key';
|
|
217
|
+
return 'none';
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return 'none';
|
|
221
|
+
}
|
|
222
|
+
}
|
|
172
223
|
//# sourceMappingURL=credentials.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/infra/credentials.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/infra/credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/infra/update-check.ts — Self-update detection for myshell-tools.
|
|
3
|
+
*
|
|
4
|
+
* Checks the npm registry for the latest published version, caches the result
|
|
5
|
+
* so the check costs nothing on subsequent runs within the TTL, and reports
|
|
6
|
+
* whether an update is available.
|
|
7
|
+
*
|
|
8
|
+
* Architecture rules:
|
|
9
|
+
* - NEVER throws — all errors are caught and return a safe default.
|
|
10
|
+
* - NEVER hits the network in tests — `fetchLatest` is injected so tests stay hermetic.
|
|
11
|
+
* - Cache is stored atomically at ~/.myshell-tools/update-check.json.
|
|
12
|
+
* - Date.now() is allowed here (infra layer, same as config.ts / atomic.ts).
|
|
13
|
+
*/
|
|
14
|
+
export interface UpdateCheckResult {
|
|
15
|
+
readonly current: string;
|
|
16
|
+
readonly latest: string | null;
|
|
17
|
+
readonly updateAvailable: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface UpdateCache {
|
|
20
|
+
checkedAt: number;
|
|
21
|
+
latest: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load the update cache from disk. Returns null on missing/corrupt file.
|
|
25
|
+
* Never throws.
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadUpdateCache(homeDir?: string): Promise<UpdateCache | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Persist the update cache atomically. Creates the .myshell-tools directory
|
|
30
|
+
* if it does not exist. Never throws.
|
|
31
|
+
*/
|
|
32
|
+
export declare function saveUpdateCache(latest: string, now: number, homeDir?: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Compare two semver-ish version strings.
|
|
35
|
+
*
|
|
36
|
+
* Splits on `.`, compares numeric major/minor/patch segments in order.
|
|
37
|
+
* Any `-prerelease` suffix is stripped before comparison.
|
|
38
|
+
* Non-numeric segments are treated as 0.
|
|
39
|
+
* Returns true iff latest > current.
|
|
40
|
+
* Never throws.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isNewerVersion(latest: string, current: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Fetch the latest published version of myshell-tools from the npm registry.
|
|
45
|
+
*
|
|
46
|
+
* Uses global fetch with a 1500ms AbortSignal timeout.
|
|
47
|
+
* Returns the version string, or null on any error/timeout.
|
|
48
|
+
* Never throws.
|
|
49
|
+
*/
|
|
50
|
+
export declare function fetchLatestFromNpm(): Promise<string | null>;
|
|
51
|
+
export interface CheckForUpdateOpts {
|
|
52
|
+
readonly currentVersion: string;
|
|
53
|
+
readonly now: number;
|
|
54
|
+
readonly homeDir?: string;
|
|
55
|
+
readonly ttlMs?: number;
|
|
56
|
+
readonly fetchLatest?: () => Promise<string | null>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check whether a newer version of myshell-tools is available.
|
|
60
|
+
*
|
|
61
|
+
* Uses a cache file so the npm registry is only contacted once per TTL (default 24h).
|
|
62
|
+
* If the cache is fresh, the registry is NOT contacted at all.
|
|
63
|
+
* On any error returns { current, latest: null, updateAvailable: false }.
|
|
64
|
+
* Never throws.
|
|
65
|
+
*/
|
|
66
|
+
export declare function checkForUpdate(opts: CheckForUpdateOpts): Promise<UpdateCheckResult>;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/infra/update-check.ts — Self-update detection for myshell-tools.
|
|
3
|
+
*
|
|
4
|
+
* Checks the npm registry for the latest published version, caches the result
|
|
5
|
+
* so the check costs nothing on subsequent runs within the TTL, and reports
|
|
6
|
+
* whether an update is available.
|
|
7
|
+
*
|
|
8
|
+
* Architecture rules:
|
|
9
|
+
* - NEVER throws — all errors are caught and return a safe default.
|
|
10
|
+
* - NEVER hits the network in tests — `fetchLatest` is injected so tests stay hermetic.
|
|
11
|
+
* - Cache is stored atomically at ~/.myshell-tools/update-check.json.
|
|
12
|
+
* - Date.now() is allowed here (infra layer, same as config.ts / atomic.ts).
|
|
13
|
+
*/
|
|
14
|
+
import { mkdir, readFile } from 'node:fs/promises';
|
|
15
|
+
import { homedir } from 'node:os';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { atomicWrite } from './atomic.js';
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Constants
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
const TTL_MS_DEFAULT = 24 * 60 * 60 * 1000; // 24 hours
|
|
22
|
+
const FETCH_TIMEOUT_MS = 1_500;
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Path helpers
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
function getCacheDir(homeDir) {
|
|
27
|
+
return join(homeDir, '.myshell-tools');
|
|
28
|
+
}
|
|
29
|
+
function getCachePath(homeDir) {
|
|
30
|
+
return join(getCacheDir(homeDir), 'update-check.json');
|
|
31
|
+
}
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Cache helpers
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
/**
|
|
36
|
+
* Load the update cache from disk. Returns null on missing/corrupt file.
|
|
37
|
+
* Never throws.
|
|
38
|
+
*/
|
|
39
|
+
export async function loadUpdateCache(homeDir) {
|
|
40
|
+
const home = homeDir ?? homedir();
|
|
41
|
+
try {
|
|
42
|
+
const raw = await readFile(getCachePath(home), 'utf8');
|
|
43
|
+
const parsed = JSON.parse(raw);
|
|
44
|
+
if (parsed !== null &&
|
|
45
|
+
typeof parsed === 'object' &&
|
|
46
|
+
'checkedAt' in parsed &&
|
|
47
|
+
'latest' in parsed &&
|
|
48
|
+
typeof parsed['checkedAt'] === 'number' &&
|
|
49
|
+
typeof parsed['latest'] === 'string') {
|
|
50
|
+
return parsed;
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Persist the update cache atomically. Creates the .myshell-tools directory
|
|
60
|
+
* if it does not exist. Never throws.
|
|
61
|
+
*/
|
|
62
|
+
export async function saveUpdateCache(latest, now, homeDir) {
|
|
63
|
+
const home = homeDir ?? homedir();
|
|
64
|
+
try {
|
|
65
|
+
await mkdir(getCacheDir(home), { recursive: true });
|
|
66
|
+
const cache = { checkedAt: now, latest };
|
|
67
|
+
await atomicWrite(getCachePath(home), JSON.stringify(cache, null, 2));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Silently ignore — failing to cache is not a fatal error.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Version comparison
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
/**
|
|
77
|
+
* Compare two semver-ish version strings.
|
|
78
|
+
*
|
|
79
|
+
* Splits on `.`, compares numeric major/minor/patch segments in order.
|
|
80
|
+
* Any `-prerelease` suffix is stripped before comparison.
|
|
81
|
+
* Non-numeric segments are treated as 0.
|
|
82
|
+
* Returns true iff latest > current.
|
|
83
|
+
* Never throws.
|
|
84
|
+
*/
|
|
85
|
+
export function isNewerVersion(latest, current) {
|
|
86
|
+
try {
|
|
87
|
+
const parse = (v) => {
|
|
88
|
+
// Strip any prerelease suffix (e.g. "1.2.3-beta.1" → "1.2.3")
|
|
89
|
+
const base = v.split('-')[0] ?? '';
|
|
90
|
+
return base.split('.').map((part) => {
|
|
91
|
+
const n = parseInt(part, 10);
|
|
92
|
+
return Number.isFinite(n) ? n : 0;
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const lParts = parse(latest);
|
|
96
|
+
const cParts = parse(current);
|
|
97
|
+
const len = Math.max(lParts.length, cParts.length);
|
|
98
|
+
for (let i = 0; i < len; i++) {
|
|
99
|
+
const l = lParts[i] ?? 0;
|
|
100
|
+
const c = cParts[i] ?? 0;
|
|
101
|
+
if (l > c)
|
|
102
|
+
return true;
|
|
103
|
+
if (l < c)
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
return false; // equal
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
// npm registry fetch (real network — injected in tests)
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
/**
|
|
116
|
+
* Fetch the latest published version of myshell-tools from the npm registry.
|
|
117
|
+
*
|
|
118
|
+
* Uses global fetch with a 1500ms AbortSignal timeout.
|
|
119
|
+
* Returns the version string, or null on any error/timeout.
|
|
120
|
+
* Never throws.
|
|
121
|
+
*/
|
|
122
|
+
export async function fetchLatestFromNpm() {
|
|
123
|
+
const ac = new AbortController();
|
|
124
|
+
const timer = setTimeout(() => { ac.abort(); }, FETCH_TIMEOUT_MS);
|
|
125
|
+
try {
|
|
126
|
+
const res = await fetch('https://registry.npmjs.org/myshell-tools/latest', {
|
|
127
|
+
signal: ac.signal,
|
|
128
|
+
});
|
|
129
|
+
if (!res.ok)
|
|
130
|
+
return null;
|
|
131
|
+
const data = await res.json();
|
|
132
|
+
if (data !== null &&
|
|
133
|
+
typeof data === 'object' &&
|
|
134
|
+
'version' in data &&
|
|
135
|
+
typeof data['version'] === 'string') {
|
|
136
|
+
return data['version'] ?? null;
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
clearTimeout(timer);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Check whether a newer version of myshell-tools is available.
|
|
149
|
+
*
|
|
150
|
+
* Uses a cache file so the npm registry is only contacted once per TTL (default 24h).
|
|
151
|
+
* If the cache is fresh, the registry is NOT contacted at all.
|
|
152
|
+
* On any error returns { current, latest: null, updateAvailable: false }.
|
|
153
|
+
* Never throws.
|
|
154
|
+
*/
|
|
155
|
+
export async function checkForUpdate(opts) {
|
|
156
|
+
const { currentVersion, now, homeDir, ttlMs = TTL_MS_DEFAULT } = opts;
|
|
157
|
+
const fetchFn = opts.fetchLatest ?? fetchLatestFromNpm;
|
|
158
|
+
try {
|
|
159
|
+
// Check if we have a fresh cache
|
|
160
|
+
const cache = await loadUpdateCache(homeDir);
|
|
161
|
+
if (cache !== null && now - cache.checkedAt < ttlMs) {
|
|
162
|
+
// Cache is fresh — use it without hitting the network
|
|
163
|
+
const updateAvailable = isNewerVersion(cache.latest, currentVersion);
|
|
164
|
+
return { current: currentVersion, latest: cache.latest, updateAvailable };
|
|
165
|
+
}
|
|
166
|
+
// Cache is stale or missing — fetch from the registry
|
|
167
|
+
const latest = await fetchFn();
|
|
168
|
+
if (latest !== null) {
|
|
169
|
+
await saveUpdateCache(latest, now, homeDir);
|
|
170
|
+
}
|
|
171
|
+
if (latest === null) {
|
|
172
|
+
return { current: currentVersion, latest: null, updateAvailable: false };
|
|
173
|
+
}
|
|
174
|
+
const updateAvailable = isNewerVersion(latest, currentVersion);
|
|
175
|
+
return { current: currentVersion, latest, updateAvailable };
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return { current: currentVersion, latest: null, updateAvailable: false };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/infra/update-check.ts"],"names":[],"mappings":"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"}
|
package/dist/interface/menu.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ import type { EnvironmentStatus } from '../providers/detect.js';
|
|
|
23
23
|
import type { Provider, ProviderId, SandboxLevel } from '../providers/port.js';
|
|
24
24
|
import type { OutputSink } from './render.js';
|
|
25
25
|
import type { LoginMethod } from '../commands/login.js';
|
|
26
|
+
import type { UpdateCheckResult } from '../infra/update-check.js';
|
|
26
27
|
export interface MenuContext {
|
|
27
28
|
readonly version: string;
|
|
28
29
|
readonly clock: Clock;
|
|
@@ -67,7 +68,48 @@ export interface MenuContext {
|
|
|
67
68
|
* spawning during tests (e.g. after first-run onboarding or [j]/[k]/[o] login).
|
|
68
69
|
*/
|
|
69
70
|
readonly detectEnvironment?: () => Promise<EnvironmentStatus>;
|
|
71
|
+
/**
|
|
72
|
+
* Optional injected update-check for testing. When provided, `startMenu` uses
|
|
73
|
+
* this instead of the real `checkForUpdate` from infra/update-check.ts,
|
|
74
|
+
* preventing real npm registry requests from being made during tests.
|
|
75
|
+
*
|
|
76
|
+
* Returns the update check result (current, latest, updateAvailable).
|
|
77
|
+
*/
|
|
78
|
+
readonly checkForUpdate?: () => Promise<UpdateCheckResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Optional injected self-update function for testing. When provided, `startMenu`
|
|
81
|
+
* uses this instead of the real `npm install -g myshell-tools@latest` subprocess.
|
|
82
|
+
*
|
|
83
|
+
* Returns true when the update succeeded (exit code 0), false otherwise.
|
|
84
|
+
* Never throws.
|
|
85
|
+
*/
|
|
86
|
+
readonly updateSelf?: (out: OutputSink) => Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* Optional injected relaunch function for testing. When provided, `startMenu`
|
|
89
|
+
* uses this instead of the real `execa('myshell-tools', …)` re-exec.
|
|
90
|
+
*
|
|
91
|
+
* Returns the exit code of the relaunched process (or 1 on spawn failure).
|
|
92
|
+
* Used only for the opt-in auto-update path.
|
|
93
|
+
*/
|
|
94
|
+
readonly relaunch?: () => Promise<number>;
|
|
70
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Parse a yes/no answer from a raw input line, with a configurable default.
|
|
98
|
+
*
|
|
99
|
+
* Accepts (case-insensitive, trimmed):
|
|
100
|
+
* - `"y"` or `"yes"` → true
|
|
101
|
+
* - `"n"` or `"no"` → false
|
|
102
|
+
* - empty string or `null` (EOF) → `defaultYes`
|
|
103
|
+
* - anything else → `defaultYes` (lenient)
|
|
104
|
+
*
|
|
105
|
+
* Never throws. Callers should display `(Y/n)` when `defaultYes` is true and
|
|
106
|
+
* `(y/N)` when `defaultYes` is false so the user knows which choice Enter gives.
|
|
107
|
+
*
|
|
108
|
+
* @param input - The raw line from readLine(), or null on EOF.
|
|
109
|
+
* @param defaultYes - True if pressing Enter (or EOF) means yes.
|
|
110
|
+
* @returns True for yes, false for no.
|
|
111
|
+
*/
|
|
112
|
+
export declare function parseYesNo(input: string | null, defaultYes: boolean): boolean;
|
|
71
113
|
/**
|
|
72
114
|
* Return the shell alias hint the user can add to their shell profile to make
|
|
73
115
|
* `myshell-tools` the default command-line assistant.
|