umbrella-context 0.1.2 → 0.1.32
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/bin/um.js +2 -0
- package/dist/adapters/byterover-context-runtime-store.d.ts +15 -0
- package/dist/adapters/byterover-context-runtime-store.js +57 -0
- package/dist/adapters/byterover-runtime-bridge.d.ts +218 -0
- package/dist/adapters/byterover-runtime-bridge.js +343 -0
- package/dist/adapters/byterover-transport-task-store.d.ts +13 -0
- package/dist/adapters/byterover-transport-task-store.js +50 -0
- package/dist/adapters/umbrella-onboarding.d.ts +27 -0
- package/dist/adapters/umbrella-onboarding.js +79 -0
- package/dist/adapters/umbrella-provider-runtime.d.ts +38 -0
- package/dist/adapters/umbrella-provider-runtime.js +199 -0
- package/dist/adapters/vendor-byterover.d.ts +4 -0
- package/dist/adapters/vendor-byterover.js +19 -0
- package/dist/commands/activity.d.ts +2 -0
- package/dist/commands/activity.js +82 -0
- package/dist/commands/bridge.d.ts +2 -0
- package/dist/commands/bridge.js +40 -0
- package/dist/commands/catalog.d.ts +34 -0
- package/dist/commands/catalog.js +234 -0
- package/dist/commands/connect.js +14 -14
- package/dist/commands/connectors.d.ts +24 -0
- package/dist/commands/connectors.js +626 -0
- package/dist/commands/curate.d.ts +1 -0
- package/dist/commands/curate.js +48 -3
- package/dist/commands/debug.d.ts +2 -0
- package/dist/commands/debug.js +55 -0
- package/dist/commands/fix.js +54 -0
- package/dist/commands/hub.d.ts +22 -0
- package/dist/commands/hub.js +487 -0
- package/dist/commands/interactive.d.ts +2 -0
- package/dist/commands/interactive.js +970 -62
- package/dist/commands/locations.d.ts +1 -0
- package/dist/commands/locations.js +15 -12
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.js +34 -0
- package/dist/commands/model.d.ts +11 -0
- package/dist/commands/model.js +225 -0
- package/dist/commands/providers.d.ts +17 -0
- package/dist/commands/providers.js +379 -0
- package/dist/commands/pull.js +60 -1
- package/dist/commands/push.js +62 -2
- package/dist/commands/reset.d.ts +2 -0
- package/dist/commands/reset.js +35 -0
- package/dist/commands/restart.d.ts +2 -0
- package/dist/commands/restart.js +21 -0
- package/dist/commands/search.js +65 -1
- package/dist/commands/session.d.ts +2 -0
- package/dist/commands/session.js +241 -0
- package/dist/commands/setup.js +58 -56
- package/dist/commands/space.d.ts +12 -0
- package/dist/commands/space.js +138 -42
- package/dist/commands/status.d.ts +29 -0
- package/dist/commands/status.js +120 -19
- package/dist/commands/tasks.d.ts +2 -0
- package/dist/commands/tasks.js +95 -0
- package/dist/commands/transport.d.ts +2 -0
- package/dist/commands/transport.js +88 -0
- package/dist/commands/tree.d.ts +2 -0
- package/dist/commands/tree.js +98 -0
- package/dist/commands/tui.d.ts +2 -0
- package/dist/commands/tui.js +1273 -0
- package/dist/config.d.ts +23 -0
- package/dist/config.js +69 -0
- package/dist/index.js +41 -5
- package/dist/repo-state.d.ts +227 -1
- package/dist/repo-state.js +920 -4
- package/dist/umbrella.js +29 -5
- package/package.json +11 -3
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import prompts from "prompts";
|
|
3
|
+
import { configManager } from "../config.js";
|
|
4
|
+
import { connectSavedProviderFromDraft, createEmptyProviderConnectDraft, getActiveSavedProvider, getProviderRuntimeReadiness, inspectRecentSavedProvider, inspectSavedProvider, resolveSavedProvider, switchActiveSavedProvider, testActiveSavedProviderRuntime, disconnectSavedProvider, UMBRELLA_PROVIDER_CHOICES, } from "../adapters/umbrella-provider-runtime.js";
|
|
5
|
+
import { recordSessionEvent, setSessionPanel } from "../repo-state.js";
|
|
6
|
+
import { modelCommandAction } from "./model.js";
|
|
7
|
+
function printProviders(providers, activeProvider) {
|
|
8
|
+
console.log(chalk.bold("\n Connected Providers\n"));
|
|
9
|
+
if (providers.length === 0) {
|
|
10
|
+
console.log(chalk.yellow(" No providers connected yet. Run: umbrella-context providers connect"));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
providers.forEach((provider, index) => {
|
|
14
|
+
const active = provider.id === activeProvider ? " (active)" : "";
|
|
15
|
+
const base = provider.baseUrl ? ` -> ${provider.baseUrl}` : "";
|
|
16
|
+
console.log(` ${index + 1}. ${provider.name} [${provider.kind}]${active}${base}`);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function runProviderSetupFlow() {
|
|
20
|
+
const providers = configManager.providers;
|
|
21
|
+
let provider = getActiveSavedProvider();
|
|
22
|
+
let changed = false;
|
|
23
|
+
await setSessionPanel("providers", provider?.id ?? "setup");
|
|
24
|
+
if (providers.length === 0) {
|
|
25
|
+
console.log(chalk.cyan("\n No provider is connected yet, so setup will start by connecting one."));
|
|
26
|
+
const connectResult = await providersCommandAction("connect");
|
|
27
|
+
if (!connectResult?.activeProvider)
|
|
28
|
+
return;
|
|
29
|
+
provider = connectResult.activeProvider;
|
|
30
|
+
changed = changed || connectResult.changed;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const answer = await prompts({
|
|
34
|
+
type: "select",
|
|
35
|
+
name: "value",
|
|
36
|
+
message: provider
|
|
37
|
+
? `Runtime setup (active provider: ${provider.name})`
|
|
38
|
+
: "Runtime setup",
|
|
39
|
+
choices: [
|
|
40
|
+
...(provider
|
|
41
|
+
? [
|
|
42
|
+
{
|
|
43
|
+
title: `Keep ${provider.name} as the active provider`,
|
|
44
|
+
description: "Use the current provider and continue into model setup",
|
|
45
|
+
value: "__keep__",
|
|
46
|
+
},
|
|
47
|
+
]
|
|
48
|
+
: []),
|
|
49
|
+
...providers.map((entry) => ({
|
|
50
|
+
title: `${entry.name} (${entry.kind})${entry.id === provider?.id ? " [active]" : ""}`,
|
|
51
|
+
description: "Switch to this provider and continue the setup flow",
|
|
52
|
+
value: entry.id,
|
|
53
|
+
})),
|
|
54
|
+
{
|
|
55
|
+
title: "Connect a new provider",
|
|
56
|
+
description: "Add another provider to this device first",
|
|
57
|
+
value: "__connect__",
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
if (!answer.value) {
|
|
62
|
+
console.log(chalk.yellow("\n Provider setup cancelled."));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (answer.value === "__connect__") {
|
|
66
|
+
const connectResult = await providersCommandAction("connect");
|
|
67
|
+
if (!connectResult?.activeProvider)
|
|
68
|
+
return;
|
|
69
|
+
provider = connectResult.activeProvider;
|
|
70
|
+
changed = changed || connectResult.changed;
|
|
71
|
+
}
|
|
72
|
+
else if (answer.value !== "__keep__") {
|
|
73
|
+
const switchResult = await providersCommandAction("switch", answer.value);
|
|
74
|
+
if (!switchResult?.activeProvider)
|
|
75
|
+
return;
|
|
76
|
+
provider = switchResult.activeProvider;
|
|
77
|
+
changed = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!provider) {
|
|
81
|
+
console.log(chalk.yellow("\n Provider setup could not find an active provider."));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!configManager.config?.activeModel) {
|
|
85
|
+
const modelResult = await modelCommandAction("switch");
|
|
86
|
+
if (!modelResult?.activeModel) {
|
|
87
|
+
console.log(chalk.yellow("\n Model setup cancelled before the runtime was fully ready."));
|
|
88
|
+
return {
|
|
89
|
+
action: "setup",
|
|
90
|
+
changed,
|
|
91
|
+
activeProvider: provider,
|
|
92
|
+
needsModelSelection: true,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
changed = changed || modelResult.changed;
|
|
96
|
+
}
|
|
97
|
+
const runtimeResult = await providersCommandAction("test");
|
|
98
|
+
const activeModel = configManager.config?.activeModel ?? null;
|
|
99
|
+
const runtimeReady = Boolean(provider.apiKey && activeModel);
|
|
100
|
+
await recordSessionEvent({
|
|
101
|
+
kind: "provider",
|
|
102
|
+
title: runtimeReady ? `Completed runtime setup for ${provider.name}` : `Runtime setup stopped early for ${provider.name}`,
|
|
103
|
+
detail: runtimeReady
|
|
104
|
+
? `${provider.name} and ${activeModel} are ready for terminal Context work.`
|
|
105
|
+
: `${provider.name} is selected, but the runtime still needs attention.`,
|
|
106
|
+
panel: "providers",
|
|
107
|
+
focus: provider.id,
|
|
108
|
+
status: runtimeReady ? "success" : "warning",
|
|
109
|
+
});
|
|
110
|
+
console.log("");
|
|
111
|
+
console.log(chalk.bold(" Runtime Setup Summary"));
|
|
112
|
+
console.log(` Provider: ${provider.name}`);
|
|
113
|
+
console.log(` Model: ${activeModel ?? "Not selected"}`);
|
|
114
|
+
console.log(` Ready: ${runtimeReady ? "Yes" : "No"}`);
|
|
115
|
+
console.log("");
|
|
116
|
+
console.log(chalk.cyan(" Recommended Next Step"));
|
|
117
|
+
console.log(runtimeReady
|
|
118
|
+
? ' - Ask a plain question in the shell or run "umbrella-context query".'
|
|
119
|
+
: ' - Run "umbrella-context model switch" or "umbrella-context providers test" to finish setup.');
|
|
120
|
+
return {
|
|
121
|
+
action: "setup",
|
|
122
|
+
changed: changed || Boolean(runtimeResult?.changed),
|
|
123
|
+
activeProvider: provider,
|
|
124
|
+
needsModelSelection: !runtimeReady,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export function getActiveProvider() {
|
|
128
|
+
return getActiveSavedProvider();
|
|
129
|
+
}
|
|
130
|
+
export function getProviderReadinessSummary() {
|
|
131
|
+
return getProviderRuntimeReadiness();
|
|
132
|
+
}
|
|
133
|
+
export async function providersCommandAction(action, target) {
|
|
134
|
+
const normalized = action.toLowerCase();
|
|
135
|
+
const providers = configManager.providers;
|
|
136
|
+
const activeProvider = configManager.config?.activeProvider;
|
|
137
|
+
await setSessionPanel("providers", null);
|
|
138
|
+
if (normalized === "list") {
|
|
139
|
+
await setSessionPanel("providers", "list");
|
|
140
|
+
printProviders(providers, activeProvider);
|
|
141
|
+
const current = getActiveSavedProvider();
|
|
142
|
+
return {
|
|
143
|
+
action: "list",
|
|
144
|
+
changed: false,
|
|
145
|
+
activeProvider: current,
|
|
146
|
+
needsModelSelection: Boolean(current && !configManager.config?.activeModel),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (normalized === "setup") {
|
|
150
|
+
return runProviderSetupFlow();
|
|
151
|
+
}
|
|
152
|
+
if (normalized === "test") {
|
|
153
|
+
const runtime = await testActiveSavedProviderRuntime();
|
|
154
|
+
if (!runtime) {
|
|
155
|
+
console.log(chalk.yellow("\n No active provider. Run: umbrella-context providers connect"));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const { provider: current, runtimeReady } = runtime;
|
|
159
|
+
console.log(chalk.bold(`\n Runtime check for ${current.name}\n`));
|
|
160
|
+
console.log(` Kind: ${current.kind}`);
|
|
161
|
+
console.log(` API key saved: ${current.apiKey ? "Yes" : "No"}`);
|
|
162
|
+
console.log(` Active model: ${configManager.config?.activeModel ?? "Not selected"}`);
|
|
163
|
+
console.log(` Runtime ready: ${runtimeReady ? "Yes" : "No"}`);
|
|
164
|
+
console.log("");
|
|
165
|
+
console.log(chalk.cyan(" Recommended Next Step"));
|
|
166
|
+
console.log(runtimeReady
|
|
167
|
+
? " - Runtime is ready. Ask a plain question or run umbrella-context query."
|
|
168
|
+
: ' - Run umbrella-context model switch to finish the runtime setup.');
|
|
169
|
+
return {
|
|
170
|
+
action: "test",
|
|
171
|
+
changed: false,
|
|
172
|
+
activeProvider: current,
|
|
173
|
+
needsModelSelection: !configManager.config?.activeModel,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (normalized === "inspect") {
|
|
177
|
+
if (providers.length === 0) {
|
|
178
|
+
console.log(chalk.yellow(" No connected providers yet. Run: umbrella-context providers connect"));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
let selectedId = target;
|
|
182
|
+
if (!selectedId) {
|
|
183
|
+
const answer = await prompts({
|
|
184
|
+
type: "select",
|
|
185
|
+
name: "value",
|
|
186
|
+
message: "Choose a provider to inspect",
|
|
187
|
+
choices: providers.map((provider) => ({
|
|
188
|
+
title: `${provider.name} (${provider.kind})`,
|
|
189
|
+
value: provider.id,
|
|
190
|
+
})),
|
|
191
|
+
});
|
|
192
|
+
if (!answer.value) {
|
|
193
|
+
console.log(chalk.yellow("\n No provider selected."));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
selectedId = answer.value;
|
|
197
|
+
}
|
|
198
|
+
if (!selectedId) {
|
|
199
|
+
console.log(chalk.yellow("\n No provider selected."));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const provider = await inspectSavedProvider(selectedId);
|
|
203
|
+
if (!provider)
|
|
204
|
+
return;
|
|
205
|
+
console.log(chalk.bold(`\n ${provider.name}\n`));
|
|
206
|
+
console.log(` Kind: ${provider.kind}`);
|
|
207
|
+
console.log(` Active: ${provider.id === activeProvider ? "Yes" : "No"}`);
|
|
208
|
+
console.log(` Base URL: ${provider.baseUrl ?? "Default"}`);
|
|
209
|
+
console.log(` Updated: ${new Date(provider.updatedAt).toLocaleString()}`);
|
|
210
|
+
console.log("");
|
|
211
|
+
console.log(chalk.cyan(" Recommended Next Step"));
|
|
212
|
+
if (provider.id !== activeProvider) {
|
|
213
|
+
console.log(" - Run umbrella-context providers switch to make this the active runtime.");
|
|
214
|
+
}
|
|
215
|
+
else if (!configManager.config?.activeModel) {
|
|
216
|
+
console.log(" - Run umbrella-context model switch to choose a model for this provider.");
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
console.log(" - Runtime is ready. Ask a question or run umbrella-context query.");
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
action: "inspect",
|
|
223
|
+
changed: false,
|
|
224
|
+
activeProvider: getActiveSavedProvider(),
|
|
225
|
+
needsModelSelection: Boolean(provider.id === activeProvider && !configManager.config?.activeModel),
|
|
226
|
+
inspectedProvider: provider,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
if (normalized === "recent") {
|
|
230
|
+
const recent = await inspectRecentSavedProvider(target);
|
|
231
|
+
if (!recent) {
|
|
232
|
+
console.log(chalk.yellow("\n No recent provider in this session yet."));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const { provider } = recent;
|
|
236
|
+
console.log(chalk.bold(`\n ${provider.name}\n`));
|
|
237
|
+
console.log(` Kind: ${provider.kind}`);
|
|
238
|
+
console.log(` Active: ${provider.id === activeProvider ? "Yes" : "No"}`);
|
|
239
|
+
console.log(` Base URL: ${provider.baseUrl ?? "Default"}`);
|
|
240
|
+
console.log(` Updated: ${new Date(provider.updatedAt).toLocaleString()}`);
|
|
241
|
+
console.log("");
|
|
242
|
+
console.log(chalk.cyan(" Recommended Next Step"));
|
|
243
|
+
if (provider.id !== activeProvider) {
|
|
244
|
+
console.log(" - Run umbrella-context providers switch to make this the active runtime.");
|
|
245
|
+
}
|
|
246
|
+
else if (!configManager.config?.activeModel) {
|
|
247
|
+
console.log(" - Run umbrella-context model switch to choose a model for this provider.");
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
console.log(" - Runtime is ready. Ask a question or run umbrella-context query.");
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
action: "inspect",
|
|
254
|
+
changed: false,
|
|
255
|
+
activeProvider: getActiveSavedProvider(),
|
|
256
|
+
needsModelSelection: Boolean(provider.id === activeProvider && !configManager.config?.activeModel),
|
|
257
|
+
inspectedProvider: provider,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
if (normalized === "connect") {
|
|
261
|
+
const draft = createEmptyProviderConnectDraft();
|
|
262
|
+
const answer = await prompts([
|
|
263
|
+
{
|
|
264
|
+
type: "select",
|
|
265
|
+
name: "kind",
|
|
266
|
+
message: "Choose a provider",
|
|
267
|
+
choices: UMBRELLA_PROVIDER_CHOICES.map((entry) => ({ title: entry.name, value: entry.kind })),
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
type: "text",
|
|
271
|
+
name: "label",
|
|
272
|
+
message: "What label should this provider use on this device?",
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
type: "password",
|
|
276
|
+
name: "apiKey",
|
|
277
|
+
message: "Paste the provider API key (stored only on this device)",
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
type: (prev) => (prev === "openai-compatible" ? "text" : null),
|
|
281
|
+
name: "baseUrl",
|
|
282
|
+
message: "Base URL for the compatible API",
|
|
283
|
+
},
|
|
284
|
+
]);
|
|
285
|
+
if (!answer.kind || !answer.label || !answer.apiKey) {
|
|
286
|
+
console.log(chalk.yellow("\n Provider connection cancelled."));
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
draft.kind = answer.kind;
|
|
290
|
+
draft.label = answer.label;
|
|
291
|
+
draft.apiKey = answer.apiKey;
|
|
292
|
+
draft.baseUrl = answer.baseUrl || "";
|
|
293
|
+
const provider = await connectSavedProviderFromDraft(draft);
|
|
294
|
+
console.log(chalk.green(`\n Connected ${provider.name}.`));
|
|
295
|
+
console.log(chalk.gray(" Use 'umbrella-context model switch' to choose a model next."));
|
|
296
|
+
return {
|
|
297
|
+
action: "connect",
|
|
298
|
+
changed: true,
|
|
299
|
+
activeProvider: provider,
|
|
300
|
+
needsModelSelection: true,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
if (normalized === "switch") {
|
|
304
|
+
if (providers.length === 0) {
|
|
305
|
+
console.log(chalk.yellow(" No connected providers yet. Run: umbrella-context providers connect"));
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
let provider = resolveSavedProvider(target);
|
|
309
|
+
if (!provider) {
|
|
310
|
+
const answer = await prompts({
|
|
311
|
+
type: "select",
|
|
312
|
+
name: "value",
|
|
313
|
+
message: "Choose the active provider",
|
|
314
|
+
choices: providers.map((provider) => ({
|
|
315
|
+
title: `${provider.name} (${provider.kind})`,
|
|
316
|
+
value: provider.id,
|
|
317
|
+
})),
|
|
318
|
+
});
|
|
319
|
+
if (!answer.value) {
|
|
320
|
+
console.log(chalk.yellow("\n No provider selected."));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
provider = resolveSavedProvider(answer.value);
|
|
324
|
+
}
|
|
325
|
+
if (!provider) {
|
|
326
|
+
console.log(chalk.yellow("\n No provider selected."));
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
provider = await switchActiveSavedProvider(provider.id);
|
|
330
|
+
console.log(chalk.green(`\n Active provider: ${provider?.name ?? "Updated"}`));
|
|
331
|
+
return {
|
|
332
|
+
action: "switch",
|
|
333
|
+
changed: true,
|
|
334
|
+
activeProvider: provider ?? null,
|
|
335
|
+
needsModelSelection: true,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
if (normalized === "disconnect") {
|
|
339
|
+
if (providers.length === 0) {
|
|
340
|
+
console.log(chalk.yellow(" No connected providers yet."));
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
let provider = resolveSavedProvider(target);
|
|
344
|
+
if (!provider) {
|
|
345
|
+
const answer = await prompts({
|
|
346
|
+
type: "select",
|
|
347
|
+
name: "value",
|
|
348
|
+
message: "Choose a provider to disconnect",
|
|
349
|
+
choices: providers.map((provider) => ({
|
|
350
|
+
title: `${provider.name} (${provider.kind})`,
|
|
351
|
+
value: provider.id,
|
|
352
|
+
})),
|
|
353
|
+
});
|
|
354
|
+
if (!answer.value) {
|
|
355
|
+
console.log(chalk.yellow("\n No provider selected."));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
provider = resolveSavedProvider(answer.value);
|
|
359
|
+
}
|
|
360
|
+
if (!provider) {
|
|
361
|
+
console.log(chalk.yellow("\n No provider selected."));
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
const disconnectResult = await disconnectSavedProvider(provider.id);
|
|
365
|
+
console.log(chalk.green(`\n Disconnected ${disconnectResult?.removedProvider.name ?? "provider"}.`));
|
|
366
|
+
return {
|
|
367
|
+
action: "disconnect",
|
|
368
|
+
changed: true,
|
|
369
|
+
activeProvider: disconnectResult?.activeProvider ?? getActiveSavedProvider(),
|
|
370
|
+
needsModelSelection: false,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
console.log(chalk.red("Use one of: providers list, providers setup, providers inspect, providers recent, providers test, providers connect, providers switch, providers disconnect"));
|
|
374
|
+
}
|
|
375
|
+
export function providersCommand(cli) {
|
|
376
|
+
cli.command("providers <action> [target]", "Manage local LLM providers for the interactive Context terminal").action(async (action, target) => {
|
|
377
|
+
await providersCommandAction(action, target);
|
|
378
|
+
});
|
|
379
|
+
}
|
package/dist/commands/pull.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { configManager } from "../config.js";
|
|
3
|
-
import { ensureRepoContext, setPulledFixes, setPulledMemories } from "../repo-state.js";
|
|
3
|
+
import { addTaskReasoningContent, addTaskToolCall, completeTask, createTask, ensureRepoContext, recordSessionEvent, setPulledFixes, setPulledMemories, setSessionPanel, } from "../repo-state.js";
|
|
4
4
|
export async function pullCommandAction() {
|
|
5
5
|
const config = configManager.config;
|
|
6
6
|
if (!config) {
|
|
@@ -9,6 +9,26 @@ export async function pullCommandAction() {
|
|
|
9
9
|
}
|
|
10
10
|
try {
|
|
11
11
|
await ensureRepoContext(config);
|
|
12
|
+
await setSessionPanel("pull", config.projectName);
|
|
13
|
+
const task = await createTask({
|
|
14
|
+
kind: "pull",
|
|
15
|
+
title: `Pull shared Context for ${config.companyName} / ${config.projectName}`,
|
|
16
|
+
detail: "Refreshing the repo-local snapshot from the server.",
|
|
17
|
+
status: "running",
|
|
18
|
+
panel: "pull",
|
|
19
|
+
focus: config.projectName,
|
|
20
|
+
});
|
|
21
|
+
await addTaskReasoningContent(task.id, "Requesting shared memories and known fixes from the server.");
|
|
22
|
+
await addTaskToolCall(task.id, {
|
|
23
|
+
toolName: "server.memory.list",
|
|
24
|
+
status: "running",
|
|
25
|
+
args: { limit: 50 },
|
|
26
|
+
});
|
|
27
|
+
await addTaskToolCall(task.id, {
|
|
28
|
+
toolName: "server.evolutions.list",
|
|
29
|
+
status: "running",
|
|
30
|
+
args: { limit: 50 },
|
|
31
|
+
});
|
|
12
32
|
const [memoriesRes, fixesRes] = await Promise.all([
|
|
13
33
|
fetch(`${config.serverUrl}/api/memories?limit=50`, {
|
|
14
34
|
headers: { Authorization: `Bearer ${config.apiKey}` },
|
|
@@ -19,11 +39,32 @@ export async function pullCommandAction() {
|
|
|
19
39
|
]);
|
|
20
40
|
if (!memoriesRes.ok) {
|
|
21
41
|
const err = await memoriesRes.text();
|
|
42
|
+
await addTaskToolCall(task.id, {
|
|
43
|
+
toolName: "server.memory.list",
|
|
44
|
+
status: "error",
|
|
45
|
+
args: { limit: 50 },
|
|
46
|
+
error: err || memoriesRes.statusText,
|
|
47
|
+
});
|
|
48
|
+
await completeTask(task.id, "failed", err || memoriesRes.statusText);
|
|
22
49
|
console.log(chalk.red(`\n Pull failed: ${err || memoriesRes.statusText}`));
|
|
23
50
|
return;
|
|
24
51
|
}
|
|
25
52
|
const memoriesJson = await memoriesRes.json();
|
|
26
53
|
const fixesJson = fixesRes.ok ? await fixesRes.json() : { results: [] };
|
|
54
|
+
await addTaskToolCall(task.id, {
|
|
55
|
+
toolName: "server.memory.list",
|
|
56
|
+
status: "completed",
|
|
57
|
+
args: { limit: 50 },
|
|
58
|
+
result: { total: memoriesJson.results?.length ?? 0 },
|
|
59
|
+
});
|
|
60
|
+
await addTaskToolCall(task.id, {
|
|
61
|
+
toolName: "server.evolutions.list",
|
|
62
|
+
status: fixesRes.ok ? "completed" : "error",
|
|
63
|
+
args: { limit: 50 },
|
|
64
|
+
result: fixesRes.ok ? { total: fixesJson.results?.length ?? 0 } : undefined,
|
|
65
|
+
error: fixesRes.ok ? undefined : fixesRes.statusText,
|
|
66
|
+
});
|
|
67
|
+
await addTaskReasoningContent(task.id, `Pulled ${memoriesJson.results?.length ?? 0} context entr${(memoriesJson.results?.length ?? 0) === 1 ? "y" : "ies"} and ${fixesJson.results?.length ?? 0} known fix${(fixesJson.results?.length ?? 0) === 1 ? "" : "es"}.`);
|
|
27
68
|
await setPulledMemories((memoriesJson.results ?? []).map((entry) => ({
|
|
28
69
|
id: entry.id,
|
|
29
70
|
content: entry.content,
|
|
@@ -42,12 +83,30 @@ export async function pullCommandAction() {
|
|
|
42
83
|
createdAt: entry.createdAt ?? new Date().toISOString(),
|
|
43
84
|
lastApplied: entry.lastApplied ?? null,
|
|
44
85
|
})));
|
|
86
|
+
await recordSessionEvent({
|
|
87
|
+
kind: "pull",
|
|
88
|
+
title: `Pulled ${memoriesJson.results?.length ?? 0} Context entr${(memoriesJson.results?.length ?? 0) === 1 ? "y" : "ies"}`,
|
|
89
|
+
detail: `Cached ${fixesJson.results?.length ?? 0} known fix${(fixesJson.results?.length ?? 0) === 1 ? "" : "es"} for ${config.companyName} / ${config.projectName}.`,
|
|
90
|
+
panel: "pull",
|
|
91
|
+
focus: config.projectName,
|
|
92
|
+
status: "success",
|
|
93
|
+
});
|
|
94
|
+
await completeTask(task.id, "completed", `Pulled ${memoriesJson.results?.length ?? 0} context entr${(memoriesJson.results?.length ?? 0) === 1 ? "y" : "ies"} and ${fixesJson.results?.length ?? 0} known fix${(fixesJson.results?.length ?? 0) === 1 ? "" : "es"}.`);
|
|
45
95
|
console.log(chalk.green(`\n Pulled ${memoriesJson.results?.length ?? 0} context entries from the server.`));
|
|
46
96
|
console.log(chalk.gray(` Company: ${config.companyName}`));
|
|
47
97
|
console.log(chalk.gray(` Space: ${config.projectName}`));
|
|
48
98
|
console.log(chalk.gray(` Known fixes cached: ${fixesJson.results?.length ?? 0}`));
|
|
49
99
|
}
|
|
50
100
|
catch (err) {
|
|
101
|
+
const failedTask = await createTask({
|
|
102
|
+
kind: "pull",
|
|
103
|
+
title: `Pull failed for ${config.companyName} / ${config.projectName}`,
|
|
104
|
+
detail: err.message,
|
|
105
|
+
status: "failed",
|
|
106
|
+
panel: "pull",
|
|
107
|
+
focus: config.projectName,
|
|
108
|
+
});
|
|
109
|
+
await completeTask(failedTask.id, "failed", err.message);
|
|
51
110
|
console.log(chalk.red(`\n Error: ${err.message}`));
|
|
52
111
|
}
|
|
53
112
|
}
|
package/dist/commands/push.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { configManager } from "../config.js";
|
|
3
|
-
import { clearPendingMemories, ensureRepoContext, getPendingMemories, getPulledMemories, markPushCompleted, setPulledMemories, } from "../repo-state.js";
|
|
3
|
+
import { addTaskReasoningContent, addTaskToolCall, clearPendingMemories, completeTask, createTask, ensureRepoContext, getPendingMemories, getPulledMemories, markPushCompleted, recordSessionEvent, setSessionPanel, setPulledMemories, } from "../repo-state.js";
|
|
4
4
|
export async function pushCommandAction() {
|
|
5
5
|
const config = configManager.config;
|
|
6
6
|
if (!config) {
|
|
@@ -9,13 +9,41 @@ export async function pushCommandAction() {
|
|
|
9
9
|
}
|
|
10
10
|
try {
|
|
11
11
|
await ensureRepoContext(config);
|
|
12
|
+
await setSessionPanel("push", config.projectName);
|
|
13
|
+
const task = await createTask({
|
|
14
|
+
kind: "push",
|
|
15
|
+
title: `Push Context to ${config.companyName} / ${config.projectName}`,
|
|
16
|
+
detail: "Syncing repo-local drafts to the shared server.",
|
|
17
|
+
status: "running",
|
|
18
|
+
panel: "push",
|
|
19
|
+
focus: config.projectName,
|
|
20
|
+
});
|
|
12
21
|
const pending = await getPendingMemories();
|
|
22
|
+
await addTaskReasoningContent(task.id, `Found ${pending.length} pending local draft${pending.length === 1 ? "" : "s"} ready for upload.`);
|
|
13
23
|
if (pending.length === 0) {
|
|
24
|
+
await completeTask(task.id, "completed", "Nothing was pending, so no push was needed.");
|
|
25
|
+
await recordSessionEvent({
|
|
26
|
+
kind: "push",
|
|
27
|
+
title: "Push skipped because nothing was pending",
|
|
28
|
+
detail: `This repo had no local drafts waiting to sync for ${config.companyName} / ${config.projectName}.`,
|
|
29
|
+
panel: "push",
|
|
30
|
+
focus: config.projectName,
|
|
31
|
+
status: "info",
|
|
32
|
+
});
|
|
14
33
|
console.log(chalk.yellow("\n Nothing to push. Your local .um folder is already in sync."));
|
|
15
34
|
return;
|
|
16
35
|
}
|
|
17
36
|
const synced = [];
|
|
18
37
|
for (const entry of pending) {
|
|
38
|
+
await addTaskToolCall(task.id, {
|
|
39
|
+
toolName: "server.memory.create",
|
|
40
|
+
status: "running",
|
|
41
|
+
args: {
|
|
42
|
+
source: entry.source,
|
|
43
|
+
systemType: entry.systemType,
|
|
44
|
+
tags: entry.tags,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
19
47
|
const res = await fetch(`${config.serverUrl}/api/memories`, {
|
|
20
48
|
method: "POST",
|
|
21
49
|
headers: {
|
|
@@ -31,10 +59,24 @@ export async function pushCommandAction() {
|
|
|
31
59
|
});
|
|
32
60
|
if (!res.ok) {
|
|
33
61
|
const err = await res.text();
|
|
62
|
+
await addTaskToolCall(task.id, {
|
|
63
|
+
toolName: "server.memory.create",
|
|
64
|
+
status: "error",
|
|
65
|
+
args: { source: entry.source, systemType: entry.systemType },
|
|
66
|
+
error: err || res.statusText,
|
|
67
|
+
});
|
|
68
|
+
await completeTask(task.id, "failed", err || res.statusText);
|
|
34
69
|
console.log(chalk.red(`\n Push failed: ${err || res.statusText}`));
|
|
35
70
|
return;
|
|
36
71
|
}
|
|
37
|
-
|
|
72
|
+
const created = await res.json();
|
|
73
|
+
await addTaskToolCall(task.id, {
|
|
74
|
+
toolName: "server.memory.create",
|
|
75
|
+
status: "completed",
|
|
76
|
+
args: { source: entry.source, systemType: entry.systemType },
|
|
77
|
+
result: { id: created.id },
|
|
78
|
+
});
|
|
79
|
+
synced.push(created);
|
|
38
80
|
}
|
|
39
81
|
const existingPulled = await getPulledMemories();
|
|
40
82
|
await setPulledMemories([
|
|
@@ -50,11 +92,29 @@ export async function pushCommandAction() {
|
|
|
50
92
|
]);
|
|
51
93
|
await clearPendingMemories();
|
|
52
94
|
await markPushCompleted();
|
|
95
|
+
await recordSessionEvent({
|
|
96
|
+
kind: "push",
|
|
97
|
+
title: `Pushed ${synced.length} Context entr${synced.length === 1 ? "y" : "ies"}`,
|
|
98
|
+
detail: `Shared local drafts from ${config.companyName} / ${config.projectName} with the server.`,
|
|
99
|
+
panel: "push",
|
|
100
|
+
focus: config.projectName,
|
|
101
|
+
status: "success",
|
|
102
|
+
});
|
|
103
|
+
await completeTask(task.id, "completed", `Pushed ${synced.length} entr${synced.length === 1 ? "y" : "ies"} to the server.`);
|
|
53
104
|
console.log(chalk.green(`\n Pushed ${synced.length} local context entr${synced.length === 1 ? "y" : "ies"}.`));
|
|
54
105
|
console.log(chalk.gray(` Company: ${config.companyName}`));
|
|
55
106
|
console.log(chalk.gray(` Space: ${config.projectName}`));
|
|
56
107
|
}
|
|
57
108
|
catch (err) {
|
|
109
|
+
const failedTask = await createTask({
|
|
110
|
+
kind: "push",
|
|
111
|
+
title: `Push failed for ${config.companyName} / ${config.projectName}`,
|
|
112
|
+
detail: err.message,
|
|
113
|
+
status: "failed",
|
|
114
|
+
panel: "push",
|
|
115
|
+
focus: config.projectName,
|
|
116
|
+
});
|
|
117
|
+
await completeTask(failedTask.id, "failed", err.message);
|
|
58
118
|
console.log(chalk.red(`\n Error: ${err.message}`));
|
|
59
119
|
}
|
|
60
120
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import prompts from "prompts";
|
|
3
|
+
import { recordSessionEvent, resetRepoState } from "../repo-state.js";
|
|
4
|
+
export async function resetCommandAction(skipConfirm = false) {
|
|
5
|
+
if (!skipConfirm) {
|
|
6
|
+
const answer = await prompts({
|
|
7
|
+
type: "confirm",
|
|
8
|
+
name: "value",
|
|
9
|
+
message: "Reset this repo's local Context state? This clears .um drafts, pulled snapshots, hub installs, connectors, and saved session history for this repo.",
|
|
10
|
+
initial: false,
|
|
11
|
+
});
|
|
12
|
+
if (!answer.value) {
|
|
13
|
+
console.log(chalk.yellow("\n Reset cancelled. Your local Context state was left alone."));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const result = await resetRepoState();
|
|
18
|
+
await recordSessionEvent({
|
|
19
|
+
kind: "session",
|
|
20
|
+
title: "Completed a local Context reset",
|
|
21
|
+
detail: `Local Context files were reset inside ${result.umDir}.`,
|
|
22
|
+
panel: "reset",
|
|
23
|
+
focus: null,
|
|
24
|
+
status: "warning",
|
|
25
|
+
});
|
|
26
|
+
console.log(chalk.green("\n Local Context state reset."));
|
|
27
|
+
console.log(chalk.gray(` Repo root: ${result.repoRoot}`));
|
|
28
|
+
console.log(chalk.gray(` Local folder: ${result.umDir}`));
|
|
29
|
+
console.log(chalk.gray(" Your repo link to the company stayed in place, but the local Context cache and session state were cleared."));
|
|
30
|
+
}
|
|
31
|
+
export function resetCommand(cli) {
|
|
32
|
+
cli.command("reset", "Reset this repo's local Context state and clear the .um working set").action(async () => {
|
|
33
|
+
await resetCommandAction();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { configManager } from "../config.js";
|
|
3
|
+
import { ensureRepoContext, ensureSessionState, resetSessionState } from "../repo-state.js";
|
|
4
|
+
export async function restartCommandAction() {
|
|
5
|
+
const config = configManager.config;
|
|
6
|
+
if (!config) {
|
|
7
|
+
console.log(chalk.red("Not configured. Run: umbrella-context setup"));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
await ensureRepoContext(config);
|
|
11
|
+
const session = await resetSessionState();
|
|
12
|
+
await ensureSessionState();
|
|
13
|
+
console.log(chalk.green("\n Context terminal restarted for this repo."));
|
|
14
|
+
console.log(chalk.gray(` New session: ${session.id}`));
|
|
15
|
+
console.log(chalk.gray(" Local .um context files were kept. Only the live shell session was refreshed."));
|
|
16
|
+
}
|
|
17
|
+
export function restartCommand(cli) {
|
|
18
|
+
cli.command("restart", "Refresh the local repo session without deleting .um data").action(async () => {
|
|
19
|
+
await restartCommandAction();
|
|
20
|
+
});
|
|
21
|
+
}
|