@easbot/terminal 0.3.11 → 0.3.12

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/README.en.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  # @easbot/terminal
4
4
 
5
- > Terminal interaction toolkit — unified terminal output, formatting, prompts, and state recovery for EASBOT
5
+ > Terminal interaction toolkit — unified terminal output, formatting, prompts, and state recovery for the EASBOT ecosystem.
6
6
 
7
7
  ## Introduction
8
8
 
9
- `@easbot/terminal` is a terminal interaction toolkit for the EASBOT ecosystem. It encapsulates the common capabilities required by CLI / TUI scenarios: themed color output, ANSI handling, OSC-8 hyperlinks, table rendering, styled prompts, safe stream writes, progress-line management, and terminal-state recovery. Every module auto-detects terminal capability (`NO_COLOR` / `FORCE_COLOR` / TTY) and degrades gracefully in non-TTY environments (pipes, redirected files, CI logs).
9
+ `@easbot/terminal` is a terminal interaction toolkit for the EASBOT ecosystem. It encapsulates the common capabilities required by CLI / TUI scenarios: themed color output, ANSI handling, OSC-8 hyperlinks, table rendering, styled prompts, safe stream writes, progress-line management, terminal-state recovery, an interactive searchable multi-select prompt, a simple CLI input helper, and a lightweight markdown renderer. Every module auto-detects terminal capability (`NO_COLOR` / `FORCE_COLOR` / TTY) and degrades gracefully in non-TTY environments (pipes, redirected files, CI logs).
10
+
11
+ The package is **vendor-neutral**: it does not hard-code any external doc site or vendor-specific configuration. Helper functions such as `formatRootedLink` / `formatRootLink` accept an explicit root URL, leaving integration choices to the caller.
10
12
 
11
13
  ## Features
12
14
 
@@ -18,10 +20,16 @@
18
20
  - **Table rendering** — `renderTable` with auto-fit columns, Unicode / ASCII / borderless styles, ANSI-safe wrapping
19
21
  - **Command output formatting** — success / error / warning / info / heading / key-value / command / list / status / count helpers
20
22
  - **Styled prompts** — styled wrappers around `@clack/prompts` (`selectStyled` / `note` / `stylePromptMessage` …)
23
+ - **Searchable multi-select** — `Search.multiselect` is an interactive, real-time-filtered, multi-select prompt with full keyboard control, optional locked section, and graceful stdin / signal cleanup
24
+ - **Loader** — `Loader.create()` returns a stateless spinner instance (no Component / TUI inheritance). Customizable frames, color, message; integrates with `MockTerminalIO` for tests
25
+ - **Input** — `Input.readText` / `Input.readConfirm` / `Input.readPassword` are readline-based helpers for CLI prompts; inject `input` / `output` streams for test isolation
26
+ - **Markdown** — `renderMarkdown` parses a minimal markdown subset (heading / list / code-block / bold / italic / link) without pulling in `marked`
21
27
  - **Safe stream writer** — `createSafeStreamWriter` swallows `EPIPE` / `EIO`, so a closed pipe never throws
22
28
  - **Progress line** — register / clear / unregister an active progress line (TTY-only)
23
29
  - **Terminal-state recovery** — `restoreTerminalState` resets cursor, mouse tracking, and bracketed paste on exit
24
30
  - **CLI JSON output** — `emitJsonOk` / `emitJsonError` implement the EASBOT CLI `--json` contract (`{ ok, data | error }`)
31
+ - **Color discipline** — every styled output goes through `isRich()` + `colorize()`, and snapshot / non-TTY runs never leak ANSI sequences
32
+ - **TTY injection for tests** — interactive components (e.g. `formatTerminalLink`, `Search.multiselect`, `Input.readText`) accept an optional `isTTY` parameter so unit tests can run without depending on `process.stdout.isTTY`
25
33
 
26
34
  ## Installation
27
35
 
@@ -73,10 +81,15 @@ console.log(formatStatus('running', 'Building...'));
73
81
  ```typescript
74
82
  import { resolveUserPath, resolveConfigDir, displayPath, formatTerminalLink } from '@easbot/terminal';
75
83
 
76
- const configDir = resolveConfigDir(); // ~/.openclaw or $OPENCLAW_STATE_DIR
84
+ const configDir = resolveConfigDir(); // ~/.config/easbot (or $EASBOT_STATE_DIR if set)
77
85
  console.log(displayPath(configDir));
78
86
 
87
+ // TTY: OSC-8 link; non-TTY: "Label (URL)" fallback
79
88
  console.log(formatTerminalLink('EASBOT repo', 'https://github.com/houjallen/easbot'));
89
+
90
+ // Generic root-URL helper — call site controls the root (vendor-neutral)
91
+ import { formatRootedLink } from '@easbot/terminal';
92
+ console.log(formatRootedLink('https://docs.example.com', '/guide', 'Quick start'));
80
93
  ```
81
94
 
82
95
  ### Table rendering
@@ -95,7 +108,8 @@ console.log(
95
108
  { name: '@easbot/terminal', version: '0.3.11', status: '✓' },
96
109
  { name: '@easbot/note', version: '0.3.11', status: '✓' },
97
110
  ],
98
- style: 'unicode',
111
+ width: 80,
112
+ border: 'unicode',
99
113
  }),
100
114
  );
101
115
  ```
@@ -116,6 +130,77 @@ const choice = await selectStyled({
116
130
  note(wrapNoteMessage('Config file saved to ~/.config/app/config.json'), 'Success');
117
131
  ```
118
132
 
133
+ ### Loader (CLI spinner)
134
+
135
+ ```typescript
136
+ import { Loader, colorize, isRich, theme } from '@easbot/terminal';
137
+
138
+ const loader = Loader.create({
139
+ message: 'Loading…',
140
+ spinnerColor: (s) => colorize(isRich(), theme.accent, s),
141
+ messageColor: (s) => colorize(isRich(), theme.muted, s),
142
+ });
143
+ loader.start();
144
+
145
+ // Each tick: print the latest line (caller controls output)
146
+ process.stdout.write(`\r${loader.line()}\x1b[K`);
147
+
148
+ loader.stop();
149
+ process.stdout.write('\n');
150
+ ```
151
+
152
+ `Loader` is a **namespace** (stateless factory). It does not depend on any TUI component model — it returns a plain object with `start` / `stop` / `isRunning` / `line` / `setMessage` / `setIndicator`. Defaults: 10-frame Braille spinner, 80 ms interval.
153
+
154
+ ### Input (readline-based prompts)
155
+
156
+ ```typescript
157
+ import { Input } from '@easbot/terminal';
158
+
159
+ const name = await Input.readText({ message: 'Name:' });
160
+ const ok = await Input.readConfirm({ message: 'Continue?' });
161
+ const pw = await Input.readPassword({ message: 'Password:' });
162
+ ```
163
+
164
+ `Input` is a **namespace** with three stateless helpers. For tests, inject `input` / `output` streams (use `MockTerminalIO` from the `__tests__/helpers` path).
165
+
166
+ ### Markdown (minimal subset)
167
+
168
+ ```typescript
169
+ import { renderMarkdown } from '@easbot/terminal';
170
+
171
+ console.log(renderMarkdown('# Title\n\nHello **world**.', { stripAnsi: true }).join('\n'));
172
+ ```
173
+
174
+ Supports `# / ## / ###` headings, `-` / `*` / `1.` lists, fenced code blocks, and inline `**bold**` / `*italic*` / `` `code` `` / `[text](url)`. Does not depend on `marked` — keeps the bundle small for CLI output.
175
+
176
+ ### Searchable multi-select
177
+
178
+ ```typescript
179
+ import { Search, cancelSymbol } from '@easbot/terminal';
180
+
181
+ const result = await Search.multiselect({
182
+ message: 'Select agents to enable:',
183
+ items: [
184
+ { value: 'a', label: 'Agent A', hint: 'General-purpose' },
185
+ { value: 'b', label: 'Agent B', hint: 'Code-focused' },
186
+ ],
187
+ required: true,
188
+ lockedSection: {
189
+ title: 'Always included',
190
+ items: [{ value: 'core', label: 'Core agent' }],
191
+ hiddenCount: 2,
192
+ },
193
+ // Test / embedded scenarios can override the TTY state explicitly:
194
+ // isTTY: true // force raw mode + colors
195
+ // isTTY: false // force no raw mode and no colors
196
+ });
197
+
198
+ if (result === cancelSymbol) return;
199
+ // result is T[] of selected values
200
+ ```
201
+
202
+ Keyboard shortcuts: `↑↓ ←→` move · `PageUp/Down` page · `Home/End` jump · `Space` toggle · `Backspace` delete search · `Enter` confirm · `Esc` / `Ctrl+C` cancel.
203
+
119
204
  ### Safe stream writes & state recovery
120
205
 
121
206
  ```typescript
@@ -148,10 +233,10 @@ emitJsonError('E_NOT_FOUND', 'Resource not found');
148
233
 
149
234
  ### Theme & styling
150
235
 
151
- - `theme` — themed color helpers (`accent`, `info`, `success`, `warn`, `error`, `muted`, `heading`, `command`, `option`)
236
+ - `theme` — themed color helpers (`accent`, `accentBright`, `accentDim`, `info`, `success`, `warn`, `error`, `muted`, `heading`, `command`, `option`)
152
237
  - `isRich()` — whether the terminal supports rich color output
153
238
  - `colorize(rich, color, value)` — conditional coloring helper
154
- - `LOBSTER_PALETTE` — raw Lobster palette values
239
+ - `LOBSTER_PALETTE` — raw Lobster palette values (8 colors, `as const`)
155
240
 
156
241
  ### ANSI utilities
157
242
 
@@ -161,19 +246,20 @@ emitJsonError('E_NOT_FOUND', 'Resource not found');
161
246
  ### Paths & display
162
247
 
163
248
  - `resolveUserPath(input)` — resolve user paths (supports `~`)
164
- - `resolveConfigDir(env?, homedir?)` — resolve the config dir (supports `OPENCLAW_STATE_DIR` / `CLAWDBOT_STATE_DIR`)
249
+ - `resolveConfigDir(env?, homedir?)` — resolve the config dir (overridable via `EASBOT_STATE_DIR`; defaults to `~/.config/easbot`)
165
250
  - `resolveHomeDir()` — resolve the effective home directory
166
251
  - `shortenHomePath(input)` / `displayPath(input)` — shorten the home prefix in a single path
167
252
  - `shortenHomeInString(input)` / `displayString(input)` — replace every occurrence of the home prefix in a string
168
253
  - `resolveEffectiveHomeDir` / `resolveRequiredHomeDir` / `expandHomePrefix` — low-level home helpers
169
- - `formatTerminalLink(label, url, opts?)` — format an OSC-8 hyperlink
170
- - `formatDocsLink(path, label?, opts?)` / `formatDocsRootLink(label?)` / `DOCS_ROOT` docs-link helpers
254
+ - `formatTerminalLink(label, url, opts?, isTTY?)` — format an OSC-8 hyperlink with explicit TTY injection
255
+ - `formatRootedLink(root, path, label?, opts?, isTTY?)` generic root-URL link helper (vendor-neutral)
256
+ - `formatRootLink(root, label?, isTTY?)` — generic root-URL single link
171
257
 
172
258
  ### Command output formatting
173
259
 
174
- - `formatSuccess` / `formatError` / `formatWarning` / `formatInfo`
175
- - `formatHeading` / `formatKeyValue` / `formatCommandExample` / `formatListItem`
176
- - `formatStatus` / `formatSeparator` / `formatEmptyMessage` / `formatCount`
260
+ - `formatSuccess` / `formatError` / `formatWarning` / `formatInfo` — icon-prefixed messages
261
+ - `formatHeading` / `formatKeyValue` / `formatCommandExample` / `formatListItem` — sections & lists
262
+ - `formatStatus` / `formatSeparator` / `formatEmptyMessage` / `formatCount` — progress & counters
177
263
 
178
264
  ### Tables
179
265
 
@@ -184,9 +270,54 @@ emitJsonError('E_NOT_FOUND', 'Resource not found');
184
270
 
185
271
  - `stylePromptMessage` / `stylePromptTitle` / `stylePromptHint` — prompt text styling
186
272
  - `selectStyled<T>(params)` — themed select prompt
187
- - `note(message, title?)` — themed note box
273
+ - `note(message, title?, options?)` — themed note box (supports `columns` / `maxWidth` injection)
188
274
  - `wrapNoteMessage(message, options?)` — auto-wrap a note's message
189
275
 
276
+ ### Interactive multi-select
277
+
278
+ - `Search.multiselect<T>(options)` — searchable, real-time-filtered multi-select prompt
279
+ - `options.message` — prompt message
280
+ - `options.items` — selectable items
281
+ - `options.maxVisible?` — page size
282
+ - `options.initialSelected?` — pre-selected values (deduplicated)
283
+ - `options.required?` — reject empty submission
284
+ - `options.lockedSection?` — always-included partition
285
+ - `options.isTTY?` — explicit TTY state (test / embedded injection)
286
+ - `Search.cancelSymbol` — sentinel returned on cancel / stdin end
287
+ - `Search.approxStringWidth` / `Search.visualRowsForLine` / `Search.countVisualRowsForLines` — display-width helpers
288
+ - `cancelSymbol` — top-level re-export of `Search.cancelSymbol` (kept for backwards compatibility)
289
+
290
+ ### Loader (CLI spinner)
291
+
292
+ `Loader` is a **namespace** with a single factory:
293
+
294
+ - `Loader.create(options?)` → `Loader.Instance`
295
+ - `options.message?` — main text (default `'Loading...'`)
296
+ - `options.spinnerColor?` — color function for the frame (default: `colorize(isRich(), theme.accent, ...)`)
297
+ - `options.messageColor?` — color function for the message (default: `colorize(isRich(), theme.muted, ...)`)
298
+ - `options.indicator?` — `{ frames?: string[]; intervalMs?: number }` (default: 10 Braille frames, 80 ms)
299
+ - `Loader.Instance`:
300
+ - `start()` — idempotent (restarts the interval)
301
+ - `stop()` — idempotent
302
+ - `isRunning()` — current animation state
303
+ - `line()` — current rendered line (`'<spinner> <message>'`)
304
+ - `setMessage(message)` — update text
305
+ - `setIndicator(indicator?)` — update frames / interval; auto-restarts
306
+
307
+ ### Input (readline-based prompts)
308
+
309
+ `Input` is a **namespace** with three stateless helpers. Pass `input` / `output` to swap in a mock stream for tests.
310
+
311
+ - `Input.readText(options)` — read a single line. Options: `message`, `hint?`, `defaultValue?`, `hidden?`, `messageColor?`, `hintColor?`, `input?`, `output?`
312
+ - `Input.readConfirm(options)` — yes/no prompt; recursively re-prompts on invalid input. Options: `message`, `hint?`, `defaultValue?` (default `true`)
313
+ - `Input.readPassword(options)` — alias for `readText` with `hidden: true`
314
+
315
+ ### Markdown (minimal subset)
316
+
317
+ - `renderMarkdown(md, opts?)` → `string[]` (one entry per logical line)
318
+ - Supports: `# / ## / ###` headings, `---` horizontal rules, `- / * / 1.` lists, fenced code blocks (` ``` `), inline `**bold**` / `*italic*` / `` `code` `` / `[text](url)`
319
+ - `opts.headingColor?` / `boldColor?` / `italicColor?` / `codeColor?` / `linkColor?` — color functions to override the default theme
320
+
190
321
  ### CLI JSON output
191
322
 
192
323
  - `emitJsonOk(data, meta?)` — emit `{ ok: true, data, meta? }`
@@ -198,10 +329,12 @@ emitJsonError('E_NOT_FOUND', 'Resource not found');
198
329
  - `createSafeStreamWriter(options?)` — create a writer that swallows `EPIPE` / `EIO`
199
330
  - `registerActiveProgressLine(stream)` / `clearActiveProgressLine()` / `unregisterActiveProgressLine(stream?)` — progress line management
200
331
  - `restoreTerminalState(reason?, options?)` — restore cursor / mouse / bracketed-paste state
332
+ - `RestoreTerminalStateOptions` — `{ resumeStdin? | resumeStdinIfPaused? }` (default `false`; Docker TTY behavior)
201
333
 
202
334
  ### Misc
203
335
 
204
336
  - `styleHealthChannelLine(line, rich)` — themed health-check channel line
337
+ - `StatusKind` — `'pending' | 'running' | 'success' | 'error' | 'skipped'`
205
338
 
206
339
  ## Environment Variables
207
340
 
@@ -210,8 +343,12 @@ emitJsonError('E_NOT_FOUND', 'Resource not found');
210
343
  | `NO_COLOR` | Disables colors when set (unless `FORCE_COLOR` is also set) — see [no-color.org](https://no-color.org/) |
211
344
  | `FORCE_COLOR` | Forces colors when non-empty and not equal to `'0'` |
212
345
  | `HOME` / `USERPROFILE` | Fallback sources for home directory resolution |
346
+ | `EASBOT_TEST_HOME` | **Test-only** highest-priority home override (highest priority; see `home-dir.ts`) |
213
347
  | `EASBOT_HOME` | Explicit override for the home directory; changes the display prefix from `~` to `$EASBOT_HOME` |
214
- | `OPENCLAW_STATE_DIR` / `CLAWDBOT_STATE_DIR` | Override the resolved config directory |
348
+ | `EASBOT_STATE_DIR` | Override the resolved config directory |
349
+
350
+ **Home resolution order (highest to lowest):**
351
+ `EASBOT_TEST_HOME` → `EASBOT_HOME` → `HOME` → `USERPROFILE` → `os.homedir()`.
215
352
 
216
353
  ## Development
217
354
 
@@ -233,6 +370,20 @@ pnpm lint
233
370
  pnpm format:fix
234
371
  ```
235
372
 
373
+ ## Publishing
374
+
375
+ ```bash
376
+ # Linux / macOS
377
+ pnpm publish:npm # = bash scripts/publish.sh
378
+
379
+ # Windows PowerShell
380
+ pnpm publish:npm:win # = powershell -ExecutionPolicy Bypass -File scripts/publish.ps1
381
+
382
+ # Equivalent manual flow
383
+ pnpm build
384
+ pnpm publish --access public --git-checks false --registry https://registry.npmjs.org
385
+ ```
386
+
236
387
  ## License
237
388
 
238
389
  MIT
package/README.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  # @easbot/terminal
4
4
 
5
- > 终端交互工具库 — 为 EASBOT 生态提供统一的终端输出、格式化、提示与状态恢复能力
5
+ > 终端交互工具库 — 为 EASBOT 生态提供统一的终端输出、格式化、提示与状态恢复能力。
6
6
 
7
7
  ## 简介
8
8
 
9
- `@easbot/terminal` 是一个面向 EASBOT 生态的终端交互工具库,封装了命令行 / TUI 场景下常用的能力:终端主题色、ANSI 处理、超链接、表格渲染、提示样式、安全流写入、进度行管理以及终端状态恢复。所有能力都基于终端能力自动检测(`NO_COLOR` / `FORCE_COLOR` / TTY)进行降级,可在管道、文件重定向等非 TTY 场景下安全使用。
9
+ `@easbot/terminal` 是一个面向 EASBOT 生态的终端交互工具库,封装了命令行 / TUI 场景下常用的能力:终端主题色、ANSI 处理、超链接、表格渲染、提示样式、安全流写入、进度行管理、终端状态恢复、一个**可搜索的多选交互 prompt**、一个**CLI 输入 helper** 以及一个**轻量级 markdown 渲染器**。所有能力都基于终端能力自动检测(`NO_COLOR` / `FORCE_COLOR` / TTY)进行降级,可在管道、文件重定向等非 TTY 场景下安全使用。
10
+
11
+ 本包**完全 vendor-neutral**:不绑定任何外部文档站或 vendor-specific 配置。`formatRootedLink` / `formatRootLink` 等 helper 显式接受 `root` 参数,由调用方决定集成方式。
10
12
 
11
13
  ## 特性
12
14
 
@@ -18,10 +20,16 @@
18
20
  - **表格渲染**:`renderTable` 支持自适应列宽、Unicode / ASCII / 无边框三种样式、文本换行、ANSI 样式保持
19
21
  - **命令输出格式化**:成功 / 错误 / 警告 / 信息 / 标题 / 键值对 / 命令示例 / 列表项 / 进度状态 / 计数等
20
22
  - **提示样式化**:`@clack/prompts` 的样式化封装(`selectStyled` / `note` / `stylePromptMessage` 等)
23
+ - **可搜索多选 prompt**:`Search.multiselect` 是交互式、实时过滤的多选 prompt,支持完整键盘控制、可选锁定分区、对 stdin / 信号优雅清理
24
+ - **Loader 旋转动画**:`Loader.create()` 返回**stateless** spinner 实例(不继承 tui 组件模型),可定制帧 / 颜色 / 消息
25
+ - **Input CLI 输入**:`Input.readText` / `Input.readConfirm` / `Input.readPassword` 是 readline 薄包装的 CLI prompt;支持注入 `input` / `output` 用于测试隔离
26
+ - **Markdown 渲染**:`renderMarkdown` 解析极简 markdown 子集(标题 / 列表 / 代码块 / 加粗 / 斜体 / 链接),**不引 `marked`**,保持 CLI 包体小
21
27
  - **安全流写入**:`createSafeStreamWriter` 自动处理 `EPIPE` / `EIO`,流关闭后静默忽略后续写入
22
28
  - **进度行管理**:注册 / 清除 / 注销活动进度行,仅在 TTY 下生效
23
29
  - **终端状态恢复**:`restoreTerminalState` 在退出 / 异常时重置光标、鼠标跟踪、括号粘贴模式
24
30
  - **JSON 规范输出**:`emitJsonOk` / `emitJsonError` 实现 CLI `--json` 规范的 `{ ok, data | error }` 协议
31
+ - **色彩一致性**:所有样式化输出统一经过 `isRich()` + `colorize()`,快照 / 非 TTY 场景不会泄漏 ANSI 转义
32
+ - **TTY 注入**:交互组件(`formatTerminalLink`、`Search.multiselect`、`Input.readText` 等)接受可选 `isTTY` 参数,单元测试不再依赖 `process.stdout.isTTY`
25
33
 
26
34
  ## 安装
27
35
 
@@ -73,10 +81,15 @@ console.log(formatStatus('running', '正在执行构建...'));
73
81
  ```typescript
74
82
  import { resolveUserPath, resolveConfigDir, displayPath, formatTerminalLink } from '@easbot/terminal';
75
83
 
76
- const configDir = resolveConfigDir(); // ~/.openclaw $OPENCLAW_STATE_DIR
84
+ const configDir = resolveConfigDir(); // ~/.config/easbot(如设了 EASBOT_STATE_DIR 则用之)
77
85
  console.log(displayPath(configDir));
78
86
 
79
- console.log(formatTerminalLink('查看文档', 'https://github.com/houjallen/easbot'));
87
+ // TTY: OSC-8 链接;非 TTY: "Label (URL)" 降级
88
+ console.log(formatTerminalLink('EASBOT 仓库', 'https://github.com/houjallen/easbot'));
89
+
90
+ // 通用根域名 helper(vendor-neutral —— 调用方决定 root)
91
+ import { formatRootedLink } from '@easbot/terminal';
92
+ console.log(formatRootedLink('https://docs.example.com', '/guide', '快速开始'));
80
93
  ```
81
94
 
82
95
  ### 表格渲染
@@ -95,7 +108,8 @@ console.log(
95
108
  { name: '@easbot/terminal', version: '0.3.11', status: '✓' },
96
109
  { name: '@easbot/note', version: '0.3.11', status: '✓' },
97
110
  ],
98
- style: 'unicode',
111
+ width: 80,
112
+ border: 'unicode',
99
113
  }),
100
114
  );
101
115
  ```
@@ -116,6 +130,77 @@ const choice = await selectStyled({
116
130
  note(wrapNoteMessage('配置文件已成功保存到 ~/.config/app/config.json'), '成功');
117
131
  ```
118
132
 
133
+ ### Loader 旋转动画
134
+
135
+ ```typescript
136
+ import { Loader, colorize, isRich, theme } from '@easbot/terminal';
137
+
138
+ const loader = Loader.create({
139
+ message: '正在加载…',
140
+ spinnerColor: (s) => colorize(isRich(), theme.accent, s),
141
+ messageColor: (s) => colorize(isRich(), theme.muted, s),
142
+ });
143
+ loader.start();
144
+
145
+ // 每帧调用 line() 取出最新一行的文本
146
+ process.stdout.write(`\r${loader.line()}\x1b[K`);
147
+
148
+ loader.stop();
149
+ process.stdout.write('\n');
150
+ ```
151
+
152
+ `Loader` 是一个 **namespace**(stateless 工厂),不依赖 tui 组件模型 —— 返回一个普通对象,方法:`start` / `stop` / `isRunning` / `line` / `setMessage` / `setIndicator`。默认:10 帧 Braille spinner,80 ms 间隔。
153
+
154
+ ### Input CLI 输入
155
+
156
+ ```typescript
157
+ import { Input } from '@easbot/terminal';
158
+
159
+ const name = await Input.readText({ message: '请输入名称:' });
160
+ const ok = await Input.readConfirm({ message: '继续吗?' });
161
+ const pw = await Input.readPassword({ message: '密码:' });
162
+ ```
163
+
164
+ `Input` 是一个 **namespace**,含 3 个 stateless helper。测试时通过 `input` / `output` 注入 mock stream(使用 `__tests__/helpers/mock-terminal.ts` 的 `MockTerminalIO`)。
165
+
166
+ ### Markdown 渲染
167
+
168
+ ```typescript
169
+ import { renderMarkdown } from '@easbot/terminal';
170
+
171
+ console.log(renderMarkdown('# 标题\n\n这是一段 **加粗** 文本。').join('\n'));
172
+ ```
173
+
174
+ 支持 `# / ## / ###` 标题、`- / * / 1.` 列表、围栏代码块、行内 `**加粗**` / `*斜体*` / `` `code` `` / `[文本](链接)`。**不依赖 `marked`**,保持 CLI 包体小。
175
+
176
+ ### 可搜索多选(`Search.multiselect`)
177
+
178
+ ```typescript
179
+ import { Search, cancelSymbol } from '@easbot/terminal';
180
+
181
+ const result = await Search.multiselect({
182
+ message: '请选择要启用的 Agent:',
183
+ items: [
184
+ { value: 'a', label: 'Agent A', hint: '通用任务' },
185
+ { value: 'b', label: 'Agent B', hint: '代码导向' },
186
+ ],
187
+ required: true,
188
+ lockedSection: {
189
+ title: '始终包含',
190
+ items: [{ value: 'core', label: '核心 Agent' }],
191
+ hiddenCount: 2,
192
+ },
193
+ // 测试 / 嵌入式场景可显式注入 TTY 状态:
194
+ // isTTY: true // 强制启用 raw mode + 颜色
195
+ // isTTY: false // 强制禁用 raw mode 与颜色
196
+ });
197
+
198
+ if (result === cancelSymbol) return;
199
+ // result 为已选项的值数组(type T[])
200
+ ```
201
+
202
+ 键盘约定:`↑↓ ←→` 单步移动 · `PageUp/Down` 翻页 · `Home/End` 跳首末 · `Space` 切换 · `Backspace` 删除搜索字符 · `Enter` 提交 · `Esc` / `Ctrl+C` 取消。
203
+
119
204
  ### 安全流写入与状态恢复
120
205
 
121
206
  ```typescript
@@ -148,10 +233,10 @@ emitJsonError('E_NOT_FOUND', '资源不存在');
148
233
 
149
234
  ### 主题与样式
150
235
 
151
- - `theme` — 主题颜色对象(accent / info / success / warn / error / muted / heading / command / option
236
+ - `theme` — 主题颜色对象(`accent` / `accentBright` / `accentDim` / `info` / `success` / `warn` / `error` / `muted` / `heading` / `command` / `option`)
152
237
  - `isRich()` — 判断终端是否支持富文本颜色
153
238
  - `colorize(rich, color, value)` — 条件着色工具
154
- - `LOBSTER_PALETTE` — Lobster 调色板原始色值
239
+ - `LOBSTER_PALETTE` — Lobster 调色板原始色值(8 种颜色,`as const` 锁定)
155
240
 
156
241
  ### ANSI 工具
157
242
 
@@ -161,19 +246,20 @@ emitJsonError('E_NOT_FOUND', '资源不存在');
161
246
  ### 路径与显示
162
247
 
163
248
  - `resolveUserPath(input)` — 解析用户路径(支持 `~` 波浪号)
164
- - `resolveConfigDir(env?, homedir?)` — 解析配置目录(支持 `OPENCLAW_STATE_DIR` / `CLAWDBOT_STATE_DIR` 覆盖)
249
+ - `resolveConfigDir(env?, homedir?)` — 解析配置目录(可被 `EASBOT_STATE_DIR` 覆盖;默认 `~/.config/easbot`)
165
250
  - `resolveHomeDir()` — 解析用户主目录
166
251
  - `shortenHomePath(input)` / `displayPath(input)` — 缩短路径中的主目录部分
167
252
  - `shortenHomeInString(input)` / `displayString(input)` — 替换字符串中所有匹配的主目录路径
168
253
  - `resolveEffectiveHomeDir` / `resolveRequiredHomeDir` / `expandHomePrefix` — 主目录解析工具
169
- - `formatTerminalLink(label, url, opts?)` — 格式化 OSC-8 终端超链接
170
- - `formatDocsLink(path, label?, opts?)` / `formatDocsRootLink(label?)` / `DOCS_ROOT` — 文档链接辅助
254
+ - `formatTerminalLink(label, url, opts?, isTTY?)` — 格式化 OSC-8 终端超链接,支持 `isTTY` 注入
255
+ - `formatRootedLink(root, path, label?, opts?, isTTY?)` 通用根 URL 链接 helper(vendor-neutral)
256
+ - `formatRootLink(root, label?, isTTY?)` — 通用根 URL 单链接
171
257
 
172
258
  ### 命令输出格式化
173
259
 
174
- - `formatSuccess` / `formatError` / `formatWarning` / `formatInfo`
175
- - `formatHeading` / `formatKeyValue` / `formatCommandExample` / `formatListItem`
176
- - `formatStatus` / `formatSeparator` / `formatEmptyMessage` / `formatCount`
260
+ - `formatSuccess` / `formatError` / `formatWarning` / `formatInfo` — 带图标的前缀消息
261
+ - `formatHeading` / `formatKeyValue` / `formatCommandExample` / `formatListItem` — 章节与列表
262
+ - `formatStatus` / `formatSeparator` / `formatEmptyMessage` / `formatCount` — 进度与计数
177
263
 
178
264
  ### 表格
179
265
 
@@ -184,9 +270,54 @@ emitJsonError('E_NOT_FOUND', '资源不存在');
184
270
 
185
271
  - `stylePromptMessage` / `stylePromptTitle` / `stylePromptHint` — 提示文本样式化
186
272
  - `selectStyled<T>(params)` — 样式化的选择提示
187
- - `note(message, title?)` — 样式化的注释框
273
+ - `note(message, title?, options?)` — 样式化的注释框(支持 `columns` / `maxWidth` 注入)
188
274
  - `wrapNoteMessage(message, options?)` — 注释消息自动换行
189
275
 
276
+ ### 交互式多选
277
+
278
+ - `Search.multiselect<T>(options)` — 可搜索、实时过滤的多选 prompt
279
+ - `options.message` — 提示信息
280
+ - `options.items` — 候选项列表
281
+ - `options.maxVisible?` — 每页显示条数
282
+ - `options.initialSelected?` — 预选值集合(去重)
283
+ - `options.required?` — 是否强制至少选一项
284
+ - `options.lockedSection?` — 始终包含的锁定分区
285
+ - `options.isTTY?` — 显式 TTY 状态(测试 / 嵌入式注入)
286
+ - `Search.cancelSymbol` — 用户取消或 stdin 关闭时返回的哨兵值
287
+ - `Search.approxStringWidth` / `Search.visualRowsForLine` / `Search.countVisualRowsForLines` — 渲染器用到的显示宽度辅助
288
+ - `cancelSymbol` — 顶层再导出,等价于 `Search.cancelSymbol`(保留旧调用点无需改动)
289
+
290
+ ### Loader 旋转动画
291
+
292
+ `Loader` 是 **namespace**,提供单一工厂方法:
293
+
294
+ - `Loader.create(options?)` → `Loader.Instance`
295
+ - `options.message?` — 主文本(默认 `'Loading...'`)
296
+ - `options.spinnerColor?` — 帧字符颜色函数(默认 `colorize(isRich(), theme.accent, ...)`)
297
+ - `options.messageColor?` — 消息颜色函数(默认 `colorize(isRich(), theme.muted, ...)`)
298
+ - `options.indicator?` — `{ frames?: string[]; intervalMs?: number }`(默认 10 帧 Braille / 80 ms)
299
+ - `Loader.Instance`:
300
+ - `start()` — 幂等(重启 interval)
301
+ - `stop()` — 幂等
302
+ - `isRunning()` — 当前动画状态
303
+ - `line()` — 当前渲染行(`'帧 消息'`)
304
+ - `setMessage(message)` — 更新文本
305
+ - `setIndicator(indicator?)` — 更新帧 / 间隔;自动重启
306
+
307
+ ### Input CLI 输入
308
+
309
+ `Input` 是 **namespace**,含 3 个 stateless helper。测试时通过 `input` / `output` 注入 mock stream。
310
+
311
+ - `Input.readText(options)` — 读单行。Options: `message` / `hint?` / `defaultValue?` / `hidden?` / `messageColor?` / `hintColor?` / `input?` / `output?`
312
+ - `Input.readConfirm(options)` — y/n 确认,无效输入会递归重试。Options: `message` / `hint?` / `defaultValue?`(默认 `true`)
313
+ - `Input.readPassword(options)` — `readText` 的 `hidden: true` 别名
314
+
315
+ ### Markdown 渲染
316
+
317
+ - `renderMarkdown(md, opts?)` → `string[]`(每行一段)
318
+ - 支持:`# / ## / ###` 标题、`---` 分隔线、`- / * / 1.` 列表、围栏代码块(` ``` `)、行内 `**加粗**` / `*斜体*` / `` `code` `` / `[文本](链接)`
319
+ - `opts.headingColor?` / `boldColor?` / `italicColor?` / `codeColor?` / `linkColor?` — 覆盖默认主题的颜色函数
320
+
190
321
  ### JSON 规范输出
191
322
 
192
323
  - `emitJsonOk(data, meta?)` — 输出 `{ ok: true, data, meta? }` JSON 响应
@@ -198,10 +329,12 @@ emitJsonError('E_NOT_FOUND', '资源不存在');
198
329
  - `createSafeStreamWriter(options?)` — 创建安全流写入器,自动处理 `EPIPE` / `EIO`
199
330
  - `registerActiveProgressLine(stream)` / `clearActiveProgressLine()` / `unregisterActiveProgressLine(stream?)` — 进度行管理
200
331
  - `restoreTerminalState(reason?, options?)` — 恢复终端状态(光标 / 鼠标 / 括号粘贴模式)
332
+ - `RestoreTerminalStateOptions` — `{ resumeStdin? | resumeStdinIfPaused? }`(默认 `false`;Docker TTY 行为)
201
333
 
202
334
  ### 其它
203
335
 
204
336
  - `styleHealthChannelLine(line, rich)` — 健康检查通道行样式化
337
+ - `StatusKind` — `'pending' | 'running' | 'success' | 'error' | 'skipped'`
205
338
 
206
339
  ## 环境变量
207
340
 
@@ -210,8 +343,12 @@ emitJsonError('E_NOT_FOUND', '资源不存在');
210
343
  | `NO_COLOR` | 存在时禁用终端颜色(除非同时设置了 `FORCE_COLOR`),遵循 [no-color.org](https://no-color.org/) 规范 |
211
344
  | `FORCE_COLOR` | 非空且不为 `'0'` 时强制启用颜色 |
212
345
  | `HOME` / `USERPROFILE` | 主目录解析的备选来源(OS 默认值) |
346
+ | `EASBOT_TEST_HOME` | **测试专用** 最高优先级的主目录覆盖(详见 `home-dir.ts`) |
213
347
  | `EASBOT_HOME` | 显式指定主目录;设置后路径显示前缀由 `~` 切换为 `$EASBOT_HOME` |
214
- | `OPENCLAW_STATE_DIR` / `CLAWDBOT_STATE_DIR` | 配置目录覆盖项 |
348
+ | `EASBOT_STATE_DIR` | 配置目录覆盖项 |
349
+
350
+ **主目录解析顺序(高 → 低)**:
351
+ `EASBOT_TEST_HOME` → `EASBOT_HOME` → `HOME` → `USERPROFILE` → `os.homedir()`。
215
352
 
216
353
  ## 开发
217
354
 
@@ -233,6 +370,16 @@ pnpm lint
233
370
  pnpm format:fix
234
371
  ```
235
372
 
373
+ ## 发布
374
+
375
+ ```bash
376
+ # Windows
377
+ powershell -ExecutionPolicy Bypass -File scripts/publish.ps1
378
+
379
+ # Unix/macOS
380
+ bash scripts/publish.sh
381
+ ```
382
+
236
383
  ## 许可证
237
384
 
238
385
  MIT
package/dist/index.cjs CHANGED
@@ -1,11 +1,17 @@
1
- 'use strict';var xe=require('chalk'),Ne=require('fs'),B=require('os'),K=require('path'),utils=require('@easbot/utils'),prompts=require('@clack/prompts');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var xe__default=/*#__PURE__*/_interopDefault(xe);var Ne__default=/*#__PURE__*/_interopDefault(Ne);var B__default=/*#__PURE__*/_interopDefault(B);var K__default=/*#__PURE__*/_interopDefault(K);var de="\\x1b\\[[0-9;]*m",pe="\\x1b\\]8;;.*?\\x1b\\\\|\\x1b\\]8;;\\x1b\\\\",he=new RegExp(de,"g"),ge=new RegExp(pe,"g");function re(e){return !e||e.length===0?"":e.replace(ge,"").replace(he,"")}function O(e){return !e||e.length===0?0:Array.from(re(e)).length}var T={accent:"#FF5A2D",accentBright:"#FF7A3D",accentDim:"#D14A22",info:"#FF8A5B",success:"#2FBF71",warn:"#FFB020",error:"#E23D2D",muted:"#8B7F77"};var Se=typeof process.env.FORCE_COLOR=="string"&&process.env.FORCE_COLOR.trim().length>0&&process.env.FORCE_COLOR.trim()!=="0",z=process.env.NO_COLOR&&!Se?new xe.Chalk({level:0}):xe__default.default,R=e=>z.hex(e),m={accent:R(T.accent),accentBright:R(T.accentBright),accentDim:R(T.accentDim),info:R(T.info),success:R(T.success),warn:R(T.warn),error:R(T.error),muted:R(T.muted),heading:z.bold.hex(T.accent),command:R(T.accentBright),option:R(T.warn)},S=()=>z.level>0,E=(e,r,n)=>e?r(n):n;function Ee(e){let r=S();return E(r,m.success,"\u2713")+` ${e}`}function ke(e){let r=S();return E(r,m.error,"\u2717")+` ${e}`}function ve(e){let r=S();return E(r,m.warn,"\u26A0")+` ${e}`}function $e(e){let r=S();return E(r,m.info,"\u2139")+` ${e}`}function We(e){let r=S();return E(r,m.heading,e)}function we(e,r,n=15){let i=S(),o=e.padEnd(n);return `${E(i,m.muted,o)} ${r}`}function Te(e,r){let n=S(),i=E(n,m.command,e);if(!r)return ` ${i}`;let o=E(n,m.muted,`# ${r}`);return ` ${i} ${o}`}function ye(e,r,n){let i=S(),o=E(i,m.info,e),l=E(i,m.command,r),d=n?` ${E(i,m.muted,n)}`:"";return `${o} ${l}${d}`}function Pe(e,r){let n=S(),i,o;switch(e){case "pending":i="\u25CB",o=m.muted;break;case "running":i="\u25CF",o=m.info;break;case "success":i="\u2713",o=m.success;break;case "error":i="\u2717",o=m.error;break;case "skipped":i="\u25CB",o=m.muted;break}return E(n,o,i)+` ${r}`}function Oe(e=80,r="\u2500"){let n=S();return E(n,m.muted,r.repeat(e))}function Re(e){let r=S();return E(r,m.muted,e)}function Le(e,r,n){let i=S(),o=e===1?r:n||`${r}s`;return `${E(i,m.accent,String(e))} ${o}`}function L(e){let r=e?.trim();return r?utils.Filesystem.toUnixPath(r):void 0}function M(e=process.env,r=B__default.default.homedir){let n=Ce(e,r);return n?utils.Filesystem.resolve(n):void 0}function Ce(e,r){let n=L(e.EASBOT_HOME);if(n){if(n==="~"||n.startsWith("~/")||n.startsWith("~\\")){let l=L(e.HOME)??L(e.USERPROFILE)??te(r);return l?n.replace(/^~(?=$|[\\/])/,l):void 0}return n}let i=L(e.HOME);if(i)return i;let o=L(e.USERPROFILE);return o||te(r)}function te(e){try{return L(e())}catch{return}}function F(e=process.env,r=B__default.default.homedir){return M(e,r)??utils.Filesystem.resolve(process.cwd())}function Y(e,r){if(!e.startsWith("~"))return L(e);let n=process.env.EASBOT_TEST_HOME?.trim();return n||(n=L(r?.home)??M(r?.env??process.env,r?.homedir??B__default.default.homedir)),n?e.replace(/^~(?=$|[\\/])/,n):L(e)}function ne(e){if(!e)return "";let r=e.trim();if(!r)return r;if(r.startsWith("~")){let n=Y(r,{home:F(process.env,B__default.default.homedir),env:process.env,homedir:B__default.default.homedir});return K__default.default.resolve(n)}return K__default.default.resolve(r)}function Ae(e=process.env,r=B__default.default.homedir){let n=e.OPENCLAW_STATE_DIR?.trim()||e.CLAWDBOT_STATE_DIR?.trim();if(n)return ne(n);let i=K__default.default.join(F(e,r),".openclaw");try{if(Ne__default.default.existsSync(i))return i}catch{}return i}function oe(){return M(process.env,B__default.default.homedir)}function ie(){let e=oe();return e?process.env.EASBOT_HOME?.trim()?{home:e,prefix:"$EASBOT_HOME"}:{home:e,prefix:"~"}:void 0}function se(e){if(!e)return e;let r=ie();if(!r)return e;let{home:n,prefix:i}=r;return e===n?i:e.startsWith(`${n}/`)||e.startsWith(`${n}\\`)?`${i}${e.slice(n.length)}`:e}function ce(e){if(!e)return e;let r=ie();return r?e.split(r.home).join(r.prefix):e}function Ie(e){return se(e)}function q(e){return ce(e)}function J(e,r,n){let o=e.replaceAll("\x1B",""),l=r.replaceAll("\x1B","");return (n?.force===true?true:n?.force===false?false:!!process.stdout.isTTY)?`\x1B]8;;${l}\x07${o}\x1B]8;;\x07`:n?.fallback??`${o} (${l})`}var D="https://docs.openclaw.ai";function _e(e,r,n){let i=e.trim(),o=i.startsWith("http")?i:`${D}${i.startsWith("/")?i:`/${i}`}`;return J(r??o,o,{fallback:n?.fallback??o,force:n?.force})}function He(e){return J(e??D,D,{fallback:D})}function Me(e,r){let n={ok:true,data:e};r!==void 0&&(n.meta=r),console.log(JSON.stringify(n,null,2));}function De(e,r){console.log(JSON.stringify({ok:false,error:{code:e,message:r}},null,2));}var G=e=>S()?m.accent(e):e,X=e=>e&&S()?m.heading(e):e,Z=e=>e&&S()?m.muted(e):e;var Be=/^(https?:\/\/|file:\/\/)/i,Je=/^[a-zA-Z]:[\\/]/,je=/^[a-zA-Z0-9._-]+$/;function ae(e,r){if(r<=0)return [e];let n=Array.from(e),i=[];for(let o=0;o<n.length;o+=r)i.push(n.slice(o,o+r).join(""));return i.length>0?i:[e]}function fe(e){return e?Be.test(e)||e.startsWith("/")||e.startsWith("~/")||e.startsWith("./")||e.startsWith("../")||Je.test(e)||e.startsWith("\\\\")||e.includes("/")||e.includes("\\")?true:e.includes("_")&&je.test(e):false}function ze(e,r){if(e.trim().length===0)return [e];if(r<=0)return [e];let n=e.match(/^(\s*)([-*\u2022]\s+)?(.*)$/),i=n?.[1]??"",o=n?.[2]??"",l=n?.[3]??"",d=`${i}${o}`,g=`${i}${o?" ".repeat(o.length):""}`,$=Math.max(10,r-O(d)),W=Math.max(10,r-O(g)),A=l.split(/\s+/).filter(Boolean),y=[],p="",x=d,k=$;for(let b of A){if(!p){if(O(b)>k){if(fe(b)){p=b;continue}let w=ae(b,k),f=w.shift()??"";y.push(x+f),x=g,k=W;for(let u of w)y.push(x+u);continue}p=b;continue}let C=`${p} ${b}`;if(O(C)<=k){p=C;continue}if(y.push(x+p),x=g,k=W,O(b)>k){if(fe(b)){p=b;continue}let w=ae(b,k),f=w.shift()??"";y.push(x+f);for(let u of w)y.push(x+u);p="";continue}p=b;}return (p||A.length===0)&&y.push(x+p),y}function ue(e,r={}){let n=r.columns??process.stdout.columns??80,i=r.maxWidth??Math.max(40,Math.min(88,n-10));return e.split(`
2
- `).flatMap(o=>ze(o,i)).join(`
3
- `)}function Ue(e,r){prompts.note(ue(e),X(r));}var _=null;function Ve(e){e.isTTY&&(_=e);}function Q(){_?.isTTY&&_.write("\r\x1B[2K");}function Ye(e){_&&(e&&_!==e||(_=null));}function qe(e){return prompts.select({...e,message:G(e.message),options:e.options.map(r=>r.hint===void 0?r:{...r,hint:Z(r.hint)})})}var Ge="\x1B[0m\x1B[?25h\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?2004l";function j(e,r,n){let i=n?` (${n})`:"",o=`[terminal] restore ${e} failed${i}: ${String(r)}`;try{process.stderr.write(`${o}
4
- `);}catch(l){console.error(`[terminal] restore reporting failed${i}: ${String(l)}`);}}function Xe(e,r={}){let n=r.resumeStdinIfPaused??r.resumeStdin??false;try{Q();}catch(o){j("progress line",o,e);}let i=process.stdin;if(i.isTTY&&typeof i.setRawMode=="function"){try{i.setRawMode(!1);}catch(o){j("raw mode",o,e);}if(n&&typeof i.isPaused=="function"&&i.isPaused())try{i.resume();}catch(o){j("stdin resume",o,e);}}if(process.stdout.isTTY)try{process.stdout.write(Ge);}catch(o){j("stdout reset",o,e);}}function Ze(e){let r=e?.code;return r==="EPIPE"||r==="EIO"}function Qe(e={}){let r=false,n=false,i=(g,$)=>{n||(n=true,e.onBrokenPipe?.(g,$));},o=(g,$)=>{if(!Ze(g))throw g;return r=true,i(g,$),false},l=(g,$)=>{if(r)return false;try{e.beforeWrite?.();}catch(W){return o(W,process.stderr)}try{return g.write($),!r}catch(W){return o(W,g)}};return {write:l,writeLine:(g,$)=>l(g,`${$}
5
- `),reset:()=>{r=false,n=false;},isClosed:()=>r}}function H(e,r){return !Number.isFinite(r)||r<=0?"":e.repeat(r)}function er(e,r,n){let i=O(e);if(i>=r)return e;let o=r-i;if(n==="right")return `${H(" ",o)}${e}`;if(n==="center"){let l=Math.floor(o/2),d=o-l;return `${H(" ",l)}${e}${H(" ",d)}`}return `${e}${H(" ",o)}`}function rr(e,r){if(!e||e.length===0)return [""];if(!Number.isFinite(r)||r<=0)return [e];let n="\x1B",i=[];for(let t=0;t<e.length;){if(e[t]===n){if(e[t+1]==="["){let a=t+2;for(;a<e.length;){let h=e[a];if(h==="m")break;if(h&&h>="0"&&h<="9"){a+=1;continue}if(h===";"){a+=1;continue}break}if(e[a]==="m"){i.push({kind:"ansi",value:e.slice(t,a+1)}),t=a+1;continue}}if(e[t+1]==="]"&&e.slice(t+2,t+5)==="8;;"){let a=e.indexOf(`${n}\\`,t+5);if(a>=0){i.push({kind:"ansi",value:e.slice(t,a+2)}),t=a+2;continue}}}let s=e.codePointAt(t);if(!s)break;let c=String.fromCodePoint(s);i.push({kind:"char",value:c}),t+=c.length;}let o=i.findIndex(t=>t.kind==="char");if(o<0)return [e];let l=-1;for(let t=i.length-1;t>=0;t-=1){let s=i[t];if(s&&s.kind==="char"){l=t;break}}let d=i.slice(0,o).filter(t=>t.kind==="ansi").map(t=>t.value).join(""),g=i.slice(l+1).filter(t=>t.kind==="ansi").map(t=>t.value).join(""),$=i.slice(o,l+1),W=[],A=t=>t===" "||t===" "||t==="/"||t==="-"||t==="_"||t===".",y=t=>t===" "||t===" ",p=false,x=[],k=0,b=null,C=t=>(t??x).map(s=>s.value).join(""),w=t=>t.reduce((s,c)=>s+(c.kind==="char"?1:0),0),f=t=>{let s=t.replace(/\s+$/,"");s.trim().length!==0&&W.push(s);},u=t=>{if(x.length===0)return;if(t==null||t<=0){f(C()),x.length=0,k=0,b=null;return}let s=x.slice(0,t),c=x.slice(t);for(f(C(s));c.length>0;){let a=c[0];if(a?.kind!=="char"||!y(a.value))break;c.shift();}x.length=0,x.push(...c),k=w(x),b=null;};for(let t of $){if(t.kind==="ansi"){x.push(t);continue}let s=t.value;if(!(p&&(p=false,s===`
6
- `))){if(s===`
7
- `||s==="\r"){u(x.length),s==="\r"&&(p=true);continue}k+1>r&&k>0&&u(b),x.push(t),k+=1,A(s)&&(b=x.length);}}return u(x.length),W.length===0?[""]:!d&&!g?W:W.map(t=>t&&`${d}${t}${g}`)}function tr(e){if(e!=null&&!(!Number.isFinite(e)||e<=0))return Math.floor(e)}function nr(e){let r=e.rows.map(f=>{let u={};for(let[t,s]of Object.entries(f))u[t]=q(s);return u}),n=e.border??"unicode";if(n==="none"){let f=e.columns;return `${[f.map(s=>s.header).join(" | "),...r.map(s=>f.map(c=>s[c.key]??"").join(" | "))].join(`
1
+ 'use strict';var fe=require('chalk'),ae=require('os'),$e=require('path'),utils=require('@easbot/utils'),prompts=require('@clack/prompts'),ue=require('process'),de=require('readline'),util=require('util'),stream=require('stream');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var fe__default=/*#__PURE__*/_interopDefault(fe);var ae__default=/*#__PURE__*/_interopDefault(ae);var $e__default=/*#__PURE__*/_interopDefault($e);var ue__default=/*#__PURE__*/_interopDefault(ue);var de__namespace=/*#__PURE__*/_interopNamespace(de);var xt="\\x1b\\[[0-9;]*m",bt="\\x1b\\]8;;.*?\\x1b\\\\|\\x1b\\]8;;\\x1b\\\\",St=new RegExp(xt,"g"),$t=new RegExp(bt,"g");function ne(e){return e?e.replace($t,"").replace(St,""):""}function D(e){return e?Array.from(ne(e)).length:0}var B={accent:"#FF5A2D",accentBright:"#FF7A3D",accentDim:"#D14A22",info:"#FF8A5B",success:"#2FBF71",warn:"#FFB020",error:"#E23D2D",muted:"#8B7F77"};var Ct=typeof process.env.FORCE_COLOR=="string"&&process.env.FORCE_COLOR.trim().length>0&&process.env.FORCE_COLOR.trim()!=="0",he=process.env.NO_COLOR&&!Ct?new fe.Chalk({level:0}):fe__default.default,j=e=>he.hex(e),b={accent:j(B.accent),accentBright:j(B.accentBright),accentDim:j(B.accentDim),info:j(B.info),success:j(B.success),warn:j(B.warn),error:j(B.error),muted:j(B.muted),heading:he.bold.hex(B.accent),command:j(B.accentBright),option:j(B.warn)},k=()=>he.level>0,y=(e,t,r)=>e?t(r):r;function yt(e){return y(k(),b.success,"\u2713")+` ${e}`}function wt(e){return y(k(),b.error,"\u2717")+` ${e}`}function Et(e){return y(k(),b.warn,"\u26A0")+` ${e}`}function Rt(e){return y(k(),b.info,"\u2139")+` ${e}`}function It(e){return y(k(),b.heading,e)}function kt(e,t,r=15){let s=e.padEnd(r);return `${y(k(),b.muted,s)} ${t}`}function Ot(e,t){let r=k(),s=y(r,b.command,e);if(!t)return ` ${s}`;let c=y(r,b.muted,`# ${t}`);return ` ${s} ${c}`}function Wt(e,t,r){let s=k(),c=y(s,b.info,e),f=y(s,b.command,t),m=r?` ${y(s,b.muted,r)}`:"";return `${c} ${f}${m}`}var Lt={pending:{icon:"\u25CB",color:b.muted},running:{icon:"\u25CF",color:b.info},success:{icon:"\u2713",color:b.success},error:{icon:"\u2717",color:b.error},skipped:{icon:"\u25CB",color:b.muted}};function Mt(e,t){let{icon:r,color:s}=Lt[e];return y(k(),s,r)+` ${t}`}function Pt(e=80,t="\u2500"){return y(k(),b.muted,t.repeat(e))}function Ft(e){return y(k(),b.muted,e)}function Nt(e,t,r){let s=e===1?t:r||`${t}s`;return `${y(k(),b.accent,String(e))} ${s}`}function V(e){let t=e?.trim();return t?utils.Filesystem.toUnixPath(t):void 0}function Je(e){try{return V(e())}catch{return}}function At(e,t){let r=V(e.EASBOT_TEST_HOME);if(r)return r;let s=V(e.EASBOT_HOME);if(s){if(s==="~"||s.startsWith("~/")||s.startsWith("~\\")){let m=V(e.HOME)??V(e.USERPROFILE)??Je(t);return m?s.replace(/^~(?=$|[\\/])/,m):void 0}return s}let c=V(e.HOME);if(c)return c;let f=V(e.USERPROFILE);return f||Je(t)}function q(e=process.env,t=ae__default.default.homedir){let r=At(e,t);if(r)return r}function be(e=process.env,t=ae__default.default.homedir){return q(e,t)??utils.Filesystem.resolve(process.cwd())}function Se(e,t){if(!e.startsWith("~"))return V(e);let r=process.env.EASBOT_TEST_HOME?.trim();return r||(r=V(t?.home)??q(t?.env??process.env,t?.homedir??ae__default.default.homedir)),r?e.replace(/^~(?=$|[\\/])/,r):V(e)}function je(e){if(!e)return "";let t=e.trim();if(!t)return t;if(t.startsWith("~")){let r=Se(t,{home:be(process.env,ae__default.default.homedir),env:process.env,homedir:ae__default.default.homedir});return $e__default.default.resolve(r)}return $e__default.default.resolve(t)}function _t(e=process.env,t=ae__default.default.homedir){let r=e.EASBOT_STATE_DIR?.trim();if(r)return je(r);let c=q(e,t)??process.cwd();return $e__default.default.join(c,".config","easbot")}function Ve(){return q(process.env,ae__default.default.homedir)}function Ke(){let e=Ve();return e?process.env.EASBOT_TEST_HOME?.trim()?{home:e,prefix:"~"}:process.env.EASBOT_HOME?.trim()?{home:e,prefix:"$EASBOT_HOME"}:{home:e,prefix:"~"}:void 0}function ze(e){if(!e)return e;let t=Ke();if(!t)return e;let{home:r,prefix:s}=t;return e===r?s:e.startsWith(`${r}/`)||e.startsWith(`${r}\\`)?`${s}${e.slice(r.length)}`:e}function Ye(e){if(!e)return e;let t=Ke();return t?e.split(t.home).join(t.prefix):e}function Ht(e){return ze(e)}function ve(e){return Ye(e)}function Bt(e,t){return e?.force===true?true:e?.force===false?false:!!(t??process.stdout?.isTTY)}function re(e,t,r,s){let c=ne(e??""),f=ne(t??"");return Bt(r,s)?`\x1B]8;;${f}\x07${c}\x1B]8;;\x07`:r?.fallback??`${c} (${f})`}function Jt(e,t,r,s,c){let f=t.trim();if(!e)return re(r??f,f,s,c);let m=/^[a-z]+:\/\//i.test(f)?f:`${e}${f.startsWith("/")?f:`/${f}`}`;return re(r??m,m,s,c)}function Dt(e,t,r){return re(t??e,e,void 0,r)}function jt(e,t){let r={ok:true,data:e};t!==void 0&&(r.meta=t),console.log(JSON.stringify(r,null,2));}function Vt(e,t){console.log(JSON.stringify({ok:false,error:{code:e,message:t}},null,2));}var Te=e=>k()?b.accent(e):e,Ce=e=>e&&k()?b.heading(e):e,ye=e=>e&&k()?b.muted(e):e;var zt=/^(https?:\/\/|file:\/\/)/i,Yt=/^[a-zA-Z]:[\\/]/,Ut=/^[a-zA-Z0-9._-]+$/;function Ue(e,t){if(t<=0)return [e];let r=Array.from(e),s=[];for(let c=0;c<r.length;c+=t)s.push(r.slice(c,c+t).join(""));return s.length>0?s:[e]}function Ge(e){return e?zt.test(e)||e.startsWith("/")||e.startsWith("~/")||e.startsWith("./")||e.startsWith("../")||Yt.test(e)||e.startsWith("\\\\")||e.includes("/")||e.includes("\\")?true:e.includes("_")&&Ut.test(e):false}function Gt(e,t){if(e.trim().length===0)return [e];if(t<=0)return [e];let r=e.match(/^(\s*)([-*\u2022]\s+)?(.*)$/),s=r?.[1]??"",c=r?.[2]??"",f=r?.[3]??"",m=`${s}${c}`,a=`${s}${c?" ".repeat(c.length):""}`,v=Math.max(10,t-D(m)),$=Math.max(10,t-D(a)),E=f.split(/\s+/).filter(Boolean),O=[],h="",o=m,l=v;for(let T of E){if(!h){if(D(T)>l){if(Ge(T)){h=T;continue}let w=Ue(T,l),S=w.shift()??"";O.push(o+S),o=a,l=$;for(let p of w)O.push(o+p);continue}h=T;continue}let n=`${h} ${T}`;if(D(n)<=l){h=n;continue}if(O.push(o+h),o=a,l=$,D(T)>l){if(Ge(T)){h=T;continue}let w=Ue(T,l),S=w.shift()??"";O.push(o+S);for(let p of w)O.push(o+p);h="";continue}h=T;}return (h||E.length===0)&&O.push(o+h),O}function qe(e,t={}){let r=process.stdout?.columns??80,s=t.columns??r,c=t.maxWidth??Math.max(40,Math.min(88,s-10));return e.split(`
2
+ `).flatMap(f=>Gt(f,c)).join(`
3
+ `)}function qt(e,t,r={}){let s=r.columns??process.stdout?.columns,c=qe(e,{columns:s,maxWidth:r.maxWidth});prompts.note(c,Ce(t));}var Q=null;function Qt(e,t){try{e.write(t);}catch{}}function Xt(e){e.isTTY&&(Q=e);}function we(){Q?.isTTY&&Qt(Q,"\r\x1B[2K");}function Zt(e){Q&&(e&&Q!==e||(Q=null));}function tn(e){return prompts.select({...e,message:Te(e.message),options:e.options.map(t=>t.hint===void 0?t:{...t,hint:ye(t.hint)})})}var nn="\x1B[0m\x1B[?25h\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?2004l";function le(e,t,r){let s=r?` (${r})`:"",c=`[terminal] restore ${e} failed${s}: ${String(t)}`;try{ue__default.default.stderr.write(`${c}
4
+ `);}catch(f){console.error(`[terminal] restore reporting failed${s}: ${String(f)}`);}}function rn(e,t={}){let r=t.resumeStdinIfPaused??t.resumeStdin??false;try{we();}catch(c){le("progress line",c,e);}let s=ue__default.default.stdin;if(s?.isTTY&&typeof s.setRawMode=="function"){try{s.setRawMode(!1);}catch(c){le("raw mode",c,e);}if(r&&typeof s.isPaused=="function"&&s.isPaused())try{s.resume();}catch(c){le("stdin resume",c,e);}}if(ue__default.default.stdout?.isTTY)try{ue__default.default.stdout.write(nn);}catch(c){le("stdout reset",c,e);}}function sn(e){let t=e?.code;return t==="EPIPE"||t==="EIO"}function cn(e={}){let t=false,r=false,s=(a,v)=>{r||(r=true,e.onBrokenPipe?.(a,v));},c=(a,v)=>{if(!sn(a))throw a;return t=true,s(a,v),false},f=(a,v)=>{if(t)return false;try{e.beforeWrite?.();}catch($){return c($,ue__default.default.stderr)}try{return a.write(v),!t}catch($){return c($,a)}};return {write:f,writeLine:(a,v)=>f(a,`${v}
5
+ `),reset:()=>{t=false,r=false;},isClosed:()=>t}}function X(e,t){return !Number.isFinite(t)||t<=0?"":e.repeat(t)}function an(e,t,r){let s=D(e);if(s>=t)return e;let c=t-s;if(r==="right")return `${X(" ",c)}${e}`;if(r==="center"){let f=Math.floor(c/2),m=c-f;return `${X(" ",f)}${e}${X(" ",m)}`}return `${e}${X(" ",c)}`}function ln(e,t){if(!e||e.length===0)return [""];if(!Number.isFinite(t)||t<=0)return [e];let r="\x1B",s=[];for(let i=0;i<e.length;){if(e[i]===r){if(e[i+1]==="["){let g=i+2;for(;g<e.length;){let C=e[g];if(C==="m")break;if(C&&C>="0"&&C<="9"){g+=1;continue}if(C===";"){g+=1;continue}break}if(e[g]==="m"){s.push({kind:"ansi",value:e.slice(i,g+1)}),i=g+1;continue}}if(e[i+1]==="]"&&e.slice(i+2,i+5)==="8;;"){let g=e.indexOf(`${r}\\`,i+5);if(g>=0){s.push({kind:"ansi",value:e.slice(i,g+2)}),i=g+2;continue}}}let u=e.codePointAt(i);if(!u)break;let x=String.fromCodePoint(u);s.push({kind:"char",value:x}),i+=x.length;}let c=s.findIndex(i=>i.kind==="char");if(c<0)return [e];let f=-1;for(let i=s.length-1;i>=0;i-=1){let u=s[i];if(u&&u.kind==="char"){f=i;break}}let m=s.slice(0,c).filter(i=>i.kind==="ansi").map(i=>i.value).join(""),a=s.slice(f+1).filter(i=>i.kind==="ansi").map(i=>i.value).join(""),v=s.slice(c,f+1),$=[],E=i=>i===" "||i===" "||i==="/"||i==="-"||i==="_"||i===".",O=i=>i===" "||i===" ",h=false,o=[],l=0,T=null,n=i=>(i??o).map(u=>u.value).join(""),w=i=>i.reduce((u,x)=>u+(x.kind==="char"?1:0),0),S=i=>{let u=i.replace(/\s+$/,"");u.trim().length!==0&&$.push(u);},p=i=>{if(o.length===0)return;if(i==null||i<=0){S(n()),o.length=0,l=0,T=null;return}let u=o.slice(0,i),x=o.slice(i);for(S(n(u));x.length>0;){let g=x[0];if(g?.kind!=="char"||!O(g.value))break;x.shift();}o.length=0,o.push(...x),l=w(o),T=null;};for(let i of v){if(i.kind==="ansi"){o.push(i);continue}let u=i.value;if(!(h&&(h=false,u===`
6
+ `))){if(u===`
7
+ `||u==="\r"){p(o.length),u==="\r"&&(h=true);continue}l+1>t&&l>0&&p(T),o.push(i),l+=1,E(u)&&(T=o.length);}}return p(o.length),$.length===0?[""]:!m&&!a?$:$.map(i=>i&&`${m}${i}${a}`)}function un(e){if(e!=null&&!(!Number.isFinite(e)||e<=0))return Math.floor(e)}function fn(e){let t=e.rows.map(S=>{let p={};for(let[i,u]of Object.entries(S))p[i]=ve(u);return p}),r=e.border??"unicode";if(r==="none"){let S=e.columns;return `${[S.map(u=>u.header).join(" | "),...t.map(u=>S.map(x=>u[x.key]??"").join(" | "))].join(`
8
8
  `)}
9
- `}let i=Math.max(0,e.padding??1),o=e.columns,l=o.map(f=>{let u=O(f.header),t=Math.max(0,...r.map(s=>O(s[f.key]??"")));return {headerW:u,cellW:t}}),d=o.map((f,u)=>{let t=l[u];if(!t)throw new Error(`Internal error: metrics[${u}] is undefined`);let s=Math.max(t.headerW,t.cellW)+i*2,c=f.maxWidth?Math.min(s,f.maxWidth):s;return Math.max(f.minWidth??3,c)}),g=tr(e.width),$=o.length+1,W=d.reduce((f,u)=>f+u,0)+$,A=o.map((f,u)=>{let t=l[u];if(!t)throw new Error(`Internal error: metrics[${u}] is undefined`);return Math.max(f.minWidth??3,t.headerW+i*2,3)}),y=o.map((f,u)=>{let t=l[u];if(!t)throw new Error(`Internal error: metrics[${u}] is undefined`);return Math.max(t.headerW+i*2,3)});if(g&&W>g){let f=W-g,u=o.map((c,a)=>{let h=d[a];if(h===void 0)throw new Error(`Internal error: widths[${a}] is undefined`);return {i:a,w:h}}).filter(({i:c})=>!!o[c]?.flex).toSorted((c,a)=>a.w-c.w).map(c=>c.i),t=o.map((c,a)=>{let h=d[a];if(h===void 0)throw new Error(`Internal error: widths[${a}] is undefined`);return {i:a,w:h}}).filter(({i:c})=>!o[c]?.flex).toSorted((c,a)=>a.w-c.w).map(c=>c.i),s=(c,a)=>{for(;f>0;){let h=false;for(let P of c){let N=d[P],I=a[P];if(!(N===void 0||I===void 0)&&!(N<=I)&&(d[P]=N-1,f-=1,h=true,f<=0))break}if(!h)break}};s(u,A),s(u,y),s(t,A),s(t,y);}if(g){let f=o.length+1,u=d.reduce((s,c)=>s+c,0)+f,t=g-u;if(t>0){let s=o.map((c,a)=>({c,i:a})).filter(({c})=>!!c.flex).map(({i:c})=>c);if(s.length>0){let c=o.map(a=>typeof a.maxWidth=="number"&&a.maxWidth>0?Math.floor(a.maxWidth):Number.POSITIVE_INFINITY);for(;t>0;){let a=false;for(let h of s){let P=d[h],N=c[h];if(!(P===void 0||N===void 0)&&!(P>=N)&&(d[h]=P+1,t-=1,a=true,t<=0))break}if(!a)break}}}}let p=n==="ascii"?{tl:"+",tr:"+",bl:"+",br:"+",h:"-",v:"|",t:"+",ml:"+",m:"+",mr:"+",b:"+"}:{tl:"\u250C",tr:"\u2510",bl:"\u2514",br:"\u2518",h:"\u2500",v:"\u2502",t:"\u252C",ml:"\u251C",m:"\u253C",mr:"\u2524",b:"\u2534"},x=(f,u,t)=>`${f}${d.map(s=>{if(s===void 0)throw new Error("Internal error: width is undefined");return H(p.h,s)}).join(u)}${t}`,k=f=>{let u=d[f];if(u===void 0)throw new Error(`Internal error: widths[${f}] is undefined`);return Math.max(1,u-i*2)},b=H(" ",i),C=(f,u=false)=>{let s=o.map(h=>u?h.header:f[h.key]??"").map((h,P)=>rr(h,k(P))),c=Math.max(...s.map(h=>h.length)),a=[];for(let h=0;h<c;h+=1){let P=s.map((N,I)=>{let le=N[h]??"",ee=o[I];if(!ee)throw new Error(`Internal error: columns[${I}] is undefined`);let me=er(le,k(I),ee.align??"left");return `${b}${me}${b}`});a.push(`${p.v}${P.join(p.v)}${p.v}`);}return a},w=[];w.push(x(p.tl,p.t,p.tr)),w.push(...C({},true)),w.push(x(p.ml,p.m,p.mr));for(let f of r)w.push(...C(f,false));return w.push(x(p.bl,p.b,p.br)),`${w.join(`
9
+ `}let s=Math.max(0,e.padding??1),c=e.columns,f=c.map(S=>{let p=D(S.header),i=Math.max(0,...t.map(u=>D(u[S.key]??"")));return {headerW:p,cellW:i}}),m=c.map((S,p)=>{let i=f[p];if(!i)throw new Error(`Internal error: metrics[${p}] is undefined`);let u=Math.max(i.headerW,i.cellW)+s*2,x=S.maxWidth?Math.min(u,S.maxWidth):u;return Math.max(S.minWidth??3,x)}),a=un(e.width),v=c.length+1,$=m.reduce((S,p)=>S+p,0)+v,E=c.map((S,p)=>{let i=f[p];if(!i)throw new Error(`Internal error: metrics[${p}] is undefined`);return Math.max(S.minWidth??3,i.headerW+s*2,3)}),O=c.map((S,p)=>{let i=f[p];if(!i)throw new Error(`Internal error: metrics[${p}] is undefined`);return Math.max(i.headerW+s*2,3)});if(a&&$>a){let S=$-a,p=c.map((x,g)=>{let C=m[g];if(C===void 0)throw new Error(`Internal error: widths[${g}] is undefined`);return {i:g,w:C}}).filter(({i:x})=>!!c[x]?.flex).toSorted((x,g)=>g.w-x.w).map(x=>x.i),i=c.map((x,g)=>{let C=m[g];if(C===void 0)throw new Error(`Internal error: widths[${g}] is undefined`);return {i:g,w:C}}).filter(({i:x})=>!c[x]?.flex).toSorted((x,g)=>g.w-x.w).map(x=>x.i),u=(x,g)=>{for(;S>0;){let C=false;for(let A of x){let F=m[A],_=g[A];if(!(F===void 0||_===void 0)&&!(F<=_)&&(m[A]=F-1,S-=1,C=true,S<=0))break}if(!C)break}};u(p,E),u(p,O),u(i,E),u(i,O);}if(a){let S=c.length+1,p=m.reduce((u,x)=>u+x,0)+S,i=a-p;if(i>0){let u=c.map((x,g)=>({c:x,i:g})).filter(({c:x})=>!!x.flex).map(({i:x})=>x);if(u.length>0){let x=c.map(g=>typeof g.maxWidth=="number"&&g.maxWidth>0?Math.floor(g.maxWidth):Number.POSITIVE_INFINITY);for(;i>0;){let g=false;for(let C of u){let A=m[C],F=x[C];if(!(A===void 0||F===void 0)&&!(A>=F)&&(m[C]=A+1,i-=1,g=true,i<=0))break}if(!g)break}}}}let h=r==="ascii"?{tl:"+",tr:"+",bl:"+",br:"+",h:"-",v:"|",t:"+",ml:"+",m:"+",mr:"+",b:"+"}:{tl:"\u250C",tr:"\u2510",bl:"\u2514",br:"\u2518",h:"\u2500",v:"\u2502",t:"\u252C",ml:"\u251C",m:"\u253C",mr:"\u2524",b:"\u2534"},o=(S,p,i)=>`${S}${m.map(u=>{if(u===void 0)throw new Error("Internal error: width is undefined");return X(h.h,u)}).join(p)}${i}`,l=S=>{let p=m[S];if(p===void 0)throw new Error(`Internal error: widths[${S}] is undefined`);return Math.max(1,p-s*2)},T=X(" ",s),n=(S,p=false)=>{let u=c.map(C=>p?C.header:S[C.key]??"").map((C,A)=>ln(C,l(A))),x=Math.max(...u.map(C=>C.length)),g=[];for(let C=0;C<x;C+=1){let A=u.map((F,_)=>{let W=F[C]??"",J=c[_];if(!J)throw new Error(`Internal error: columns[${_}] is undefined`);let M=an(W,l(_),J.align??"left");return `${T}${M}${T}`});g.push(`${h.v}${A.join(h.v)}${h.v}`);}return g},w=[];w.push(o(h.tl,h.t,h.tr)),w.push(...n({},true)),w.push(o(h.ml,h.m,h.mr));for(let S of t)w.push(...n(S,false));return w.push(o(h.bl,h.b,h.br)),`${w.join(`
10
10
  `)}
11
- `}function or(e,r){if(!r)return e;let n=e.indexOf(":");if(n===-1)return e;let i=e.slice(0,n+1),o=e.slice(n+1).trimStart(),l=o.toLowerCase(),d=(g,$)=>`${i} ${$(o.slice(0,g.length))}${o.slice(g.length)}`;return l.startsWith("failed")?d("failed",m.error):l.startsWith("ok")?d("ok",m.success):l.startsWith("linked")?d("linked",m.success):l.startsWith("configured")?d("configured",m.success):l.startsWith("not linked")?d("not linked",m.warn):l.startsWith("not configured")?d("not configured",m.muted):l.startsWith("unknown")?d("unknown",m.warn):e}exports.DOCS_ROOT=D;exports.LOBSTER_PALETTE=T;exports.clearActiveProgressLine=Q;exports.colorize=E;exports.createSafeStreamWriter=Qe;exports.displayPath=Ie;exports.displayString=q;exports.emitJsonError=De;exports.emitJsonOk=Me;exports.expandHomePrefix=Y;exports.formatCommandExample=Te;exports.formatCount=Le;exports.formatDocsLink=_e;exports.formatDocsRootLink=He;exports.formatEmptyMessage=Re;exports.formatError=ke;exports.formatHeading=We;exports.formatInfo=$e;exports.formatKeyValue=we;exports.formatListItem=ye;exports.formatSeparator=Oe;exports.formatStatus=Pe;exports.formatSuccess=Ee;exports.formatTerminalLink=J;exports.formatWarning=ve;exports.isRich=S;exports.note=Ue;exports.registerActiveProgressLine=Ve;exports.renderTable=nr;exports.resolveConfigDir=Ae;exports.resolveEffectiveHomeDir=M;exports.resolveHomeDir=oe;exports.resolveRequiredHomeDir=F;exports.resolveUserPath=ne;exports.restoreTerminalState=Xe;exports.selectStyled=qe;exports.shortenHomeInString=ce;exports.shortenHomePath=se;exports.stripAnsi=re;exports.styleHealthChannelLine=or;exports.stylePromptHint=Z;exports.stylePromptMessage=G;exports.stylePromptTitle=X;exports.theme=m;exports.unregisterActiveProgressLine=Ye;exports.visibleWidth=O;exports.wrapNoteMessage=ue;
11
+ `}var dn=[{prefix:"failed",color:b.error},{prefix:"ok",color:b.success},{prefix:"linked",color:b.success},{prefix:"configured",color:b.success},{prefix:"not linked",color:b.warn},{prefix:"not configured",color:b.muted},{prefix:"unknown",color:b.warn}];function mn(e,t){if(!t)return e;let r=e.indexOf(":");if(r===-1)return e;let s=e.slice(0,r+1),c=e.slice(r+1).trimStart(),f=c.toLowerCase();for(let{prefix:m,color:a}of dn)if(f.startsWith(m))return `${s} ${a(c.slice(0,m.length))}${c.slice(m.length)}`;return e}var hn=new stream.Writable({write(e,t,r){r();}}),oe;(h=>{h.cancelSymbol=Symbol("Search.cancel");function t(o){let l=0;for(let T of o){let n=T.codePointAt(0);if(n===void 0||n===0)continue;let w=n>=4352&&n<=4447||n>=8986&&n<=8987||n>=9001&&n<=9002||n>=9193&&n<=9196||n===9200||n===9203||n>=9725&&n<=9726||n>=9748&&n<=9749||n>=9800&&n<=9811||n===9855||n===9875||n===9889||n>=9898&&n<=9899||n>=9917&&n<=9918||n>=9924&&n<=9925||n===9934||n===9940||n===9962||n>=9970&&n<=9971||n===9973||n===9978||n===9981||n===9989||n>=9994&&n<=9995||n===10024||n===10060||n===10062||n>=10067&&n<=10069||n===10071||n>=10133&&n<=10135||n===10160||n===10175||n>=11035&&n<=11036||n===11088||n===11093||n>=11904&&n<=42191&&n!==12351||n>=43360&&n<=43388||n>=44032&&n<=55203||n>=63744&&n<=64255||n>=65040&&n<=65049||n>=65072&&n<=65135||n>=65280&&n<=65376||n>=65504&&n<=65510||n>=126976&&n<=129535;l+=w?2:1;}return l}h.approxStringWidth=t;function r(o,l){let T=util.stripVTControlCharacters(o),n=Math.max(1,l),w=t(T);return Math.max(1,Math.ceil(w/n))}h.visualRowsForLine=r;function s(o,l){let T=l!==void 0&&l>0?l:process.stdout.columns&&process.stdout.columns>0?process.stdout.columns:80,n=0;for(let w of o)n+=r(w,T);return n}h.countVisualRowsForLines=s;function c(o){let l=new Array(o.length);for(let T=0;T<o.length;T++){let n=o[T],w=n.value===null||n.value===void 0?"":String(n.value);l[T]={...n,searchKey:`${n.label}
12
+ ${w}`.toLowerCase()};}return l}function f(o,l){return l===""||o.searchKey.includes(l)}function m(o,l){return l<=0||o<0?0:o>=l?l-1:o}function a(o){if(o?.length!==1)return false;let l=o.codePointAt(0);return !(l===void 0||l<32||l===127||l===27)}function v(){let o=process.stdout.rows;if(!o||o<=0)return 8;let l=Math.floor((o-8)/2);return Math.max(5,Math.min(15,l))}function $(o,l){try{o.write(l);}catch{}}function E(o){if(o&&o.isTTY&&typeof o.setRawMode=="function")try{o.setRawMode(!1);}catch{}}function O(o){let l=o.message,T=c(o.items),n=Math.max(1,o.maxVisible??v()),w=o.initialSelected??[],S=o.required??false,p=o.lockedSection,i=o.isTTY;i??!!process.stdout?.isTTY;return new Promise(x=>{let g=process.stdin,C=process.stdout,A=de__namespace.createInterface({input:g,output:hn,terminal:false});try{(i===!0||i===void 0&&g.isTTY)&&g.setRawMode?.(!0);}catch{}de__namespace.emitKeypressEvents(g,A);let F="",_="",W=0,J=new Set(w),M=0,U=false,z=p?p.items.map(R=>R.value):[],me=p?p.items.map(R=>R.label):[],ie=[],Oe=()=>{if(ie.length=0,_==="")for(let R=0;R<T.length;R++){let d=T[R];ie.push(d);}else for(let R=0;R<T.length;R++){let d=T[R];f(d,_)&&ie.push(d);}return ie},Xe=()=>{if(M>0){$(C,`\x1B[${M}A`);for(let R=0;R<M;R++)$(C,"\x1B[2K\x1B[1B");$(C,`\x1B[${M}A`);}},We=()=>{let R=me.slice();for(let d=0;d<T.length;d++){let L=T[d];J.has(L.value)&&R.push(L.label);}return R},H=(R="active")=>{Xe();let d=[],L=Oe(),K=i===false?false:i===true?true:k(),Ae=P=>y(K,b.error,P),ce=P=>y(K,b.success,P),I=P=>y(K,b.muted,P),pe=P=>y(K,b.heading,P),ot=P=>y(K,b.accentBright,P),it=P=>y(K,fe__default.default.bold,P),st=P=>y(K,fe__default.default.underline,P),ct=P=>y(K,fe__default.default.inverse,P),at=P=>y(K,fe__default.default.strikethrough,P),_e=R==="active"||R==="error"?"\u25C6":R==="cancel"?"\u25A0":"\u25C7",lt=R==="cancel"||R==="error"?Ae(_e):ce(_e);if(d.push(`${lt} ${it(l)}`),R==="active"||R==="error"){if(p&&p.items.length>0){d.push(I("\u2502"));let G=`${pe(p.title)} ${I("\u2500\u2500 always included")}`;d.push(`${I("\u2502")} ${I("\u2500\u2500")} ${G} ${I("\u2500".repeat(12))}`);for(let ee of p.items)d.push(`${I("\u2502")} ${ce("\u2022")} ${pe(ee.label)}`);p.hiddenCount&&p.hiddenCount>0&&d.push(`${I("\u2502")} ${I(`...and ${p.hiddenCount} more`)}`),d.push(I("\u2502")),d.push(`${I("\u2502")} ${I("\u2500\u2500")} ${pe("Additional agents")} ${I("\u2500".repeat(29))}`);}let P=`${I("\u2502")} ${I("Search:")} ${F}${ct(" ")}`;d.push(P),d.push(`${I("\u2502")} ${I("\u2191\u2193 move \xB7 space select \xB7 enter confirm")}`),d.push(I("\u2502"));let ut=Math.max(0,L.length-n),ft=W-Math.floor(n/2),ge=Math.max(0,Math.min(ft,ut)),He=Math.min(L.length,ge+n);if(L.length===0)d.push(`${I("\u2502")} ${I("No matches found")}`);else {for(let Y=ge;Y<He;Y++){let te=L[Y],dt=J.has(te.value),Be=Y===W,mt=dt?ce("\u25CF"):I("\u25CB"),pt=Be?st(te.label):te.label,gt=te.hint?I(` (${te.hint})`):"",ht=Be?ot("\u276F"):" ";d.push(`${I("\u2502")} ${ht} ${mt} ${pt}${gt}`);}let G=ge,ee=L.length-He;if(G>0||ee>0){let Y=[];G>0&&Y.push(`\u2191 ${G} more`),ee>0&&Y.push(`\u2193 ${ee} more`),d.push(`${I("\u2502")} ${I(Y.join(" "))}`);}}d.push(I("\u2502"));let Z=We();if(Z.length===0)d.push(`${I("\u2502")} ${I("Selected: (none)")}`);else {let G=Z.length<=3?Z.join(", "):`${Z.slice(0,3).join(", ")} +${Z.length-3} more`;d.push(`${I("\u2502")} ${ce("Selected:")} ${G}`);}R==="error"&&d.push(`${I("\u2502")} ${Ae("\u26A0 Please select at least one item before submitting")}`),d.push(`${I("\u2514")}`);}else if(R==="submit"){let P=We();d.push(`${I("\u2502")} ${I(P.join(", "))}`);}else d.push(`${I("\u2502")} ${at(I("Cancelled"))}`);$(C,`${d.join(`
13
+ `)}
14
+ `);try{M=s(d,C.columns);}catch{M=d.length;}},Le=false,Ze=()=>{if(!Le){Le=true;try{g.removeListener("keypress",Ne),g.removeListener("end",Fe);}catch{}try{process.removeListener("SIGINT",se),process.removeListener("SIGTERM",se);}catch{}E(g);try{A.close();}catch{}}},Me=R=>{U||(U=true,Ze(),x(R));},et=()=>{if(S&&J.size===0&&z.length===0){H("error");return}H("submit"),Me([...z,...Array.from(J)]);},Pe=()=>{H("cancel"),Me(h.cancelSymbol);},Fe=()=>{Pe();},se=()=>{E(g);},tt=R=>{let d=R[W];d&&(J.has(d.value)?J.delete(d.value):J.add(d.value));},nt=R=>{F+=R,_+=R.toLowerCase();},rt=()=>{F.length!==0&&(F=F.slice(0,-1),_=_.slice(0,-1));},Ne=(R,d)=>{if(!d)return;let L=Oe();if(W=m(W,L.length),d.name==="return"){et();return}if(d.name==="escape"||d.ctrl&&d.name==="c"){Pe();return}if(d.name==="up"||d.name==="left"){L.length>0&&(W=m(W-1,L.length),H());return}if(d.name==="down"||d.name==="right"){L.length>0&&(W=m(W+1,L.length),H());return}if(d.name==="pageup"){L.length>0&&(W=m(W-n,L.length),H());return}if(d.name==="pagedown"){L.length>0&&(W=m(W+n,L.length),H());return}if(d.name==="home"){L.length>0&&(W=0,H());return}if(d.name==="end"){L.length>0&&(W=L.length-1,H());return}if(d.name==="space"){tt(L),H();return}if(d.name==="backspace"){F.length>0&&(rt(),W=0,H());return}!d.ctrl&&!d.meta&&a(d.sequence)&&(nt(d.sequence),W=0,H());};g.on("keypress",Ne),g.once("end",Fe),process.on("SIGINT",se),process.on("SIGTERM",se),H();})}h.multiselect=O;})(oe||(oe={}));var Ee=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Re=80;exports.Loader=void 0;(t=>{function e(r={}){let s=[...Ee],c=Re,f=0,m=null,a=r.message??"Loading...",v=r.spinnerColor??(o=>y(k(),b.accent,o)),$=r.messageColor??(o=>y(k(),b.muted,o)),E=o=>{s=o.frames!==void 0?[...o.frames]:[...Ee],c=o.intervalMs!==void 0&&o.intervalMs>0?o.intervalMs:Re,f=0;};r.indicator&&E(r.indicator);function O(){h(),!(s.length<=1)&&(m=setInterval(()=>{f=(f+1)%s.length;},c));}function h(){m!==null&&(clearInterval(m),m=null);}return {start:O,stop:h,isRunning(){return m!==null},line(){let o=s[f]??"";return `${o.length>0?`${v(o)} `:""}${$(a)}`},setMessage(o){a=o;},setIndicator(o){o?E(o):(s=[...Ee],c=Re,f=0),O();}}}t.create=e;})(exports.Loader||(exports.Loader={}));var xn=e=>y(k(),b.accent,e),bn=e=>y(k(),b.muted,e);exports.Input=void 0;(m=>{function e(a){let v=a;typeof v.resume=="function"&&v.resume();}function t(a,v){try{a.write(v);}catch{}}function r(a,v,$){let E=a;for(let O=0;O<v.length;O+=1){let h=v[O],o=h.charCodeAt(0);if(o===3)return {buffer:E,done:true,line:""};if(o===4)return {buffer:E,done:true,line:E};if(o===10||o===13)return {buffer:"",done:true,line:E};if((o===8||o===127)){E=E.slice(0,-1);continue}E+=h;}return {buffer:E,done:false,line:""}}function s(a){return new Promise((v,$)=>{let{message:E,hint:O,defaultValue:h,hidden:o,input:l,output:T,messageColor:n,hintColor:w}=a,S=(n??xn)(E),p=O?` ${(w??bn)(`(${O})`)}`:"",i=h?` [${h}]`:"",u=o?`${S}${p}: `:`${S}${p}${i}: `,x=l??ue__default.default.stdin,g=T??ue__default.default.stdout;t(g,u);let C="",A=false,F=M=>{A||(A=true,M(),x.off("data",_),x.off("end",W));},_=M=>{let U=typeof M=="string"?M:M.toString("utf8"),z=r(C,U);if(C=z.buffer,!z.done)return;if(z.line===""&&C===""&&!U.includes(`
15
+ `)&&!U.includes("\r")){F(()=>$(new Error("Input canceled")));return}let me=z.line.length===0&&h!==void 0?h:z.line;F(()=>v(me));},W=()=>{if(A)return;let M=C.length===0&&h!==void 0?h:C;F(()=>v(M));},J=M=>{if((typeof M=="string"?M:M.toString("utf8")).includes("")){F(()=>$(new Error("Input canceled")));return}_(M);};x.on("data",J),x.once("end",W),e(x);})}m.readText=s;async function c(a){let v=a.defaultValue!==false,E=(await s({message:a.message,hint:a.hint??`y/n, default ${v?"y":"n"}`,defaultValue:v?"y":"n",messageColor:a.messageColor,hintColor:a.hintColor,input:a.input,output:a.output})).trim().toLowerCase();return E===""?v:E==="y"||E==="yes"?true:E==="n"||E==="no"?false:c(a)}m.readConfirm=c;function f(a){return s({...a,hidden:true})}m.readPassword=f;})(exports.Input||(exports.Input={}));var Sn=e=>y(k(),b.heading,e),$n=e=>y(k(),b.command,e),vn=e=>y(k(),b.muted,e),Tn=e=>y(k(),b.warn,e),Cn=e=>y(k(),b.accent,e);function yn(e,t,r,s,c,f){let m=e;return m=m.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(a,v,$)=>`${f(v)} (${$})`),m=m.replace(/`([^`]+)`/g,(a,v)=>c(v)),m=m.replace(/\*\*([^*]+)\*\*/g,(a,v)=>r(v)),m=m.replace(/(^|[^*])\*([^*]+)\*(?!\*)/g,(a,v,$)=>`${v}${s($)}`),m}function wn(e,t={}){if(!e)return [];let r=t.headingColor??Sn,s=t.boldColor??$n,c=t.italicColor??vn,f=t.codeColor??Tn,m=t.linkColor??Cn,a=n=>yn(n,r,s,c,f,m),v=e.replace(/\r\n/g,`
16
+ `).split(`
17
+ `),$=[],E=false,O=[],h="",o=0,l=true,T=()=>{if(O.length!==0){$.push(f(`\`\`\`${h}`));for(let n of O)$.push(f(n));$.push(f("```")),O=[],h="";}};for(let n of v){let w=n;if(w.trim().startsWith("```")){if(!E){T(),E=true,h=w.trim().slice(3).trim(),$.push(f(`\`\`\`${h}`)),l=false;continue}for(let u of O)$.push(f(u));O=[],$.push(f("```")),E=false,h="",l=false;continue}if(E){O.push(w);continue}let S=/^(#{1,3})\s+(.+)$/.exec(w);if(S){let u=S[1]??"#",x=S[2]??"";$.push(r(`${u} ${a(x)}`)),l=false;continue}if(/^(\s*[-*_])\s*\1\s*\1[-*_\s]*$/.test(w)||/^---\s*$/.test(w)||/^\*\*\*\s*$/.test(w)){$.push(f("\u2500".repeat(40))),l=true;continue}let p=/^\s*[-*]\s+(.+)$/.exec(w),i=/^\s*\d+\.\s+(.+)$/.exec(w);if(p){let u=p[1]??"";$.push(` \u2022 ${a(u)}`),o=0,l=false;continue}if(i){let u=i[1]??"";o+=1,$.push(` ${o}. ${a(u)}`),l=false;continue}if(w.trim()===""){l||$.push(""),l=true,o=0;continue}$.push(a(w)),l=false,o=0;}return E&&T(),$}var jr=oe,Vr=oe.cancelSymbol;exports.LOBSTER_PALETTE=B;exports.Search=jr;exports.cancelSymbol=Vr;exports.clearActiveProgressLine=we;exports.colorize=y;exports.createSafeStreamWriter=cn;exports.displayPath=Ht;exports.displayString=ve;exports.emitJsonError=Vt;exports.emitJsonOk=jt;exports.expandHomePrefix=Se;exports.formatCommandExample=Ot;exports.formatCount=Nt;exports.formatEmptyMessage=Ft;exports.formatError=wt;exports.formatHeading=It;exports.formatInfo=Rt;exports.formatKeyValue=kt;exports.formatListItem=Wt;exports.formatRootLink=Dt;exports.formatRootedLink=Jt;exports.formatSeparator=Pt;exports.formatStatus=Mt;exports.formatSuccess=yt;exports.formatTerminalLink=re;exports.formatWarning=Et;exports.isRich=k;exports.note=qt;exports.registerActiveProgressLine=Xt;exports.renderMarkdown=wn;exports.renderTable=fn;exports.resolveConfigDir=_t;exports.resolveEffectiveHomeDir=q;exports.resolveHomeDir=Ve;exports.resolveRequiredHomeDir=be;exports.resolveUserPath=je;exports.restoreTerminalState=rn;exports.selectStyled=tn;exports.shortenHomeInString=Ye;exports.shortenHomePath=ze;exports.stripAnsi=ne;exports.styleHealthChannelLine=mn;exports.stylePromptHint=ye;exports.stylePromptMessage=Te;exports.stylePromptTitle=Ce;exports.theme=b;exports.unregisterActiveProgressLine=Zt;exports.visibleWidth=D;exports.wrapNoteMessage=qe;
package/dist/index.d.cts CHANGED
@@ -14,6 +14,8 @@ declare const LOBSTER_PALETTE: {
14
14
  readonly error: "#E23D2D";
15
15
  readonly muted: "#8B7F77";
16
16
  };
17
+ type LobsterPalette = typeof LOBSTER_PALETTE;
18
+ type LobsterPaletteKey = keyof LobsterPalette;
17
19
 
18
20
  declare const theme: {
19
21
  readonly accent: chalk.ChalkInstance;
@@ -39,7 +41,8 @@ declare function formatHeading(title: string): string;
39
41
  declare function formatKeyValue(key: string, value: string, keyWidth?: number): string;
40
42
  declare function formatCommandExample(command: string, description?: string): string;
41
43
  declare function formatListItem(icon: string, text: string, description?: string): string;
42
- declare function formatStatus(status: 'pending' | 'running' | 'success' | 'error' | 'skipped', message: string): string;
44
+ type StatusKind = 'pending' | 'running' | 'success' | 'error' | 'skipped';
45
+ declare function formatStatus(status: StatusKind, message: string): string;
43
46
  declare function formatSeparator(width?: number, char?: string): string;
44
47
  declare function formatEmptyMessage(message: string): string;
45
48
  declare function formatCount(count: number, singular: string, plural?: string): string;
@@ -51,10 +54,11 @@ declare function shortenHomePath(input: string): string;
51
54
  declare function shortenHomeInString(input: string): string;
52
55
  declare function displayPath(input: string): string;
53
56
  declare function displayString(input: string): string;
54
- declare function formatTerminalLink(label: string, url: string, opts?: {
57
+ type FormatTerminalLinkOptions = {
55
58
  fallback?: string;
56
59
  force?: boolean;
57
- }): string;
60
+ };
61
+ declare function formatTerminalLink(label: string, url: string, opts?: FormatTerminalLinkOptions, isTTY?: boolean): string;
58
62
 
59
63
  declare function resolveEffectiveHomeDir(env?: NodeJS.ProcessEnv, homedir?: () => string): string | undefined;
60
64
  declare function resolveRequiredHomeDir(env?: NodeJS.ProcessEnv, homedir?: () => string): string;
@@ -64,21 +68,25 @@ declare function expandHomePrefix(input: string, opts?: {
64
68
  homedir?: () => string;
65
69
  }): string;
66
70
 
67
- declare const DOCS_ROOT = "https://docs.openclaw.ai";
68
- declare function formatDocsLink(path: string, label?: string, opts?: {
71
+ declare function formatRootedLink(root: string, path: string, label?: string, opts?: {
69
72
  fallback?: string;
70
73
  force?: boolean;
71
- }): string;
72
- declare function formatDocsRootLink(label?: string): string;
74
+ }, isTTY?: boolean): string;
75
+ declare function formatRootLink(root: string, label?: string, isTTY?: boolean): string;
73
76
 
74
77
  declare function emitJsonOk(data: unknown, meta?: Record<string, unknown>): void;
75
78
  declare function emitJsonError(code: string, message: string): void;
76
79
 
77
- declare function wrapNoteMessage(message: string, options?: {
80
+ type WrapNoteMessageOptions = {
78
81
  maxWidth?: number;
79
82
  columns?: number;
80
- }): string;
81
- declare function note(message: string, title?: string): void;
83
+ };
84
+ declare function wrapNoteMessage(message: string, options?: WrapNoteMessageOptions): string;
85
+ type NoteOptions = {
86
+ columns?: number;
87
+ maxWidth?: number;
88
+ };
89
+ declare function note(message: string, title?: string, options?: NoteOptions): void;
82
90
 
83
91
  declare function registerActiveProgressLine(stream: NodeJS.WriteStream): void;
84
92
  declare function clearActiveProgressLine(): void;
@@ -128,4 +136,93 @@ declare function renderTable(opts: RenderTableOptions): string;
128
136
 
129
137
  declare function styleHealthChannelLine(line: string, rich: boolean): string;
130
138
 
131
- export { DOCS_ROOT, LOBSTER_PALETTE, type RenderTableOptions, type SafeStreamWriter, type SafeStreamWriterOptions, type TableColumn, clearActiveProgressLine, colorize, createSafeStreamWriter, displayPath, displayString, emitJsonError, emitJsonOk, expandHomePrefix, formatCommandExample, formatCount, formatDocsLink, formatDocsRootLink, formatEmptyMessage, formatError, formatHeading, formatInfo, formatKeyValue, formatListItem, formatSeparator, formatStatus, formatSuccess, formatTerminalLink, formatWarning, isRich, note, registerActiveProgressLine, renderTable, resolveConfigDir, resolveEffectiveHomeDir, resolveHomeDir, resolveRequiredHomeDir, resolveUserPath, restoreTerminalState, selectStyled, shortenHomeInString, shortenHomePath, stripAnsi, styleHealthChannelLine, stylePromptHint, stylePromptMessage, stylePromptTitle, theme, unregisterActiveProgressLine, visibleWidth, wrapNoteMessage };
139
+ declare namespace Search$1 {
140
+ interface Item<T> {
141
+ value: T;
142
+ label: string;
143
+ hint?: string;
144
+ }
145
+ interface LockedSection<T> {
146
+ title: string;
147
+ items: Item<T>[];
148
+ hiddenCount?: number;
149
+ }
150
+ interface MultiselectOptions<T> {
151
+ message: string;
152
+ items: Item<T>[];
153
+ maxVisible?: number;
154
+ initialSelected?: T[];
155
+ required?: boolean;
156
+ lockedSection?: LockedSection<T>;
157
+ isTTY?: boolean;
158
+ }
159
+ const cancelSymbol: unique symbol;
160
+ function approxStringWidth(plain: string): number;
161
+ function visualRowsForLine(line: string, columns: number): number;
162
+ function countVisualRowsForLines(lines: string[], columns: number | undefined): number;
163
+ function multiselect<T>(options: MultiselectOptions<T>): Promise<T[] | typeof cancelSymbol>;
164
+ }
165
+
166
+ type ColorFn$2 = (text: string) => string;
167
+ declare namespace Loader {
168
+ interface IndicatorOptions {
169
+ frames?: string[];
170
+ intervalMs?: number;
171
+ }
172
+ interface Options {
173
+ message?: string;
174
+ spinnerColor?: ColorFn$2;
175
+ messageColor?: ColorFn$2;
176
+ indicator?: IndicatorOptions;
177
+ }
178
+ interface Instance {
179
+ start(): void;
180
+ stop(): void;
181
+ isRunning(): boolean;
182
+ line(): string;
183
+ setMessage(message: string): void;
184
+ setIndicator(indicator?: IndicatorOptions): void;
185
+ }
186
+ function create(options?: Options): Instance;
187
+ }
188
+
189
+ type ColorFn$1 = (text: string) => string;
190
+ declare namespace Input {
191
+ interface ReadTextBaseOptions {
192
+ message: string;
193
+ hint?: string;
194
+ defaultValue?: string;
195
+ hidden?: boolean;
196
+ messageColor?: ColorFn$1;
197
+ hintColor?: ColorFn$1;
198
+ input?: NodeJS.ReadStream;
199
+ output?: NodeJS.WritableStream;
200
+ }
201
+ interface ReadConfirmOptions {
202
+ message: string;
203
+ hint?: string;
204
+ defaultValue?: boolean;
205
+ messageColor?: ColorFn$1;
206
+ hintColor?: ColorFn$1;
207
+ input?: NodeJS.ReadStream;
208
+ output?: NodeJS.WritableStream;
209
+ }
210
+ function readText(options: ReadTextBaseOptions): Promise<string>;
211
+ function readConfirm(options: ReadConfirmOptions): Promise<boolean>;
212
+ function readPassword(options: Omit<ReadTextBaseOptions, 'hidden'>): Promise<string>;
213
+ }
214
+
215
+ type ColorFn = (text: string) => string;
216
+ interface RenderMarkdownOptions {
217
+ headingColor?: ColorFn;
218
+ boldColor?: ColorFn;
219
+ italicColor?: ColorFn;
220
+ codeColor?: ColorFn;
221
+ linkColor?: ColorFn;
222
+ }
223
+ declare function renderMarkdown(md: string, opts?: RenderMarkdownOptions): string[];
224
+
225
+ declare const Search: typeof Search$1;
226
+ declare const cancelSymbol: symbol;
227
+
228
+ export { type ColorFn$2 as ColorFn, type FormatTerminalLinkOptions, Input, type ColorFn$1 as InputColorFn, LOBSTER_PALETTE, Loader, type LobsterPalette, type LobsterPaletteKey, type ColorFn as MarkdownColorFn, type NoteOptions, type RenderMarkdownOptions, type RenderTableOptions, type RestoreTerminalStateOptions, type SafeStreamWriter, type SafeStreamWriterOptions, Search, type StatusKind, type TableColumn, type WrapNoteMessageOptions, cancelSymbol, clearActiveProgressLine, colorize, createSafeStreamWriter, displayPath, displayString, emitJsonError, emitJsonOk, expandHomePrefix, formatCommandExample, formatCount, formatEmptyMessage, formatError, formatHeading, formatInfo, formatKeyValue, formatListItem, formatRootLink, formatRootedLink, formatSeparator, formatStatus, formatSuccess, formatTerminalLink, formatWarning, isRich, note, registerActiveProgressLine, renderMarkdown, renderTable, resolveConfigDir, resolveEffectiveHomeDir, resolveHomeDir, resolveRequiredHomeDir, resolveUserPath, restoreTerminalState, selectStyled, shortenHomeInString, shortenHomePath, stripAnsi, styleHealthChannelLine, stylePromptHint, stylePromptMessage, stylePromptTitle, theme, unregisterActiveProgressLine, visibleWidth, wrapNoteMessage };
package/dist/index.d.ts CHANGED
@@ -14,6 +14,8 @@ declare const LOBSTER_PALETTE: {
14
14
  readonly error: "#E23D2D";
15
15
  readonly muted: "#8B7F77";
16
16
  };
17
+ type LobsterPalette = typeof LOBSTER_PALETTE;
18
+ type LobsterPaletteKey = keyof LobsterPalette;
17
19
 
18
20
  declare const theme: {
19
21
  readonly accent: chalk.ChalkInstance;
@@ -39,7 +41,8 @@ declare function formatHeading(title: string): string;
39
41
  declare function formatKeyValue(key: string, value: string, keyWidth?: number): string;
40
42
  declare function formatCommandExample(command: string, description?: string): string;
41
43
  declare function formatListItem(icon: string, text: string, description?: string): string;
42
- declare function formatStatus(status: 'pending' | 'running' | 'success' | 'error' | 'skipped', message: string): string;
44
+ type StatusKind = 'pending' | 'running' | 'success' | 'error' | 'skipped';
45
+ declare function formatStatus(status: StatusKind, message: string): string;
43
46
  declare function formatSeparator(width?: number, char?: string): string;
44
47
  declare function formatEmptyMessage(message: string): string;
45
48
  declare function formatCount(count: number, singular: string, plural?: string): string;
@@ -51,10 +54,11 @@ declare function shortenHomePath(input: string): string;
51
54
  declare function shortenHomeInString(input: string): string;
52
55
  declare function displayPath(input: string): string;
53
56
  declare function displayString(input: string): string;
54
- declare function formatTerminalLink(label: string, url: string, opts?: {
57
+ type FormatTerminalLinkOptions = {
55
58
  fallback?: string;
56
59
  force?: boolean;
57
- }): string;
60
+ };
61
+ declare function formatTerminalLink(label: string, url: string, opts?: FormatTerminalLinkOptions, isTTY?: boolean): string;
58
62
 
59
63
  declare function resolveEffectiveHomeDir(env?: NodeJS.ProcessEnv, homedir?: () => string): string | undefined;
60
64
  declare function resolveRequiredHomeDir(env?: NodeJS.ProcessEnv, homedir?: () => string): string;
@@ -64,21 +68,25 @@ declare function expandHomePrefix(input: string, opts?: {
64
68
  homedir?: () => string;
65
69
  }): string;
66
70
 
67
- declare const DOCS_ROOT = "https://docs.openclaw.ai";
68
- declare function formatDocsLink(path: string, label?: string, opts?: {
71
+ declare function formatRootedLink(root: string, path: string, label?: string, opts?: {
69
72
  fallback?: string;
70
73
  force?: boolean;
71
- }): string;
72
- declare function formatDocsRootLink(label?: string): string;
74
+ }, isTTY?: boolean): string;
75
+ declare function formatRootLink(root: string, label?: string, isTTY?: boolean): string;
73
76
 
74
77
  declare function emitJsonOk(data: unknown, meta?: Record<string, unknown>): void;
75
78
  declare function emitJsonError(code: string, message: string): void;
76
79
 
77
- declare function wrapNoteMessage(message: string, options?: {
80
+ type WrapNoteMessageOptions = {
78
81
  maxWidth?: number;
79
82
  columns?: number;
80
- }): string;
81
- declare function note(message: string, title?: string): void;
83
+ };
84
+ declare function wrapNoteMessage(message: string, options?: WrapNoteMessageOptions): string;
85
+ type NoteOptions = {
86
+ columns?: number;
87
+ maxWidth?: number;
88
+ };
89
+ declare function note(message: string, title?: string, options?: NoteOptions): void;
82
90
 
83
91
  declare function registerActiveProgressLine(stream: NodeJS.WriteStream): void;
84
92
  declare function clearActiveProgressLine(): void;
@@ -128,4 +136,93 @@ declare function renderTable(opts: RenderTableOptions): string;
128
136
 
129
137
  declare function styleHealthChannelLine(line: string, rich: boolean): string;
130
138
 
131
- export { DOCS_ROOT, LOBSTER_PALETTE, type RenderTableOptions, type SafeStreamWriter, type SafeStreamWriterOptions, type TableColumn, clearActiveProgressLine, colorize, createSafeStreamWriter, displayPath, displayString, emitJsonError, emitJsonOk, expandHomePrefix, formatCommandExample, formatCount, formatDocsLink, formatDocsRootLink, formatEmptyMessage, formatError, formatHeading, formatInfo, formatKeyValue, formatListItem, formatSeparator, formatStatus, formatSuccess, formatTerminalLink, formatWarning, isRich, note, registerActiveProgressLine, renderTable, resolveConfigDir, resolveEffectiveHomeDir, resolveHomeDir, resolveRequiredHomeDir, resolveUserPath, restoreTerminalState, selectStyled, shortenHomeInString, shortenHomePath, stripAnsi, styleHealthChannelLine, stylePromptHint, stylePromptMessage, stylePromptTitle, theme, unregisterActiveProgressLine, visibleWidth, wrapNoteMessage };
139
+ declare namespace Search$1 {
140
+ interface Item<T> {
141
+ value: T;
142
+ label: string;
143
+ hint?: string;
144
+ }
145
+ interface LockedSection<T> {
146
+ title: string;
147
+ items: Item<T>[];
148
+ hiddenCount?: number;
149
+ }
150
+ interface MultiselectOptions<T> {
151
+ message: string;
152
+ items: Item<T>[];
153
+ maxVisible?: number;
154
+ initialSelected?: T[];
155
+ required?: boolean;
156
+ lockedSection?: LockedSection<T>;
157
+ isTTY?: boolean;
158
+ }
159
+ const cancelSymbol: unique symbol;
160
+ function approxStringWidth(plain: string): number;
161
+ function visualRowsForLine(line: string, columns: number): number;
162
+ function countVisualRowsForLines(lines: string[], columns: number | undefined): number;
163
+ function multiselect<T>(options: MultiselectOptions<T>): Promise<T[] | typeof cancelSymbol>;
164
+ }
165
+
166
+ type ColorFn$2 = (text: string) => string;
167
+ declare namespace Loader {
168
+ interface IndicatorOptions {
169
+ frames?: string[];
170
+ intervalMs?: number;
171
+ }
172
+ interface Options {
173
+ message?: string;
174
+ spinnerColor?: ColorFn$2;
175
+ messageColor?: ColorFn$2;
176
+ indicator?: IndicatorOptions;
177
+ }
178
+ interface Instance {
179
+ start(): void;
180
+ stop(): void;
181
+ isRunning(): boolean;
182
+ line(): string;
183
+ setMessage(message: string): void;
184
+ setIndicator(indicator?: IndicatorOptions): void;
185
+ }
186
+ function create(options?: Options): Instance;
187
+ }
188
+
189
+ type ColorFn$1 = (text: string) => string;
190
+ declare namespace Input {
191
+ interface ReadTextBaseOptions {
192
+ message: string;
193
+ hint?: string;
194
+ defaultValue?: string;
195
+ hidden?: boolean;
196
+ messageColor?: ColorFn$1;
197
+ hintColor?: ColorFn$1;
198
+ input?: NodeJS.ReadStream;
199
+ output?: NodeJS.WritableStream;
200
+ }
201
+ interface ReadConfirmOptions {
202
+ message: string;
203
+ hint?: string;
204
+ defaultValue?: boolean;
205
+ messageColor?: ColorFn$1;
206
+ hintColor?: ColorFn$1;
207
+ input?: NodeJS.ReadStream;
208
+ output?: NodeJS.WritableStream;
209
+ }
210
+ function readText(options: ReadTextBaseOptions): Promise<string>;
211
+ function readConfirm(options: ReadConfirmOptions): Promise<boolean>;
212
+ function readPassword(options: Omit<ReadTextBaseOptions, 'hidden'>): Promise<string>;
213
+ }
214
+
215
+ type ColorFn = (text: string) => string;
216
+ interface RenderMarkdownOptions {
217
+ headingColor?: ColorFn;
218
+ boldColor?: ColorFn;
219
+ italicColor?: ColorFn;
220
+ codeColor?: ColorFn;
221
+ linkColor?: ColorFn;
222
+ }
223
+ declare function renderMarkdown(md: string, opts?: RenderMarkdownOptions): string[];
224
+
225
+ declare const Search: typeof Search$1;
226
+ declare const cancelSymbol: symbol;
227
+
228
+ export { type ColorFn$2 as ColorFn, type FormatTerminalLinkOptions, Input, type ColorFn$1 as InputColorFn, LOBSTER_PALETTE, Loader, type LobsterPalette, type LobsterPaletteKey, type ColorFn as MarkdownColorFn, type NoteOptions, type RenderMarkdownOptions, type RenderTableOptions, type RestoreTerminalStateOptions, type SafeStreamWriter, type SafeStreamWriterOptions, Search, type StatusKind, type TableColumn, type WrapNoteMessageOptions, cancelSymbol, clearActiveProgressLine, colorize, createSafeStreamWriter, displayPath, displayString, emitJsonError, emitJsonOk, expandHomePrefix, formatCommandExample, formatCount, formatEmptyMessage, formatError, formatHeading, formatInfo, formatKeyValue, formatListItem, formatRootLink, formatRootedLink, formatSeparator, formatStatus, formatSuccess, formatTerminalLink, formatWarning, isRich, note, registerActiveProgressLine, renderMarkdown, renderTable, resolveConfigDir, resolveEffectiveHomeDir, resolveHomeDir, resolveRequiredHomeDir, resolveUserPath, restoreTerminalState, selectStyled, shortenHomeInString, shortenHomePath, stripAnsi, styleHealthChannelLine, stylePromptHint, stylePromptMessage, stylePromptTitle, theme, unregisterActiveProgressLine, visibleWidth, wrapNoteMessage };
package/dist/index.mjs CHANGED
@@ -1,11 +1,17 @@
1
- import be,{Chalk}from'chalk';import Ae from'fs';import J from'os';import q from'path';import {Filesystem}from'@easbot/utils';import {note,select}from'@clack/prompts';var pe="\\x1b\\[[0-9;]*m",he="\\x1b\\]8;;.*?\\x1b\\\\|\\x1b\\]8;;\\x1b\\\\",ge=new RegExp(pe,"g"),xe=new RegExp(he,"g");function te(e){return !e||e.length===0?"":e.replace(xe,"").replace(ge,"")}function R(e){return !e||e.length===0?0:Array.from(te(e)).length}var y={accent:"#FF5A2D",accentBright:"#FF7A3D",accentDim:"#D14A22",info:"#FF8A5B",success:"#2FBF71",warn:"#FFB020",error:"#E23D2D",muted:"#8B7F77"};var Ee=typeof process.env.FORCE_COLOR=="string"&&process.env.FORCE_COLOR.trim().length>0&&process.env.FORCE_COLOR.trim()!=="0",U=process.env.NO_COLOR&&!Ee?new Chalk({level:0}):be,L=e=>U.hex(e),m={accent:L(y.accent),accentBright:L(y.accentBright),accentDim:L(y.accentDim),info:L(y.info),success:L(y.success),warn:L(y.warn),error:L(y.error),muted:L(y.muted),heading:U.bold.hex(y.accent),command:L(y.accentBright),option:L(y.warn)},S=()=>U.level>0,E=(e,r,n)=>e?r(n):n;function ke(e){let r=S();return E(r,m.success,"\u2713")+` ${e}`}function ve(e){let r=S();return E(r,m.error,"\u2717")+` ${e}`}function $e(e){let r=S();return E(r,m.warn,"\u26A0")+` ${e}`}function We(e){let r=S();return E(r,m.info,"\u2139")+` ${e}`}function we(e){let r=S();return E(r,m.heading,e)}function Te(e,r,n=15){let i=S(),o=e.padEnd(n);return `${E(i,m.muted,o)} ${r}`}function ye(e,r){let n=S(),i=E(n,m.command,e);if(!r)return ` ${i}`;let o=E(n,m.muted,`# ${r}`);return ` ${i} ${o}`}function Pe(e,r,n){let i=S(),o=E(i,m.info,e),l=E(i,m.command,r),d=n?` ${E(i,m.muted,n)}`:"";return `${o} ${l}${d}`}function Oe(e,r){let n=S(),i,o;switch(e){case "pending":i="\u25CB",o=m.muted;break;case "running":i="\u25CF",o=m.info;break;case "success":i="\u2713",o=m.success;break;case "error":i="\u2717",o=m.error;break;case "skipped":i="\u25CB",o=m.muted;break}return E(n,o,i)+` ${r}`}function Re(e=80,r="\u2500"){let n=S();return E(n,m.muted,r.repeat(e))}function Le(e){let r=S();return E(r,m.muted,e)}function Ce(e,r,n){let i=S(),o=e===1?r:n||`${r}s`;return `${E(i,m.accent,String(e))} ${o}`}function C(e){let r=e?.trim();return r?Filesystem.toUnixPath(r):void 0}function D(e=process.env,r=J.homedir){let n=Ne(e,r);return n?Filesystem.resolve(n):void 0}function Ne(e,r){let n=C(e.EASBOT_HOME);if(n){if(n==="~"||n.startsWith("~/")||n.startsWith("~\\")){let l=C(e.HOME)??C(e.USERPROFILE)??ne(r);return l?n.replace(/^~(?=$|[\\/])/,l):void 0}return n}let i=C(e.HOME);if(i)return i;let o=C(e.USERPROFILE);return o||ne(r)}function ne(e){try{return C(e())}catch{return}}function B(e=process.env,r=J.homedir){return D(e,r)??Filesystem.resolve(process.cwd())}function K(e,r){if(!e.startsWith("~"))return C(e);let n=process.env.EASBOT_TEST_HOME?.trim();return n||(n=C(r?.home)??D(r?.env??process.env,r?.homedir??J.homedir)),n?e.replace(/^~(?=$|[\\/])/,n):C(e)}function oe(e){if(!e)return "";let r=e.trim();if(!r)return r;if(r.startsWith("~")){let n=K(r,{home:B(process.env,J.homedir),env:process.env,homedir:J.homedir});return q.resolve(n)}return q.resolve(r)}function Ie(e=process.env,r=J.homedir){let n=e.OPENCLAW_STATE_DIR?.trim()||e.CLAWDBOT_STATE_DIR?.trim();if(n)return oe(n);let i=q.join(B(e,r),".openclaw");try{if(Ae.existsSync(i))return i}catch{}return i}function ie(){return D(process.env,J.homedir)}function se(){let e=ie();return e?process.env.EASBOT_HOME?.trim()?{home:e,prefix:"$EASBOT_HOME"}:{home:e,prefix:"~"}:void 0}function ce(e){if(!e)return e;let r=se();if(!r)return e;let{home:n,prefix:i}=r;return e===n?i:e.startsWith(`${n}/`)||e.startsWith(`${n}\\`)?`${i}${e.slice(n.length)}`:e}function ae(e){if(!e)return e;let r=se();return r?e.split(r.home).join(r.prefix):e}function _e(e){return ce(e)}function G(e){return ae(e)}function j(e,r,n){let o=e.replaceAll("\x1B",""),l=r.replaceAll("\x1B","");return (n?.force===true?true:n?.force===false?false:!!process.stdout.isTTY)?`\x1B]8;;${l}\x07${o}\x1B]8;;\x07`:n?.fallback??`${o} (${l})`}var F="https://docs.openclaw.ai";function He(e,r,n){let i=e.trim(),o=i.startsWith("http")?i:`${F}${i.startsWith("/")?i:`/${i}`}`;return j(r??o,o,{fallback:n?.fallback??o,force:n?.force})}function Me(e){return j(e??F,F,{fallback:F})}function De(e,r){let n={ok:true,data:e};r!==void 0&&(n.meta=r),console.log(JSON.stringify(n,null,2));}function Fe(e,r){console.log(JSON.stringify({ok:false,error:{code:e,message:r}},null,2));}var X=e=>S()?m.accent(e):e,Z=e=>e&&S()?m.heading(e):e,Q=e=>e&&S()?m.muted(e):e;var Je=/^(https?:\/\/|file:\/\/)/i,je=/^[a-zA-Z]:[\\/]/,ze=/^[a-zA-Z0-9._-]+$/;function fe(e,r){if(r<=0)return [e];let n=Array.from(e),i=[];for(let o=0;o<n.length;o+=r)i.push(n.slice(o,o+r).join(""));return i.length>0?i:[e]}function ue(e){return e?Je.test(e)||e.startsWith("/")||e.startsWith("~/")||e.startsWith("./")||e.startsWith("../")||je.test(e)||e.startsWith("\\\\")||e.includes("/")||e.includes("\\")?true:e.includes("_")&&ze.test(e):false}function Ue(e,r){if(e.trim().length===0)return [e];if(r<=0)return [e];let n=e.match(/^(\s*)([-*\u2022]\s+)?(.*)$/),i=n?.[1]??"",o=n?.[2]??"",l=n?.[3]??"",d=`${i}${o}`,g=`${i}${o?" ".repeat(o.length):""}`,W=Math.max(10,r-R(d)),w=Math.max(10,r-R(g)),I=l.split(/\s+/).filter(Boolean),P=[],p="",x=d,k=W;for(let b of I){if(!p){if(R(b)>k){if(ue(b)){p=b;continue}let T=fe(b,k),f=T.shift()??"";P.push(x+f),x=g,k=w;for(let u of T)P.push(x+u);continue}p=b;continue}let N=`${p} ${b}`;if(R(N)<=k){p=N;continue}if(P.push(x+p),x=g,k=w,R(b)>k){if(ue(b)){p=b;continue}let T=fe(b,k),f=T.shift()??"";P.push(x+f);for(let u of T)P.push(x+u);p="";continue}p=b;}return (p||I.length===0)&&P.push(x+p),P}function le(e,r={}){let n=r.columns??process.stdout.columns??80,i=r.maxWidth??Math.max(40,Math.min(88,n-10));return e.split(`
2
- `).flatMap(o=>Ue(o,i)).join(`
3
- `)}function Ve(e,r){note(le(e),Z(r));}var H=null;function Ye(e){e.isTTY&&(H=e);}function ee(){H?.isTTY&&H.write("\r\x1B[2K");}function Ke(e){H&&(e&&H!==e||(H=null));}function Ge(e){return select({...e,message:X(e.message),options:e.options.map(r=>r.hint===void 0?r:{...r,hint:Q(r.hint)})})}var Xe="\x1B[0m\x1B[?25h\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?2004l";function z(e,r,n){let i=n?` (${n})`:"",o=`[terminal] restore ${e} failed${i}: ${String(r)}`;try{process.stderr.write(`${o}
4
- `);}catch(l){console.error(`[terminal] restore reporting failed${i}: ${String(l)}`);}}function Ze(e,r={}){let n=r.resumeStdinIfPaused??r.resumeStdin??false;try{ee();}catch(o){z("progress line",o,e);}let i=process.stdin;if(i.isTTY&&typeof i.setRawMode=="function"){try{i.setRawMode(!1);}catch(o){z("raw mode",o,e);}if(n&&typeof i.isPaused=="function"&&i.isPaused())try{i.resume();}catch(o){z("stdin resume",o,e);}}if(process.stdout.isTTY)try{process.stdout.write(Xe);}catch(o){z("stdout reset",o,e);}}function Qe(e){let r=e?.code;return r==="EPIPE"||r==="EIO"}function er(e={}){let r=false,n=false,i=(g,W)=>{n||(n=true,e.onBrokenPipe?.(g,W));},o=(g,W)=>{if(!Qe(g))throw g;return r=true,i(g,W),false},l=(g,W)=>{if(r)return false;try{e.beforeWrite?.();}catch(w){return o(w,process.stderr)}try{return g.write(W),!r}catch(w){return o(w,g)}};return {write:l,writeLine:(g,W)=>l(g,`${W}
5
- `),reset:()=>{r=false,n=false;},isClosed:()=>r}}function M(e,r){return !Number.isFinite(r)||r<=0?"":e.repeat(r)}function rr(e,r,n){let i=R(e);if(i>=r)return e;let o=r-i;if(n==="right")return `${M(" ",o)}${e}`;if(n==="center"){let l=Math.floor(o/2),d=o-l;return `${M(" ",l)}${e}${M(" ",d)}`}return `${e}${M(" ",o)}`}function tr(e,r){if(!e||e.length===0)return [""];if(!Number.isFinite(r)||r<=0)return [e];let n="\x1B",i=[];for(let t=0;t<e.length;){if(e[t]===n){if(e[t+1]==="["){let a=t+2;for(;a<e.length;){let h=e[a];if(h==="m")break;if(h&&h>="0"&&h<="9"){a+=1;continue}if(h===";"){a+=1;continue}break}if(e[a]==="m"){i.push({kind:"ansi",value:e.slice(t,a+1)}),t=a+1;continue}}if(e[t+1]==="]"&&e.slice(t+2,t+5)==="8;;"){let a=e.indexOf(`${n}\\`,t+5);if(a>=0){i.push({kind:"ansi",value:e.slice(t,a+2)}),t=a+2;continue}}}let s=e.codePointAt(t);if(!s)break;let c=String.fromCodePoint(s);i.push({kind:"char",value:c}),t+=c.length;}let o=i.findIndex(t=>t.kind==="char");if(o<0)return [e];let l=-1;for(let t=i.length-1;t>=0;t-=1){let s=i[t];if(s&&s.kind==="char"){l=t;break}}let d=i.slice(0,o).filter(t=>t.kind==="ansi").map(t=>t.value).join(""),g=i.slice(l+1).filter(t=>t.kind==="ansi").map(t=>t.value).join(""),W=i.slice(o,l+1),w=[],I=t=>t===" "||t===" "||t==="/"||t==="-"||t==="_"||t===".",P=t=>t===" "||t===" ",p=false,x=[],k=0,b=null,N=t=>(t??x).map(s=>s.value).join(""),T=t=>t.reduce((s,c)=>s+(c.kind==="char"?1:0),0),f=t=>{let s=t.replace(/\s+$/,"");s.trim().length!==0&&w.push(s);},u=t=>{if(x.length===0)return;if(t==null||t<=0){f(N()),x.length=0,k=0,b=null;return}let s=x.slice(0,t),c=x.slice(t);for(f(N(s));c.length>0;){let a=c[0];if(a?.kind!=="char"||!P(a.value))break;c.shift();}x.length=0,x.push(...c),k=T(x),b=null;};for(let t of W){if(t.kind==="ansi"){x.push(t);continue}let s=t.value;if(!(p&&(p=false,s===`
6
- `))){if(s===`
7
- `||s==="\r"){u(x.length),s==="\r"&&(p=true);continue}k+1>r&&k>0&&u(b),x.push(t),k+=1,I(s)&&(b=x.length);}}return u(x.length),w.length===0?[""]:!d&&!g?w:w.map(t=>t&&`${d}${t}${g}`)}function nr(e){if(e!=null&&!(!Number.isFinite(e)||e<=0))return Math.floor(e)}function or(e){let r=e.rows.map(f=>{let u={};for(let[t,s]of Object.entries(f))u[t]=G(s);return u}),n=e.border??"unicode";if(n==="none"){let f=e.columns;return `${[f.map(s=>s.header).join(" | "),...r.map(s=>f.map(c=>s[c.key]??"").join(" | "))].join(`
1
+ import de,{Chalk}from'chalk';import le from'os';import ve from'path';import {Filesystem}from'@easbot/utils';import {note,select}from'@clack/prompts';import fe from'process';import*as me from'readline';import {stripVTControlCharacters}from'util';import {Writable}from'stream';var bt="\\x1b\\[[0-9;]*m",St="\\x1b\\]8;;.*?\\x1b\\\\|\\x1b\\]8;;\\x1b\\\\",$t=new RegExp(bt,"g"),vt=new RegExp(St,"g");function re(e){return e?e.replace(vt,"").replace($t,""):""}function j(e){return e?Array.from(re(e)).length:0}var J={accent:"#FF5A2D",accentBright:"#FF7A3D",accentDim:"#D14A22",info:"#FF8A5B",success:"#2FBF71",warn:"#FFB020",error:"#E23D2D",muted:"#8B7F77"};var yt=typeof process.env.FORCE_COLOR=="string"&&process.env.FORCE_COLOR.trim().length>0&&process.env.FORCE_COLOR.trim()!=="0",xe=process.env.NO_COLOR&&!yt?new Chalk({level:0}):de,V=e=>xe.hex(e),b={accent:V(J.accent),accentBright:V(J.accentBright),accentDim:V(J.accentDim),info:V(J.info),success:V(J.success),warn:V(J.warn),error:V(J.error),muted:V(J.muted),heading:xe.bold.hex(J.accent),command:V(J.accentBright),option:V(J.warn)},k=()=>xe.level>0,y=(e,t,r)=>e?t(r):r;function wt(e){return y(k(),b.success,"\u2713")+` ${e}`}function Et(e){return y(k(),b.error,"\u2717")+` ${e}`}function Rt(e){return y(k(),b.warn,"\u26A0")+` ${e}`}function It(e){return y(k(),b.info,"\u2139")+` ${e}`}function kt(e){return y(k(),b.heading,e)}function Ot(e,t,r=15){let s=e.padEnd(r);return `${y(k(),b.muted,s)} ${t}`}function Wt(e,t){let r=k(),s=y(r,b.command,e);if(!t)return ` ${s}`;let c=y(r,b.muted,`# ${t}`);return ` ${s} ${c}`}function Lt(e,t,r){let s=k(),c=y(s,b.info,e),f=y(s,b.command,t),m=r?` ${y(s,b.muted,r)}`:"";return `${c} ${f}${m}`}var Mt={pending:{icon:"\u25CB",color:b.muted},running:{icon:"\u25CF",color:b.info},success:{icon:"\u2713",color:b.success},error:{icon:"\u2717",color:b.error},skipped:{icon:"\u25CB",color:b.muted}};function Pt(e,t){let{icon:r,color:s}=Mt[e];return y(k(),s,r)+` ${t}`}function Ft(e=80,t="\u2500"){return y(k(),b.muted,t.repeat(e))}function Nt(e){return y(k(),b.muted,e)}function At(e,t,r){let s=e===1?t:r||`${t}s`;return `${y(k(),b.accent,String(e))} ${s}`}function K(e){let t=e?.trim();return t?Filesystem.toUnixPath(t):void 0}function De(e){try{return K(e())}catch{return}}function _t(e,t){let r=K(e.EASBOT_TEST_HOME);if(r)return r;let s=K(e.EASBOT_HOME);if(s){if(s==="~"||s.startsWith("~/")||s.startsWith("~\\")){let m=K(e.HOME)??K(e.USERPROFILE)??De(t);return m?s.replace(/^~(?=$|[\\/])/,m):void 0}return s}let c=K(e.HOME);if(c)return c;let f=K(e.USERPROFILE);return f||De(t)}function Q(e=process.env,t=le.homedir){let r=_t(e,t);if(r)return r}function Se(e=process.env,t=le.homedir){return Q(e,t)??Filesystem.resolve(process.cwd())}function $e(e,t){if(!e.startsWith("~"))return K(e);let r=process.env.EASBOT_TEST_HOME?.trim();return r||(r=K(t?.home)??Q(t?.env??process.env,t?.homedir??le.homedir)),r?e.replace(/^~(?=$|[\\/])/,r):K(e)}function Ve(e){if(!e)return "";let t=e.trim();if(!t)return t;if(t.startsWith("~")){let r=$e(t,{home:Se(process.env,le.homedir),env:process.env,homedir:le.homedir});return ve.resolve(r)}return ve.resolve(t)}function Ht(e=process.env,t=le.homedir){let r=e.EASBOT_STATE_DIR?.trim();if(r)return Ve(r);let c=Q(e,t)??process.cwd();return ve.join(c,".config","easbot")}function Ke(){return Q(process.env,le.homedir)}function ze(){let e=Ke();return e?process.env.EASBOT_TEST_HOME?.trim()?{home:e,prefix:"~"}:process.env.EASBOT_HOME?.trim()?{home:e,prefix:"$EASBOT_HOME"}:{home:e,prefix:"~"}:void 0}function Ye(e){if(!e)return e;let t=ze();if(!t)return e;let{home:r,prefix:s}=t;return e===r?s:e.startsWith(`${r}/`)||e.startsWith(`${r}\\`)?`${s}${e.slice(r.length)}`:e}function Ue(e){if(!e)return e;let t=ze();return t?e.split(t.home).join(t.prefix):e}function Bt(e){return Ye(e)}function Te(e){return Ue(e)}function Jt(e,t){return e?.force===true?true:e?.force===false?false:!!(t??process.stdout?.isTTY)}function oe(e,t,r,s){let c=re(e??""),f=re(t??"");return Jt(r,s)?`\x1B]8;;${f}\x07${c}\x1B]8;;\x07`:r?.fallback??`${c} (${f})`}function Dt(e,t,r,s,c){let f=t.trim();if(!e)return oe(r??f,f,s,c);let m=/^[a-z]+:\/\//i.test(f)?f:`${e}${f.startsWith("/")?f:`/${f}`}`;return oe(r??m,m,s,c)}function jt(e,t,r){return oe(t??e,e,void 0,r)}function Vt(e,t){let r={ok:true,data:e};t!==void 0&&(r.meta=t),console.log(JSON.stringify(r,null,2));}function Kt(e,t){console.log(JSON.stringify({ok:false,error:{code:e,message:t}},null,2));}var Ce=e=>k()?b.accent(e):e,ye=e=>e&&k()?b.heading(e):e,we=e=>e&&k()?b.muted(e):e;var Yt=/^(https?:\/\/|file:\/\/)/i,Ut=/^[a-zA-Z]:[\\/]/,Gt=/^[a-zA-Z0-9._-]+$/;function Ge(e,t){if(t<=0)return [e];let r=Array.from(e),s=[];for(let c=0;c<r.length;c+=t)s.push(r.slice(c,c+t).join(""));return s.length>0?s:[e]}function qe(e){return e?Yt.test(e)||e.startsWith("/")||e.startsWith("~/")||e.startsWith("./")||e.startsWith("../")||Ut.test(e)||e.startsWith("\\\\")||e.includes("/")||e.includes("\\")?true:e.includes("_")&&Gt.test(e):false}function qt(e,t){if(e.trim().length===0)return [e];if(t<=0)return [e];let r=e.match(/^(\s*)([-*\u2022]\s+)?(.*)$/),s=r?.[1]??"",c=r?.[2]??"",f=r?.[3]??"",m=`${s}${c}`,a=`${s}${c?" ".repeat(c.length):""}`,v=Math.max(10,t-j(m)),$=Math.max(10,t-j(a)),E=f.split(/\s+/).filter(Boolean),O=[],h="",o=m,l=v;for(let T of E){if(!h){if(j(T)>l){if(qe(T)){h=T;continue}let w=Ge(T,l),S=w.shift()??"";O.push(o+S),o=a,l=$;for(let p of w)O.push(o+p);continue}h=T;continue}let n=`${h} ${T}`;if(j(n)<=l){h=n;continue}if(O.push(o+h),o=a,l=$,j(T)>l){if(qe(T)){h=T;continue}let w=Ge(T,l),S=w.shift()??"";O.push(o+S);for(let p of w)O.push(o+p);h="";continue}h=T;}return (h||E.length===0)&&O.push(o+h),O}function Qe(e,t={}){let r=process.stdout?.columns??80,s=t.columns??r,c=t.maxWidth??Math.max(40,Math.min(88,s-10));return e.split(`
2
+ `).flatMap(f=>qt(f,c)).join(`
3
+ `)}function Qt(e,t,r={}){let s=r.columns??process.stdout?.columns,c=Qe(e,{columns:s,maxWidth:r.maxWidth});note(c,ye(t));}var X=null;function Xt(e,t){try{e.write(t);}catch{}}function Zt(e){e.isTTY&&(X=e);}function Ee(){X?.isTTY&&Xt(X,"\r\x1B[2K");}function en(e){X&&(e&&X!==e||(X=null));}function nn(e){return select({...e,message:Ce(e.message),options:e.options.map(t=>t.hint===void 0?t:{...t,hint:we(t.hint)})})}var rn="\x1B[0m\x1B[?25h\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?2004l";function ue(e,t,r){let s=r?` (${r})`:"",c=`[terminal] restore ${e} failed${s}: ${String(t)}`;try{fe.stderr.write(`${c}
4
+ `);}catch(f){console.error(`[terminal] restore reporting failed${s}: ${String(f)}`);}}function on(e,t={}){let r=t.resumeStdinIfPaused??t.resumeStdin??false;try{Ee();}catch(c){ue("progress line",c,e);}let s=fe.stdin;if(s?.isTTY&&typeof s.setRawMode=="function"){try{s.setRawMode(!1);}catch(c){ue("raw mode",c,e);}if(r&&typeof s.isPaused=="function"&&s.isPaused())try{s.resume();}catch(c){ue("stdin resume",c,e);}}if(fe.stdout?.isTTY)try{fe.stdout.write(rn);}catch(c){ue("stdout reset",c,e);}}function cn(e){let t=e?.code;return t==="EPIPE"||t==="EIO"}function an(e={}){let t=false,r=false,s=(a,v)=>{r||(r=true,e.onBrokenPipe?.(a,v));},c=(a,v)=>{if(!cn(a))throw a;return t=true,s(a,v),false},f=(a,v)=>{if(t)return false;try{e.beforeWrite?.();}catch($){return c($,fe.stderr)}try{return a.write(v),!t}catch($){return c($,a)}};return {write:f,writeLine:(a,v)=>f(a,`${v}
5
+ `),reset:()=>{t=false,r=false;},isClosed:()=>t}}function Z(e,t){return !Number.isFinite(t)||t<=0?"":e.repeat(t)}function ln(e,t,r){let s=j(e);if(s>=t)return e;let c=t-s;if(r==="right")return `${Z(" ",c)}${e}`;if(r==="center"){let f=Math.floor(c/2),m=c-f;return `${Z(" ",f)}${e}${Z(" ",m)}`}return `${e}${Z(" ",c)}`}function un(e,t){if(!e||e.length===0)return [""];if(!Number.isFinite(t)||t<=0)return [e];let r="\x1B",s=[];for(let i=0;i<e.length;){if(e[i]===r){if(e[i+1]==="["){let g=i+2;for(;g<e.length;){let C=e[g];if(C==="m")break;if(C&&C>="0"&&C<="9"){g+=1;continue}if(C===";"){g+=1;continue}break}if(e[g]==="m"){s.push({kind:"ansi",value:e.slice(i,g+1)}),i=g+1;continue}}if(e[i+1]==="]"&&e.slice(i+2,i+5)==="8;;"){let g=e.indexOf(`${r}\\`,i+5);if(g>=0){s.push({kind:"ansi",value:e.slice(i,g+2)}),i=g+2;continue}}}let u=e.codePointAt(i);if(!u)break;let x=String.fromCodePoint(u);s.push({kind:"char",value:x}),i+=x.length;}let c=s.findIndex(i=>i.kind==="char");if(c<0)return [e];let f=-1;for(let i=s.length-1;i>=0;i-=1){let u=s[i];if(u&&u.kind==="char"){f=i;break}}let m=s.slice(0,c).filter(i=>i.kind==="ansi").map(i=>i.value).join(""),a=s.slice(f+1).filter(i=>i.kind==="ansi").map(i=>i.value).join(""),v=s.slice(c,f+1),$=[],E=i=>i===" "||i===" "||i==="/"||i==="-"||i==="_"||i===".",O=i=>i===" "||i===" ",h=false,o=[],l=0,T=null,n=i=>(i??o).map(u=>u.value).join(""),w=i=>i.reduce((u,x)=>u+(x.kind==="char"?1:0),0),S=i=>{let u=i.replace(/\s+$/,"");u.trim().length!==0&&$.push(u);},p=i=>{if(o.length===0)return;if(i==null||i<=0){S(n()),o.length=0,l=0,T=null;return}let u=o.slice(0,i),x=o.slice(i);for(S(n(u));x.length>0;){let g=x[0];if(g?.kind!=="char"||!O(g.value))break;x.shift();}o.length=0,o.push(...x),l=w(o),T=null;};for(let i of v){if(i.kind==="ansi"){o.push(i);continue}let u=i.value;if(!(h&&(h=false,u===`
6
+ `))){if(u===`
7
+ `||u==="\r"){p(o.length),u==="\r"&&(h=true);continue}l+1>t&&l>0&&p(T),o.push(i),l+=1,E(u)&&(T=o.length);}}return p(o.length),$.length===0?[""]:!m&&!a?$:$.map(i=>i&&`${m}${i}${a}`)}function fn(e){if(e!=null&&!(!Number.isFinite(e)||e<=0))return Math.floor(e)}function dn(e){let t=e.rows.map(S=>{let p={};for(let[i,u]of Object.entries(S))p[i]=Te(u);return p}),r=e.border??"unicode";if(r==="none"){let S=e.columns;return `${[S.map(u=>u.header).join(" | "),...t.map(u=>S.map(x=>u[x.key]??"").join(" | "))].join(`
8
8
  `)}
9
- `}let i=Math.max(0,e.padding??1),o=e.columns,l=o.map(f=>{let u=R(f.header),t=Math.max(0,...r.map(s=>R(s[f.key]??"")));return {headerW:u,cellW:t}}),d=o.map((f,u)=>{let t=l[u];if(!t)throw new Error(`Internal error: metrics[${u}] is undefined`);let s=Math.max(t.headerW,t.cellW)+i*2,c=f.maxWidth?Math.min(s,f.maxWidth):s;return Math.max(f.minWidth??3,c)}),g=nr(e.width),W=o.length+1,w=d.reduce((f,u)=>f+u,0)+W,I=o.map((f,u)=>{let t=l[u];if(!t)throw new Error(`Internal error: metrics[${u}] is undefined`);return Math.max(f.minWidth??3,t.headerW+i*2,3)}),P=o.map((f,u)=>{let t=l[u];if(!t)throw new Error(`Internal error: metrics[${u}] is undefined`);return Math.max(t.headerW+i*2,3)});if(g&&w>g){let f=w-g,u=o.map((c,a)=>{let h=d[a];if(h===void 0)throw new Error(`Internal error: widths[${a}] is undefined`);return {i:a,w:h}}).filter(({i:c})=>!!o[c]?.flex).toSorted((c,a)=>a.w-c.w).map(c=>c.i),t=o.map((c,a)=>{let h=d[a];if(h===void 0)throw new Error(`Internal error: widths[${a}] is undefined`);return {i:a,w:h}}).filter(({i:c})=>!o[c]?.flex).toSorted((c,a)=>a.w-c.w).map(c=>c.i),s=(c,a)=>{for(;f>0;){let h=false;for(let O of c){let A=d[O],_=a[O];if(!(A===void 0||_===void 0)&&!(A<=_)&&(d[O]=A-1,f-=1,h=true,f<=0))break}if(!h)break}};s(u,I),s(u,P),s(t,I),s(t,P);}if(g){let f=o.length+1,u=d.reduce((s,c)=>s+c,0)+f,t=g-u;if(t>0){let s=o.map((c,a)=>({c,i:a})).filter(({c})=>!!c.flex).map(({i:c})=>c);if(s.length>0){let c=o.map(a=>typeof a.maxWidth=="number"&&a.maxWidth>0?Math.floor(a.maxWidth):Number.POSITIVE_INFINITY);for(;t>0;){let a=false;for(let h of s){let O=d[h],A=c[h];if(!(O===void 0||A===void 0)&&!(O>=A)&&(d[h]=O+1,t-=1,a=true,t<=0))break}if(!a)break}}}}let p=n==="ascii"?{tl:"+",tr:"+",bl:"+",br:"+",h:"-",v:"|",t:"+",ml:"+",m:"+",mr:"+",b:"+"}:{tl:"\u250C",tr:"\u2510",bl:"\u2514",br:"\u2518",h:"\u2500",v:"\u2502",t:"\u252C",ml:"\u251C",m:"\u253C",mr:"\u2524",b:"\u2534"},x=(f,u,t)=>`${f}${d.map(s=>{if(s===void 0)throw new Error("Internal error: width is undefined");return M(p.h,s)}).join(u)}${t}`,k=f=>{let u=d[f];if(u===void 0)throw new Error(`Internal error: widths[${f}] is undefined`);return Math.max(1,u-i*2)},b=M(" ",i),N=(f,u=false)=>{let s=o.map(h=>u?h.header:f[h.key]??"").map((h,O)=>tr(h,k(O))),c=Math.max(...s.map(h=>h.length)),a=[];for(let h=0;h<c;h+=1){let O=s.map((A,_)=>{let me=A[h]??"",re=o[_];if(!re)throw new Error(`Internal error: columns[${_}] is undefined`);let de=rr(me,k(_),re.align??"left");return `${b}${de}${b}`});a.push(`${p.v}${O.join(p.v)}${p.v}`);}return a},T=[];T.push(x(p.tl,p.t,p.tr)),T.push(...N({},true)),T.push(x(p.ml,p.m,p.mr));for(let f of r)T.push(...N(f,false));return T.push(x(p.bl,p.b,p.br)),`${T.join(`
9
+ `}let s=Math.max(0,e.padding??1),c=e.columns,f=c.map(S=>{let p=j(S.header),i=Math.max(0,...t.map(u=>j(u[S.key]??"")));return {headerW:p,cellW:i}}),m=c.map((S,p)=>{let i=f[p];if(!i)throw new Error(`Internal error: metrics[${p}] is undefined`);let u=Math.max(i.headerW,i.cellW)+s*2,x=S.maxWidth?Math.min(u,S.maxWidth):u;return Math.max(S.minWidth??3,x)}),a=fn(e.width),v=c.length+1,$=m.reduce((S,p)=>S+p,0)+v,E=c.map((S,p)=>{let i=f[p];if(!i)throw new Error(`Internal error: metrics[${p}] is undefined`);return Math.max(S.minWidth??3,i.headerW+s*2,3)}),O=c.map((S,p)=>{let i=f[p];if(!i)throw new Error(`Internal error: metrics[${p}] is undefined`);return Math.max(i.headerW+s*2,3)});if(a&&$>a){let S=$-a,p=c.map((x,g)=>{let C=m[g];if(C===void 0)throw new Error(`Internal error: widths[${g}] is undefined`);return {i:g,w:C}}).filter(({i:x})=>!!c[x]?.flex).toSorted((x,g)=>g.w-x.w).map(x=>x.i),i=c.map((x,g)=>{let C=m[g];if(C===void 0)throw new Error(`Internal error: widths[${g}] is undefined`);return {i:g,w:C}}).filter(({i:x})=>!c[x]?.flex).toSorted((x,g)=>g.w-x.w).map(x=>x.i),u=(x,g)=>{for(;S>0;){let C=false;for(let _ of x){let F=m[_],H=g[_];if(!(F===void 0||H===void 0)&&!(F<=H)&&(m[_]=F-1,S-=1,C=true,S<=0))break}if(!C)break}};u(p,E),u(p,O),u(i,E),u(i,O);}if(a){let S=c.length+1,p=m.reduce((u,x)=>u+x,0)+S,i=a-p;if(i>0){let u=c.map((x,g)=>({c:x,i:g})).filter(({c:x})=>!!x.flex).map(({i:x})=>x);if(u.length>0){let x=c.map(g=>typeof g.maxWidth=="number"&&g.maxWidth>0?Math.floor(g.maxWidth):Number.POSITIVE_INFINITY);for(;i>0;){let g=false;for(let C of u){let _=m[C],F=x[C];if(!(_===void 0||F===void 0)&&!(_>=F)&&(m[C]=_+1,i-=1,g=true,i<=0))break}if(!g)break}}}}let h=r==="ascii"?{tl:"+",tr:"+",bl:"+",br:"+",h:"-",v:"|",t:"+",ml:"+",m:"+",mr:"+",b:"+"}:{tl:"\u250C",tr:"\u2510",bl:"\u2514",br:"\u2518",h:"\u2500",v:"\u2502",t:"\u252C",ml:"\u251C",m:"\u253C",mr:"\u2524",b:"\u2534"},o=(S,p,i)=>`${S}${m.map(u=>{if(u===void 0)throw new Error("Internal error: width is undefined");return Z(h.h,u)}).join(p)}${i}`,l=S=>{let p=m[S];if(p===void 0)throw new Error(`Internal error: widths[${S}] is undefined`);return Math.max(1,p-s*2)},T=Z(" ",s),n=(S,p=false)=>{let u=c.map(C=>p?C.header:S[C.key]??"").map((C,_)=>un(C,l(_))),x=Math.max(...u.map(C=>C.length)),g=[];for(let C=0;C<x;C+=1){let _=u.map((F,H)=>{let W=F[C]??"",D=c[H];if(!D)throw new Error(`Internal error: columns[${H}] is undefined`);let M=ln(W,l(H),D.align??"left");return `${T}${M}${T}`});g.push(`${h.v}${_.join(h.v)}${h.v}`);}return g},w=[];w.push(o(h.tl,h.t,h.tr)),w.push(...n({},true)),w.push(o(h.ml,h.m,h.mr));for(let S of t)w.push(...n(S,false));return w.push(o(h.bl,h.b,h.br)),`${w.join(`
10
10
  `)}
11
- `}function ir(e,r){if(!r)return e;let n=e.indexOf(":");if(n===-1)return e;let i=e.slice(0,n+1),o=e.slice(n+1).trimStart(),l=o.toLowerCase(),d=(g,W)=>`${i} ${W(o.slice(0,g.length))}${o.slice(g.length)}`;return l.startsWith("failed")?d("failed",m.error):l.startsWith("ok")?d("ok",m.success):l.startsWith("linked")?d("linked",m.success):l.startsWith("configured")?d("configured",m.success):l.startsWith("not linked")?d("not linked",m.warn):l.startsWith("not configured")?d("not configured",m.muted):l.startsWith("unknown")?d("unknown",m.warn):e}export{F as DOCS_ROOT,y as LOBSTER_PALETTE,ee as clearActiveProgressLine,E as colorize,er as createSafeStreamWriter,_e as displayPath,G as displayString,Fe as emitJsonError,De as emitJsonOk,K as expandHomePrefix,ye as formatCommandExample,Ce as formatCount,He as formatDocsLink,Me as formatDocsRootLink,Le as formatEmptyMessage,ve as formatError,we as formatHeading,We as formatInfo,Te as formatKeyValue,Pe as formatListItem,Re as formatSeparator,Oe as formatStatus,ke as formatSuccess,j as formatTerminalLink,$e as formatWarning,S as isRich,Ve as note,Ye as registerActiveProgressLine,or as renderTable,Ie as resolveConfigDir,D as resolveEffectiveHomeDir,ie as resolveHomeDir,B as resolveRequiredHomeDir,oe as resolveUserPath,Ze as restoreTerminalState,Ge as selectStyled,ae as shortenHomeInString,ce as shortenHomePath,te as stripAnsi,ir as styleHealthChannelLine,Q as stylePromptHint,X as stylePromptMessage,Z as stylePromptTitle,m as theme,Ke as unregisterActiveProgressLine,R as visibleWidth,le as wrapNoteMessage};
11
+ `}var mn=[{prefix:"failed",color:b.error},{prefix:"ok",color:b.success},{prefix:"linked",color:b.success},{prefix:"configured",color:b.success},{prefix:"not linked",color:b.warn},{prefix:"not configured",color:b.muted},{prefix:"unknown",color:b.warn}];function pn(e,t){if(!t)return e;let r=e.indexOf(":");if(r===-1)return e;let s=e.slice(0,r+1),c=e.slice(r+1).trimStart(),f=c.toLowerCase();for(let{prefix:m,color:a}of mn)if(f.startsWith(m))return `${s} ${a(c.slice(0,m.length))}${c.slice(m.length)}`;return e}var xn=new Writable({write(e,t,r){r();}}),ie;(h=>{h.cancelSymbol=Symbol("Search.cancel");function t(o){let l=0;for(let T of o){let n=T.codePointAt(0);if(n===void 0||n===0)continue;let w=n>=4352&&n<=4447||n>=8986&&n<=8987||n>=9001&&n<=9002||n>=9193&&n<=9196||n===9200||n===9203||n>=9725&&n<=9726||n>=9748&&n<=9749||n>=9800&&n<=9811||n===9855||n===9875||n===9889||n>=9898&&n<=9899||n>=9917&&n<=9918||n>=9924&&n<=9925||n===9934||n===9940||n===9962||n>=9970&&n<=9971||n===9973||n===9978||n===9981||n===9989||n>=9994&&n<=9995||n===10024||n===10060||n===10062||n>=10067&&n<=10069||n===10071||n>=10133&&n<=10135||n===10160||n===10175||n>=11035&&n<=11036||n===11088||n===11093||n>=11904&&n<=42191&&n!==12351||n>=43360&&n<=43388||n>=44032&&n<=55203||n>=63744&&n<=64255||n>=65040&&n<=65049||n>=65072&&n<=65135||n>=65280&&n<=65376||n>=65504&&n<=65510||n>=126976&&n<=129535;l+=w?2:1;}return l}h.approxStringWidth=t;function r(o,l){let T=stripVTControlCharacters(o),n=Math.max(1,l),w=t(T);return Math.max(1,Math.ceil(w/n))}h.visualRowsForLine=r;function s(o,l){let T=l!==void 0&&l>0?l:process.stdout.columns&&process.stdout.columns>0?process.stdout.columns:80,n=0;for(let w of o)n+=r(w,T);return n}h.countVisualRowsForLines=s;function c(o){let l=new Array(o.length);for(let T=0;T<o.length;T++){let n=o[T],w=n.value===null||n.value===void 0?"":String(n.value);l[T]={...n,searchKey:`${n.label}
12
+ ${w}`.toLowerCase()};}return l}function f(o,l){return l===""||o.searchKey.includes(l)}function m(o,l){return l<=0||o<0?0:o>=l?l-1:o}function a(o){if(o?.length!==1)return false;let l=o.codePointAt(0);return !(l===void 0||l<32||l===127||l===27)}function v(){let o=process.stdout.rows;if(!o||o<=0)return 8;let l=Math.floor((o-8)/2);return Math.max(5,Math.min(15,l))}function $(o,l){try{o.write(l);}catch{}}function E(o){if(o&&o.isTTY&&typeof o.setRawMode=="function")try{o.setRawMode(!1);}catch{}}function O(o){let l=o.message,T=c(o.items),n=Math.max(1,o.maxVisible??v()),w=o.initialSelected??[],S=o.required??false,p=o.lockedSection,i=o.isTTY;i??!!process.stdout?.isTTY;return new Promise(x=>{let g=process.stdin,C=process.stdout,_=me.createInterface({input:g,output:xn,terminal:false});try{(i===!0||i===void 0&&g.isTTY)&&g.setRawMode?.(!0);}catch{}me.emitKeypressEvents(g,_);let F="",H="",W=0,D=new Set(w),M=0,G=false,Y=p?p.items.map(R=>R.value):[],pe=p?p.items.map(R=>R.label):[],se=[],We=()=>{if(se.length=0,H==="")for(let R=0;R<T.length;R++){let d=T[R];se.push(d);}else for(let R=0;R<T.length;R++){let d=T[R];f(d,H)&&se.push(d);}return se},Ze=()=>{if(M>0){$(C,`\x1B[${M}A`);for(let R=0;R<M;R++)$(C,"\x1B[2K\x1B[1B");$(C,`\x1B[${M}A`);}},Le=()=>{let R=pe.slice();for(let d=0;d<T.length;d++){let L=T[d];D.has(L.value)&&R.push(L.label);}return R},B=(R="active")=>{Ze();let d=[],L=We(),z=i===false?false:i===true?true:k(),_e=P=>y(z,b.error,P),ae=P=>y(z,b.success,P),I=P=>y(z,b.muted,P),ge=P=>y(z,b.heading,P),it=P=>y(z,b.accentBright,P),st=P=>y(z,de.bold,P),ct=P=>y(z,de.underline,P),at=P=>y(z,de.inverse,P),lt=P=>y(z,de.strikethrough,P),He=R==="active"||R==="error"?"\u25C6":R==="cancel"?"\u25A0":"\u25C7",ut=R==="cancel"||R==="error"?_e(He):ae(He);if(d.push(`${ut} ${st(l)}`),R==="active"||R==="error"){if(p&&p.items.length>0){d.push(I("\u2502"));let q=`${ge(p.title)} ${I("\u2500\u2500 always included")}`;d.push(`${I("\u2502")} ${I("\u2500\u2500")} ${q} ${I("\u2500".repeat(12))}`);for(let te of p.items)d.push(`${I("\u2502")} ${ae("\u2022")} ${ge(te.label)}`);p.hiddenCount&&p.hiddenCount>0&&d.push(`${I("\u2502")} ${I(`...and ${p.hiddenCount} more`)}`),d.push(I("\u2502")),d.push(`${I("\u2502")} ${I("\u2500\u2500")} ${ge("Additional agents")} ${I("\u2500".repeat(29))}`);}let P=`${I("\u2502")} ${I("Search:")} ${F}${at(" ")}`;d.push(P),d.push(`${I("\u2502")} ${I("\u2191\u2193 move \xB7 space select \xB7 enter confirm")}`),d.push(I("\u2502"));let ft=Math.max(0,L.length-n),dt=W-Math.floor(n/2),he=Math.max(0,Math.min(dt,ft)),Be=Math.min(L.length,he+n);if(L.length===0)d.push(`${I("\u2502")} ${I("No matches found")}`);else {for(let U=he;U<Be;U++){let ne=L[U],mt=D.has(ne.value),Je=U===W,pt=mt?ae("\u25CF"):I("\u25CB"),gt=Je?ct(ne.label):ne.label,ht=ne.hint?I(` (${ne.hint})`):"",xt=Je?it("\u276F"):" ";d.push(`${I("\u2502")} ${xt} ${pt} ${gt}${ht}`);}let q=he,te=L.length-Be;if(q>0||te>0){let U=[];q>0&&U.push(`\u2191 ${q} more`),te>0&&U.push(`\u2193 ${te} more`),d.push(`${I("\u2502")} ${I(U.join(" "))}`);}}d.push(I("\u2502"));let ee=Le();if(ee.length===0)d.push(`${I("\u2502")} ${I("Selected: (none)")}`);else {let q=ee.length<=3?ee.join(", "):`${ee.slice(0,3).join(", ")} +${ee.length-3} more`;d.push(`${I("\u2502")} ${ae("Selected:")} ${q}`);}R==="error"&&d.push(`${I("\u2502")} ${_e("\u26A0 Please select at least one item before submitting")}`),d.push(`${I("\u2514")}`);}else if(R==="submit"){let P=Le();d.push(`${I("\u2502")} ${I(P.join(", "))}`);}else d.push(`${I("\u2502")} ${lt(I("Cancelled"))}`);$(C,`${d.join(`
13
+ `)}
14
+ `);try{M=s(d,C.columns);}catch{M=d.length;}},Me=false,et=()=>{if(!Me){Me=true;try{g.removeListener("keypress",Ae),g.removeListener("end",Ne);}catch{}try{process.removeListener("SIGINT",ce),process.removeListener("SIGTERM",ce);}catch{}E(g);try{_.close();}catch{}}},Pe=R=>{G||(G=true,et(),x(R));},tt=()=>{if(S&&D.size===0&&Y.length===0){B("error");return}B("submit"),Pe([...Y,...Array.from(D)]);},Fe=()=>{B("cancel"),Pe(h.cancelSymbol);},Ne=()=>{Fe();},ce=()=>{E(g);},nt=R=>{let d=R[W];d&&(D.has(d.value)?D.delete(d.value):D.add(d.value));},rt=R=>{F+=R,H+=R.toLowerCase();},ot=()=>{F.length!==0&&(F=F.slice(0,-1),H=H.slice(0,-1));},Ae=(R,d)=>{if(!d)return;let L=We();if(W=m(W,L.length),d.name==="return"){tt();return}if(d.name==="escape"||d.ctrl&&d.name==="c"){Fe();return}if(d.name==="up"||d.name==="left"){L.length>0&&(W=m(W-1,L.length),B());return}if(d.name==="down"||d.name==="right"){L.length>0&&(W=m(W+1,L.length),B());return}if(d.name==="pageup"){L.length>0&&(W=m(W-n,L.length),B());return}if(d.name==="pagedown"){L.length>0&&(W=m(W+n,L.length),B());return}if(d.name==="home"){L.length>0&&(W=0,B());return}if(d.name==="end"){L.length>0&&(W=L.length-1,B());return}if(d.name==="space"){nt(L),B();return}if(d.name==="backspace"){F.length>0&&(ot(),W=0,B());return}!d.ctrl&&!d.meta&&a(d.sequence)&&(rt(d.sequence),W=0,B());};g.on("keypress",Ae),g.once("end",Ne),process.on("SIGINT",ce),process.on("SIGTERM",ce),B();})}h.multiselect=O;})(ie||(ie={}));var Re=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Ie=80,ke;(t=>{function e(r={}){let s=[...Re],c=Ie,f=0,m=null,a=r.message??"Loading...",v=r.spinnerColor??(o=>y(k(),b.accent,o)),$=r.messageColor??(o=>y(k(),b.muted,o)),E=o=>{s=o.frames!==void 0?[...o.frames]:[...Re],c=o.intervalMs!==void 0&&o.intervalMs>0?o.intervalMs:Ie,f=0;};r.indicator&&E(r.indicator);function O(){h(),!(s.length<=1)&&(m=setInterval(()=>{f=(f+1)%s.length;},c));}function h(){m!==null&&(clearInterval(m),m=null);}return {start:O,stop:h,isRunning(){return m!==null},line(){let o=s[f]??"";return `${o.length>0?`${v(o)} `:""}${$(a)}`},setMessage(o){a=o;},setIndicator(o){o?E(o):(s=[...Re],c=Ie,f=0),O();}}}t.create=e;})(ke||(ke={}));var bn=e=>y(k(),b.accent,e),Sn=e=>y(k(),b.muted,e),Oe;(m=>{function e(a){let v=a;typeof v.resume=="function"&&v.resume();}function t(a,v){try{a.write(v);}catch{}}function r(a,v,$){let E=a;for(let O=0;O<v.length;O+=1){let h=v[O],o=h.charCodeAt(0);if(o===3)return {buffer:E,done:true,line:""};if(o===4)return {buffer:E,done:true,line:E};if(o===10||o===13)return {buffer:"",done:true,line:E};if((o===8||o===127)){E=E.slice(0,-1);continue}E+=h;}return {buffer:E,done:false,line:""}}function s(a){return new Promise((v,$)=>{let{message:E,hint:O,defaultValue:h,hidden:o,input:l,output:T,messageColor:n,hintColor:w}=a,S=(n??bn)(E),p=O?` ${(w??Sn)(`(${O})`)}`:"",i=h?` [${h}]`:"",u=o?`${S}${p}: `:`${S}${p}${i}: `,x=l??fe.stdin,g=T??fe.stdout;t(g,u);let C="",_=false,F=M=>{_||(_=true,M(),x.off("data",H),x.off("end",W));},H=M=>{let G=typeof M=="string"?M:M.toString("utf8"),Y=r(C,G);if(C=Y.buffer,!Y.done)return;if(Y.line===""&&C===""&&!G.includes(`
15
+ `)&&!G.includes("\r")){F(()=>$(new Error("Input canceled")));return}let pe=Y.line.length===0&&h!==void 0?h:Y.line;F(()=>v(pe));},W=()=>{if(_)return;let M=C.length===0&&h!==void 0?h:C;F(()=>v(M));},D=M=>{if((typeof M=="string"?M:M.toString("utf8")).includes("")){F(()=>$(new Error("Input canceled")));return}H(M);};x.on("data",D),x.once("end",W),e(x);})}m.readText=s;async function c(a){let v=a.defaultValue!==false,E=(await s({message:a.message,hint:a.hint??`y/n, default ${v?"y":"n"}`,defaultValue:v?"y":"n",messageColor:a.messageColor,hintColor:a.hintColor,input:a.input,output:a.output})).trim().toLowerCase();return E===""?v:E==="y"||E==="yes"?true:E==="n"||E==="no"?false:c(a)}m.readConfirm=c;function f(a){return s({...a,hidden:true})}m.readPassword=f;})(Oe||(Oe={}));var $n=e=>y(k(),b.heading,e),vn=e=>y(k(),b.command,e),Tn=e=>y(k(),b.muted,e),Cn=e=>y(k(),b.warn,e),yn=e=>y(k(),b.accent,e);function wn(e,t,r,s,c,f){let m=e;return m=m.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(a,v,$)=>`${f(v)} (${$})`),m=m.replace(/`([^`]+)`/g,(a,v)=>c(v)),m=m.replace(/\*\*([^*]+)\*\*/g,(a,v)=>r(v)),m=m.replace(/(^|[^*])\*([^*]+)\*(?!\*)/g,(a,v,$)=>`${v}${s($)}`),m}function En(e,t={}){if(!e)return [];let r=t.headingColor??$n,s=t.boldColor??vn,c=t.italicColor??Tn,f=t.codeColor??Cn,m=t.linkColor??yn,a=n=>wn(n,r,s,c,f,m),v=e.replace(/\r\n/g,`
16
+ `).split(`
17
+ `),$=[],E=false,O=[],h="",o=0,l=true,T=()=>{if(O.length!==0){$.push(f(`\`\`\`${h}`));for(let n of O)$.push(f(n));$.push(f("```")),O=[],h="";}};for(let n of v){let w=n;if(w.trim().startsWith("```")){if(!E){T(),E=true,h=w.trim().slice(3).trim(),$.push(f(`\`\`\`${h}`)),l=false;continue}for(let u of O)$.push(f(u));O=[],$.push(f("```")),E=false,h="",l=false;continue}if(E){O.push(w);continue}let S=/^(#{1,3})\s+(.+)$/.exec(w);if(S){let u=S[1]??"#",x=S[2]??"";$.push(r(`${u} ${a(x)}`)),l=false;continue}if(/^(\s*[-*_])\s*\1\s*\1[-*_\s]*$/.test(w)||/^---\s*$/.test(w)||/^\*\*\*\s*$/.test(w)){$.push(f("\u2500".repeat(40))),l=true;continue}let p=/^\s*[-*]\s+(.+)$/.exec(w),i=/^\s*\d+\.\s+(.+)$/.exec(w);if(p){let u=p[1]??"";$.push(` \u2022 ${a(u)}`),o=0,l=false;continue}if(i){let u=i[1]??"";o+=1,$.push(` ${o}. ${a(u)}`),l=false;continue}if(w.trim()===""){l||$.push(""),l=true,o=0;continue}$.push(a(w)),l=false,o=0;}return E&&T(),$}var Vr=ie,Kr=ie.cancelSymbol;export{Oe as Input,J as LOBSTER_PALETTE,ke as Loader,Vr as Search,Kr as cancelSymbol,Ee as clearActiveProgressLine,y as colorize,an as createSafeStreamWriter,Bt as displayPath,Te as displayString,Kt as emitJsonError,Vt as emitJsonOk,$e as expandHomePrefix,Wt as formatCommandExample,At as formatCount,Nt as formatEmptyMessage,Et as formatError,kt as formatHeading,It as formatInfo,Ot as formatKeyValue,Lt as formatListItem,jt as formatRootLink,Dt as formatRootedLink,Ft as formatSeparator,Pt as formatStatus,wt as formatSuccess,oe as formatTerminalLink,Rt as formatWarning,k as isRich,Qt as note,Zt as registerActiveProgressLine,En as renderMarkdown,dn as renderTable,Ht as resolveConfigDir,Q as resolveEffectiveHomeDir,Ke as resolveHomeDir,Se as resolveRequiredHomeDir,Ve as resolveUserPath,on as restoreTerminalState,nn as selectStyled,Ue as shortenHomeInString,Ye as shortenHomePath,re as stripAnsi,pn as styleHealthChannelLine,we as stylePromptHint,Ce as stylePromptMessage,ye as stylePromptTitle,b as theme,en as unregisterActiveProgressLine,j as visibleWidth,Qe as wrapNoteMessage};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easbot/terminal",
3
- "version": "0.3.11",
3
+ "version": "0.3.12",
4
4
  "description": "Terminal interaction toolkit for the EASBOT ecosystem — themed colors, ANSI utilities, OSC-8 hyperlinks, command formatting, table rendering, styled prompts, safe stream writes, and terminal-state recovery",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -47,9 +47,8 @@
47
47
  "dependencies": {
48
48
  "@clack/prompts": "^1.7.0",
49
49
  "chalk": "^6.0.0",
50
- "picocolors": "^1.1.1",
51
- "@easbot/types": "0.3.11",
52
- "@easbot/utils": "0.3.11"
50
+ "@easbot/utils": "0.3.12",
51
+ "@easbot/types": "0.3.12"
53
52
  },
54
53
  "devDependencies": {
55
54
  "@types/node": "^25.6.2",