umbrella-context 0.1.39 → 0.1.41

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.
@@ -4,15 +4,16 @@ import { Box, render, Text, useApp, useInput } from "ink";
4
4
  import TextInput from "ink-text-input";
5
5
  import Spinner from "ink-spinner";
6
6
  import chalk from "chalk";
7
- import { formatUmbrellaAuthStatus } from "../auth-state.js";
7
+ import { getAdaptiveKnowledgeSummary } from "../adaptive/runtime.js";
8
+ import { createDefaultUmbrellaAuthSnapshot, formatUmbrellaAuthStatus } from "../auth-state.js";
8
9
  import { getUmbrellaContextRuntimeSummary, useUmbrellaContextRuntimeBridgeStore, hydrateUmbrellaContextRuntimeBridgeFromSnapshot, } from "../adapters/byterover-context-runtime-store.js";
9
10
  import { getUmbrellaTransportTaskBridgeSummary, useUmbrellaTransportTaskBridgeStore, hydrateUmbrellaTransportTaskBridgeFromSnapshot, } from "../adapters/byterover-transport-task-store.js";
10
11
  import { buildVendorRuntimeBridgeSnapshot, } from "../adapters/byterover-runtime-bridge.js";
11
- import { addPendingMemory, completeTask, createTask, ensureRepoContext, getContextTreeState, ensureSessionState, getConnectorRuns, getInstalledConnectors, getInstalledHubEntries, getPendingMemories, getPulledFixes, getPulledMemories, getRepoContext, removeTask, getSessionState, getTasks, getTransportState, recordSessionEvent, setSessionPanel, summarizeLocalMemoryMatches, } from "../repo-state.js";
12
+ import { addPendingMemory, completeTask, createTask, ensureRepoContext, getContextTreeState, ensureSessionState, getConnectorRuns, getInstalledConnectors, getInstalledHubEntries, getPendingMemories, getPulledFixes, getPulledMemories, getRepoContext, getRepoResolution, removeTask, getSessionState, getTasks, getTransportState, listKnowledgeSources, listRegisteredWorktrees, recordSessionEvent, setSessionPanel, summarizeLocalMemoryMatches, } from "../repo-state.js";
12
13
  import { configManager } from "../config.js";
13
14
  import { getStoredUmbrellaAuthSnapshot, setUmbrellaAuthAuthorized, setUmbrellaAuthChecking, setUmbrellaAuthFailure, } from "../adapters/umbrella-auth-runtime.js";
14
15
  import { checkUmbrellaOnboardingServer, connectUmbrellaDevice, createUmbrellaOnboardingCompany, createUmbrellaOnboardingSpace, loadUmbrellaOnboardingSpaces, signInUmbrellaOnboarding, } from "../adapters/umbrella-onboarding.js";
15
- import { buildProviderDraftValue, connectSavedProviderFromDraft, createEmptyProviderConnectDraft, UMBRELLA_PROVIDER_CHOICES, updateProviderDraftValue, } from "../adapters/umbrella-provider-runtime.js";
16
+ import { buildProviderDraftValue, connectSavedProviderFromDraft, createEmptyProviderConnectDraft, getProviderChoice, UMBRELLA_PROVIDER_CHOICES, updateProviderDraftValue, } from "../adapters/umbrella-provider-runtime.js";
16
17
  import { connectorsCommandAction, listConnectorTemplates } from "./connectors.js";
17
18
  import { hubCommandAction, listHubRegistryEntries } from "./hub.js";
18
19
  import { modelCommandAction } from "./model.js";
@@ -21,6 +22,7 @@ import { pushCommandAction } from "./push.js";
21
22
  import { getProviderReadinessSummary, providersCommandAction } from "./providers.js";
22
23
  import { spaceCommandAction } from "./space.js";
23
24
  import { buildConnectionPresentation } from "./status.js";
25
+ import { getSwarmStatus } from "../swarm/runtime.js";
24
26
  const PANELS = [
25
27
  { id: "home", title: "Home", description: "Repo status, sync, and next steps" },
26
28
  { id: "tasks", title: "Tasks", description: "Live local task activity from .um" },
@@ -43,6 +45,23 @@ const PANEL_SHORTCUTS = [
43
45
  { id: "connectors", key: "c", label: "Connectors" },
44
46
  { id: "session", key: "u", label: "Session" },
45
47
  ];
48
+ const SESSION_ACTIONS = [
49
+ {
50
+ id: "repair-setup",
51
+ title: "Repair setup / switch server or company",
52
+ description: "Restart the setup flow so you can choose the live server, sign in again, and pick a different company if needed.",
53
+ },
54
+ {
55
+ id: "switch-space",
56
+ title: "Switch to another space",
57
+ description: "Open the Spaces panel for this company and pick a different space for this repo.",
58
+ },
59
+ {
60
+ id: "sign-out",
61
+ title: "Sign out this device and start over",
62
+ description: "Clear the saved Umbrella link on this computer, then restart setup from the beginning.",
63
+ },
64
+ ];
46
65
  const DEFAULT_UMBRELLA_SERVER_URL = "http://5.161.55.138:3100";
47
66
  const LOCAL_UMBRELLA_SERVER_URL = "http://127.0.0.1:3100";
48
67
  const SETUP_SERVER_CHOICES = [
@@ -62,6 +81,16 @@ const SETUP_SERVER_CHOICES = [
62
81
  description: "Type a different Umbrella server URL yourself.",
63
82
  },
64
83
  ];
84
+ function inferSetupServerChoiceIndex(serverUrl) {
85
+ const normalized = trimSlash(serverUrl ?? "");
86
+ if (!normalized)
87
+ return 0;
88
+ if (normalized === DEFAULT_UMBRELLA_SERVER_URL)
89
+ return 0;
90
+ if (normalized === LOCAL_UMBRELLA_SERVER_URL)
91
+ return 1;
92
+ return 2;
93
+ }
65
94
  function trimSlash(value) {
66
95
  return value.trim().replace(/\/+$/, "");
67
96
  }
@@ -148,6 +177,34 @@ function formatAgo(value) {
148
177
  return "Never";
149
178
  return new Date(value).toLocaleString();
150
179
  }
180
+ function summarizeNames(items, emptyLabel) {
181
+ if (items.length === 0)
182
+ return emptyLabel;
183
+ if (items.length <= 3)
184
+ return items.join(", ");
185
+ return `${items.slice(0, 3).join(", ")} +${items.length - 3} more`;
186
+ }
187
+ function isAutoBootstrappedSwarm(sw) {
188
+ return sw.suggestions.some((suggestion) => suggestion.toLowerCase().includes("auto-created config"));
189
+ }
190
+ function hasLiveSourceProvider(sw) {
191
+ return sw.providers.some((provider) => provider.type === "umbrella-source" && provider.available);
192
+ }
193
+ function getSwarmReadinessLabel(sw, sourceCount) {
194
+ if (sourceCount === 0)
195
+ return "No linked source repos yet";
196
+ if (hasLiveSourceProvider(sw))
197
+ return "Cross-repo search is live";
198
+ if (sw.configured)
199
+ return "Sources linked, but not all searchable yet";
200
+ return "Sources linked, but swarm still needs setup";
201
+ }
202
+ function getSwarmHealthyCount(sw) {
203
+ return sw.providers.filter((provider) => provider.available).length;
204
+ }
205
+ function getSwarmWritableCount(sw) {
206
+ return sw.providers.filter((provider) => provider.available && provider.writable).length;
207
+ }
151
208
  function StatusLine({ label, value }) {
152
209
  return (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "cyan", children: label.padEnd(18) }), _jsx(Text, { children: value })] }));
153
210
  }
@@ -168,7 +225,7 @@ function SpacePanelView(props) {
168
225
  function ProviderPanelView(props) {
169
226
  const { activeModel, activeProviderId, connectDraftValue, connectKindIndex, mode, onConnectDraftChange, providers, recentProviderId, readinessState, selectedIndex, } = props;
170
227
  if (mode === "connect-kind") {
171
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Connect a Provider" }), _jsx(Text, { color: "gray", children: "Pick the model company you want this device to use for Context work." }), _jsx(Section, { title: "Provider Types", children: UMBRELLA_PROVIDER_CHOICES.map((choice, index) => (_jsxs(Text, { color: index === connectKindIndex ? "yellow" : "white", children: [index === connectKindIndex ? ">" : " ", " ", choice.name] }, choice.kind))) }), _jsx(Text, { color: "gray", children: "Up and down move through provider types. Enter confirms. Esc goes back." })] }));
228
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Connect a Provider" }), _jsx(Text, { color: "gray", children: "Pick the model company you want this device to use for Context work." }), _jsx(Section, { title: "Provider Types", children: UMBRELLA_PROVIDER_CHOICES.map((choice, index) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: index === connectKindIndex ? "yellow" : "white", children: [index === connectKindIndex ? ">" : " ", " ", choice.name] }), _jsx(Text, { color: "gray", children: choice.description }), choice.baseUrl ? _jsxs(Text, { color: "gray", children: ["Base URL: ", choice.baseUrl] }) : null, _jsxs(Text, { color: "gray", children: ["Examples: ", choice.exampleModels.join(", ")] })] }, choice.kind))) }), _jsx(Text, { color: "gray", children: "Up and down move through provider types. Enter confirms. Esc goes back." })] }));
172
229
  }
173
230
  if (mode === "connect-label" || mode === "connect-key" || mode === "connect-base-url") {
174
231
  const label = mode === "connect-label"
@@ -180,7 +237,7 @@ function ProviderPanelView(props) {
180
237
  ? "Give this provider a simple name you will recognize later."
181
238
  : mode === "connect-key"
182
239
  ? "This key stays on this device and is used for terminal Context work."
183
- : "This is only needed for OpenAI-compatible providers.";
240
+ : "This is only needed when you chose the custom compatible provider option.";
184
241
  return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Connect a Provider" }), _jsx(Text, { color: "gray", children: help }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "yellow", children: label }), _jsx(TextInput, { value: connectDraftValue, onChange: onConnectDraftChange })] }), _jsx(Text, { color: "gray", children: "Press Enter to continue. Esc goes back one step." })] }));
185
242
  }
186
243
  return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Provider Runtime" }), _jsx(Text, { color: "gray", children: "This is the device-side runtime picker for Context work." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Connected providers", value: String(providers.length) }), _jsx(StatusLine, { label: "Active provider", value: providers.find((entry) => entry.id === activeProviderId)?.name ?? "Not connected" }), _jsx(StatusLine, { label: "Active model", value: activeModel ?? "Not selected" }), _jsx(StatusLine, { label: "State", value: readinessState })] }), _jsx(Section, { title: "Select a Provider", children: providers.length === 0 ? (_jsx(Text, { color: "yellow", children: "No providers are connected yet. Press c to start the live connect flow." })) : providers.map((provider, index) => {
@@ -188,11 +245,11 @@ function ProviderPanelView(props) {
188
245
  const active = provider.id === activeProviderId;
189
246
  const recent = provider.id === recentProviderId;
190
247
  return (_jsxs(Text, { color: highlighted ? "yellow" : active ? "green" : "white", children: [highlighted ? ">" : " ", " ", provider.name, " (", provider.kind, ")", active ? " (active)" : "", recent ? " (recent)" : ""] }, provider.id));
191
- }) }), _jsx(Text, { color: "gray", children: "Up and down move through providers. Enter or w makes one active. c connects a new provider. d disconnects the highlighted one." }), _jsx(Text, { color: "gray", children: "t tests the runtime, i inspects the recent provider, g runs the full guided setup, and m jumps to models." })] }));
248
+ }) }), _jsx(Text, { color: "gray", children: "Providers are the AI companies, like OpenAI, Anthropic, Google, MiniMax, or OpenRouter." }), _jsx(Text, { color: "gray", children: "Up and down move through providers. Enter or w makes one active. c connects a new provider. d disconnects the highlighted one." }), _jsx(Text, { color: "gray", children: "t tests the runtime, i inspects the recent provider, g runs the full guided setup, and m jumps to models." })] }));
192
249
  }
193
250
  function ModelPanelView(props) {
194
251
  const { activeModel, providerName, recentModel, selectedIndex, models } = props;
195
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Model Runtime" }), _jsx(Text, { color: "gray", children: "This is the live model picker for the active provider." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Provider", value: providerName }), _jsx(StatusLine, { label: "Active model", value: activeModel ?? "Not selected" }), _jsx(StatusLine, { label: "Available models", value: String(models.length) })] }), _jsx(Section, { title: "Select a Model", children: models.length === 0 ? (_jsx(Text, { color: "yellow", children: "No models are available for the active provider yet." })) : models.map((model, index) => {
252
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Model Runtime" }), _jsx(Text, { color: "gray", children: "Models are the specific AI brains offered by the active provider. First pick a provider, then pick the model you want it to use." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Provider", value: providerName }), _jsx(StatusLine, { label: "Active model", value: activeModel ?? "Not selected" }), _jsx(StatusLine, { label: "Available models", value: String(models.length) })] }), _jsx(Section, { title: "Select a Model", children: models.length === 0 ? (_jsx(Text, { color: "yellow", children: "No models are available for the active provider yet." })) : models.map((model, index) => {
196
253
  const highlighted = index === selectedIndex;
197
254
  const active = model === activeModel;
198
255
  const recent = model === recentModel;
@@ -201,22 +258,22 @@ function ModelPanelView(props) {
201
258
  }
202
259
  function HubPanelView(props) {
203
260
  const { installedSlugs, recentSlug, registryEntries, selectedIndex } = props;
204
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Hub" }), _jsx(Text, { color: "gray", children: "This is the live Hub picker for reusable bundles, skills, and connector packs in this repo." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Available entries", value: String(registryEntries.length) }), _jsx(StatusLine, { label: "Installed entries", value: String(installedSlugs.length) })] }), _jsx(Section, { title: "Browse Hub Registry", children: registryEntries.map((entry, index) => {
261
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Hub" }), _jsx(Text, { color: "gray", children: "Hub is the install shelf for bigger repo packs. Think of it like bundles of reusable setup, skills, and connector kits." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Available entries", value: String(registryEntries.length) }), _jsx(StatusLine, { label: "Installed entries", value: String(installedSlugs.length) })] }), _jsx(Section, { title: "Browse Hub Registry", children: registryEntries.map((entry, index) => {
205
262
  const highlighted = index === selectedIndex;
206
263
  const installed = installedSlugs.includes(entry.slug);
207
264
  const recent = recentSlug === entry.slug;
208
265
  return (_jsxs(Text, { color: highlighted ? "yellow" : installed ? "green" : "white", children: [highlighted ? ">" : " ", " ", entry.name, " [", entry.type, "]", installed ? " (installed)" : "", recent ? " (recent)" : ""] }, entry.slug));
209
- }) }), _jsx(Section, { title: "Selected Entry", children: registryEntries[selectedIndex] ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: registryEntries[selectedIndex].description }), _jsxs(Text, { color: "gray", children: ["Includes: ", registryEntries[selectedIndex].includes.join(", ")] }), _jsxs(Text, { color: "gray", children: ["Next: ", registryEntries[selectedIndex].nextSteps[0] ?? "Review and install"] })] })) : (_jsx(Text, { color: "yellow", children: "No Hub entries are available right now." })) }), _jsx(Text, { color: "gray", children: "Up and down move through hub entries. Enter or n installs the selected entry. i inspects it. b opens the guided browse flow. l refreshes installed items." })] }));
266
+ }) }), _jsx(Section, { title: "Selected Entry", children: registryEntries[selectedIndex] ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: registryEntries[selectedIndex].description }), _jsx(Text, { color: "gray", children: "A Hub entry can include more than one thing at once, like skills plus connectors plus setup files." }), _jsxs(Text, { color: "gray", children: ["Includes: ", registryEntries[selectedIndex].includes.join(", ")] }), _jsxs(Text, { color: "gray", children: ["Next: ", registryEntries[selectedIndex].nextSteps[0] ?? "Review and install"] })] })) : (_jsx(Text, { color: "yellow", children: "No Hub entries are available right now." })) }), _jsx(Text, { color: "gray", children: "Up and down move through hub entries. Enter or n installs the selected entry. i inspects it. b opens the guided browse flow. l refreshes installed items." })] }));
210
267
  }
211
268
  function ConnectorsPanelView(props) {
212
269
  const { installedSources, recentSource, recentRunSource, registryEntries, selectedIndex } = props;
213
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Connectors" }), _jsx(Text, { color: "gray", children: "This is the live repo connector picker for MCP wiring, hooks, rules, and skill bridges." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Available connectors", value: String(registryEntries.length) }), _jsx(StatusLine, { label: "Installed connectors", value: String(installedSources.length) })] }), _jsx(Section, { title: "Browse Connector Registry", children: registryEntries.map((entry, index) => {
270
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Connectors" }), _jsx(Text, { color: "gray", children: "A connector is a repo helper. MCP, rule, hook, and skill are the four connector types shown here." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Available connectors", value: String(registryEntries.length) }), _jsx(StatusLine, { label: "Installed connectors", value: String(installedSources.length) })] }), _jsx(Section, { title: "Browse Connector Registry", children: registryEntries.map((entry, index) => {
214
271
  const highlighted = index === selectedIndex;
215
272
  const installed = installedSources.includes(entry.key);
216
273
  const recent = recentSource === entry.key;
217
274
  const recentRun = recentRunSource === entry.key;
218
275
  return (_jsxs(Text, { color: highlighted ? "yellow" : installed ? "green" : "white", children: [highlighted ? ">" : " ", " ", entry.name, " [", entry.type, "]", installed ? " (installed)" : "", recent ? " (recent)" : "", recentRun ? " (ran)" : ""] }, entry.key));
219
- }) }), _jsx(Section, { title: "Selected Connector", children: registryEntries[selectedIndex] ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: registryEntries[selectedIndex].description }), _jsxs(Text, { color: "gray", children: ["Best for: ", registryEntries[selectedIndex].type, " workflows in this repo."] }), _jsx(Text, { color: "gray", children: "Next: install it, then run it to apply repo changes or stage local Context output." })] })) : (_jsx(Text, { color: "yellow", children: "No connector templates are available right now." })) }), _jsx(Text, { color: "gray", children: "Up and down move through connectors. Enter or i installs the selected connector. r runs it. o opens its outputs. v inspects the recent connector." })] }));
276
+ }) }), _jsx(Section, { title: "Selected Connector", children: registryEntries[selectedIndex] ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: registryEntries[selectedIndex].description }), _jsxs(Text, { color: "gray", children: ["Type: ", registryEntries[selectedIndex].type, ". This is one flavor of connector, not a separate product."] }), _jsx(Text, { color: "gray", children: "Next: install it, then run it to apply repo changes or stage local Context output." })] })) : (_jsx(Text, { color: "yellow", children: "No connector templates are available right now." })) }), _jsx(Text, { color: "gray", children: "Up and down move through connectors. Enter or i installs the selected connector. r runs it. o opens its outputs. v inspects the recent connector." })] }));
220
277
  }
221
278
  function TasksPanelView(props) {
222
279
  const { mode, selectedIndex, tasks, transportStatus, queueLength, activeTaskId } = props;
@@ -247,14 +304,25 @@ function PanelShell({ activePanel, children, footer, message, navigationFocus, s
247
304
  }
248
305
  function SetupView(props) {
249
306
  const { busyLabel, companies, config, authSnapshot, inputValue, message, onInputChange, selectedCompanyIndex, selectedServerChoiceIndex, selectedSpaceIndex, serverUrl, spaces, step, } = props;
250
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: config ? "Connected Device" : "Connect This Device" }), _jsx(Text, { color: "gray", children: "Sign into Umbrella, choose a company, then choose the team space for this repo." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Server", value: serverUrl || "Not set" }), _jsx(StatusLine, { label: "Step", value: step }), _jsx(StatusLine, { label: "Auth state", value: formatUmbrellaAuthStatus(authSnapshot.status) }), _jsx(StatusLine, { label: "Auth message", value: authSnapshot.message ?? "No auth check yet" }), _jsx(StatusLine, { label: "Auth hint", value: authSnapshot.hint ?? "No auth hint yet" }), config ? _jsx(StatusLine, { label: "Current link", value: `${config.companyName} / ${config.projectName}` }) : null] }), busyLabel ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "cyan", children: [_jsx(Spinner, { type: "dots" }), " ", busyLabel] }) })) : null, message ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "green", children: message }) })) : null, step === "server-choice" ? (_jsx(Section, { title: "Choose an Umbrella Server", children: SETUP_SERVER_CHOICES.map((choice, index) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: index === selectedServerChoiceIndex ? "yellow" : "white", children: [index === selectedServerChoiceIndex ? ">" : " ", " ", choice.title] }), _jsx(Text, { color: "gray", children: choice.description })] }, choice.value))) })) : null, (step === "server" || step === "email" || step === "password" || step === "company-create" || step === "space-create") ? (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "yellow", children: step === "server" ? "Server URL" :
307
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: config ? "Connected Device" : "Connect This Device" }), _jsx(Text, { color: "gray", children: "Sign into Umbrella, choose a company, then choose the team space for this repo." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Server", value: serverUrl || "Not set" }), _jsx(StatusLine, { label: "Step", value: step }), _jsx(StatusLine, { label: "Auth state", value: formatUmbrellaAuthStatus(authSnapshot.status) }), _jsx(StatusLine, { label: "Auth message", value: authSnapshot.message ?? "No auth check yet" }), _jsx(StatusLine, { label: "Auth hint", value: authSnapshot.hint ?? "No auth hint yet" }), config ? _jsx(StatusLine, { label: "Current link", value: `${config.companyName} / ${config.projectName}` }) : null, config?.umbrellaUrl ? _jsx(StatusLine, { label: "Saved app URL", value: config.umbrellaUrl }) : null, config ? _jsx(StatusLine, { label: "Saved backend URL", value: config.serverUrl }) : null] }), busyLabel ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "cyan", children: [_jsx(Spinner, { type: "dots" }), " ", busyLabel] }) })) : null, message ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "green", children: message }) })) : null, step === "server-choice" ? (_jsx(Section, { title: "Choose an Umbrella Server", children: SETUP_SERVER_CHOICES.map((choice, index) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: index === selectedServerChoiceIndex ? "yellow" : "white", children: [index === selectedServerChoiceIndex ? ">" : " ", " ", choice.title] }), _jsx(Text, { color: "gray", children: choice.description })] }, choice.value))) })) : null, (step === "server" || step === "email" || step === "password" || step === "company-create" || step === "space-create") ? (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "yellow", children: step === "server" ? "Server URL" :
251
308
  step === "email" ? "Umbrella email" :
252
309
  step === "password" ? "Umbrella password" :
253
310
  step === "company-create" ? "New company name" :
254
- "New space name" }), _jsx(TextInput, { value: inputValue, onChange: onInputChange })] })) : null, step === "company" ? (_jsxs(Section, { title: "Companies", children: [companies.map((company, index) => (_jsxs(Text, { color: index === selectedCompanyIndex ? "yellow" : "white", children: [index === selectedCompanyIndex ? ">" : " ", " ", company.name, " (", company.issuePrefix, ")"] }, company.id))), _jsxs(Text, { color: selectedCompanyIndex === companies.length ? "yellow" : "white", children: [selectedCompanyIndex === companies.length ? ">" : " ", " + Create new company"] })] })) : null, step === "space" ? (_jsxs(Section, { title: "Spaces", children: [spaces.map((space, index) => (_jsxs(Text, { color: index === selectedSpaceIndex ? "yellow" : "white", children: [index === selectedSpaceIndex ? ">" : " ", " ", space.name, space.isPrimary ? " (core)" : ""] }, space.id))), _jsxs(Text, { color: selectedSpaceIndex === spaces.length ? "yellow" : "white", children: [selectedSpaceIndex === spaces.length ? ">" : " ", " + Create new space"] })] })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Enter confirms the current step. Up and down move through server choices, companies, or spaces." }), _jsx(Text, { color: "gray", children: "Esc leaves setup. This terminal saves the final link into your device config and the repo's .um folder." })] })] }));
311
+ "New space name" }), _jsx(TextInput, { value: inputValue, onChange: onInputChange, mask: step === "password" ? "*" : undefined })] })) : null, step === "company" ? (_jsxs(Section, { title: "Companies", children: [companies.map((company, index) => (_jsxs(Text, { color: index === selectedCompanyIndex ? "yellow" : "white", children: [index === selectedCompanyIndex ? ">" : " ", " ", company.name, " (", company.issuePrefix, ")"] }, company.id))), _jsxs(Text, { color: selectedCompanyIndex === companies.length ? "yellow" : "white", children: [selectedCompanyIndex === companies.length ? ">" : " ", " + Create new company"] })] })) : null, step === "space" ? (_jsxs(Section, { title: "Spaces", children: [spaces.map((space, index) => (_jsxs(Text, { color: index === selectedSpaceIndex ? "yellow" : "white", children: [index === selectedSpaceIndex ? ">" : " ", " ", space.name, space.isPrimary ? " (core)" : ""] }, space.id))), _jsxs(Text, { color: selectedSpaceIndex === spaces.length ? "yellow" : "white", children: [selectedSpaceIndex === spaces.length ? ">" : " ", " + Create new space"] })] })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Enter confirms the current step. Up and down move through server choices, companies, or spaces." }), _jsx(Text, { color: "gray", children: "Esc leaves setup. Press x to sign out on this device and start over from the beginning." })] })] }));
255
312
  }
256
313
  function App() {
257
314
  const { exit } = useApp();
315
+ const initialConfig = configManager.config;
316
+ const initialAuthSnapshot = getStoredUmbrellaAuthSnapshot();
317
+ const initialConnectionPresentation = initialConfig
318
+ ? buildConnectionPresentation({
319
+ umbrellaUrl: initialConfig.umbrellaUrl ?? undefined,
320
+ serverUrl: initialConfig.serverUrl,
321
+ }, initialAuthSnapshot)
322
+ : null;
323
+ const needsSetupRepair = !initialConfig ||
324
+ (initialConnectionPresentation?.connectionMode === "saved_local_config" ||
325
+ (initialConnectionPresentation?.warnings.length ?? 0) > 0);
258
326
  const vendorTaskStore = useUmbrellaTransportTaskBridgeStore((state) => state.taskStore);
259
327
  const vendorTransportStore = useUmbrellaTransportTaskBridgeStore((state) => state.transportStore);
260
328
  const vendorTreeStore = useUmbrellaContextRuntimeBridgeStore((state) => state.treeStore);
@@ -264,7 +332,7 @@ function App() {
264
332
  const vendorHubStore = useUmbrellaContextRuntimeBridgeStore((state) => state.hubStore);
265
333
  const vendorConnectorsStore = useUmbrellaContextRuntimeBridgeStore((state) => state.connectorsStore);
266
334
  const [selectedPanelIndex, setSelectedPanelIndex] = useState(0);
267
- const [activePanel, setActivePanel] = useState(configManager.config ? "home" : "setup");
335
+ const [activePanel, setActivePanel] = useState(needsSetupRepair ? "setup" : "home");
268
336
  const [navigationFocus, setNavigationFocus] = useState("sidebar");
269
337
  const [refreshTick, setRefreshTick] = useState(0);
270
338
  const [message, setMessage] = useState(null);
@@ -273,11 +341,12 @@ function App() {
273
341
  const [inputValue, setInputValue] = useState("");
274
342
  const [queryResult, setQueryResult] = useState(null);
275
343
  const [refreshState, setRefreshState] = useState(null);
276
- const [setupStep, setSetupStep] = useState(configManager.config ? "done" : "server-choice");
277
- const [serverUrl, setServerUrl] = useState(configManager.config?.umbrellaUrl ?? configManager.config?.serverUrl ?? DEFAULT_UMBRELLA_SERVER_URL);
278
- const [selectedServerChoiceIndex, setSelectedServerChoiceIndex] = useState(0);
344
+ const [refreshError, setRefreshError] = useState(null);
345
+ const [setupStep, setSetupStep] = useState(needsSetupRepair ? "server-choice" : "done");
346
+ const [serverUrl, setServerUrl] = useState(initialConfig?.umbrellaUrl ?? initialConfig?.serverUrl ?? DEFAULT_UMBRELLA_SERVER_URL);
347
+ const [selectedServerChoiceIndex, setSelectedServerChoiceIndex] = useState(inferSetupServerChoiceIndex(initialConfig?.umbrellaUrl ?? initialConfig?.serverUrl ?? null));
279
348
  const [setupEmail, setSetupEmail] = useState("");
280
- const [authSnapshot, setAuthSnapshot] = useState(getStoredUmbrellaAuthSnapshot());
349
+ const [authSnapshot, setAuthSnapshot] = useState(initialAuthSnapshot);
281
350
  const [setupCookie, setSetupCookie] = useState(null);
282
351
  const [companies, setCompanies] = useState([]);
283
352
  const [selectedCompanyIndex, setSelectedCompanyIndex] = useState(0);
@@ -304,11 +373,52 @@ function App() {
304
373
  const [tasksPanelSelectedIndex, setTasksPanelSelectedIndex] = useState(0);
305
374
  const [activityPanelMode, setActivityPanelMode] = useState("browse");
306
375
  const [activityPanelSelectedIndex, setActivityPanelSelectedIndex] = useState(0);
376
+ const [sessionPanelSelectedIndex, setSessionPanelSelectedIndex] = useState(0);
307
377
  function focusPanel(panelId, focus = "sidebar") {
308
378
  setActivePanel(panelId);
309
379
  setSelectedPanelIndex(panelIndexFor(panelId));
310
380
  setNavigationFocus(focus);
311
381
  }
382
+ function restartSetupFlow() {
383
+ const currentConfig = configManager.config;
384
+ const nextServerUrl = currentConfig?.umbrellaUrl ?? currentConfig?.serverUrl ?? DEFAULT_UMBRELLA_SERVER_URL;
385
+ setSetupStep("server-choice");
386
+ setServerUrl(nextServerUrl);
387
+ setSelectedServerChoiceIndex(inferSetupServerChoiceIndex(nextServerUrl));
388
+ setSetupEmail("");
389
+ setSetupCookie(null);
390
+ setCompanies([]);
391
+ setSelectedCompanyIndex(0);
392
+ setSpaces([]);
393
+ setSelectedSpaceIndex(0);
394
+ setSelectedCompany(null);
395
+ setInputValue("");
396
+ setBusyLabel(null);
397
+ setMessage(currentConfig
398
+ ? "Choose the Umbrella server you want to use for this device. This will repair the saved link."
399
+ : "Choose the Umbrella server you want to use for this device.");
400
+ focusPanel("setup", "panel");
401
+ }
402
+ async function signOutAndRestartSetup() {
403
+ configManager.clearUmbrellaSession();
404
+ configManager.clearAuthSnapshot();
405
+ setAuthSnapshot(createDefaultUmbrellaAuthSnapshot());
406
+ setRefreshTick((value) => value + 1);
407
+ restartSetupFlow();
408
+ setMessage("This device was signed out. Choose the Umbrella server you want to use and start over.");
409
+ }
410
+ async function runSessionAction(actionId) {
411
+ if (actionId === "repair-setup") {
412
+ restartSetupFlow();
413
+ return;
414
+ }
415
+ if (actionId === "switch-space") {
416
+ focusPanel("spaces", "panel");
417
+ setMessage("Opened Spaces so you can choose a different space inside the current company.");
418
+ return;
419
+ }
420
+ await signOutAndRestartSetup();
421
+ }
312
422
  async function refreshAll() {
313
423
  try {
314
424
  if (configManager.config) {
@@ -318,7 +428,7 @@ function App() {
318
428
  const vendorSnapshot = await buildVendorRuntimeBridgeSnapshot();
319
429
  hydrateUmbrellaTransportTaskBridgeFromSnapshot(vendorSnapshot);
320
430
  hydrateUmbrellaContextRuntimeBridgeFromSnapshot(vendorSnapshot);
321
- const [transport, treeState, pending, pulled, fixes, connectors, hubEntries, connectorRuns, session, repoContext, tasks] = await Promise.all([
431
+ const [transport, treeState, pending, pulled, fixes, connectors, hubEntries, connectorRuns, session, repoContext, tasks, swarm, repoResolution, worktrees, sources, adaptive] = await Promise.all([
322
432
  getTransportState(),
323
433
  getContextTreeState(),
324
434
  getPendingMemories(),
@@ -330,6 +440,11 @@ function App() {
330
440
  ensureSessionState(),
331
441
  getRepoContext(),
332
442
  getTasks(),
443
+ getSwarmStatus(),
444
+ getRepoResolution(),
445
+ listRegisteredWorktrees(),
446
+ listKnowledgeSources(),
447
+ getAdaptiveKnowledgeSummary(),
333
448
  ]);
334
449
  setRefreshState({
335
450
  transport,
@@ -343,10 +458,17 @@ function App() {
343
458
  session,
344
459
  repoContext,
345
460
  tasks,
461
+ swarm,
462
+ repoResolution,
463
+ worktrees,
464
+ sources,
465
+ adaptive,
346
466
  activity: buildActivityItems(vendorSnapshot.stores.transport, session.events ?? []),
347
467
  });
468
+ setRefreshError(null);
348
469
  }
349
- catch {
470
+ catch (error) {
471
+ setRefreshError(error instanceof Error ? error.message : "Unknown refresh error");
350
472
  setRefreshState(null);
351
473
  }
352
474
  }
@@ -855,7 +977,12 @@ function App() {
855
977
  const choice = UMBRELLA_PROVIDER_CHOICES[providerPanelConnectKindIndex];
856
978
  if (!choice)
857
979
  return;
858
- setProviderPanelConnectDraft((value) => ({ ...value, kind: choice.kind, label: "" }));
980
+ setProviderPanelConnectDraft((value) => ({
981
+ ...value,
982
+ kind: choice.kind,
983
+ label: choice.suggestedLabel,
984
+ baseUrl: choice.baseUrl ?? "",
985
+ }));
859
986
  setProviderPanelMode("connect-label");
860
987
  return;
861
988
  }
@@ -891,7 +1018,7 @@ function App() {
891
1018
  return;
892
1019
  }
893
1020
  setProviderPanelConnectDraft((value) => ({ ...value, apiKey: nextKey }));
894
- if (providerPanelConnectDraft.kind === "openai-compatible") {
1021
+ if (getProviderChoice(providerPanelConnectDraft.kind)?.requiresBaseUrlInput) {
895
1022
  setProviderPanelMode("connect-base-url");
896
1023
  }
897
1024
  else {
@@ -980,7 +1107,7 @@ function App() {
980
1107
  setMessage(`Opened ${PANELS[selectedPanelIndex]?.title ?? "panel"}.`);
981
1108
  return;
982
1109
  }
983
- const shortcutPanel = panelForShortcut(input);
1110
+ const shortcutPanel = navigationFocus === "sidebar" ? panelForShortcut(input) : null;
984
1111
  if (shortcutPanel && activePanel !== "setup") {
985
1112
  focusPanel(shortcutPanel, "panel");
986
1113
  setMessage(`Jumped to ${PANELS[panelIndexFor(shortcutPanel)]?.title ?? shortcutPanel}.`);
@@ -1038,9 +1165,11 @@ function App() {
1038
1165
  return;
1039
1166
  }
1040
1167
  if (input === "s") {
1041
- setActivePanel("setup");
1042
- setSelectedPanelIndex(0);
1043
- setNavigationFocus("panel");
1168
+ restartSetupFlow();
1169
+ return;
1170
+ }
1171
+ if (input === "x") {
1172
+ void signOutAndRestartSetup();
1044
1173
  return;
1045
1174
  }
1046
1175
  if (activePanel === "providers") {
@@ -1177,6 +1306,31 @@ function App() {
1177
1306
  return;
1178
1307
  }
1179
1308
  }
1309
+ if (activePanel === "session") {
1310
+ if (navigationFocus === "sidebar")
1311
+ return;
1312
+ if (key.upArrow || input === "k") {
1313
+ setSessionPanelSelectedIndex((value) => Math.max(0, value - 1));
1314
+ return;
1315
+ }
1316
+ if (key.downArrow || input === "j") {
1317
+ setSessionPanelSelectedIndex((value) => Math.min(SESSION_ACTIONS.length - 1, value + 1));
1318
+ return;
1319
+ }
1320
+ if (key.return || input === "o") {
1321
+ const action = SESSION_ACTIONS[sessionPanelSelectedIndex];
1322
+ if (!action)
1323
+ return;
1324
+ if (action.id === "sign-out") {
1325
+ void runPanelAction("Signing out this device...", async () => {
1326
+ await runSessionAction(action.id);
1327
+ }, "Signed out this device and restarted setup.");
1328
+ return;
1329
+ }
1330
+ void runSessionAction(action.id);
1331
+ return;
1332
+ }
1333
+ }
1180
1334
  if (activePanel === "tasks") {
1181
1335
  if (key.escape) {
1182
1336
  if (tasksPanelMode === "inspect") {
@@ -1436,45 +1590,58 @@ function App() {
1436
1590
  ? navigationFocus === "sidebar"
1437
1591
  ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens it | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | q quit"
1438
1592
  : "Spaces: Enter or w switch | n create | i refresh | Esc or Left returns to sidebar | ? query | + curate | q quit"
1439
- : activePanel === "hub"
1440
- ? hubPanelMode === "browse"
1441
- ? navigationFocus === "sidebar"
1442
- ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens it | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | q quit"
1443
- : "Hub: Up/Down choose | Enter or n install | i inspect | b guided browse | l refresh | Esc or Left returns to sidebar | ? query | + curate | q quit"
1444
- : "Hub live panel"
1445
- : activePanel === "connectors"
1446
- ? connectorsPanelMode === "browse"
1593
+ : activePanel === "session"
1594
+ ? navigationFocus === "sidebar"
1595
+ ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens it | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | x sign out/start over | q quit"
1596
+ : "Session: Up/Down choose action | Enter or o runs it | Use this panel to inspect server, company, and space info | Esc or Left returns to sidebar | q quit"
1597
+ : activePanel === "hub"
1598
+ ? hubPanelMode === "browse"
1447
1599
  ? navigationFocus === "sidebar"
1448
1600
  ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens it | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | q quit"
1449
- : "Connectors: Up/Down choose | Enter or i install | r run | o outputs | v inspect | Esc or Left returns to sidebar | ? query | + curate | q quit"
1450
- : "Connectors live panel"
1451
- : activePanel === "tasks"
1452
- ? tasksPanelMode === "browse"
1601
+ : "Hub: Up/Down choose | Enter or n install | i inspect | b guided browse | l refresh | Esc or Left returns to sidebar | ? query | + curate | q quit"
1602
+ : "Hub live panel"
1603
+ : activePanel === "connectors"
1604
+ ? connectorsPanelMode === "browse"
1453
1605
  ? navigationFocus === "sidebar"
1454
- ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens tasks | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | q quit"
1455
- : "Tasks: Up/Down choose | Enter or i inspect | o open related panel | Esc or Left returns to sidebar | r refresh | ? query | + curate | q quit"
1456
- : "Tasks inspect: Esc goes back to the task list | Enter or o opens related panel | Left returns to sidebar | r refresh | ? query | + curate | q quit"
1457
- : activePanel === "activity"
1458
- ? activityPanelMode === "browse"
1606
+ ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens it | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | q quit"
1607
+ : "Connectors: Up/Down choose | Enter or i install | r run | o outputs | v inspect | Esc or Left returns to sidebar | ? query | + curate | q quit"
1608
+ : "Connectors live panel"
1609
+ : activePanel === "tasks"
1610
+ ? tasksPanelMode === "browse"
1459
1611
  ? navigationFocus === "sidebar"
1460
- ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens activity | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | q quit"
1461
- : "Activity: Up/Down choose | Enter or i inspect | o open related panel | Esc or Left returns to sidebar | r refresh | ? query | + curate | q quit"
1462
- : "Activity inspect: Esc goes back to the event list | Left returns to sidebar | Enter or o opens related panel | r refresh | ? query | + curate | q quit"
1463
- : "Sidebar focus: Up/Down or j/k move panels | Enter, Right, or Tab opens a panel | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | r refresh | s setup | q quit";
1612
+ ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens tasks | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | q quit"
1613
+ : "Tasks: Up/Down choose | Enter or i inspect | o open related panel | Esc or Left returns to sidebar | r refresh | ? query | + curate | q quit"
1614
+ : "Tasks inspect: Esc goes back to the task list | Enter or o opens related panel | Left returns to sidebar | r refresh | ? query | + curate | q quit"
1615
+ : activePanel === "activity"
1616
+ ? activityPanelMode === "browse"
1617
+ ? navigationFocus === "sidebar"
1618
+ ? "Sidebar focus: Up/Down choose panel | Enter, Right, or Tab opens activity | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | s setup | q quit"
1619
+ : "Activity: Up/Down choose | Enter or i inspect | o open related panel | Esc or Left returns to sidebar | r refresh | ? query | + curate | q quit"
1620
+ : "Activity inspect: Esc goes back to the event list | Left returns to sidebar | Enter or o opens related panel | r refresh | ? query | + curate | q quit"
1621
+ : "Sidebar focus: Up/Down or j/k move panels | Enter, Right, or Tab opens a panel | [ ] cycle panels | 1-9 or h/t/a/v/m/w/b/c/u jumps panels | ? query | + curate | p push | l pull | r refresh | s setup | x sign out/start over | q quit";
1464
1622
  const config = configManager.config;
1465
1623
  let mainContent = null;
1466
1624
  if (activePanel === "setup") {
1467
1625
  mainContent = (_jsx(SetupView, { authSnapshot: authSnapshot, busyLabel: busyLabel, companies: companies, config: config, inputValue: inputValue, message: message, onInputChange: setInputValue, selectedCompanyIndex: selectedCompanyIndex, selectedServerChoiceIndex: selectedServerChoiceIndex, selectedSpaceIndex: selectedSpaceIndex, serverUrl: serverUrl, spaces: spaces, step: setupStep }));
1468
1626
  }
1469
- else if (!config || !refreshState) {
1627
+ else if (!config) {
1470
1628
  mainContent = (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "yellow", children: "This terminal app can open before live sign-in is finished." }), _jsx(Text, { color: "gray", children: "Right now this repo is not fully linked to a company and space yet." }), _jsx(Text, { color: "gray", children: "Open Setup and finish the device link before you expect shared server context to work." })] }));
1471
1629
  }
1630
+ else if (!refreshState) {
1631
+ mainContent = (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "yellow", children: "Refreshing the linked repo Context\u2026" }), _jsxs(Text, { color: "gray", children: ["Saved link: ", config.companyName, " / ", config.projectName] }), _jsxs(Text, { color: "gray", children: ["Server: ", config.umbrellaUrl ?? config.serverUrl] }), _jsx(Text, { color: "gray", children: "This device is linked. Press r to refresh if this takes more than a moment." }), refreshError ? _jsxs(Text, { color: "red", children: ["Refresh detail: ", refreshError] }) : null] }));
1632
+ }
1472
1633
  else if (activePanel === "home") {
1473
- mainContent = (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [config.companyName, " / ", config.projectName] }), _jsx(Text, { color: "gray", children: "This is the repo-level Context home for the current company space." }), _jsx(Text, { color: "gray", children: "The TUI is local-first: it reads this repo's .um folder even before the live server is queried." }), connectionPresentation ? (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: connectionPresentation.connectionMode === "verified_live_connection" ? "green" : "yellow", children: connectionPresentation.connectionMode === "verified_live_connection"
1634
+ mainContent = (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [config.companyName, " / ", config.projectName] }), _jsx(Text, { color: "gray", children: "This is the repo-level Context home for the current company space." }), refreshError ? _jsxs(Text, { color: "yellow", children: ["Last refresh had a hiccup: ", refreshError] }) : null, _jsx(Text, { color: "gray", children: "The TUI is local-first: it reads this repo's .um folder even before the live server is queried." }), connectionPresentation ? (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: connectionPresentation.connectionMode === "verified_live_connection" ? "green" : "yellow", children: connectionPresentation.connectionMode === "verified_live_connection"
1474
1635
  ? "Live connection verified"
1475
- : "Saved local setup only" }), _jsx(Text, { color: "gray", children: connectionPresentation.connectionSummary }), connectionPresentation.warnings.map((warning) => (_jsxs(Text, { color: "yellow", children: ["- ", warning] }, warning)))] })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Section, { title: "Connection", children: [_jsx(StatusLine, { label: "Umbrella server", value: config.umbrellaUrl ?? config.serverUrl }), _jsx(StatusLine, { label: "Auth state", value: formatUmbrellaAuthStatus(connectionPresentation?.authSnapshot.status ?? authSnapshot.status) }), _jsx(StatusLine, { label: "Shared API key", value: config.apiKey ? "Saved" : "Missing" }), _jsx(StatusLine, { label: "Connection mode", value: connectionPresentation?.connectionMode === "verified_live_connection"
1636
+ : "Saved local setup only" }), _jsx(Text, { color: "gray", children: connectionPresentation.connectionSummary }), connectionPresentation.warnings.map((warning) => (_jsxs(Text, { color: "yellow", children: ["- ", warning] }, warning)))] })) : null, _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Section, { title: "Connection", children: [_jsx(StatusLine, { label: "Umbrella app URL", value: config.umbrellaUrl ?? "Not saved" }), _jsx(StatusLine, { label: "Context backend URL", value: config.serverUrl }), _jsx(StatusLine, { label: "Saved company link", value: `${config.companyName} / ${config.projectName}` }), _jsx(StatusLine, { label: "Auth state", value: formatUmbrellaAuthStatus(connectionPresentation?.authSnapshot.status ?? authSnapshot.status) }), _jsx(StatusLine, { label: "Shared API key", value: config.apiKey ? "Saved" : "Missing" }), _jsx(StatusLine, { label: "Connection mode", value: connectionPresentation?.connectionMode === "verified_live_connection"
1476
1637
  ? "Verified live connection"
1477
- : "Saved local config only" })] }), _jsxs(Section, { title: "Sync", children: [_jsx(StatusLine, { label: "Pending drafts", value: String(refreshState.pending.length) }), _jsx(StatusLine, { label: "Pulled context", value: String(refreshState.pulled.length) }), _jsx(StatusLine, { label: "Known fixes", value: String(refreshState.fixes.length) }), _jsx(StatusLine, { label: "Last push", value: formatAgo(refreshState.repoContext.state?.lastPushAt) }), _jsx(StatusLine, { label: "Last pull", value: formatAgo(refreshState.repoContext.state?.lastPullAt) })] }), _jsxs(Section, { title: "Runtime", children: [_jsx(StatusLine, { label: "Provider", value: readiness.activeProvider?.name ?? "Not connected" }), _jsx(StatusLine, { label: "Model", value: readiness.activeModel ?? "Not selected" }), _jsx(StatusLine, { label: "Transport", value: vendorTransportStore?.status ?? refreshState.transport.status }), _jsx(StatusLine, { label: "Repo .um", value: refreshState.repoContext.umDir })] }), _jsxs(Section, { title: "Context Tree", children: [_jsx(StatusLine, { label: "Summary", value: vendorTreeStore?.summaryHandle ?? refreshState.treeState.summaryHandle }), _jsx(StatusLine, { label: "Nodes", value: String(vendorTreeStore?.nodes.length ?? refreshState.treeState.nodes.length) }), _jsx(StatusLine, { label: "Runtime provider", value: vendorTreeStore?.runtime.provider ?? "No provider" }), _jsx(StatusLine, { label: "Runtime model", value: vendorTreeStore?.runtime.model ?? "No model" })] }), queryResult ? (_jsxs(Section, { title: `Latest Query: ${queryResult.query}`, children: [_jsxs(Text, { children: ["Local matches: ", String(queryResult.localMatches.length)] }), _jsxs(Text, { children: ["Shared matches: ", String(queryResult.remoteMatches.length)] })] })) : null, connectionPresentation?.connectionMode === "saved_local_config" ? (_jsx(Section, { title: "Next Step", children: _jsx(Text, { color: "yellow", children: "Run setup again before you trust shared server actions for this repo." }) })) : null] })] }));
1638
+ : "Saved local config only" })] }), _jsxs(Section, { title: "Sync", children: [_jsx(StatusLine, { label: "Pending drafts", value: String(refreshState.pending.length) }), _jsx(StatusLine, { label: "Pulled context", value: String(refreshState.pulled.length) }), _jsx(StatusLine, { label: "Known fixes", value: String(refreshState.fixes.length) }), _jsx(StatusLine, { label: "Last push", value: formatAgo(refreshState.repoContext.state?.lastPushAt) }), _jsx(StatusLine, { label: "Last pull", value: formatAgo(refreshState.repoContext.state?.lastPullAt) })] }), _jsxs(Section, { title: "Runtime", children: [_jsx(StatusLine, { label: "Provider", value: readiness.activeProvider?.name ?? "Not connected" }), _jsx(StatusLine, { label: "Model", value: readiness.activeModel ?? "Not selected" }), _jsx(StatusLine, { label: "Transport", value: vendorTransportStore?.status ?? refreshState.transport.status }), _jsx(StatusLine, { label: "Repo .um", value: refreshState.repoContext.umDir }), _jsx(StatusLine, { label: "Repo mode", value: refreshState.repoResolution.mode === "linked" ? "Linked worktree" : "Direct project" })] }), _jsxs(Section, { title: "Workspace Links", children: [_jsx(StatusLine, { label: "Registered worktrees", value: String(refreshState.worktrees.length) }), _jsx(StatusLine, { label: "Knowledge sources", value: String(refreshState.sources.length) }), _jsx(StatusLine, { label: "Cross-repo search", value: getSwarmReadinessLabel(refreshState.swarm, refreshState.sources.length) }), _jsx(StatusLine, { label: "Worktree names", value: summarizeNames(refreshState.worktrees.map((entry) => entry.name), "None") }), _jsx(StatusLine, { label: "Source aliases", value: summarizeNames(refreshState.sources.map((entry) => entry.alias), "None") }), _jsx(Text, { color: "gray", children: "Worktrees are extra folders that point back to this main repo. Sources are read-only Umbrella repos that swarm can search beside this repo." }), _jsx(Text, { color: "gray", children: "Use: umbrella-context worktree add/list/remove and umbrella-context source add/list/remove." })] }), _jsxs(Section, { title: "Adaptive Knowledge", children: [_jsx(StatusLine, { label: "Entries with abstracts", value: String(refreshState.adaptive.entryCount) }), _jsx(StatusLine, { label: "Last refresh", value: formatAgo(refreshState.adaptive.generatedAt) }), _jsx(StatusLine, { label: "Hottest note", value: refreshState.adaptive.hottestEntries[0]?.title ?? "None yet" })] }), _jsxs(Section, { title: "Swarm", children: [_jsx(StatusLine, { label: "Configured", value: refreshState.swarm.configured ? "Yes" : "No" }), _jsx(StatusLine, { label: "Mode", value: !refreshState.swarm.configured
1639
+ ? "Off"
1640
+ : isAutoBootstrappedSwarm(refreshState.swarm)
1641
+ ? "Auto-ready from linked sources"
1642
+ : "Custom onboarded setup" }), _jsx(StatusLine, { label: "Healthy providers", value: `${getSwarmHealthyCount(refreshState.swarm)} / ${refreshState.swarm.providers.length}` }), _jsx(StatusLine, { label: "Writable providers", value: String(getSwarmWritableCount(refreshState.swarm)) }), _jsx(StatusLine, { label: "Config file", value: refreshState.swarm.configPath }), _jsx(StatusLine, { label: "Searching now", value: summarizeNames(refreshState.swarm.providers.map((provider) => provider.label), "Umbrella Context only") }), refreshState.sources.length > 0 ? (_jsx(Text, { color: hasLiveSourceProvider(refreshState.swarm) ? "green" : "yellow", children: hasLiveSourceProvider(refreshState.swarm)
1643
+ ? "Linked source repos are already live in swarm search."
1644
+ : "This repo has linked sources, but swarm still needs one more setup step before they can be searched." })) : (_jsx(Text, { color: "gray", children: "Add a source repo when you want this repo to search another Umbrella repo too." })), refreshState.swarm.suggestions.slice(0, 2).map((suggestion) => (_jsx(Text, { color: "gray", children: suggestion }, suggestion)))] }), _jsxs(Section, { title: "Context Tree", children: [_jsx(StatusLine, { label: "Summary", value: vendorTreeStore?.summaryHandle ?? refreshState.treeState.summaryHandle }), _jsx(StatusLine, { label: "Nodes", value: String(vendorTreeStore?.nodes.length ?? refreshState.treeState.nodes.length) }), _jsx(StatusLine, { label: "Runtime provider", value: vendorTreeStore?.runtime.provider ?? "No provider" }), _jsx(StatusLine, { label: "Runtime model", value: vendorTreeStore?.runtime.model ?? "No model" })] }), queryResult ? (_jsxs(Section, { title: `Latest Query: ${queryResult.query}`, children: [_jsxs(Text, { children: ["Local matches: ", String(queryResult.localMatches.length)] }), _jsxs(Text, { children: ["Shared matches: ", String(queryResult.remoteMatches.length)] })] })) : null, connectionPresentation?.connectionMode === "saved_local_config" ? (_jsxs(Section, { title: "Next Step", children: [_jsx(Text, { color: "yellow", children: "Run setup again before you trust shared server actions for this repo." }), _jsx(Text, { color: "gray", children: "Press x if you want to sign out on this device and start over from the beginning." })] })) : null] })] }));
1478
1645
  }
1479
1646
  else if (activePanel === "tasks") {
1480
1647
  mainContent = (_jsx(TasksPanelView, { mode: tasksPanelMode, selectedIndex: tasksPanelSelectedIndex, tasks: vendorTasks, transportStatus: vendorTransportStore?.status ?? vendorTransportSummary.transportStatus, queueLength: vendorTransportStore?.queue.length ?? vendorTransportSummary.queueDepth, activeTaskId: vendorTransportStore?.queue[0]?.id ??
@@ -1506,7 +1673,11 @@ function App() {
1506
1673
  mainContent = (_jsx(ConnectorsPanelView, { installedSources: vendorConnectorsStore?.installedSources ?? [], recentSource: vendorConnectorsStore?.recentSource ?? null, recentRunSource: vendorConnectorsStore?.recentRunSource ?? null, registryEntries: registryEntries, selectedIndex: connectorsPanelSelectedIndex }));
1507
1674
  }
1508
1675
  else {
1509
- mainContent = (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Session Memory" }), _jsx(Text, { color: "gray", children: "This is the live terminal memory saved inside the repo, plus the internal runtime stores hydrated from the same Context engine." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Session ID", value: refreshState.session?.id ?? "None" }), _jsx(StatusLine, { label: "Current panel", value: refreshState.session?.currentPanel ?? "None" }), _jsx(StatusLine, { label: "Current focus", value: refreshState.session?.currentFocus ?? "None" }), _jsx(StatusLine, { label: "Commands", value: String(refreshState.session?.commandHistory.length ?? 0) }), _jsx(StatusLine, { label: "Events", value: String(refreshState.session?.events.length ?? 0) }), _jsx(StatusLine, { label: "Transport", value: vendorTransportStore?.status ?? refreshState.transport.status }), _jsx(StatusLine, { label: "Tree summary", value: vendorTreeStore?.summaryHandle ?? refreshState.treeState.summaryHandle })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Section, { title: "Transport and Tasks", children: [_jsx(StatusLine, { label: "Queue depth", value: String(vendorTransportStore?.queue.length ?? 0) }), _jsx(StatusLine, { label: "Recent tasks", value: String(vendorTasks.length) }), _jsx(StatusLine, { label: "Active task", value: vendorTransportSummary.activeTaskId ?? "None" }), _jsx(StatusLine, { label: "Started tasks", value: String(vendorTransportSummary.startedTasks) }), vendorRecentTransportEvents.length ? (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: "yellow", children: "Recent transport events" }), vendorRecentTransportEvents.map((event) => (_jsxs(Text, { color: "gray", children: [new Date(event.at).toLocaleString(), " | ", event.kind, " | ", event.title] }, `${event.kind}-${event.at}-${event.taskId ?? "no-task"}`)))] })) : (_jsx(Text, { color: "gray", children: "No transport events yet." }))] }), _jsxs(Section, { title: "Context Runtime Tree", children: [_jsx(StatusLine, { label: "Nodes", value: String(vendorTreeStore?.nodes.length ?? 0) }), _jsx(StatusLine, { label: "Pending drafts", value: String(vendorTreeStore?.stats.pendingDrafts ?? 0) }), _jsx(StatusLine, { label: "Pulled context", value: String(vendorTreeStore?.stats.pulledContext ?? 0) }), _jsx(StatusLine, { label: "Known fixes", value: String(vendorTreeStore?.stats.pulledFixes ?? 0) }), _jsx(StatusLine, { label: "Runtime transport", value: vendorTreeStore?.runtime.transportStatus ?? "idle" }), vendorRootTreeNodes.length ? (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: "yellow", children: "Top runtime nodes" }), vendorRootTreeNodes.map((node) => (_jsx(Text, { color: "gray", children: `${" ".repeat(node.depth)}- ${node.label}${node.detail ? ` | ${node.detail}` : ""}` }, node.id)))] })) : (_jsx(Text, { color: "gray", children: "The context tree has not been built yet." }))] }), _jsxs(Section, { title: "Session Continuity", children: [_jsx(StatusLine, { label: "Panel history", value: refreshState.session?.panelHistory.join(" -> ") || "None" }), _jsx(StatusLine, { label: "Recent providers", value: refreshState.session?.recentProviderIds.join(", ") || "None" }), _jsx(StatusLine, { label: "Recent models", value: refreshState.session?.recentModels.join(", ") || "None" }), _jsx(StatusLine, { label: "Recent hub items", value: refreshState.session?.recentHubSlugs.join(", ") || "None" }), _jsx(StatusLine, { label: "Recent connectors", value: refreshState.session?.recentConnectorSources.join(", ") || "None" })] }), _jsxs(Section, { title: "Runtime Bridge", children: [_jsx(StatusLine, { label: "Hydrated", value: vendorTransportSummary.isHydrated ? "Yes" : "No" }), _jsx(StatusLine, { label: "Generated", value: formatAgo(vendorTransportSummary.generatedAt) }), _jsx(StatusLine, { label: "Bridge queue", value: String(vendorTransportSummary.queueDepth) }), _jsx(StatusLine, { label: "Bridge tasks", value: String(vendorTransportSummary.recentTaskCount) }), _jsx(StatusLine, { label: "Bridge company", value: vendorContextSummary.companyName ?? "Unlinked company" }), _jsx(StatusLine, { label: "Bridge space", value: vendorContextSummary.spaceName ?? "Unlinked space" }), _jsx(StatusLine, { label: "Bridge provider", value: vendorContextSummary.providerName ?? "No provider" }), _jsx(StatusLine, { label: "Bridge model", value: vendorContextSummary.modelName ?? "No model" }), _jsx(StatusLine, { label: "Tree nodes", value: String(vendorContextSummary.treeNodes) }), _jsx(StatusLine, { label: "Runtime status", value: vendorContextSummary.runtimeStatus })] })] })] }));
1676
+ mainContent = (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Session Memory" }), _jsx(Text, { color: "gray", children: "Session is the control room for this device and this repo. It shows what is saved, what is active now, and what the local runtime has been doing." }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StatusLine, { label: "Session ID", value: refreshState.session?.id ?? "None" }), _jsx(StatusLine, { label: "Current panel", value: refreshState.session?.currentPanel ?? "None" }), _jsx(StatusLine, { label: "Current focus", value: refreshState.session?.currentFocus ?? "None" }), _jsx(StatusLine, { label: "Commands", value: String(refreshState.session?.commandHistory.length ?? 0) }), _jsx(StatusLine, { label: "Events", value: String(refreshState.session?.events.length ?? 0) }), _jsx(StatusLine, { label: "Transport", value: vendorTransportStore?.status ?? refreshState.transport.status }), _jsx(StatusLine, { label: "Tree summary", value: vendorTreeStore?.summaryHandle ?? refreshState.treeState.summaryHandle })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Section, { title: "Swarm", children: [_jsx(StatusLine, { label: "Configured", value: refreshState.swarm.configured ? "Yes" : "No" }), _jsx(StatusLine, { label: "Mode", value: !refreshState.swarm.configured
1677
+ ? "Off"
1678
+ : isAutoBootstrappedSwarm(refreshState.swarm)
1679
+ ? "Auto-ready from linked sources"
1680
+ : "Custom onboarded setup" }), _jsx(StatusLine, { label: "Healthy providers", value: `${getSwarmHealthyCount(refreshState.swarm)} / ${refreshState.swarm.providers.length}` }), _jsx(StatusLine, { label: "Writable providers", value: String(getSwarmWritableCount(refreshState.swarm)) }), _jsx(StatusLine, { label: "Searching now", value: summarizeNames(refreshState.swarm.providers.map((provider) => provider.label), "Umbrella Context only") }), _jsx(Text, { color: "gray", children: "Use: umbrella-context swarm onboard, swarm status, swarm query, and swarm curate." }), refreshState.swarm.suggestions.slice(0, 2).map((suggestion) => (_jsx(Text, { color: "gray", children: suggestion }, suggestion)))] }), _jsxs(Section, { title: "Workspace Links", children: [_jsx(StatusLine, { label: "Repo mode", value: refreshState.repoResolution.mode === "linked" ? "Linked worktree" : "Direct project" }), _jsx(StatusLine, { label: "Registered worktrees", value: String(refreshState.worktrees.length) }), _jsx(StatusLine, { label: "Knowledge sources", value: String(refreshState.sources.length) }), _jsx(StatusLine, { label: "Cross-repo search", value: getSwarmReadinessLabel(refreshState.swarm, refreshState.sources.length) }), _jsx(StatusLine, { label: "Worktree names", value: summarizeNames(refreshState.worktrees.map((entry) => entry.name), "None") }), _jsx(StatusLine, { label: "Source aliases", value: summarizeNames(refreshState.sources.map((entry) => entry.alias), "None") }), _jsx(Text, { color: "gray", children: "Sources are read-only Umbrella repos that swarm can search beside this one." })] }), _jsxs(Section, { title: "Adaptive Knowledge", children: [_jsx(StatusLine, { label: "Entries with abstracts", value: String(refreshState.adaptive.entryCount) }), _jsx(StatusLine, { label: "Last refresh", value: formatAgo(refreshState.adaptive.generatedAt) }), _jsx(Text, { color: "gray", children: "Frequently used notes get a hotness boost so the most useful saved context rises first." })] }), _jsxs(Section, { title: "Saved Device Setup", children: [_jsx(StatusLine, { label: "Umbrella app URL", value: config?.umbrellaUrl ?? "Not saved" }), _jsx(StatusLine, { label: "Context backend URL", value: config?.serverUrl ?? "Not saved" }), _jsx(StatusLine, { label: "Saved company link", value: config ? `${config.companyName} / ${config.projectName}` : "Not saved" }), _jsx(StatusLine, { label: "Auth state", value: formatUmbrellaAuthStatus(connectionPresentation?.authSnapshot.status ?? authSnapshot.status) }), _jsx(Text, { color: "gray", children: "This is what this computer is signed into right now." })] }), _jsxs(Section, { title: "Connection Actions", children: [SESSION_ACTIONS.map((action, index) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: index === sessionPanelSelectedIndex ? "yellow" : "white", children: [index === sessionPanelSelectedIndex ? ">" : " ", " ", action.title] }), _jsx(Text, { color: "gray", children: action.description })] }, action.id))), _jsx(Text, { color: "gray", children: "Enter runs the selected action. \"Repair setup\" is how you switch server or company. \"Switch space\" stays inside the current company." }), _jsx(Text, { color: "gray", children: "You can still run: umbrella-context logout" })] }), _jsxs(Section, { title: "Transport and Tasks", children: [_jsx(StatusLine, { label: "Queue depth", value: String(vendorTransportStore?.queue.length ?? 0) }), _jsx(StatusLine, { label: "Recent tasks", value: String(vendorTasks.length) }), _jsx(StatusLine, { label: "Active task", value: vendorTransportSummary.activeTaskId ?? "None" }), _jsx(StatusLine, { label: "Started tasks", value: String(vendorTransportSummary.startedTasks) }), vendorRecentTransportEvents.length ? (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: "yellow", children: "Recent transport events" }), vendorRecentTransportEvents.map((event) => (_jsxs(Text, { color: "gray", children: [new Date(event.at).toLocaleString(), " | ", event.kind, " | ", event.title] }, `${event.kind}-${event.at}-${event.taskId ?? "no-task"}`)))] })) : (_jsx(Text, { color: "gray", children: "No transport events yet." }))] }), _jsxs(Section, { title: "Context Runtime Tree", children: [_jsx(StatusLine, { label: "Nodes", value: String(vendorTreeStore?.nodes.length ?? 0) }), _jsx(StatusLine, { label: "Pending drafts", value: String(vendorTreeStore?.stats.pendingDrafts ?? 0) }), _jsx(StatusLine, { label: "Pulled context", value: String(vendorTreeStore?.stats.pulledContext ?? 0) }), _jsx(StatusLine, { label: "Known fixes", value: String(vendorTreeStore?.stats.pulledFixes ?? 0) }), _jsx(StatusLine, { label: "Runtime transport", value: vendorTreeStore?.runtime.transportStatus ?? "idle" }), vendorRootTreeNodes.length ? (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, color: "yellow", children: "Top runtime nodes" }), vendorRootTreeNodes.map((node) => (_jsx(Text, { color: "gray", children: `${" ".repeat(node.depth)}- ${node.label}${node.detail ? ` | ${node.detail}` : ""}` }, node.id)))] })) : (_jsx(Text, { color: "gray", children: "The context tree has not been built yet." }))] }), _jsxs(Section, { title: "Session Continuity", children: [_jsx(StatusLine, { label: "Panel history", value: refreshState.session?.panelHistory.join(" -> ") || "None" }), _jsx(StatusLine, { label: "Recent providers", value: refreshState.session?.recentProviderIds.join(", ") || "None" }), _jsx(StatusLine, { label: "Recent models", value: refreshState.session?.recentModels.join(", ") || "None" }), _jsx(StatusLine, { label: "Recent hub items", value: refreshState.session?.recentHubSlugs.join(", ") || "None" }), _jsx(StatusLine, { label: "Recent connectors", value: refreshState.session?.recentConnectorSources.join(", ") || "None" })] }), _jsxs(Section, { title: "Runtime Bridge", children: [_jsx(StatusLine, { label: "Hydrated", value: vendorTransportSummary.isHydrated ? "Yes" : "No" }), _jsx(StatusLine, { label: "Generated", value: formatAgo(vendorTransportSummary.generatedAt) }), _jsx(StatusLine, { label: "Bridge queue", value: String(vendorTransportSummary.queueDepth) }), _jsx(StatusLine, { label: "Bridge tasks", value: String(vendorTransportSummary.recentTaskCount) }), _jsx(StatusLine, { label: "Bridge company", value: vendorContextSummary.companyName ?? "Unlinked company" }), _jsx(StatusLine, { label: "Bridge space", value: vendorContextSummary.spaceName ?? "Unlinked space" }), _jsx(StatusLine, { label: "Bridge provider", value: vendorContextSummary.providerName ?? "No provider" }), _jsx(StatusLine, { label: "Bridge model", value: vendorContextSummary.modelName ?? "No model" }), _jsx(StatusLine, { label: "Tree nodes", value: String(vendorContextSummary.treeNodes) }), _jsx(StatusLine, { label: "Runtime status", value: vendorContextSummary.runtimeStatus })] })] })] }));
1510
1681
  }
1511
1682
  return (_jsxs(PanelShell, { activePanel: activePanel, footer: footer, message: busyLabel ? `${busyLabel}` : message, navigationFocus: navigationFocus, selectedPanelIndex: selectedPanelIndex, children: [mainContent, inputMode ? (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "yellow", children: inputMode === "query" ? "Ask Context" : "Save a local Context note" }), _jsx(TextInput, { value: inputValue, onChange: setInputValue })] })) : null] }));
1512
1683
  }
@@ -0,0 +1,12 @@
1
+ export declare function worktreeAddCommandAction(targetPath?: string, opts?: {
2
+ force?: boolean;
3
+ format?: string;
4
+ name?: string;
5
+ }): Promise<void>;
6
+ export declare function worktreeListCommandAction(opts?: {
7
+ format?: string;
8
+ }): Promise<void>;
9
+ export declare function worktreeRemoveCommandAction(targetPath?: string, opts?: {
10
+ format?: string;
11
+ }): Promise<void>;
12
+ export declare function worktreeCommand(cli: any): void;