bfi-cli 0.1.89 → 0.1.92
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.md +40 -0
- package/dist/THIRD-PARTY-LICENSES.md.gz +0 -0
- package/dist/_chunks/agents2.mjs +15 -1
- package/dist/_chunks/config.mjs +141 -0
- package/dist/_chunks/libs/@clack/core.mjs +63 -58
- package/dist/_chunks/libs/@clack/prompts.mjs +48 -45
- package/dist/_chunks/libs/@kwsites/file-exists.mjs +10 -9
- package/dist/_chunks/libs/simple-git.mjs +4 -2
- package/dist/_chunks/package-plugin.mjs +595 -0
- package/dist/_chunks/package-skill-identity.mjs +18 -0
- package/dist/_chunks/registry-client.mjs +535 -0
- package/dist/_chunks/rolldown-runtime.mjs +1 -1
- package/dist/_chunks/skills.mjs +6 -3
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +875 -1097
- package/dist/mcp-codesearch/main.d.mts +1 -1
- package/dist/mcp-codesearch/main.mjs +17 -24
- package/dist/mcp-db/main.d.mts +1 -1
- package/dist/mcp-db/main.mjs +1 -1
- package/package.json +6 -2
- package/dist/THIRD-PARTY-LICENSES.md +0 -293
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# BFI CLI:技能包与可选插件
|
|
2
|
+
|
|
3
|
+
技能安装沿用 skills.sh 衍生安装器。技能包默认仍是技能的组合;插件导入、编辑、发布在同一个包的可选插件能力中管理,两者的内容和版本独立。
|
|
4
|
+
|
|
5
|
+
## 默认安装技能
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
bfi package install @team/kit --agent claude-code
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
默认不会安装 Hook、MCP 或原生插件。包内来源保留完整 `@namespace/skill`,不同空间的同名技能使用来源 hash 派生的独立安装目录,原始 SKILL.md 不改写;不再按裸 slug 合并。
|
|
12
|
+
|
|
13
|
+
旧安装记录不会静默迁移或批量删除;无法证明归属或没有确认卸载成功时保留记录并提示。独立 `bfi add` 的命名不因此改变。
|
|
14
|
+
|
|
15
|
+
## 明确选择插件
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
bfi package install @team/kit --as plugin --agent claude-code --version 1.0.0 --plan
|
|
19
|
+
bfi package install @team/kit --as plugin --agent claude-code --version 1.0.0 --export ./kit-1.0.0.zip
|
|
20
|
+
bfi package install ./kit.tgz --as plugin --agent codex --root bundle --version 1.0.0 --plan
|
|
21
|
+
bfi package list --as plugin --scope project
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- 当前 Claude Code、Codex、ZCode、CodeBuddy、Qwen Code 均为 **EXPORT_ONLY**。尚未取得完整运行时/安装归属证据,不执行原生安装或静默退回只装技能。
|
|
25
|
+
- `--plan` 只给计划/阻断原因;`--export` 原样导出归档,不计作安装。目标文件必须不存在,扩展名与源格式一致。
|
|
26
|
+
- 市场来源必须写完整名称 `@namespace/package`,不要求用户输入数据库 ID。未指定版本时只解析一次可见 stable;没有 stable 则要求明确版本,不猜 latest。
|
|
27
|
+
- 本地支持 zip/tgz/tar.gz,多根必须用 `--root` 选择;保留全部原始文件、执行位和未知字段,不自动转换各宿主格式。缺原生版本时可用 `--version` 描述本地导出身份,但不会改源文件或绕过市场正式发布的版本校验。
|
|
28
|
+
- `--scope project` 为默认;`--scope user`(或 `-g`)显式选择用户范围。插件独立使用 `.bfi/plugin-lock.json`,不与旧技能锁混用。
|
|
29
|
+
- 未知安装结果保留 PREPARED 并阻止盲目重试;更新/卸载必须证明精确来源、宿主、范围、版本及安装归属。
|
|
30
|
+
|
|
31
|
+
服务器插件功能默认开启;显式设置 `PACKAGE_PLUGIN_ENABLED=false` 时仍可使用既有技能包,但插件市场操作不可用。本地原始包计划/导出不等于服务器发布。
|
|
32
|
+
|
|
33
|
+
## 开发验证
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
pnpm exec vitest run src/commands/package.test.ts src/commands/package-plugin.test.ts src/lib/plugin src/test-utils.test.ts
|
|
37
|
+
pnpm build
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
官方样本用例需显式 `SKILLHUB_PLUGIN_FIXTURES`;不要为测试使用生产数据源或真实 Agent 用户配置。CLI 子进程测试工具使用临时 HOME 和环境白名单。完整限制、继承的失败用例、数据库发布门禁及本次测试事故见 `../docs/testing/package-plugin-release-checklist.md`。
|
|
Binary file
|
package/dist/_chunks/agents2.mjs
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
import { loadGlobalConfig } from "./config.mjs";
|
|
1
2
|
import { agents } from "./agents.mjs";
|
|
2
|
-
import { loadGlobalConfig } from "../cli.mjs";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import os from "node:os";
|
|
6
|
+
function parseCapabilities(json) {
|
|
7
|
+
if (!json) return null;
|
|
8
|
+
try {
|
|
9
|
+
const parsed = JSON.parse(json);
|
|
10
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
6
15
|
const CACHE_FILE = path.join(os.homedir(), ".bfi", "agents-cache.json");
|
|
7
16
|
function makeDetectInstalled(globalSkillsDir) {
|
|
8
17
|
return async () => {
|
|
@@ -45,9 +54,14 @@ function mapToAgentConfig(a) {
|
|
|
45
54
|
skillsDir: a.skillsDir,
|
|
46
55
|
globalSkillsDir: gsd,
|
|
47
56
|
sortOrder: typeof a.sortOrder === "number" ? a.sortOrder : 0,
|
|
57
|
+
capabilities: mapCapabilities(a),
|
|
48
58
|
detectInstalled: makeDetectInstalled(gsd)
|
|
49
59
|
};
|
|
50
60
|
}
|
|
61
|
+
function mapCapabilities(agent) {
|
|
62
|
+
if (typeof agent.capabilitiesJson === "string") return parseCapabilities(agent.capabilitiesJson) ?? void 0;
|
|
63
|
+
return agent.capabilities ?? void 0;
|
|
64
|
+
}
|
|
51
65
|
function mapCustomEntry(name, entry) {
|
|
52
66
|
const gsd = expandTilde(entry.globalSkillsDir || void 0);
|
|
53
67
|
return {
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { __exportAll } from "./rolldown-runtime.mjs";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
var config_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
+
GLOBAL_CONFIG_DIR: () => GLOBAL_CONFIG_DIR,
|
|
7
|
+
GLOBAL_CONFIG_FILE: () => GLOBAL_CONFIG_FILE,
|
|
8
|
+
LOCK_FILE: () => LOCK_FILE,
|
|
9
|
+
PROJECT_CONFIG_FILE: () => PROJECT_CONFIG_FILE,
|
|
10
|
+
getConfigValue: () => getConfigValue,
|
|
11
|
+
loadGlobalConfig: () => loadGlobalConfig,
|
|
12
|
+
loadLockfile: () => loadLockfile,
|
|
13
|
+
loadProjectConfig: () => loadProjectConfig,
|
|
14
|
+
resolveConfig: () => resolveConfig,
|
|
15
|
+
saveGlobalConfig: () => saveGlobalConfig,
|
|
16
|
+
saveLockfile: () => saveLockfile,
|
|
17
|
+
saveProjectConfig: () => saveProjectConfig,
|
|
18
|
+
setConfigValue: () => setConfigValue
|
|
19
|
+
});
|
|
20
|
+
const GLOBAL_CONFIG_DIR = path.join(os.homedir(), ".bfi");
|
|
21
|
+
const GLOBAL_CONFIG_FILE = path.join(GLOBAL_CONFIG_DIR, "config.json");
|
|
22
|
+
const PROJECT_CONFIG_FILE = ".bfirc";
|
|
23
|
+
const LOCK_FILE_DIR = ".bfi";
|
|
24
|
+
const LOCK_FILE = path.join(LOCK_FILE_DIR, "lock.json");
|
|
25
|
+
function resolveConfig(globalOpts = {}) {
|
|
26
|
+
return {
|
|
27
|
+
registry: getConfigValue("registry", globalOpts) || "https://bfi.yyuap.com:811",
|
|
28
|
+
token: getConfigValue("token", globalOpts) || null,
|
|
29
|
+
namespace: getConfigValue("namespace", globalOpts) || "global",
|
|
30
|
+
ide: getConfigValue("ide", globalOpts) || null
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function loadGlobalConfig() {
|
|
34
|
+
try {
|
|
35
|
+
if (fs.existsSync(GLOBAL_CONFIG_FILE)) {
|
|
36
|
+
const content = fs.readFileSync(GLOBAL_CONFIG_FILE, "utf8");
|
|
37
|
+
return JSON.parse(content);
|
|
38
|
+
}
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.warn(`Warning: Failed to load global config: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function saveGlobalConfig(config) {
|
|
45
|
+
try {
|
|
46
|
+
if (!fs.existsSync(GLOBAL_CONFIG_DIR)) fs.mkdirSync(GLOBAL_CONFIG_DIR, {
|
|
47
|
+
recursive: true,
|
|
48
|
+
mode: 448
|
|
49
|
+
});
|
|
50
|
+
const content = JSON.stringify(config, null, 2);
|
|
51
|
+
fs.writeFileSync(GLOBAL_CONFIG_FILE, content, { mode: 384 });
|
|
52
|
+
return true;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
throw new Error(`Failed to save global config: ${error.message}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function loadProjectConfig(workdir) {
|
|
58
|
+
try {
|
|
59
|
+
const configPath = path.join(workdir, PROJECT_CONFIG_FILE);
|
|
60
|
+
if (fs.existsSync(configPath)) {
|
|
61
|
+
const content = fs.readFileSync(configPath, "utf8");
|
|
62
|
+
return JSON.parse(content);
|
|
63
|
+
}
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.warn(`Warning: Failed to load project config: ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
function saveProjectConfig(workdir, config) {
|
|
70
|
+
try {
|
|
71
|
+
const configPath = path.join(workdir, PROJECT_CONFIG_FILE);
|
|
72
|
+
const content = JSON.stringify(config, null, 2);
|
|
73
|
+
fs.writeFileSync(configPath, content);
|
|
74
|
+
return true;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
throw new Error(`Failed to save project config: ${error.message}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function loadLockfile(workdir) {
|
|
80
|
+
try {
|
|
81
|
+
const lockPath = path.join(workdir, LOCK_FILE);
|
|
82
|
+
if (fs.existsSync(lockPath)) {
|
|
83
|
+
const content = fs.readFileSync(lockPath, "utf8");
|
|
84
|
+
return JSON.parse(content);
|
|
85
|
+
}
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.warn(`Warning: Failed to load lockfile: ${error.message}`);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
version: 1,
|
|
91
|
+
skills: {},
|
|
92
|
+
packages: {}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function saveLockfile(workdir, lock) {
|
|
96
|
+
try {
|
|
97
|
+
const lockDir = path.join(workdir, LOCK_FILE_DIR);
|
|
98
|
+
if (!fs.existsSync(lockDir)) fs.mkdirSync(lockDir, { recursive: true });
|
|
99
|
+
const lockPath = path.join(workdir, LOCK_FILE);
|
|
100
|
+
const content = JSON.stringify(lock, null, 2);
|
|
101
|
+
fs.writeFileSync(lockPath, content);
|
|
102
|
+
return true;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
throw new Error(`Failed to save lockfile: ${error.message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function getConfigValue(key, globalOpts = {}) {
|
|
108
|
+
const projectConfig = loadProjectConfig(globalOpts.workdir || process.cwd());
|
|
109
|
+
const globalConfig = loadGlobalConfig();
|
|
110
|
+
const configMap = {
|
|
111
|
+
registry: globalOpts.registry || projectConfig && projectConfig.registry || globalConfig && globalConfig.registry || null,
|
|
112
|
+
token: globalOpts.token || projectConfig && projectConfig.token || globalConfig && globalConfig.token || null,
|
|
113
|
+
namespace: globalOpts.namespace || projectConfig && projectConfig.namespace || globalConfig && globalConfig.defaultNamespace || "global",
|
|
114
|
+
ide: globalOpts.ide || projectConfig && projectConfig.ide || globalConfig && globalConfig.defaultIDE || null
|
|
115
|
+
};
|
|
116
|
+
return key ? configMap[key] : void 0;
|
|
117
|
+
}
|
|
118
|
+
function setConfigValue(key, value, isGlobal = false) {
|
|
119
|
+
if (isGlobal) {
|
|
120
|
+
const config = loadGlobalConfig() || { version: 1 };
|
|
121
|
+
const configKey = {
|
|
122
|
+
"registry": "registry",
|
|
123
|
+
"token": "token",
|
|
124
|
+
"default-namespace": "defaultNamespace",
|
|
125
|
+
"default-ide": "defaultIDE"
|
|
126
|
+
}[key] || key;
|
|
127
|
+
config[configKey] = value;
|
|
128
|
+
saveGlobalConfig(config);
|
|
129
|
+
} else {
|
|
130
|
+
const workdir = process.cwd();
|
|
131
|
+
const config = loadProjectConfig(workdir) || {};
|
|
132
|
+
const configKey = {
|
|
133
|
+
"registry": "registry",
|
|
134
|
+
"namespace": "namespace",
|
|
135
|
+
"ide": "ide"
|
|
136
|
+
}[key] || key;
|
|
137
|
+
config[configKey] = value;
|
|
138
|
+
saveProjectConfig(workdir, config);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export { config_exports, loadGlobalConfig, loadLockfile, loadProjectConfig, resolveConfig, saveGlobalConfig, saveLockfile, setConfigValue };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __commonJSMin } from "../../rolldown-runtime.mjs";
|
|
2
2
|
import "node:util";
|
|
3
3
|
import { stdin, stdout } from "node:process";
|
|
4
|
-
import * as l from "node:readline";
|
|
5
|
-
import l__default from "node:readline";
|
|
4
|
+
import l__default, * as l from "node:readline";
|
|
6
5
|
import { ReadStream } from "node:tty";
|
|
7
6
|
const getCodePointsLength = (() => {
|
|
8
7
|
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
@@ -359,6 +358,7 @@ const settings = {
|
|
|
359
358
|
error: "Something went wrong"
|
|
360
359
|
},
|
|
361
360
|
withGuide: true,
|
|
361
|
+
accessible: void 0,
|
|
362
362
|
date: {
|
|
363
363
|
monthNames: [...[
|
|
364
364
|
"January",
|
|
@@ -383,6 +383,12 @@ const settings = {
|
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
385
|
};
|
|
386
|
+
function isAccessible(n) {
|
|
387
|
+
if (n !== void 0) return n;
|
|
388
|
+
if (settings.accessible !== void 0) return settings.accessible;
|
|
389
|
+
const e = process.env.ACCESSIBLE;
|
|
390
|
+
return e !== void 0 && e !== "" && e !== "0" && e !== "false";
|
|
391
|
+
}
|
|
386
392
|
function isActionKey(n, e) {
|
|
387
393
|
if (typeof n == "string") return settings.aliases.get(n) === e;
|
|
388
394
|
for (const s of n) if (s !== void 0 && isActionKey(s, e)) return true;
|
|
@@ -410,7 +416,7 @@ function setRawMode(e, r) {
|
|
|
410
416
|
const o = e;
|
|
411
417
|
o.isTTY && o.setRawMode(r);
|
|
412
418
|
}
|
|
413
|
-
function block({ input: e = stdin, output: r = stdout, overwrite: o = true, hideCursor:
|
|
419
|
+
function block({ input: e = stdin, output: r = stdout, overwrite: o = true, hideCursor: n = true } = {}) {
|
|
414
420
|
const s = l.createInterface({
|
|
415
421
|
input: e,
|
|
416
422
|
output: r,
|
|
@@ -418,49 +424,48 @@ function block({ input: e = stdin, output: r = stdout, overwrite: o = true, hide
|
|
|
418
424
|
tabSize: 1
|
|
419
425
|
});
|
|
420
426
|
l.emitKeypressEvents(e, s), e instanceof ReadStream && e.isTTY && e.setRawMode(true);
|
|
421
|
-
const
|
|
427
|
+
const t = (f, { name: a, sequence: w }) => {
|
|
422
428
|
if (isActionKey([
|
|
423
429
|
String(f),
|
|
424
430
|
a,
|
|
425
|
-
|
|
431
|
+
w
|
|
426
432
|
], "cancel")) {
|
|
427
|
-
|
|
433
|
+
n && r.write(import_src.cursor.show), process.exit(0);
|
|
428
434
|
return;
|
|
429
435
|
}
|
|
430
436
|
if (!o) return;
|
|
431
437
|
const i = a === "return" ? 0 : -1, m = a === "return" ? -1 : 0;
|
|
432
438
|
l.moveCursor(r, i, m, () => {
|
|
433
439
|
l.clearLine(r, 1, () => {
|
|
434
|
-
e.once("keypress",
|
|
440
|
+
e.once("keypress", t);
|
|
435
441
|
});
|
|
436
442
|
});
|
|
437
443
|
};
|
|
438
|
-
return
|
|
439
|
-
e.off("keypress",
|
|
444
|
+
return n && r.write(import_src.cursor.hide), e.once("keypress", t), () => {
|
|
445
|
+
e.off("keypress", t), n && r.write(import_src.cursor.show), e instanceof ReadStream && e.isTTY && !R && e.setRawMode(false), s.terminal = false, s.close();
|
|
440
446
|
};
|
|
441
447
|
}
|
|
442
448
|
const getColumns = (e) => "columns" in e && typeof e.columns == "number" ? e.columns : 80;
|
|
443
449
|
const getRows = (e) => "rows" in e && typeof e.rows == "number" ? e.rows : 20;
|
|
444
|
-
function wrapTextWithPrefix(e, r, o,
|
|
450
|
+
function wrapTextWithPrefix(e, r, o, n = o, s = o, t) {
|
|
445
451
|
return wrapAnsi(r, getColumns(e ?? stdout) - o.length, {
|
|
446
452
|
hard: true,
|
|
447
453
|
trim: false
|
|
448
454
|
}).split(`
|
|
449
455
|
`).map((c, i, m) => {
|
|
450
|
-
const d =
|
|
451
|
-
return i === 0 ? `${
|
|
456
|
+
const d = t ? t(c, i) : c;
|
|
457
|
+
return i === 0 ? `${n}${d}` : i === m.length - 1 ? `${s}${d}` : `${o}${d}`;
|
|
452
458
|
}).join(`
|
|
453
459
|
`);
|
|
454
460
|
}
|
|
455
|
-
function runValidation(e,
|
|
461
|
+
function runValidation(e, a) {
|
|
456
462
|
if ("~standard" in e) {
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
return a.issues?.at(0)?.message;
|
|
463
|
+
const n = e["~standard"].validate(a);
|
|
464
|
+
return n instanceof Promise ? n.then((r) => r.issues?.at(0)?.message) : n.issues?.at(0)?.message;
|
|
460
465
|
}
|
|
461
|
-
return e(
|
|
466
|
+
return e(a);
|
|
462
467
|
}
|
|
463
|
-
var
|
|
468
|
+
var y = class {
|
|
464
469
|
input;
|
|
465
470
|
output;
|
|
466
471
|
_abortSignal;
|
|
@@ -475,9 +480,12 @@ var V = class {
|
|
|
475
480
|
error = "";
|
|
476
481
|
value;
|
|
477
482
|
userInput = "";
|
|
483
|
+
get accessible() {
|
|
484
|
+
return isAccessible(this.opts.accessible);
|
|
485
|
+
}
|
|
478
486
|
constructor(t, e = true) {
|
|
479
|
-
const { input: i = stdin, output:
|
|
480
|
-
this.opts = o, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render =
|
|
487
|
+
const { input: i = stdin, output: s = stdout, render: r, signal: n, ...o } = t;
|
|
488
|
+
this.opts = o, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = r.bind(this), this._track = e, this._abortSignal = n, this.input = i, this.output = s;
|
|
481
489
|
}
|
|
482
490
|
unsubscribe() {
|
|
483
491
|
this._subscribers.clear();
|
|
@@ -496,9 +504,9 @@ var V = class {
|
|
|
496
504
|
});
|
|
497
505
|
}
|
|
498
506
|
emit(t, ...e) {
|
|
499
|
-
const i = this._subscribers.get(t) ?? [],
|
|
500
|
-
for (const
|
|
501
|
-
for (const
|
|
507
|
+
const i = this._subscribers.get(t) ?? [], s = [];
|
|
508
|
+
for (const r of i) r.cb(...e), r.once && s.push(() => i.splice(i.indexOf(r), 1));
|
|
509
|
+
for (const r of s) r();
|
|
502
510
|
}
|
|
503
511
|
prompt() {
|
|
504
512
|
return new Promise((t) => {
|
|
@@ -539,22 +547,25 @@ var V = class {
|
|
|
539
547
|
name: "u"
|
|
540
548
|
}), this._setUserInput("");
|
|
541
549
|
}
|
|
542
|
-
onKeypress(t, e) {
|
|
543
|
-
if (this.
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
+
async onKeypress(t, e) {
|
|
551
|
+
if (this.state !== "validating") {
|
|
552
|
+
if (this._track && e.name !== "return" && (e.name && this._isActionKey(t, e) && this.rl?.write(null, {
|
|
553
|
+
ctrl: true,
|
|
554
|
+
name: "h"
|
|
555
|
+
}), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), e?.name && (!this._track && settings.aliases.has(e.name) && this.emit("cursor", settings.aliases.get(e.name)), settings.actions.has(e.name) && this.emit("cursor", e.name)), t && (t.toLowerCase() === "y" || t.toLowerCase() === "n") && this.emit("confirm", t.toLowerCase() === "y"), this.emit("key", t, e), e?.name === "return" && this._shouldSubmit(t, e)) {
|
|
556
|
+
if (this.opts.validate) {
|
|
557
|
+
const i = runValidation(this.opts.validate, this.value);
|
|
558
|
+
let s;
|
|
559
|
+
i instanceof Promise ? (this.state = "validating", this.render(), s = await i) : s = i, s && (this.error = s instanceof Error ? s.message : s, this.state = "error", this.rl?.write(this.userInput));
|
|
560
|
+
}
|
|
561
|
+
this.state !== "error" && (this.state = "submit");
|
|
550
562
|
}
|
|
551
|
-
|
|
563
|
+
isActionKey([
|
|
564
|
+
t,
|
|
565
|
+
e?.name,
|
|
566
|
+
e?.sequence
|
|
567
|
+
], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
552
568
|
}
|
|
553
|
-
isActionKey([
|
|
554
|
-
t,
|
|
555
|
-
e?.name,
|
|
556
|
-
e?.sequence
|
|
557
|
-
], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
558
569
|
}
|
|
559
570
|
close() {
|
|
560
571
|
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
@@ -578,27 +589,27 @@ var V = class {
|
|
|
578
589
|
else {
|
|
579
590
|
const e = diffLines(this._prevFrame, t), i = getRows(this.output);
|
|
580
591
|
if (this.restoreCursor(), e) {
|
|
581
|
-
const
|
|
582
|
-
let
|
|
583
|
-
if (
|
|
592
|
+
const s = Math.max(0, e.numLinesAfter - i), r = Math.max(0, e.numLinesBefore - i);
|
|
593
|
+
let n = e.lines.find((o) => o >= s);
|
|
594
|
+
if (n === void 0) {
|
|
584
595
|
this._prevFrame = t;
|
|
585
596
|
return;
|
|
586
597
|
}
|
|
587
598
|
if (e.lines.length === 1) {
|
|
588
|
-
this.output.write(import_src.cursor.move(0,
|
|
599
|
+
this.output.write(import_src.cursor.move(0, n - r)), this.output.write(import_src.erase.lines(1));
|
|
589
600
|
const o = t.split(`
|
|
590
601
|
`);
|
|
591
|
-
this.output.write(o[
|
|
602
|
+
this.output.write(o[n]), this._prevFrame = t, this.output.write(import_src.cursor.move(0, o.length - n - 1));
|
|
592
603
|
return;
|
|
593
604
|
} else if (e.lines.length > 1) {
|
|
594
|
-
if (
|
|
605
|
+
if (s < r) n = s;
|
|
595
606
|
else {
|
|
596
|
-
const h =
|
|
607
|
+
const h = n - r;
|
|
597
608
|
h > 0 && this.output.write(import_src.cursor.move(0, h));
|
|
598
609
|
}
|
|
599
610
|
this.output.write(import_src.erase.down());
|
|
600
611
|
const f = t.split(`
|
|
601
|
-
`).slice(
|
|
612
|
+
`).slice(n);
|
|
602
613
|
this.output.write(f.join(`
|
|
603
614
|
`)), this._prevFrame = t;
|
|
604
615
|
return;
|
|
@@ -610,7 +621,7 @@ var V = class {
|
|
|
610
621
|
}
|
|
611
622
|
}
|
|
612
623
|
};
|
|
613
|
-
var r = class extends
|
|
624
|
+
var r = class extends y {
|
|
614
625
|
get cursor() {
|
|
615
626
|
return this.value ? 0 : 1;
|
|
616
627
|
}
|
|
@@ -627,7 +638,7 @@ var r = class extends V {
|
|
|
627
638
|
});
|
|
628
639
|
}
|
|
629
640
|
};
|
|
630
|
-
let u$2 = class u extends
|
|
641
|
+
let u$2 = class u extends y {
|
|
631
642
|
options;
|
|
632
643
|
cursor = 0;
|
|
633
644
|
#t;
|
|
@@ -674,14 +685,12 @@ let u$2 = class u extends V {
|
|
|
674
685
|
!this.#t && s && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
675
686
|
break;
|
|
676
687
|
}
|
|
677
|
-
case "space":
|
|
678
|
-
this.toggleValue();
|
|
679
|
-
break;
|
|
688
|
+
case "space": this.toggleValue();
|
|
680
689
|
}
|
|
681
690
|
});
|
|
682
691
|
}
|
|
683
692
|
};
|
|
684
|
-
var a = class extends
|
|
693
|
+
var a = class extends y {
|
|
685
694
|
options;
|
|
686
695
|
cursor = 0;
|
|
687
696
|
get _value() {
|
|
@@ -720,14 +729,12 @@ var a = class extends V {
|
|
|
720
729
|
case "right":
|
|
721
730
|
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
722
731
|
break;
|
|
723
|
-
case "space":
|
|
724
|
-
this.toggleValue();
|
|
725
|
-
break;
|
|
732
|
+
case "space": this.toggleValue();
|
|
726
733
|
}
|
|
727
734
|
});
|
|
728
735
|
}
|
|
729
736
|
};
|
|
730
|
-
let n$1 = class n extends
|
|
737
|
+
let n$1 = class n extends y {
|
|
731
738
|
options;
|
|
732
739
|
cursor = 0;
|
|
733
740
|
get _selectedValue() {
|
|
@@ -747,9 +754,7 @@ let n$1 = class n extends V {
|
|
|
747
754
|
this.cursor = findCursor(this.cursor, -1, this.options);
|
|
748
755
|
break;
|
|
749
756
|
case "down":
|
|
750
|
-
case "right":
|
|
751
|
-
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
752
|
-
break;
|
|
757
|
+
case "right": this.cursor = findCursor(this.cursor, 1, this.options);
|
|
753
758
|
}
|
|
754
759
|
this.changeValue();
|
|
755
760
|
});
|