toolcraft 0.0.152 → 0.0.154
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/composition.json +2 -2
- package/dist/cli.js +7 -1
- package/dist/composition.json +2 -2
- package/dist/renderer.js +1 -14
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- package/node_modules/toolcraft-design/README.md +30 -0
- package/node_modules/toolcraft-design/dist/dashboard/terminal-width.d.ts +1 -0
- package/node_modules/toolcraft-design/dist/dashboard/terminal-width.js +18 -1
- package/node_modules/toolcraft-design/dist/explorer/actions.d.ts +1 -1
- package/node_modules/toolcraft-design/dist/explorer/actions.js +22 -4
- package/node_modules/toolcraft-design/dist/explorer/filter.js +1 -1
- package/node_modules/toolcraft-design/dist/explorer/index.d.ts +2 -4
- package/node_modules/toolcraft-design/dist/explorer/index.js +1 -2
- package/node_modules/toolcraft-design/dist/explorer/jobs.d.ts +2 -2
- package/node_modules/toolcraft-design/dist/explorer/jobs.js +3 -5
- package/node_modules/toolcraft-design/dist/explorer/keymap.d.ts +13 -3
- package/node_modules/toolcraft-design/dist/explorer/keymap.js +89 -348
- package/node_modules/toolcraft-design/dist/explorer/layout.d.ts +1 -0
- package/node_modules/toolcraft-design/dist/explorer/layout.js +14 -4
- package/node_modules/toolcraft-design/dist/explorer/reducer.js +58 -9
- package/node_modules/toolcraft-design/dist/explorer/render/detail.d.ts +1 -1
- package/node_modules/toolcraft-design/dist/explorer/render/detail.js +43 -7
- package/node_modules/toolcraft-design/dist/explorer/render/footer.d.ts +1 -1
- package/node_modules/toolcraft-design/dist/explorer/render/footer.js +6 -3
- package/node_modules/toolcraft-design/dist/explorer/render/header.d.ts +1 -1
- package/node_modules/toolcraft-design/dist/explorer/render/header.js +6 -2
- package/node_modules/toolcraft-design/dist/explorer/render/index.d.ts +1 -1
- package/node_modules/toolcraft-design/dist/explorer/render/index.js +2 -1
- package/node_modules/toolcraft-design/dist/explorer/render/list.d.ts +16 -2
- package/node_modules/toolcraft-design/dist/explorer/render/list.js +13 -34
- package/node_modules/toolcraft-design/dist/explorer/render/modal.d.ts +1 -1
- package/node_modules/toolcraft-design/dist/explorer/render/pane.d.ts +5 -2
- package/node_modules/toolcraft-design/dist/explorer/render/pane.js +9 -6
- package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.js +2 -3
- package/node_modules/toolcraft-design/dist/explorer/runtime.js +68 -63
- package/node_modules/toolcraft-design/dist/explorer/runtime.test-helpers.d.ts +23 -37
- package/node_modules/toolcraft-design/dist/explorer/runtime.test-helpers.js +32 -83
- package/node_modules/toolcraft-design/dist/explorer/state.d.ts +47 -5
- package/node_modules/toolcraft-design/dist/explorer/state.js +56 -12
- package/node_modules/toolcraft-design/dist/index.d.ts +8 -2
- package/node_modules/toolcraft-design/dist/index.js +5 -1
- package/node_modules/toolcraft-design/dist/screen/ansi-text.d.ts +2 -0
- package/node_modules/toolcraft-design/dist/screen/ansi-text.js +35 -0
- package/node_modules/toolcraft-design/dist/screen/screen.d.ts +40 -0
- package/node_modules/toolcraft-design/dist/screen/screen.js +122 -0
- package/node_modules/toolcraft-design/dist/screen/style.d.ts +16 -0
- package/node_modules/toolcraft-design/dist/screen/style.js +55 -0
- package/node_modules/toolcraft-design/dist/terminal/driver.d.ts +33 -0
- package/node_modules/toolcraft-design/dist/terminal/driver.js +61 -0
- package/node_modules/toolcraft-design/dist/terminal/input.d.ts +25 -0
- package/node_modules/toolcraft-design/dist/terminal/input.js +181 -0
- package/node_modules/toolcraft-design/dist/terminal/output.d.ts +8 -0
- package/node_modules/toolcraft-design/dist/terminal/output.js +42 -0
- package/node_modules/toolcraft-schema/package.json +1 -1
- package/package.json +2 -2
- package/dist/design/run-two-pane-explorer.d.ts +0 -2
- package/dist/design/run-two-pane-explorer.js +0 -1
- package/node_modules/toolcraft-design/dist/explorer/two-pane.d.ts +0 -102
- package/node_modules/toolcraft-design/dist/explorer/two-pane.js +0 -510
- package/node_modules/toolcraft-design/dist/run-two-pane-explorer.d.ts +0 -2
- package/node_modules/toolcraft-design/dist/run-two-pane-explorer.js +0 -1
package/composition.json
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.154",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.154",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
package/dist/cli.js
CHANGED
|
@@ -628,6 +628,9 @@ function isNegativeNumericArrayToken(token, schema) {
|
|
|
628
628
|
return (items.length > 0 && items.every((item) => isValidNumberSchemaValue(Number(item), itemSchema)));
|
|
629
629
|
}
|
|
630
630
|
function isNextArrayOptionToken(token, schema) {
|
|
631
|
+
if (token === "-" && unwrapOptional(schema.item).kind === "string") {
|
|
632
|
+
return false;
|
|
633
|
+
}
|
|
631
634
|
return token.startsWith("-") && !isNegativeNumericArrayToken(token, schema);
|
|
632
635
|
}
|
|
633
636
|
function validateArrayBounds(value, schema, label) {
|
|
@@ -3595,7 +3598,9 @@ function renderHttpError(error, options) {
|
|
|
3595
3598
|
else {
|
|
3596
3599
|
lines.push(`Response body: ${formatHttpErrorSnippet(error.response.body)}`);
|
|
3597
3600
|
}
|
|
3598
|
-
|
|
3601
|
+
if (options.verboseControlEnabled) {
|
|
3602
|
+
lines.push("Re-run with --verbose to see headers and full body.");
|
|
3603
|
+
}
|
|
3599
3604
|
}
|
|
3600
3605
|
process.stderr.write(`${lines.join("\n")}\n`);
|
|
3601
3606
|
const stack = error instanceof Error ? error.stack : undefined;
|
|
@@ -4045,6 +4050,7 @@ export async function runCLI(roots, options = {}) {
|
|
|
4045
4050
|
? resolveOutput(resolvedFlags)
|
|
4046
4051
|
: resolveOutputFromArgv(argv, controls.outputFormats),
|
|
4047
4052
|
verbose: resolvedFlags ? Boolean(resolvedFlags.verbose) : argv.includes("--verbose"),
|
|
4053
|
+
verboseControlEnabled: controls.verbose,
|
|
4048
4054
|
program,
|
|
4049
4055
|
argv,
|
|
4050
4056
|
rootUsageName,
|
package/dist/composition.json
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.154",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.154",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
package/dist/renderer.js
CHANGED
|
@@ -129,24 +129,11 @@ function displayScalar(value) {
|
|
|
129
129
|
}
|
|
130
130
|
return stringifyValue(value) || "—";
|
|
131
131
|
}
|
|
132
|
-
function isUrl(value) {
|
|
133
|
-
return typeof value === "string" && (value.startsWith("https://") || value.startsWith("http://"));
|
|
134
|
-
}
|
|
135
|
-
function compactUrl(value) {
|
|
136
|
-
try {
|
|
137
|
-
const url = new URL(value);
|
|
138
|
-
const tail = url.pathname.split("/").filter(Boolean).at(-1);
|
|
139
|
-
return tail ? `${url.hostname}/…/${tail}` : url.hostname;
|
|
140
|
-
}
|
|
141
|
-
catch {
|
|
142
|
-
return value;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
132
|
function stackedList(value) {
|
|
146
133
|
return value.map((entry) => displayScalar(entry)).join("\n") || "—";
|
|
147
134
|
}
|
|
148
135
|
function displayRowValue(value) {
|
|
149
|
-
return
|
|
136
|
+
return displayScalar(value);
|
|
150
137
|
}
|
|
151
138
|
function directScalarRows(result) {
|
|
152
139
|
return Object.entries(result)
|
|
@@ -83,6 +83,36 @@ import { renderTable } from "toolcraft-design/render-table";
|
|
|
83
83
|
- Root-level types: `Row`, `DetailItem`, `Detail`, `DetailCtx`, `Action`, `ActionContext`, `ExplorerConfig`, `ReorderContext`, `Tone`.
|
|
84
84
|
- The namespace also exports `createInitialState`, `resolveBindings`, and the remaining explorer event, binding, layout, size, state, and effect types.
|
|
85
85
|
|
|
86
|
+
Explorers declare one to three list or detail panes. Printable input always filters; actions use optional Ctrl accelerators:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
await runExplorer({
|
|
90
|
+
title: "Plans",
|
|
91
|
+
panes: [
|
|
92
|
+
{ id: "plans", kind: "list", title: "Plans", rows: loadPlans },
|
|
93
|
+
{ id: "preview", kind: "detail", title: "Preview", render: renderPlan }
|
|
94
|
+
],
|
|
95
|
+
actions: [
|
|
96
|
+
{ id: "edit", label: "Edit", accelerator: "e", handler: editPlan },
|
|
97
|
+
{ id: "remove", label: "Remove", destructive: true, handler: removePlan }
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
| Input | Behavior |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| Printable text / paste | Filter the focused list |
|
|
105
|
+
| Up, Down, PageUp, PageDown, Home, End | Navigate |
|
|
106
|
+
| Ctrl+U, Ctrl+D | Move half a page |
|
|
107
|
+
| Enter | Open the action menu |
|
|
108
|
+
| Ctrl+P | Open the command palette |
|
|
109
|
+
| Tab | Cycle pane focus |
|
|
110
|
+
| Space | Toggle selection |
|
|
111
|
+
| Escape | Dismiss, clear the filter, then quit |
|
|
112
|
+
| Ctrl+C | Quit immediately |
|
|
113
|
+
|
|
114
|
+
Set `POE_CODE_TUI_TRACE` to a file path to write JSONL input and frame diagnostics. It is unset and disabled by default.
|
|
115
|
+
|
|
86
116
|
### Terminal Markdown
|
|
87
117
|
|
|
88
118
|
- `parse`: parses Markdown into `MdNode` values.
|
|
@@ -2,3 +2,4 @@ export declare function graphemes(value: string): string[];
|
|
|
2
2
|
export declare function displayWidth(value: string, startColumn?: number): number;
|
|
3
3
|
export declare function expandTabs(value: string, startColumn?: number): string;
|
|
4
4
|
export declare function graphemeWidth(segment: string): number;
|
|
5
|
+
export declare function truncateToWidth(text: string, width: number): string;
|
|
@@ -33,7 +33,24 @@ export function graphemeWidth(segment) {
|
|
|
33
33
|
if (codePoint === undefined || isZeroWidthCodePoint(codePoint)) {
|
|
34
34
|
return 0;
|
|
35
35
|
}
|
|
36
|
-
return isWideCodePoint(codePoint) || isFlagSegment(segment) ? 2 : 1;
|
|
36
|
+
return isWideCodePoint(codePoint) || isFlagSegment(segment) || segment.includes("\ufe0f") ? 2 : 1;
|
|
37
|
+
}
|
|
38
|
+
export function truncateToWidth(text, width) {
|
|
39
|
+
if (width <= 0)
|
|
40
|
+
return "";
|
|
41
|
+
if (displayWidth(text) <= width)
|
|
42
|
+
return text;
|
|
43
|
+
const target = Math.max(0, width - 1);
|
|
44
|
+
let result = "";
|
|
45
|
+
let used = 0;
|
|
46
|
+
for (const segment of graphemes(text)) {
|
|
47
|
+
const segmentWidth = graphemeWidth(segment);
|
|
48
|
+
if (used + segmentWidth > target)
|
|
49
|
+
break;
|
|
50
|
+
result += segment;
|
|
51
|
+
used += segmentWidth;
|
|
52
|
+
}
|
|
53
|
+
return `${result}…`;
|
|
37
54
|
}
|
|
38
55
|
function isZeroWidthCodePoint(codePoint) {
|
|
39
56
|
return (codePoint >= 0x0300 && codePoint <= 0x036f)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExplorerEvent } from "./events.js";
|
|
2
2
|
import type { Action, ActionContext, ExplorerState, Row, Tone } from "./state.js";
|
|
3
|
-
export type ActionSource = "row" | "detail";
|
|
3
|
+
export type ActionSource = "row" | "detail" | "both";
|
|
4
4
|
type ExplorerKeypressEvent = Extract<ExplorerEvent, {
|
|
5
5
|
type: "key";
|
|
6
6
|
}>["key"];
|
|
@@ -12,11 +12,13 @@ export function resolveAction(state, keyEvent) {
|
|
|
12
12
|
return actionState.action;
|
|
13
13
|
}
|
|
14
14
|
export function buildActionContext(state, _action, source, runtimeHandles, rowsOverride) {
|
|
15
|
-
const
|
|
15
|
+
const detailActive = source === "both" && state.focused === "detail";
|
|
16
|
+
const row = rowsOverride?.[0] ?? (detailActive ? currentDetailRow(state) : currentRow(state)) ?? { id: "", title: "" };
|
|
17
|
+
const panes = runtimePanes(state);
|
|
16
18
|
return {
|
|
17
19
|
row,
|
|
18
20
|
rows: rowsOverride ?? selectedRows(state, row),
|
|
19
|
-
item: source === "detail" ? currentDetailItem(state) : undefined,
|
|
21
|
+
item: source === "detail" || detailActive ? currentDetailItem(state) : undefined,
|
|
20
22
|
filter: state.filter,
|
|
21
23
|
refresh: runtimeHandles.refresh,
|
|
22
24
|
reloadDetail: runtimeHandles.reloadDetail,
|
|
@@ -24,7 +26,9 @@ export function buildActionContext(state, _action, source, runtimeHandles, rowsO
|
|
|
24
26
|
openModal: runtimeHandles.openModal,
|
|
25
27
|
toast: runtimeHandles.toast,
|
|
26
28
|
confirm: runtimeHandles.confirm,
|
|
27
|
-
exit: runtimeHandles.exit
|
|
29
|
+
exit: runtimeHandles.exit,
|
|
30
|
+
activePane: state.focused === "detail" ? panes[1] : panes[0],
|
|
31
|
+
inactivePane: state.focused === "detail" ? panes[0] : panes[1]
|
|
28
32
|
};
|
|
29
33
|
}
|
|
30
34
|
function currentRow(state) {
|
|
@@ -33,9 +37,23 @@ function currentRow(state) {
|
|
|
33
37
|
function currentDetailItem(state) {
|
|
34
38
|
return state.detail.items?.[state.detail.cursor];
|
|
35
39
|
}
|
|
40
|
+
function currentDetailRow(state) {
|
|
41
|
+
const item = currentDetailItem(state);
|
|
42
|
+
return item === undefined ? undefined : { id: item.id, title: item.title ?? item.id, subtitle: item.subtitle, badge: item.badge };
|
|
43
|
+
}
|
|
36
44
|
function selectedRows(state, fallback) {
|
|
37
45
|
if (!state.multiSelect || state.selected.size === 0) {
|
|
38
46
|
return fallback.id === "" ? [] : [fallback];
|
|
39
47
|
}
|
|
40
|
-
|
|
48
|
+
const source = state.focused === "detail"
|
|
49
|
+
? (state.detail.items ?? []).map(item => ({ id: item.id, title: item.title ?? item.id, subtitle: item.subtitle, badge: item.badge }))
|
|
50
|
+
: state.rows;
|
|
51
|
+
return source.filter((row) => state.selected.has(row.id));
|
|
52
|
+
}
|
|
53
|
+
function runtimePanes(state) {
|
|
54
|
+
const definitions = state.paneDefinitions;
|
|
55
|
+
return [
|
|
56
|
+
{ id: definitions[0]?.id ?? "list", title: definitions[0]?.title ?? state.title, rows: state.rows, cursor: state.cursor, selected: state.selected, filter: state.filter },
|
|
57
|
+
{ id: definitions[1]?.id ?? "detail", title: definitions[1]?.title ?? "Preview", rows: (state.detail.items ?? []).map(item => ({ id: item.id, title: item.title ?? item.id, subtitle: item.subtitle, badge: item.badge })), cursor: state.detail.cursor, selected: state.selected, filter: "" }
|
|
58
|
+
];
|
|
41
59
|
}
|
|
@@ -3,7 +3,7 @@ const CONSECUTIVE_BONUS = 14;
|
|
|
3
3
|
const WORD_START_BONUS = 10;
|
|
4
4
|
const EARLY_MATCH_BONUS = 3;
|
|
5
5
|
export function filterRows(query, rows, opts = {}) {
|
|
6
|
-
if (query.length === 0) {
|
|
6
|
+
if (query.trim().length === 0) {
|
|
7
7
|
return rows.map((_, index) => ({ index, score: 0, positions: [] }));
|
|
8
8
|
}
|
|
9
9
|
const preparedQuery = opts.caseSensitive === true ? query : query.toLocaleLowerCase();
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { Detail, DetailCtx, Row } from "./state.js";
|
|
2
2
|
export { runExplorer } from "./runtime.js";
|
|
3
|
-
export {
|
|
4
|
-
export { createInitialState } from "./state.js";
|
|
3
|
+
export { createInitialState, normalizeExplorerConfig } from "./state.js";
|
|
5
4
|
export { resolveBindings } from "./keymap.js";
|
|
6
5
|
export type { Effect, ExplorerEvent } from "./events.js";
|
|
7
6
|
export type { BindingTarget, ExplorerBindingDefaults, ExplorerBuiltinCommand, ResolvedBindings } from "./keymap.js";
|
|
8
|
-
export type { Action, ActionContext, Detail, DetailCtx, DetailItem, Dirty, ExplorerConfig, ExplorerLayoutMode, ExplorerSize, ExplorerState, ReorderContext, Row, Tone } from "./state.js";
|
|
9
|
-
export type { TwoPaneAction, TwoPaneActionContext, TwoPaneDefinition, TwoPaneExplorerConfig, TwoPaneExplorerState, TwoPanePaneState, TwoPaneRow } from "./two-pane.js";
|
|
7
|
+
export type { Action, ActionContext, Detail, DetailCtx, DetailItem, Dirty, ExplorerConfig, PaneConfig, ListPaneConfig, DetailPaneConfig, PaneRuntimeState, ExplorerLayoutMode, ExplorerSize, ExplorerState, ReorderContext, Row, Tone } from "./state.js";
|
|
10
8
|
export declare function singleDetail<R>(fn: (row: Row, ctx: DetailCtx) => string | Promise<string>): Detail<R>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { runExplorer } from "./runtime.js";
|
|
2
|
-
export {
|
|
3
|
-
export { createInitialState } from "./state.js";
|
|
2
|
+
export { createInitialState, normalizeExplorerConfig } from "./state.js";
|
|
4
3
|
export { resolveBindings } from "./keymap.js";
|
|
5
4
|
export function singleDetail(fn) {
|
|
6
5
|
return {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ExplorerEvent } from "./events.js";
|
|
2
2
|
import type { DetailCtx, DetailItem } from "./state.js";
|
|
3
3
|
export declare const LOADING_INDICATOR_MS = 150;
|
|
4
|
-
export declare const DETAIL_DEBOUNCE_MS =
|
|
4
|
+
export declare const DETAIL_DEBOUNCE_MS = 30;
|
|
5
5
|
export declare function createDetailJobs(emit: (event: ExplorerEvent) => void): {
|
|
6
|
-
schedule: (rowId: string, items: (ctx: DetailCtx) => Promise<DetailItem[]>, ctx: DetailCtx) => Promise<void>;
|
|
6
|
+
schedule: (rowId: string, token: number, items: (ctx: DetailCtx) => Promise<DetailItem[]>, ctx: DetailCtx) => Promise<void>;
|
|
7
7
|
abort: () => void;
|
|
8
8
|
};
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
export const LOADING_INDICATOR_MS = 150;
|
|
2
|
-
export const DETAIL_DEBOUNCE_MS =
|
|
2
|
+
export const DETAIL_DEBOUNCE_MS = 30;
|
|
3
3
|
export function createDetailJobs(emit) {
|
|
4
|
-
let token = 0;
|
|
5
4
|
let lastScheduleAt = 0;
|
|
6
5
|
let current = null;
|
|
7
6
|
const abortedTokens = new Set();
|
|
8
7
|
return {
|
|
9
|
-
async schedule(rowId, items, ctx) {
|
|
8
|
+
async schedule(rowId, nextToken, items, ctx) {
|
|
10
9
|
if (current !== null) {
|
|
11
10
|
current.controller.abort();
|
|
12
11
|
clearTimeout(current.loadingTimer);
|
|
@@ -14,7 +13,6 @@ export function createDetailJobs(emit) {
|
|
|
14
13
|
const scheduledAt = Date.now();
|
|
15
14
|
const debounce = scheduledAt - lastScheduleAt < DETAIL_DEBOUNCE_MS;
|
|
16
15
|
lastScheduleAt = scheduledAt;
|
|
17
|
-
const nextToken = ++token;
|
|
18
16
|
const controller = new AbortController();
|
|
19
17
|
let finished = false;
|
|
20
18
|
const loadingTimer = setTimeout(() => {
|
|
@@ -26,7 +24,7 @@ export function createDetailJobs(emit) {
|
|
|
26
24
|
try {
|
|
27
25
|
if (debounce) {
|
|
28
26
|
await waitUnlessAborted(DETAIL_DEBOUNCE_MS, controller.signal);
|
|
29
|
-
if (controller.signal.aborted ||
|
|
27
|
+
if (controller.signal.aborted || current?.token !== nextToken) {
|
|
30
28
|
return;
|
|
31
29
|
}
|
|
32
30
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExplorerEvent } from "./events.js";
|
|
2
2
|
import type { ExplorerConfig } from "./state.js";
|
|
3
|
-
export type ExplorerBuiltinCommand = "quit" | "filter" | "help" | "palette" | "cursorUp" | "cursorDown" | "top" | "bottom" | "pageUp" | "pageDown" | "focusNext" | "escape" | "confirm" | "toggleSelect" | "selectAll" | "clearSelection" | "detailScrollDown" | "detailScrollUp" | "extendSelectionUp" | "extendSelectionDown" | "reorderUp" | "reorderDown";
|
|
3
|
+
export type ExplorerBuiltinCommand = "quit" | "filter" | "help" | "palette" | "cursorUp" | "cursorDown" | "top" | "bottom" | "pageUp" | "pageDown" | "focusNext" | "escape" | "confirm" | "halfPageUp" | "halfPageDown" | "toggleSelect" | "selectAll" | "clearSelection" | "detailScrollDown" | "detailScrollUp" | "extendSelectionUp" | "extendSelectionDown" | "reorderUp" | "reorderDown";
|
|
4
4
|
export type BindingTarget = {
|
|
5
5
|
type: "builtin";
|
|
6
6
|
id: ExplorerBuiltinCommand;
|
|
@@ -8,14 +8,24 @@ export type BindingTarget = {
|
|
|
8
8
|
type: "action";
|
|
9
9
|
id: string;
|
|
10
10
|
};
|
|
11
|
-
type
|
|
11
|
+
type Key = Extract<ExplorerEvent, {
|
|
12
12
|
type: "key";
|
|
13
13
|
}>["key"];
|
|
14
14
|
export interface ResolvedBindings {
|
|
15
15
|
bindings: ReadonlyMap<string, BindingTarget>;
|
|
16
16
|
keysByTarget: ReadonlyMap<string, readonly string[]>;
|
|
17
|
-
resolve: (event:
|
|
17
|
+
resolve: (event: Key) => BindingTarget | undefined;
|
|
18
18
|
}
|
|
19
19
|
export type ExplorerBindingDefaults = Partial<Record<ExplorerBuiltinCommand, string[]>>;
|
|
20
|
+
export interface HelpSection {
|
|
21
|
+
title: string;
|
|
22
|
+
entries: Array<{
|
|
23
|
+
key: string;
|
|
24
|
+
label: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
20
27
|
export declare function resolveBindings<R>(config: ExplorerConfig<R>, defaults?: ExplorerBindingDefaults): ResolvedBindings;
|
|
28
|
+
export declare function assertNoBareLetterBindings<R>(config: ExplorerConfig<R>): void;
|
|
29
|
+
export declare function assertAcceleratorsFree<R>(config: ExplorerConfig<R>): void;
|
|
30
|
+
export declare function keymapToHelp<R>(config: ExplorerConfig<R>): HelpSection[];
|
|
21
31
|
export {};
|