@lidtop/loadout 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/cli.js +4 -45
- package/dist/external.d.ts +4 -0
- package/dist/external.js +40 -20
- package/dist/interactive.d.ts +13 -7
- package/dist/interactive.js +77 -34
- package/dist/picker.d.ts +22 -0
- package/dist/picker.js +211 -207
- package/dist/prepare.d.ts +10 -0
- package/dist/prepare.js +92 -0
- package/dist/retry.d.ts +1 -1
- package/dist/retry.js +3 -1
- package/dist/review.d.ts +35 -0
- package/dist/review.js +346 -0
- package/dist/setup.d.ts +9 -0
- package/dist/setup.js +120 -0
- package/dist/terminal.d.ts +1 -0
- package/dist/terminal.js +20 -8
- package/kits/dont-commit/instructions.md +1 -0
- package/kits/dont-commit/kit.yaml +6 -0
- package/kits/write-kit/skills/loadout-write-kit/SKILL.md +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,11 @@ npm install -g @lidtop/loadout
|
|
|
13
13
|
loadout
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
Pick your kits
|
|
16
|
+
Pick your kits and select **Review changes**. Any kit questions and downloads happen automatically, then one compact review shows your kit changes and file totals for Repository and Global. Expand **Unchanged** to inspect your complete selection, or choose **View files** to browse paths and diffs. Choose **Apply changes** to save, or **Back to kits** to edit your selection. Inside a provider, choose **Back to providers** to keep browsing with your selections preserved. Run `loadout` again to change your selection.
|
|
17
|
+
|
|
18
|
+
The destination selector above the tabs shows **Repository** in cyan (this repository only) and **Global** in magenta (your user configuration across repositories). Active controls and selection markers follow the destination's color. Press **Tab** to switch destinations instantly, or **Shift+Tab** to cycle backward. **←/→** switches between the Kits, Browse, and Installed sections. Each destination keeps its own selections, provider, search, and cursor position, ready to browse as soon as you switch. A **\*** marks destinations with unapplied selections; **Review changes** includes the session's changes across both. Descriptions appear beneath every provider and kit, with dependency or update notes when needed.
|
|
19
|
+
|
|
20
|
+
Press **Esc** from review, questions, or downloads to return to your kits. Inside file details, **Esc** returns to the previous view. Your kit choices, completed answers, and picker position are preserved; completed downloads are reused during the session and file plans are rebuilt before review. In review, **↑/↓** scroll and **Tab** moves between actions. Press **Ctrl+C** to cancel setup, or **Esc twice quickly** from the picker. Nothing is applied until you choose **Apply changes**.
|
|
17
21
|
|
|
18
22
|
Conflicting project instructions are skipped with a warning; the kit’s skills still install.
|
|
19
23
|
|
package/dist/cli.js
CHANGED
|
@@ -5,10 +5,9 @@ import { readFileSync, realpathSync } from 'node:fs';
|
|
|
5
5
|
import os from 'node:os';
|
|
6
6
|
import { discover } from './catalog.js';
|
|
7
7
|
import { initialize } from './init.js';
|
|
8
|
-
import { interactive
|
|
9
|
-
import { apply,
|
|
8
|
+
import { interactive } from './setup.js';
|
|
9
|
+
import { apply, hasChanges, plan } from './storage.js';
|
|
10
10
|
import { renderWithExternal } from './external.js';
|
|
11
|
-
import { DownloadCancelledError } from './retry.js';
|
|
12
11
|
import { loadTarget } from './targets.js';
|
|
13
12
|
import { configure, disableKits, reasons, resolveKits, setAnswers, } from './resolve.js';
|
|
14
13
|
import { kitSource } from './schema.js';
|
|
@@ -134,49 +133,9 @@ async function generate(catalog, state, opts) {
|
|
|
134
133
|
}
|
|
135
134
|
async function setup() {
|
|
136
135
|
const { targets, initial } = interactiveTargets();
|
|
137
|
-
const configured = await interactive(targets, initial);
|
|
138
136
|
const offline = program.opts().offline;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const catalog = target.catalog;
|
|
142
|
-
console.log(`\n${target.label} · ${target.root}`);
|
|
143
|
-
const update = await selectUpdates(catalog, state, offline);
|
|
144
|
-
const rendered = await renderWithExternal(catalog, state, {
|
|
145
|
-
offline,
|
|
146
|
-
update,
|
|
147
|
-
retry: confirmRetry,
|
|
148
|
-
onRetry: (id) => console.log(`Retrying ${id}…`),
|
|
149
|
-
onFetch: (id, source) => console.log(`Fetching ${id} from ${source.repo}…`),
|
|
150
|
-
});
|
|
151
|
-
for (const id of resolveKits(catalog, state.selected)) {
|
|
152
|
-
const kit = catalog.kits.get(id);
|
|
153
|
-
if (kit.external) {
|
|
154
|
-
const source = update.includes(id)
|
|
155
|
-
? kit.external
|
|
156
|
-
: (kit.pinned ?? kit.external);
|
|
157
|
-
console.log(`${id}: ${source.repo}@${source.ref.slice(0, 12)} · license: ${source.license}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
const result = plan(catalog, state, rendered, { adopt: true });
|
|
161
|
-
preview(result, update.length > 0 || !!result.adopted?.length);
|
|
162
|
-
if (result.adopted?.length && !(await confirmAdoption(result.adopted)))
|
|
163
|
-
throw new DownloadCancelledError();
|
|
164
|
-
plans.push(result);
|
|
165
|
-
}
|
|
166
|
-
if (!plans.some(hasChanges))
|
|
167
|
-
return;
|
|
168
|
-
if (await confirmApply()) {
|
|
169
|
-
applyAll(plans);
|
|
170
|
-
console.log('\nYour loadout is ready.');
|
|
171
|
-
for (const result of plans) {
|
|
172
|
-
if (!result.skippedInstructions?.length)
|
|
173
|
-
continue;
|
|
174
|
-
console.log(result.root);
|
|
175
|
-
showSkipped(result);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
else
|
|
179
|
-
console.log('Cancelled. No kit selections or agent outputs saved.');
|
|
137
|
+
await interactive(targets, initial, { offline });
|
|
138
|
+
console.log('\nYour loadout is ready.');
|
|
180
139
|
}
|
|
181
140
|
program.action(setup);
|
|
182
141
|
program
|
package/dist/external.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ declare const storeSchema: z.ZodObject<{
|
|
|
33
33
|
}, z.core.$strict>>;
|
|
34
34
|
}, z.core.$strict>;
|
|
35
35
|
export type Snapshot = z.infer<typeof snapshotSchema>;
|
|
36
|
+
export type SnapshotCache = Map<string, Snapshot>;
|
|
36
37
|
export type ExternalStore = z.infer<typeof storeSchema>;
|
|
37
38
|
export type FetchBytes = (url: string, limit: number, signal?: AbortSignal) => Promise<Buffer>;
|
|
38
39
|
export declare function readExternal(root: string): {
|
|
@@ -47,5 +48,8 @@ export declare function renderWithExternal(catalog: Catalog, state: State, optio
|
|
|
47
48
|
onFetch?: (id: string, source: ExternalSource) => void;
|
|
48
49
|
onRetry?: (id: string) => void;
|
|
49
50
|
retry?: (id: string, error: Error) => Promise<boolean>;
|
|
51
|
+
signal?: AbortSignal;
|
|
52
|
+
cache?: SnapshotCache;
|
|
53
|
+
onReady?: (id: string) => void;
|
|
50
54
|
}): Promise<Rendered>;
|
|
51
55
|
export {};
|
package/dist/external.js
CHANGED
|
@@ -30,6 +30,12 @@ const storeSchema = z
|
|
|
30
30
|
kits: z.record(idSchema, snapshotSchema),
|
|
31
31
|
})
|
|
32
32
|
.strict();
|
|
33
|
+
const sourceKey = (source) => JSON.stringify({
|
|
34
|
+
repo: source.repo,
|
|
35
|
+
ref: source.ref,
|
|
36
|
+
license: source.license,
|
|
37
|
+
skills: [...source.skills].sort(),
|
|
38
|
+
});
|
|
33
39
|
export function readExternal(root) {
|
|
34
40
|
const raw = readOptional(root, '.loadout-personal/external.json');
|
|
35
41
|
return {
|
|
@@ -215,6 +221,7 @@ async function download(source, get) {
|
|
|
215
221
|
return complete;
|
|
216
222
|
}
|
|
217
223
|
export async function renderWithExternal(catalog, state, options = {}) {
|
|
224
|
+
options.signal?.throwIfAborted();
|
|
218
225
|
const result = render(catalog, state);
|
|
219
226
|
const enabled = resolveKits(catalog, state.selected);
|
|
220
227
|
const { raw, store } = readExternal(catalog.root);
|
|
@@ -222,34 +229,46 @@ export async function renderWithExternal(catalog, state, options = {}) {
|
|
|
222
229
|
if (!enabled.includes(id) || !catalog.kits.get(id)?.external)
|
|
223
230
|
throw new Error(`Cannot update ${id}: choose an enabled external kit.`);
|
|
224
231
|
for (const id of enabled) {
|
|
232
|
+
options.signal?.throwIfAborted();
|
|
225
233
|
const kit = catalog.kits.get(id);
|
|
226
234
|
const source = kit.external;
|
|
227
|
-
if (!source)
|
|
235
|
+
if (!source) {
|
|
236
|
+
options.onReady?.(id);
|
|
228
237
|
continue;
|
|
238
|
+
}
|
|
229
239
|
let snapshot = Object.hasOwn(store.kits, id) ? store.kits[id] : undefined;
|
|
230
240
|
const unchanged = snapshot && sameSource(snapshot.source, source);
|
|
231
241
|
if (!snapshot ||
|
|
232
242
|
(options.update?.includes(id) && !(options.offline && unchanged))) {
|
|
233
|
-
|
|
243
|
+
const cached = options.cache?.get(sourceKey(source));
|
|
244
|
+
if (!cached && options.offline)
|
|
234
245
|
throw new Error(`${id} is not available at the requested revision offline. Run without --offline once to fetch it.`);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
requests
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
246
|
+
if (!cached)
|
|
247
|
+
options.onFetch?.(id, source);
|
|
248
|
+
snapshot =
|
|
249
|
+
cached ??
|
|
250
|
+
(await retryDownload(async () => {
|
|
251
|
+
const controller = new AbortController();
|
|
252
|
+
const requests = new Map();
|
|
253
|
+
const get = (url, limit) => {
|
|
254
|
+
if (!requests.has(url))
|
|
255
|
+
requests.set(url, (options.fetch ?? fetchBytes)(url, limit, options.signal
|
|
256
|
+
? AbortSignal.any([options.signal, controller.signal])
|
|
257
|
+
: controller.signal));
|
|
258
|
+
return requests.get(url);
|
|
259
|
+
};
|
|
260
|
+
try {
|
|
261
|
+
return await download(source, get);
|
|
262
|
+
}
|
|
263
|
+
finally {
|
|
264
|
+
controller.abort();
|
|
265
|
+
await Promise.allSettled(requests.values());
|
|
266
|
+
requests.clear();
|
|
267
|
+
}
|
|
268
|
+
}, options.retry ? (error) => options.retry(id, error) : undefined, () => options.onRetry?.(id), options.signal));
|
|
269
|
+
options.signal?.throwIfAborted();
|
|
270
|
+
validateSnapshot(snapshot, id);
|
|
271
|
+
options.cache?.set(sourceKey(source), snapshot);
|
|
253
272
|
store.kits[id] = snapshot;
|
|
254
273
|
}
|
|
255
274
|
validateSnapshot(snapshot, id);
|
|
@@ -271,6 +290,7 @@ export async function renderWithExternal(catalog, state, options = {}) {
|
|
|
271
290
|
});
|
|
272
291
|
}
|
|
273
292
|
}
|
|
293
|
+
options.onReady?.(id);
|
|
274
294
|
}
|
|
275
295
|
if (raw || Object.keys(store.kits).length)
|
|
276
296
|
result.external = {
|
package/dist/interactive.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { checkbox, confirm, select } from '@inquirer/prompts';
|
|
2
|
-
import { type Catalog, type State } from './schema.js';
|
|
3
|
-
import { type TargetSelection } from './picker.js';
|
|
2
|
+
import { type Answer, type Catalog, type State } from './schema.js';
|
|
4
3
|
import { type Target } from './targets.js';
|
|
5
|
-
export
|
|
6
|
-
export declare
|
|
7
|
-
|
|
8
|
-
export declare function
|
|
4
|
+
export type PromptContext = NonNullable<Parameters<typeof confirm>[1]>;
|
|
5
|
+
export declare class BackNavigation extends Error {
|
|
6
|
+
}
|
|
7
|
+
export declare function configureSelection(target: Target, state: State, context?: Parameters<typeof confirm>[1], onAnswer?: (kit: string, key: string, answer: Answer) => void): Promise<State>;
|
|
8
|
+
export declare function confirmApply(context?: PromptContext, scopes?: string[]): Promise<boolean>;
|
|
9
|
+
export declare function selectUpdates(catalog: Catalog, state: State, offline?: boolean, context?: Parameters<typeof checkbox>[1], options?: {
|
|
10
|
+
message?: string;
|
|
11
|
+
selected?: string[];
|
|
12
|
+
quiet?: boolean;
|
|
13
|
+
}): Promise<string[]>;
|
|
9
14
|
export declare function confirmRetry(id: string, error: Error, context?: Parameters<typeof select>[1]): Promise<boolean>;
|
|
10
|
-
export declare function confirmAdoption(paths: string[], context?: Parameters<typeof confirm>[1]): Promise<boolean>;
|
|
15
|
+
export declare function confirmAdoption(paths: string[], context?: Parameters<typeof confirm>[1], scope?: string): Promise<boolean>;
|
|
16
|
+
export declare function retryReview(error: unknown, context?: PromptContext): Promise<boolean>;
|
package/dist/interactive.js
CHANGED
|
@@ -1,32 +1,46 @@
|
|
|
1
1
|
import { checkbox, confirm, select } from '@inquirer/prompts';
|
|
2
2
|
import { configure } from './resolve.js';
|
|
3
|
-
import { validAnswer } from './schema.js';
|
|
4
|
-
import { targetPicker } from './picker.js';
|
|
3
|
+
import { validAnswer, } from './schema.js';
|
|
5
4
|
import { availableUpdates, updateDescription } from './updates.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
import { prepareInput } from './terminal.js';
|
|
6
|
+
export class BackNavigation extends Error {
|
|
7
|
+
}
|
|
8
|
+
async function backPrompt(prompt, context = {}) {
|
|
9
|
+
const input = context.input ?? process.stdin;
|
|
10
|
+
prepareInput(input);
|
|
11
|
+
const controller = new AbortController();
|
|
12
|
+
const back = (_text, key) => {
|
|
13
|
+
if (key.name === 'escape')
|
|
14
|
+
controller.abort(new BackNavigation());
|
|
15
|
+
};
|
|
16
|
+
input.on('keypress', back);
|
|
17
|
+
try {
|
|
18
|
+
return await prompt({
|
|
19
|
+
...context,
|
|
20
|
+
signal: context.signal
|
|
21
|
+
? AbortSignal.any([context.signal, controller.signal])
|
|
22
|
+
: controller.signal,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error instanceof Error && error.cause instanceof BackNavigation)
|
|
27
|
+
throw error.cause;
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
input.off('keypress', back);
|
|
17
32
|
}
|
|
18
|
-
return configured;
|
|
19
33
|
}
|
|
20
|
-
export async function configureSelection(target, state, context) {
|
|
34
|
+
export async function configureSelection(target, state, context, onAnswer) {
|
|
21
35
|
const change = new Map();
|
|
22
|
-
|
|
36
|
+
const ask = async (kit, key, question, value) => {
|
|
23
37
|
if (!change.has(kit)) {
|
|
24
38
|
const hasSaved = Object.entries(target.catalog.kits.get(kit).questions).some(([name, q]) => validAnswer(q, state.answers[kit]?.[name]));
|
|
25
39
|
change.set(kit, hasSaved
|
|
26
|
-
? await confirm({
|
|
40
|
+
? await backPrompt((context) => confirm({
|
|
27
41
|
message: `${target.label} · ${kit} · Change selection?`,
|
|
28
42
|
default: false,
|
|
29
|
-
}, context)
|
|
43
|
+
}, context), context)
|
|
30
44
|
: true);
|
|
31
45
|
}
|
|
32
46
|
const saved = state.answers[kit]?.[key];
|
|
@@ -34,47 +48,76 @@ export async function configureSelection(target, state, context) {
|
|
|
34
48
|
return saved;
|
|
35
49
|
const message = `${target.label} · ${kit} · ${question.message}`;
|
|
36
50
|
if (question.type === 'boolean')
|
|
37
|
-
return confirm({ message, default: typeof value === 'boolean' ? value : false }, context);
|
|
38
|
-
return select({
|
|
51
|
+
return backPrompt((context) => confirm({ message, default: typeof value === 'boolean' ? value : false }, context), context);
|
|
52
|
+
return backPrompt((context) => select({
|
|
39
53
|
message,
|
|
40
54
|
choices: question.choices.map((v) => ({ name: v, value: v })),
|
|
41
55
|
default: typeof value === 'string' ? value : undefined,
|
|
42
|
-
}, context);
|
|
56
|
+
}, context), context);
|
|
57
|
+
};
|
|
58
|
+
return configure(target.catalog, state, async (kit, key, question, value) => {
|
|
59
|
+
const answer = await ask(kit, key, question, value);
|
|
60
|
+
onAnswer?.(kit, key, answer);
|
|
61
|
+
return answer;
|
|
43
62
|
});
|
|
44
63
|
}
|
|
45
|
-
export async function confirmApply() {
|
|
46
|
-
return confirm({
|
|
64
|
+
export async function confirmApply(context, scopes = []) {
|
|
65
|
+
return backPrompt((context) => confirm({
|
|
66
|
+
message: scopes.length
|
|
67
|
+
? `Apply changes to ${scopes.join(' and ')}?`
|
|
68
|
+
: 'Apply changes?',
|
|
69
|
+
default: true,
|
|
70
|
+
}, context), context);
|
|
47
71
|
}
|
|
48
|
-
export async function selectUpdates(catalog, state, offline = false, context) {
|
|
72
|
+
export async function selectUpdates(catalog, state, offline = false, context, options = {}) {
|
|
49
73
|
const updates = availableUpdates(catalog, state.selected);
|
|
50
74
|
if (!updates.length)
|
|
51
75
|
return [];
|
|
52
76
|
if (offline) {
|
|
53
|
-
|
|
77
|
+
if (!options.quiet)
|
|
78
|
+
console.log(`${updates.length} catalog update(s) available. Run loadout online to review them; keeping saved versions.`);
|
|
54
79
|
return [];
|
|
55
80
|
}
|
|
56
|
-
return checkbox({
|
|
57
|
-
message:
|
|
81
|
+
return backPrompt((context) => checkbox({
|
|
82
|
+
message: options.message ??
|
|
83
|
+
'Catalog updates available · choose kits to update (Enter skips)',
|
|
58
84
|
choices: updates.map((kit) => ({
|
|
59
85
|
name: kit.id,
|
|
60
86
|
value: kit.id,
|
|
61
87
|
description: updateDescription(kit),
|
|
88
|
+
checked: options.selected?.includes(kit.id) ?? false,
|
|
62
89
|
})),
|
|
63
90
|
required: false,
|
|
64
|
-
}, context);
|
|
91
|
+
}, context), context);
|
|
65
92
|
}
|
|
66
93
|
export async function confirmRetry(id, error, context) {
|
|
67
|
-
return select({
|
|
94
|
+
return backPrompt((context) => select({
|
|
68
95
|
message: `${id}: ${error.message}`,
|
|
69
96
|
choices: [
|
|
70
97
|
{ name: 'Retry download', value: true },
|
|
71
98
|
{ name: 'Cancel', value: false },
|
|
72
99
|
],
|
|
73
|
-
}, context);
|
|
100
|
+
}, context), context);
|
|
74
101
|
}
|
|
75
|
-
export async function confirmAdoption(paths, context) {
|
|
76
|
-
return confirm({
|
|
77
|
-
message: `Keep existing content and let Loadout manage ${paths.join(', ')}? Originals will be restored when disabled.`,
|
|
102
|
+
export async function confirmAdoption(paths, context, scope) {
|
|
103
|
+
return backPrompt((context) => confirm({
|
|
104
|
+
message: `${scope ? `${scope} · ` : ''}Keep existing content and let Loadout manage ${paths.join(', ')}? Originals will be restored when disabled.`,
|
|
78
105
|
default: true,
|
|
79
|
-
}, context);
|
|
106
|
+
}, context), context);
|
|
107
|
+
}
|
|
108
|
+
export async function retryReview(error, context) {
|
|
109
|
+
try {
|
|
110
|
+
return await backPrompt((context) => select({
|
|
111
|
+
message: `Could not finish: ${error instanceof Error ? error.message : String(error)}`,
|
|
112
|
+
choices: [
|
|
113
|
+
{ name: 'Try again', value: true },
|
|
114
|
+
{ name: 'Back to kits', value: false },
|
|
115
|
+
],
|
|
116
|
+
}, context), context);
|
|
117
|
+
}
|
|
118
|
+
catch (failure) {
|
|
119
|
+
if (failure instanceof BackNavigation)
|
|
120
|
+
return false;
|
|
121
|
+
throw failure;
|
|
122
|
+
}
|
|
80
123
|
}
|
package/dist/picker.d.ts
CHANGED
|
@@ -6,11 +6,32 @@ export type PickerConfig = {
|
|
|
6
6
|
columns?: number;
|
|
7
7
|
rows?: number;
|
|
8
8
|
};
|
|
9
|
+
declare const repositorySections: readonly ['Kits', 'Browse', 'Installed'];
|
|
10
|
+
type Section = (typeof repositorySections)[number];
|
|
9
11
|
export type TargetPickerConfig = {
|
|
10
12
|
targets: Target[];
|
|
11
13
|
initial?: number;
|
|
12
14
|
columns?: number;
|
|
13
15
|
rows?: number;
|
|
16
|
+
session?: PickerSession;
|
|
17
|
+
};
|
|
18
|
+
type PickerView = {
|
|
19
|
+
section: Section;
|
|
20
|
+
provider: string | undefined;
|
|
21
|
+
providerList: {
|
|
22
|
+
query: string;
|
|
23
|
+
active: number;
|
|
24
|
+
};
|
|
25
|
+
query: string;
|
|
26
|
+
active: number;
|
|
27
|
+
};
|
|
28
|
+
export type PickerSession = {
|
|
29
|
+
snapshot?: PickerView & {
|
|
30
|
+
targetIndex: number;
|
|
31
|
+
visited: number[];
|
|
32
|
+
selections: string[][];
|
|
33
|
+
views: PickerView[];
|
|
34
|
+
};
|
|
14
35
|
};
|
|
15
36
|
export type TargetSelection = {
|
|
16
37
|
target: Target;
|
|
@@ -21,6 +42,7 @@ declare const renderPicker: import("@inquirer/type").Prompt<TargetSelection[], {
|
|
|
21
42
|
initial?: number;
|
|
22
43
|
columns?: number;
|
|
23
44
|
rows?: number;
|
|
45
|
+
session?: PickerSession;
|
|
24
46
|
} & TargetPickerConfig>;
|
|
25
47
|
export declare function targetPicker(config: TargetPickerConfig, context?: Parameters<typeof renderPicker>[1]): Promise<TargetSelection[]>;
|
|
26
48
|
export declare function kitPicker(config: PickerConfig, context?: Parameters<typeof targetPicker>[1]): Promise<string[]>;
|