umbrella-context 0.1.38 → 0.1.39
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/dist/commands/hub.d.ts +3 -1
- package/dist/commands/hub.js +218 -68
- package/dist/commands/tui.js +11 -8
- package/dist/config.d.ts +3 -0
- package/dist/config.js +1 -0
- package/package.json +1 -1
package/dist/commands/hub.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ type HubEntry = {
|
|
|
6
6
|
includes: string[];
|
|
7
7
|
nextSteps: string[];
|
|
8
8
|
installsConnector?: string;
|
|
9
|
+
registryName?: string;
|
|
10
|
+
registryUrl?: string;
|
|
9
11
|
};
|
|
10
12
|
export type HubCommandResult = {
|
|
11
13
|
action: "list" | "install" | "inspect" | "installed" | "registry" | "browse";
|
|
@@ -16,7 +18,7 @@ export type HubCommandResult = {
|
|
|
16
18
|
recommendedConnector?: string;
|
|
17
19
|
};
|
|
18
20
|
export type HubRegistryEntry = HubEntry;
|
|
19
|
-
export declare function listHubRegistryEntries(): HubRegistryEntry[]
|
|
21
|
+
export declare function listHubRegistryEntries(): Promise<HubRegistryEntry[]>;
|
|
20
22
|
export declare function hubCommandAction(action: string, subAction?: string): Promise<HubCommandResult | void>;
|
|
21
23
|
export declare function hubCommand(cli: any): void;
|
|
22
24
|
export {};
|
package/dist/commands/hub.js
CHANGED
|
@@ -2,59 +2,8 @@ import { randomUUID } from "crypto";
|
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import prompts from "prompts";
|
|
4
4
|
import { configManager } from "../config.js";
|
|
5
|
-
import { getInstalledHubEntries, getSessionState, recordSessionEvent, recordSessionHubEntry, setInstalledHubEntries, setSessionPanel, writeHubAsset, writeHubAssetFiles } from "../repo-state.js";
|
|
5
|
+
import { getInstalledHubEntries, getSessionState, recordSessionEvent, recordSessionHubEntry, setInstalledHubEntries, setSessionPanel, writeHubAsset, writeHubAssetFiles, } from "../repo-state.js";
|
|
6
6
|
import { connectorsCommandAction } from "./connectors.js";
|
|
7
|
-
async function runHubBrowseFlow() {
|
|
8
|
-
const answer = await prompts({
|
|
9
|
-
type: "select",
|
|
10
|
-
name: "value",
|
|
11
|
-
message: "Choose a hub entry to browse",
|
|
12
|
-
choices: DEFAULT_HUB_ENTRIES.map((entry) => ({
|
|
13
|
-
title: `${entry.name} (${entry.type})`,
|
|
14
|
-
description: entry.description,
|
|
15
|
-
value: entry.slug,
|
|
16
|
-
})),
|
|
17
|
-
});
|
|
18
|
-
if (!answer.value) {
|
|
19
|
-
console.log(chalk.yellow("\n No hub entry selected."));
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
const inspectResult = await hubCommandAction("inspect", answer.value);
|
|
23
|
-
if (!inspectResult?.installedEntry)
|
|
24
|
-
return;
|
|
25
|
-
const next = await prompts({
|
|
26
|
-
type: "select",
|
|
27
|
-
name: "value",
|
|
28
|
-
message: `What do you want to do with ${inspectResult.installedEntry.name}?`,
|
|
29
|
-
choices: [
|
|
30
|
-
{ title: "Install it into this repo", value: "install" },
|
|
31
|
-
...(inspectResult.recommendedConnector
|
|
32
|
-
? [{ title: `Install and run ${inspectResult.recommendedConnector}`, value: "connector" }]
|
|
33
|
-
: []),
|
|
34
|
-
{ title: "Back", value: "back" },
|
|
35
|
-
],
|
|
36
|
-
});
|
|
37
|
-
if (!next.value || next.value === "back") {
|
|
38
|
-
return {
|
|
39
|
-
action: "browse",
|
|
40
|
-
changed: false,
|
|
41
|
-
installedEntry: inspectResult.installedEntry,
|
|
42
|
-
recommendedConnector: inspectResult.recommendedConnector,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
const installResult = await hubCommandAction("install", inspectResult.installedEntry.slug);
|
|
46
|
-
if (next.value === "connector" && inspectResult.recommendedConnector) {
|
|
47
|
-
await connectorsCommandAction("run", inspectResult.recommendedConnector);
|
|
48
|
-
}
|
|
49
|
-
return {
|
|
50
|
-
action: "browse",
|
|
51
|
-
changed: Boolean(installResult?.changed),
|
|
52
|
-
installedEntry: installResult?.installedEntry ?? inspectResult.installedEntry,
|
|
53
|
-
assetPath: installResult?.assetPath,
|
|
54
|
-
filePaths: installResult?.filePaths,
|
|
55
|
-
recommendedConnector: inspectResult.recommendedConnector,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
7
|
const DEFAULT_HUB_ENTRIES = [
|
|
59
8
|
{
|
|
60
9
|
slug: "quick-ping-growth-bundle",
|
|
@@ -93,8 +42,108 @@ const DEFAULT_HUB_ENTRIES = [
|
|
|
93
42
|
installsConnector: "codex-mcp",
|
|
94
43
|
},
|
|
95
44
|
];
|
|
96
|
-
|
|
97
|
-
|
|
45
|
+
function normalizeRemoteHubEntry(raw, registry) {
|
|
46
|
+
if (!raw.slug || !raw.name) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
if (raw.type !== "bundle" && raw.type !== "skill" && raw.type !== "connector") {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
slug: raw.slug,
|
|
54
|
+
name: raw.name,
|
|
55
|
+
type: raw.type,
|
|
56
|
+
description: raw.description ?? "No description provided.",
|
|
57
|
+
includes: Array.isArray(raw.includes) ? raw.includes : [],
|
|
58
|
+
nextSteps: Array.isArray(raw.nextSteps) ? raw.nextSteps : [],
|
|
59
|
+
installsConnector: raw.installsConnector,
|
|
60
|
+
registryName: registry.name,
|
|
61
|
+
registryUrl: registry.url,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function buildRegistryHeaders(registry) {
|
|
65
|
+
const token = registry.token?.trim();
|
|
66
|
+
const scheme = registry.authScheme ?? "none";
|
|
67
|
+
if (!token || scheme === "none") {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
if (scheme === "bearer") {
|
|
71
|
+
return { Authorization: `Bearer ${token}` };
|
|
72
|
+
}
|
|
73
|
+
if (scheme === "token") {
|
|
74
|
+
return { Authorization: `Token ${token}` };
|
|
75
|
+
}
|
|
76
|
+
if (scheme === "basic") {
|
|
77
|
+
return { Authorization: `Basic ${token}` };
|
|
78
|
+
}
|
|
79
|
+
if (scheme === "custom-header") {
|
|
80
|
+
return { [registry.headerName?.trim() || "X-Registry-Token"]: token };
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
async function fetchRegistryStatus(registry) {
|
|
85
|
+
if (registry.url.startsWith("https://hub.umbrella.local/")) {
|
|
86
|
+
return {
|
|
87
|
+
registry,
|
|
88
|
+
status: "ok",
|
|
89
|
+
entryCount: DEFAULT_HUB_ENTRIES.length,
|
|
90
|
+
entries: DEFAULT_HUB_ENTRIES.map((entry) => ({
|
|
91
|
+
...entry,
|
|
92
|
+
registryName: registry.name,
|
|
93
|
+
registryUrl: registry.url,
|
|
94
|
+
})),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const response = await fetch(registry.url, {
|
|
99
|
+
headers: buildRegistryHeaders(registry),
|
|
100
|
+
});
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
return {
|
|
103
|
+
registry,
|
|
104
|
+
status: "error",
|
|
105
|
+
entryCount: 0,
|
|
106
|
+
error: `HTTP ${response.status}`,
|
|
107
|
+
entries: [],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const payload = (await response.json());
|
|
111
|
+
const entries = (payload.entries ?? [])
|
|
112
|
+
.map((entry) => normalizeRemoteHubEntry(entry, registry))
|
|
113
|
+
.filter((entry) => Boolean(entry));
|
|
114
|
+
return {
|
|
115
|
+
registry,
|
|
116
|
+
status: "ok",
|
|
117
|
+
entryCount: entries.length,
|
|
118
|
+
entries,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
return {
|
|
123
|
+
registry,
|
|
124
|
+
status: "error",
|
|
125
|
+
entryCount: 0,
|
|
126
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
127
|
+
entries: [],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async function getHubCatalog() {
|
|
132
|
+
const statuses = await Promise.all(configManager.hubRegistries.map((registry) => fetchRegistryStatus(registry)));
|
|
133
|
+
const deduped = new Map();
|
|
134
|
+
for (const entry of statuses.flatMap((status) => status.entries)) {
|
|
135
|
+
if (!deduped.has(entry.slug)) {
|
|
136
|
+
deduped.set(entry.slug, entry);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
statuses,
|
|
141
|
+
entries: [...deduped.values()],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export async function listHubRegistryEntries() {
|
|
145
|
+
const { entries } = await getHubCatalog();
|
|
146
|
+
return entries;
|
|
98
147
|
}
|
|
99
148
|
function buildHubAsset(entry) {
|
|
100
149
|
return [
|
|
@@ -102,6 +151,7 @@ function buildHubAsset(entry) {
|
|
|
102
151
|
"",
|
|
103
152
|
`Type: ${entry.type}`,
|
|
104
153
|
`Slug: ${entry.slug}`,
|
|
154
|
+
`Registry: ${entry.registryName ?? "Umbrella Hub"}`,
|
|
105
155
|
"",
|
|
106
156
|
"## Why this exists",
|
|
107
157
|
"",
|
|
@@ -246,22 +296,86 @@ function printInstalled(installed) {
|
|
|
246
296
|
console.log(chalk.gray(` Installed from ${entry.registryName} at ${new Date(entry.installedAt).toLocaleString()}`));
|
|
247
297
|
});
|
|
248
298
|
}
|
|
249
|
-
function printRegistryList() {
|
|
299
|
+
function printRegistryList(statuses) {
|
|
250
300
|
console.log(chalk.bold("\n Hub Registries\n"));
|
|
251
|
-
|
|
301
|
+
statuses.forEach(({ registry, status, entryCount, error }, index) => {
|
|
302
|
+
const authLabel = registry.authScheme && registry.authScheme !== "none"
|
|
303
|
+
? ` [${registry.authScheme}]`
|
|
304
|
+
: "";
|
|
305
|
+
const tokenLabel = registry.token ? " (authenticated)" : "";
|
|
306
|
+
const statusLabel = status === "ok"
|
|
307
|
+
? `${entryCount} entr${entryCount === 1 ? "y" : "ies"}`
|
|
308
|
+
: `error: ${error ?? "unknown"}`;
|
|
252
309
|
console.log(` ${index + 1}. ${registry.name}`);
|
|
253
|
-
console.log(chalk.gray(` ${registry.url}`));
|
|
310
|
+
console.log(chalk.gray(` ${registry.url}${authLabel}${tokenLabel}`));
|
|
311
|
+
console.log(chalk.gray(` ${statusLabel}`));
|
|
254
312
|
});
|
|
255
313
|
}
|
|
314
|
+
async function runHubBrowseFlow() {
|
|
315
|
+
const { entries } = await getHubCatalog();
|
|
316
|
+
const answer = await prompts({
|
|
317
|
+
type: "select",
|
|
318
|
+
name: "value",
|
|
319
|
+
message: "Choose a hub entry to browse",
|
|
320
|
+
choices: entries.map((entry) => ({
|
|
321
|
+
title: `${entry.name} (${entry.type})`,
|
|
322
|
+
description: entry.registryName ? `${entry.description} [${entry.registryName}]` : entry.description,
|
|
323
|
+
value: entry.slug,
|
|
324
|
+
})),
|
|
325
|
+
});
|
|
326
|
+
if (!answer.value) {
|
|
327
|
+
console.log(chalk.yellow("\n No hub entry selected."));
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const inspectResult = await hubCommandAction("inspect", answer.value);
|
|
331
|
+
if (!inspectResult?.installedEntry)
|
|
332
|
+
return;
|
|
333
|
+
const next = await prompts({
|
|
334
|
+
type: "select",
|
|
335
|
+
name: "value",
|
|
336
|
+
message: `What do you want to do with ${inspectResult.installedEntry.name}?`,
|
|
337
|
+
choices: [
|
|
338
|
+
{ title: "Install it into this repo", value: "install" },
|
|
339
|
+
...(inspectResult.recommendedConnector
|
|
340
|
+
? [{ title: `Install and run ${inspectResult.recommendedConnector}`, value: "connector" }]
|
|
341
|
+
: []),
|
|
342
|
+
{ title: "Back", value: "back" },
|
|
343
|
+
],
|
|
344
|
+
});
|
|
345
|
+
if (!next.value || next.value === "back") {
|
|
346
|
+
return {
|
|
347
|
+
action: "browse",
|
|
348
|
+
changed: false,
|
|
349
|
+
installedEntry: inspectResult.installedEntry,
|
|
350
|
+
recommendedConnector: inspectResult.recommendedConnector,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
const installResult = await hubCommandAction("install", inspectResult.installedEntry.slug);
|
|
354
|
+
if (next.value === "connector" && inspectResult.recommendedConnector) {
|
|
355
|
+
await connectorsCommandAction("run", inspectResult.recommendedConnector);
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
action: "browse",
|
|
359
|
+
changed: Boolean(installResult?.changed),
|
|
360
|
+
installedEntry: installResult?.installedEntry ?? inspectResult.installedEntry,
|
|
361
|
+
assetPath: installResult?.assetPath,
|
|
362
|
+
filePaths: installResult?.filePaths,
|
|
363
|
+
recommendedConnector: inspectResult.recommendedConnector,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
256
366
|
export async function hubCommandAction(action, subAction) {
|
|
257
367
|
const normalized = action.toLowerCase();
|
|
258
368
|
await setSessionPanel("hub", subAction ?? normalized);
|
|
259
369
|
if (normalized === "list") {
|
|
260
370
|
await setSessionPanel("hub", "list");
|
|
371
|
+
const { entries } = await getHubCatalog();
|
|
261
372
|
console.log(chalk.bold("\n Hub Catalog\n"));
|
|
262
|
-
|
|
373
|
+
entries.forEach((entry, index) => {
|
|
263
374
|
console.log(` ${index + 1}. ${entry.name} [${entry.type}]`);
|
|
264
375
|
console.log(chalk.gray(` ${entry.description}`));
|
|
376
|
+
if (entry.registryName) {
|
|
377
|
+
console.log(chalk.gray(` Source: ${entry.registryName}`));
|
|
378
|
+
}
|
|
265
379
|
});
|
|
266
380
|
const installed = await getInstalledHubEntries();
|
|
267
381
|
if (installed.length > 0) {
|
|
@@ -274,20 +388,21 @@ export async function hubCommandAction(action, subAction) {
|
|
|
274
388
|
return runHubBrowseFlow();
|
|
275
389
|
}
|
|
276
390
|
if (normalized === "install") {
|
|
391
|
+
const { entries } = await getHubCatalog();
|
|
277
392
|
const installed = await getInstalledHubEntries();
|
|
278
|
-
let selected = subAction ?
|
|
393
|
+
let selected = subAction ? entries.find((entry) => entry.slug === subAction) : undefined;
|
|
279
394
|
if (!selected) {
|
|
280
395
|
const answer = await prompts({
|
|
281
396
|
type: "select",
|
|
282
397
|
name: "value",
|
|
283
398
|
message: "Choose a hub entry to install into this repo",
|
|
284
|
-
choices:
|
|
399
|
+
choices: entries.map((entry) => ({
|
|
285
400
|
title: `${entry.name} (${entry.type})`,
|
|
286
|
-
description: entry.description,
|
|
401
|
+
description: entry.registryName ? `${entry.description} [${entry.registryName}]` : entry.description,
|
|
287
402
|
value: entry.slug,
|
|
288
403
|
})),
|
|
289
404
|
});
|
|
290
|
-
selected =
|
|
405
|
+
selected = entries.find((entry) => entry.slug === answer.value);
|
|
291
406
|
}
|
|
292
407
|
if (!selected) {
|
|
293
408
|
console.log(chalk.yellow("\n No hub entry selected."));
|
|
@@ -311,7 +426,6 @@ export async function hubCommandAction(action, subAction) {
|
|
|
311
426
|
installedEntry: selected,
|
|
312
427
|
};
|
|
313
428
|
}
|
|
314
|
-
const registry = configManager.hubRegistries[0];
|
|
315
429
|
await setInstalledHubEntries([
|
|
316
430
|
...installed,
|
|
317
431
|
{
|
|
@@ -321,7 +435,7 @@ export async function hubCommandAction(action, subAction) {
|
|
|
321
435
|
type: selected.type,
|
|
322
436
|
description: selected.description,
|
|
323
437
|
installedAt: new Date().toISOString(),
|
|
324
|
-
registryName:
|
|
438
|
+
registryName: selected.registryName ?? "Umbrella Hub",
|
|
325
439
|
},
|
|
326
440
|
]);
|
|
327
441
|
const assetPath = await writeHubAsset(selected.slug, buildHubAsset(selected));
|
|
@@ -353,9 +467,8 @@ export async function hubCommandAction(action, subAction) {
|
|
|
353
467
|
};
|
|
354
468
|
}
|
|
355
469
|
if (normalized === "inspect") {
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
: undefined;
|
|
470
|
+
const { entries } = await getHubCatalog();
|
|
471
|
+
const target = subAction ? entries.find((entry) => entry.slug === subAction) : undefined;
|
|
359
472
|
if (!target) {
|
|
360
473
|
console.log(chalk.red("Use: hub inspect <slug>"));
|
|
361
474
|
return;
|
|
@@ -376,6 +489,7 @@ export async function hubCommandAction(action, subAction) {
|
|
|
376
489
|
console.log(` Type: ${target.type}`);
|
|
377
490
|
console.log(` Slug: ${target.slug}`);
|
|
378
491
|
console.log(` Installed: ${isInstalled ? "Yes" : "No"}`);
|
|
492
|
+
console.log(` Registry: ${target.registryName ?? "Umbrella Hub"}`);
|
|
379
493
|
console.log(chalk.gray(` ${target.description}`));
|
|
380
494
|
console.log("");
|
|
381
495
|
console.log(chalk.cyan(" Includes"));
|
|
@@ -417,13 +531,38 @@ export async function hubCommandAction(action, subAction) {
|
|
|
417
531
|
await setSessionPanel("hub", `registry:${subAction ?? "list"}`);
|
|
418
532
|
const mode = (subAction ?? "list").toLowerCase();
|
|
419
533
|
if (mode === "list") {
|
|
420
|
-
|
|
534
|
+
const { statuses } = await getHubCatalog();
|
|
535
|
+
printRegistryList(statuses);
|
|
421
536
|
return { action: "registry", changed: false };
|
|
422
537
|
}
|
|
423
538
|
if (mode === "add") {
|
|
424
539
|
const answer = await prompts([
|
|
425
540
|
{ type: "text", name: "name", message: "Registry name" },
|
|
426
541
|
{ type: "text", name: "url", message: "Registry URL" },
|
|
542
|
+
{
|
|
543
|
+
type: "select",
|
|
544
|
+
name: "authScheme",
|
|
545
|
+
message: "Authentication",
|
|
546
|
+
choices: [
|
|
547
|
+
{ title: "No auth", value: "none" },
|
|
548
|
+
{ title: "Bearer token", value: "bearer" },
|
|
549
|
+
{ title: "Token header", value: "token" },
|
|
550
|
+
{ title: "Basic header", value: "basic" },
|
|
551
|
+
{ title: "Custom header", value: "custom-header" },
|
|
552
|
+
],
|
|
553
|
+
initial: 0,
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
type: (_prev, values) => values.authScheme && values.authScheme !== "none" ? "password" : null,
|
|
557
|
+
name: "token",
|
|
558
|
+
message: "Registry token",
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
type: (_prev, values) => values.authScheme === "custom-header" ? "text" : null,
|
|
562
|
+
name: "headerName",
|
|
563
|
+
message: "Custom header name",
|
|
564
|
+
initial: "X-Registry-Token",
|
|
565
|
+
},
|
|
427
566
|
]);
|
|
428
567
|
if (!answer.name || !answer.url) {
|
|
429
568
|
console.log(chalk.yellow("\n Registry add cancelled."));
|
|
@@ -433,6 +572,9 @@ export async function hubCommandAction(action, subAction) {
|
|
|
433
572
|
id: randomUUID(),
|
|
434
573
|
name: answer.name,
|
|
435
574
|
url: answer.url,
|
|
575
|
+
authScheme: answer.authScheme ?? "none",
|
|
576
|
+
token: answer.token || undefined,
|
|
577
|
+
headerName: answer.headerName || undefined,
|
|
436
578
|
updatedAt: new Date().toISOString(),
|
|
437
579
|
});
|
|
438
580
|
await recordSessionEvent({
|
|
@@ -444,6 +586,14 @@ export async function hubCommandAction(action, subAction) {
|
|
|
444
586
|
status: "success",
|
|
445
587
|
});
|
|
446
588
|
console.log(chalk.green(`\n Added registry ${answer.name}.`));
|
|
589
|
+
const { statuses } = await getHubCatalog();
|
|
590
|
+
const addedStatus = statuses.find((status) => status.registry.url === answer.url);
|
|
591
|
+
if (addedStatus?.status === "ok") {
|
|
592
|
+
console.log(chalk.gray(` Found ${addedStatus.entryCount} hub entr${addedStatus.entryCount === 1 ? "y" : "ies"} immediately.`));
|
|
593
|
+
}
|
|
594
|
+
else if (addedStatus?.error) {
|
|
595
|
+
console.log(chalk.yellow(` Registry saved, but the first fetch failed: ${addedStatus.error}`));
|
|
596
|
+
}
|
|
447
597
|
return { action: "registry", changed: true };
|
|
448
598
|
}
|
|
449
599
|
if (mode === "remove") {
|
package/dist/commands/tui.js
CHANGED
|
@@ -297,6 +297,7 @@ function App() {
|
|
|
297
297
|
const [modelPanelRecentModel, setModelPanelRecentModel] = useState(null);
|
|
298
298
|
const [hubPanelMode, setHubPanelMode] = useState("browse");
|
|
299
299
|
const [hubPanelSelectedIndex, setHubPanelSelectedIndex] = useState(0);
|
|
300
|
+
const [hubRegistryEntries, setHubRegistryEntries] = useState([]);
|
|
300
301
|
const [connectorsPanelMode, setConnectorsPanelMode] = useState("browse");
|
|
301
302
|
const [connectorsPanelSelectedIndex, setConnectorsPanelSelectedIndex] = useState(0);
|
|
302
303
|
const [tasksPanelMode, setTasksPanelMode] = useState("browse");
|
|
@@ -404,11 +405,14 @@ function App() {
|
|
|
404
405
|
useEffect(() => {
|
|
405
406
|
if (activePanel !== "hub" || busyLabel)
|
|
406
407
|
return;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
408
|
+
void (async () => {
|
|
409
|
+
const registryEntries = await listHubRegistryEntries();
|
|
410
|
+
setHubRegistryEntries(registryEntries);
|
|
411
|
+
const recentSlug = vendorHubStore?.recentSlug ?? null;
|
|
412
|
+
const recentIndex = registryEntries.findIndex((entry) => entry.slug === recentSlug);
|
|
413
|
+
setHubPanelSelectedIndex(recentIndex >= 0 ? recentIndex : 0);
|
|
414
|
+
setHubPanelMode("browse");
|
|
415
|
+
})();
|
|
412
416
|
}, [activePanel, refreshTick, busyLabel, vendorHubStore?.recentSlug]);
|
|
413
417
|
useEffect(() => {
|
|
414
418
|
if (activePanel !== "connectors" || busyLabel)
|
|
@@ -1298,7 +1302,7 @@ function App() {
|
|
|
1298
1302
|
if (activePanel === "hub") {
|
|
1299
1303
|
if (navigationFocus === "sidebar")
|
|
1300
1304
|
return;
|
|
1301
|
-
const registryEntries =
|
|
1305
|
+
const registryEntries = hubRegistryEntries;
|
|
1302
1306
|
if (key.upArrow || input === "k") {
|
|
1303
1307
|
setHubPanelSelectedIndex((value) => Math.max(0, value - 1));
|
|
1304
1308
|
return;
|
|
@@ -1495,8 +1499,7 @@ function App() {
|
|
|
1495
1499
|
mainContent = (_jsx(SpacePanelView, { companyName: vendorContextSummary.companyName ?? config.companyName, currentSpaceName: vendorContextSummary.spaceName ?? config.projectName, draftName: spacePanelDraftName, mode: spacePanelMode, onDraftChange: setSpacePanelDraftName, selectedIndex: spacePanelSelectedIndex, spaces: vendorSpaces }));
|
|
1496
1500
|
}
|
|
1497
1501
|
else if (activePanel === "hub") {
|
|
1498
|
-
|
|
1499
|
-
mainContent = (_jsx(HubPanelView, { installedSlugs: vendorHubStore?.installedSlugs ?? [], recentSlug: vendorHubStore?.recentSlug ?? null, registryEntries: registryEntries, selectedIndex: hubPanelSelectedIndex }));
|
|
1502
|
+
mainContent = (_jsx(HubPanelView, { installedSlugs: vendorHubStore?.installedSlugs ?? [], recentSlug: vendorHubStore?.recentSlug ?? null, registryEntries: hubRegistryEntries, selectedIndex: hubPanelSelectedIndex }));
|
|
1500
1503
|
}
|
|
1501
1504
|
else if (activePanel === "connectors") {
|
|
1502
1505
|
const registryEntries = listConnectorTemplates();
|
package/dist/config.d.ts
CHANGED
|
@@ -24,6 +24,9 @@ export interface HubRegistry {
|
|
|
24
24
|
id: string;
|
|
25
25
|
name: string;
|
|
26
26
|
url: string;
|
|
27
|
+
authScheme?: "none" | "bearer" | "token" | "basic" | "custom-header";
|
|
28
|
+
token?: string;
|
|
29
|
+
headerName?: string;
|
|
27
30
|
updatedAt: string;
|
|
28
31
|
}
|
|
29
32
|
export interface StoredCliState {
|
package/dist/config.js
CHANGED
package/package.json
CHANGED