@f5xc-salesdemos/xcsh 18.44.0 → 18.45.1
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5xc-salesdemos/xcsh",
|
|
4
|
-
"version": "18.
|
|
4
|
+
"version": "18.45.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/f5xc-salesdemos/xcsh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@agentclientprotocol/sdk": "0.16.1",
|
|
50
50
|
"@mozilla/readability": "^0.6",
|
|
51
|
-
"@f5xc-salesdemos/xcsh-stats": "18.
|
|
52
|
-
"@f5xc-salesdemos/pi-agent-core": "18.
|
|
53
|
-
"@f5xc-salesdemos/pi-ai": "18.
|
|
54
|
-
"@f5xc-salesdemos/pi-natives": "18.
|
|
55
|
-
"@f5xc-salesdemos/pi-tui": "18.
|
|
56
|
-
"@f5xc-salesdemos/pi-utils": "18.
|
|
51
|
+
"@f5xc-salesdemos/xcsh-stats": "18.45.1",
|
|
52
|
+
"@f5xc-salesdemos/pi-agent-core": "18.45.1",
|
|
53
|
+
"@f5xc-salesdemos/pi-ai": "18.45.1",
|
|
54
|
+
"@f5xc-salesdemos/pi-natives": "18.45.1",
|
|
55
|
+
"@f5xc-salesdemos/pi-tui": "18.45.1",
|
|
56
|
+
"@f5xc-salesdemos/pi-utils": "18.45.1",
|
|
57
57
|
"@sinclair/typebox": "^0.34",
|
|
58
58
|
"@xterm/headless": "^6.0",
|
|
59
59
|
"ajv": "^8.18",
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "18.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "18.45.1",
|
|
21
|
+
"commit": "b636990701856264c79e2544a376fc16c07ffe9f",
|
|
22
|
+
"shortCommit": "b636990",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v18.
|
|
25
|
-
"commitDate": "2026-05-
|
|
26
|
-
"buildDate": "2026-05-
|
|
24
|
+
"tag": "v18.45.1",
|
|
25
|
+
"commitDate": "2026-05-06T04:30:34Z",
|
|
26
|
+
"buildDate": "2026-05-06T04:51:28.530Z",
|
|
27
27
|
"dirty": false,
|
|
28
28
|
"prNumber": "",
|
|
29
29
|
"repoUrl": "https://github.com/f5xc-salesdemos/xcsh",
|
|
30
30
|
"repoSlug": "f5xc-salesdemos/xcsh",
|
|
31
|
-
"commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/
|
|
32
|
-
"releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.
|
|
31
|
+
"commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/b636990701856264c79e2544a376fc16c07ffe9f",
|
|
32
|
+
"releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.45.1"
|
|
33
33
|
};
|
package/src/main.ts
CHANGED
|
@@ -56,7 +56,6 @@ import type { AgentSession } from "./session/agent-session";
|
|
|
56
56
|
import { resolveResumableSession, type SessionInfo, SessionManager } from "./session/session-manager";
|
|
57
57
|
import { resolvePromptInput } from "./system-prompt";
|
|
58
58
|
import type { LspStartupServerInfo } from "./tools";
|
|
59
|
-
import { getChangelogPath, getNewEntries, parseChangelog } from "./utils/changelog";
|
|
60
59
|
import type { EventBus } from "./utils/event-bus";
|
|
61
60
|
|
|
62
61
|
async function checkForNewVersion(currentVersion: string): Promise<string | undefined> {
|
|
@@ -149,7 +148,6 @@ const INITIAL_UPDATE_CHECK_TIMEOUT_MS = 500;
|
|
|
149
148
|
async function runInteractiveMode(
|
|
150
149
|
session: AgentSession,
|
|
151
150
|
version: string,
|
|
152
|
-
changelogStatus: { hasNew: boolean; version: string } | undefined,
|
|
153
151
|
notifs: (InteractiveModeNotify | null)[],
|
|
154
152
|
versionCheckPromise: Promise<string | undefined>,
|
|
155
153
|
initialMessages: string[],
|
|
@@ -171,7 +169,6 @@ async function runInteractiveMode(
|
|
|
171
169
|
const mode = new InteractiveMode(
|
|
172
170
|
session,
|
|
173
171
|
version,
|
|
174
|
-
changelogStatus,
|
|
175
172
|
initialUpdateStatus,
|
|
176
173
|
setExtensionUIContext,
|
|
177
174
|
lspServers,
|
|
@@ -256,31 +253,6 @@ async function promptForkSession(session: SessionInfo): Promise<boolean> {
|
|
|
256
253
|
}
|
|
257
254
|
}
|
|
258
255
|
|
|
259
|
-
async function getChangelogForDisplay(parsed: Args): Promise<{ hasNew: boolean; version: string } | undefined> {
|
|
260
|
-
if (parsed.continue || parsed.resume) {
|
|
261
|
-
return undefined;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const lastVersion = settings.get("lastChangelogVersion");
|
|
265
|
-
const changelogPath = getChangelogPath();
|
|
266
|
-
const entries = await parseChangelog(changelogPath);
|
|
267
|
-
|
|
268
|
-
if (!lastVersion) {
|
|
269
|
-
if (entries.length > 0) {
|
|
270
|
-
settings.set("lastChangelogVersion", VERSION);
|
|
271
|
-
return { hasNew: true, version: VERSION };
|
|
272
|
-
}
|
|
273
|
-
} else {
|
|
274
|
-
const newEntries = getNewEntries(entries, lastVersion);
|
|
275
|
-
if (newEntries.length > 0) {
|
|
276
|
-
settings.set("lastChangelogVersion", VERSION);
|
|
277
|
-
return { hasNew: true, version: VERSION };
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return undefined;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
256
|
async function createSessionManager(parsed: Args, cwd: string): Promise<SessionManager | undefined> {
|
|
285
257
|
if (parsed.fork) {
|
|
286
258
|
if (parsed.noSession) {
|
|
@@ -890,8 +862,6 @@ export async function runRootCommand(parsed: Args, rawArgs: string[]): Promise<v
|
|
|
890
862
|
await runAcpMode(session, createAcpSession);
|
|
891
863
|
} else if (isInteractive) {
|
|
892
864
|
const versionCheckPromise = checkForNewVersion(VERSION).catch(() => undefined);
|
|
893
|
-
logger.time("main:getChangelogForDisplay");
|
|
894
|
-
const changelogStatus = await getChangelogForDisplay(parsedArgs);
|
|
895
865
|
|
|
896
866
|
const scopedModelsForDisplay = sessionOptions.scopedModels ?? scopedModels;
|
|
897
867
|
if (scopedModelsForDisplay.length > 0) {
|
|
@@ -915,7 +885,6 @@ export async function runRootCommand(parsed: Args, rawArgs: string[]): Promise<v
|
|
|
915
885
|
await runInteractiveMode(
|
|
916
886
|
session,
|
|
917
887
|
VERSION,
|
|
918
|
-
changelogStatus,
|
|
919
888
|
notifs,
|
|
920
889
|
versionCheckPromise,
|
|
921
890
|
parsedArgs.messages,
|
|
@@ -2,47 +2,30 @@ import { type Component, padding, truncateToWidth, visibleWidth } from "@f5xc-sa
|
|
|
2
2
|
import { APP_NAME } from "@f5xc-salesdemos/pi-utils";
|
|
3
3
|
import { theme } from "../../modes/theme/theme";
|
|
4
4
|
import { formatStatusIcon } from "../../services/f5xc-context-indicators";
|
|
5
|
-
import type { ModelStatus,
|
|
5
|
+
import type { ModelStatus, ServiceStatus } from "./welcome-checks";
|
|
6
6
|
|
|
7
7
|
export interface UpdateStatus {
|
|
8
8
|
available: boolean;
|
|
9
9
|
latestVersion?: string;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export interface ChangelogStatus {
|
|
13
|
-
hasNew: boolean;
|
|
14
|
-
version: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
12
|
export class WelcomeComponent implements Component {
|
|
18
13
|
constructor(
|
|
19
14
|
private readonly version: string,
|
|
20
15
|
private modelStatus: ModelStatus,
|
|
21
|
-
private
|
|
16
|
+
private services: ServiceStatus[] = [],
|
|
22
17
|
private updateStatus?: UpdateStatus,
|
|
23
|
-
private changelogStatus?: ChangelogStatus,
|
|
24
|
-
private gitlabStatus?: WelcomeGitLabStatus,
|
|
25
|
-
private salesforceStatus?: WelcomeSalesforceStatus,
|
|
26
18
|
) {}
|
|
27
19
|
invalidate(): void {}
|
|
28
20
|
setModelStatus(status: ModelStatus): void {
|
|
29
21
|
this.modelStatus = status;
|
|
30
22
|
}
|
|
31
|
-
|
|
32
|
-
this.
|
|
23
|
+
setServices(services: ServiceStatus[]): void {
|
|
24
|
+
this.services = services;
|
|
33
25
|
}
|
|
34
26
|
setUpdateStatus(status: UpdateStatus | undefined): void {
|
|
35
27
|
this.updateStatus = status;
|
|
36
28
|
}
|
|
37
|
-
setChangelogStatus(status: ChangelogStatus | undefined): void {
|
|
38
|
-
this.changelogStatus = status;
|
|
39
|
-
}
|
|
40
|
-
setGitLabStatus(status: WelcomeGitLabStatus | undefined): void {
|
|
41
|
-
this.gitlabStatus = status;
|
|
42
|
-
}
|
|
43
|
-
setSalesforceStatus(status: WelcomeSalesforceStatus | undefined): void {
|
|
44
|
-
this.salesforceStatus = status;
|
|
45
|
-
}
|
|
46
29
|
|
|
47
30
|
render(termWidth: number): string[] {
|
|
48
31
|
const minLeftCol = 48;
|
|
@@ -63,7 +46,8 @@ export class WelcomeComponent implements Component {
|
|
|
63
46
|
? preferredLeftCol
|
|
64
47
|
: Math.max(minLeftCol, dualContentWidth - idealRight);
|
|
65
48
|
const dualRightCol = Math.max(0, dualContentWidth - dualLeftCol);
|
|
66
|
-
|
|
49
|
+
// Only show dual column when both columns have enough room for their content
|
|
50
|
+
const showRightColumn = dualLeftCol >= minLeftCol && dualRightCol >= Math.max(minRightCol, naturalRight);
|
|
67
51
|
const leftCol = showRightColumn ? dualLeftCol : boxWidth - 2;
|
|
68
52
|
const rightCol = showRightColumn ? dualRightCol : 0;
|
|
69
53
|
|
|
@@ -95,7 +79,10 @@ export class WelcomeComponent implements Component {
|
|
|
95
79
|
const logoBlockPad = Math.max(0, Math.floor((leftCol - logoMaxWidth) / 2));
|
|
96
80
|
const logoPadStr = padding(logoBlockPad);
|
|
97
81
|
const leftLines = [...logoColored.map(l => logoPadStr + l), ""];
|
|
98
|
-
const rightLines = this.#buildStatusLines(rightCol);
|
|
82
|
+
const rightLines = this.#buildStatusLines(showRightColumn ? rightCol : leftCol);
|
|
83
|
+
if (!showRightColumn) {
|
|
84
|
+
leftLines.push(...rightLines);
|
|
85
|
+
}
|
|
99
86
|
const border = (s: string) => theme.fg("borderMuted", s);
|
|
100
87
|
const hChar = theme.boxRound.horizontal;
|
|
101
88
|
const h = border(hChar);
|
|
@@ -135,20 +122,11 @@ export class WelcomeComponent implements Component {
|
|
|
135
122
|
|
|
136
123
|
#measureStatusWidth(): number {
|
|
137
124
|
const lines: string[] = [" Model Provider", ...this.#renderModelStatus()];
|
|
138
|
-
|
|
139
|
-
lines.push(
|
|
140
|
-
}
|
|
141
|
-
if (this.gitlabStatus) {
|
|
142
|
-
lines.push(" GitLab", ...this.#renderGitLabStatus());
|
|
143
|
-
}
|
|
144
|
-
if (this.salesforceStatus) {
|
|
145
|
-
lines.push(" Salesforce", ...this.#renderSalesforceStatus());
|
|
125
|
+
for (const svc of this.services) {
|
|
126
|
+
lines.push(this.#renderServiceLine(svc));
|
|
146
127
|
}
|
|
147
128
|
if (this.#showUpdateSection()) {
|
|
148
|
-
lines.push(
|
|
149
|
-
}
|
|
150
|
-
if (this.#showChangelogSection()) {
|
|
151
|
-
lines.push(" What's New", ...this.#renderChangelogStatus());
|
|
129
|
+
lines.push(this.#renderUpdateLine());
|
|
152
130
|
}
|
|
153
131
|
return Math.max(...lines.map(l => visibleWidth(l)));
|
|
154
132
|
}
|
|
@@ -161,41 +139,16 @@ export class WelcomeComponent implements Component {
|
|
|
161
139
|
lines.push(` ${theme.bold(theme.fg("contentAccent", "Model Provider"))}`);
|
|
162
140
|
lines.push(...this.#renderModelStatus());
|
|
163
141
|
lines.push("");
|
|
164
|
-
if (this.
|
|
142
|
+
if (this.services.length > 0 || this.#showUpdateSection()) {
|
|
165
143
|
lines.push(separator);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
lines.push(separator);
|
|
173
|
-
lines.push("");
|
|
174
|
-
lines.push(` ${theme.bold(theme.fg("contentAccent", "GitLab"))}`);
|
|
175
|
-
lines.push(...this.#renderGitLabStatus());
|
|
176
|
-
lines.push("");
|
|
177
|
-
}
|
|
178
|
-
if (this.salesforceStatus) {
|
|
179
|
-
lines.push(separator);
|
|
180
|
-
lines.push("");
|
|
181
|
-
lines.push(` ${theme.bold(theme.fg("contentAccent", "Salesforce"))}`);
|
|
182
|
-
lines.push(...this.#renderSalesforceStatus());
|
|
183
|
-
lines.push("");
|
|
184
|
-
}
|
|
185
|
-
if (this.#showUpdateSection()) {
|
|
186
|
-
lines.push(separator);
|
|
187
|
-
lines.push("");
|
|
188
|
-
lines.push(` ${theme.bold(theme.fg("contentAccent", "Update Available"))}`);
|
|
189
|
-
lines.push(...this.#renderUpdateStatus());
|
|
190
|
-
lines.push("");
|
|
191
|
-
}
|
|
192
|
-
if (this.#showChangelogSection()) {
|
|
193
|
-
lines.push(separator);
|
|
194
|
-
lines.push("");
|
|
195
|
-
lines.push(` ${theme.bold(theme.fg("contentAccent", "What's New"))}`);
|
|
196
|
-
lines.push(...this.#renderChangelogStatus());
|
|
197
|
-
lines.push("");
|
|
144
|
+
for (const svc of this.services) {
|
|
145
|
+
lines.push(this.#renderServiceLine(svc));
|
|
146
|
+
}
|
|
147
|
+
if (this.#showUpdateSection()) {
|
|
148
|
+
lines.push(this.#renderUpdateLine());
|
|
149
|
+
}
|
|
198
150
|
}
|
|
151
|
+
lines.push("");
|
|
199
152
|
return lines;
|
|
200
153
|
}
|
|
201
154
|
|
|
@@ -203,25 +156,18 @@ export class WelcomeComponent implements Component {
|
|
|
203
156
|
return this.updateStatus?.available === true;
|
|
204
157
|
}
|
|
205
158
|
|
|
206
|
-
#
|
|
207
|
-
|
|
159
|
+
#renderServiceLine(service: ServiceStatus): string {
|
|
160
|
+
if (service.state === "connected") {
|
|
161
|
+
return ` ${formatStatusIcon("connected")} ${theme.fg("muted", service.name)}`;
|
|
162
|
+
}
|
|
163
|
+
const hint = service.hint ?? "";
|
|
164
|
+
return ` ${formatStatusIcon("warning")} ${theme.fg("muted", service.name)} ${theme.fg("dim", hint)}`;
|
|
208
165
|
}
|
|
209
166
|
|
|
210
|
-
#
|
|
167
|
+
#renderUpdateLine(): string {
|
|
211
168
|
const latest = this.updateStatus?.latestVersion;
|
|
212
169
|
const label = latest ? `v${latest}` : "new version";
|
|
213
|
-
return
|
|
214
|
-
` ${theme.fg("warning", "\u2191")} ${theme.fg("muted", label)}`,
|
|
215
|
-
` ${theme.fg("dim", "Run")} ${theme.fg("contentAccent", "xcsh update")}`,
|
|
216
|
-
];
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
#renderChangelogStatus(): string[] {
|
|
220
|
-
const v = this.changelogStatus?.version ?? this.version;
|
|
221
|
-
return [
|
|
222
|
-
` ${theme.fg("success", "\u2605")} ${theme.fg("muted", `v${v}`)}`,
|
|
223
|
-
` ${theme.fg("dim", "Run")} ${theme.fg("contentAccent", "/changelog")}`,
|
|
224
|
-
];
|
|
170
|
+
return ` ${theme.fg("warning", "↑")} ${theme.fg("muted", label)} ${theme.fg("dim", "run: xcsh update")}`;
|
|
225
171
|
}
|
|
226
172
|
|
|
227
173
|
#renderModelStatus(): string[] {
|
|
@@ -243,89 +189,6 @@ export class WelcomeComponent implements Component {
|
|
|
243
189
|
}
|
|
244
190
|
}
|
|
245
191
|
|
|
246
|
-
#renderContextStatus(): string[] {
|
|
247
|
-
if (!this.contextStatus) return [];
|
|
248
|
-
const { state, name } = this.contextStatus;
|
|
249
|
-
const n = name ?? "(unknown)";
|
|
250
|
-
switch (state) {
|
|
251
|
-
case "connected":
|
|
252
|
-
return [` ${formatStatusIcon("connected")} ${theme.fg("muted", n)}`];
|
|
253
|
-
case "auth_error":
|
|
254
|
-
return [
|
|
255
|
-
` ${formatStatusIcon("error")} ${theme.fg("muted", n)} ${theme.fg("error", "\u2014 token invalid")}`,
|
|
256
|
-
` ${theme.fg("dim", "Run /context to update")}`,
|
|
257
|
-
];
|
|
258
|
-
case "offline":
|
|
259
|
-
if (this.contextStatus?.errorClass === "url_not_found") {
|
|
260
|
-
return [
|
|
261
|
-
` ${formatStatusIcon("error")} ${theme.fg("muted", n)} ${theme.fg("error", "\u2014 tenant not found")}`,
|
|
262
|
-
` ${theme.fg("dim", "Recreate with /context create or check with /context show")}`,
|
|
263
|
-
];
|
|
264
|
-
}
|
|
265
|
-
return [
|
|
266
|
-
` ${formatStatusIcon("warning")} ${theme.fg("muted", n)} ${theme.fg("warning", "\u2014 unreachable")}`,
|
|
267
|
-
` ${theme.fg("dim", "Check network, /context")}`,
|
|
268
|
-
];
|
|
269
|
-
case "no_context":
|
|
270
|
-
return [
|
|
271
|
-
` ${formatStatusIcon("warning")} ${theme.fg("warning", "No context configured")}`,
|
|
272
|
-
` ${theme.fg("dim", "Run /context create <name> <url> <token>")}`,
|
|
273
|
-
];
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
#renderGitLabStatus(): string[] {
|
|
278
|
-
if (!this.gitlabStatus) return [];
|
|
279
|
-
const { state, project } = this.gitlabStatus;
|
|
280
|
-
switch (state) {
|
|
281
|
-
case "connected":
|
|
282
|
-
return [` ${formatStatusIcon("connected")} ${theme.fg("muted", project ?? "configured")}`];
|
|
283
|
-
case "auth_error":
|
|
284
|
-
return [
|
|
285
|
-
` ${formatStatusIcon("error")} ${theme.fg("error", "Not authenticated")}`,
|
|
286
|
-
` ${theme.fg("dim", "Run")} ${theme.fg("contentAccent", "glab auth login")}`,
|
|
287
|
-
];
|
|
288
|
-
case "not_configured":
|
|
289
|
-
return [
|
|
290
|
-
` ${formatStatusIcon("warning")} ${theme.fg("warning", "No project configured")}`,
|
|
291
|
-
` ${theme.fg("dim", "Run glab_setup action save_project project GROUP/REPO")}`,
|
|
292
|
-
];
|
|
293
|
-
case "project_inaccessible":
|
|
294
|
-
return [
|
|
295
|
-
` ${formatStatusIcon("warning")} ${theme.fg("muted", project ?? "unknown")} ${theme.fg("warning", "\u2014 access denied")}`,
|
|
296
|
-
` ${theme.fg("dim", "Check permissions or run glab_setup with action save_project")}`,
|
|
297
|
-
];
|
|
298
|
-
case "not_installed":
|
|
299
|
-
return [` ${formatStatusIcon("warning")} ${theme.fg("warning", "glab CLI not installed")}`];
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
#renderSalesforceStatus(): string[] {
|
|
304
|
-
if (!this.salesforceStatus) return [];
|
|
305
|
-
const { state, username, orgAlias } = this.salesforceStatus;
|
|
306
|
-
switch (state) {
|
|
307
|
-
case "connected":
|
|
308
|
-
return [
|
|
309
|
-
` ${formatStatusIcon("connected")} ${theme.fg("muted", orgAlias ?? "org")}${username ? ` ${theme.fg("dim", `(${username})`)}` : ""}`,
|
|
310
|
-
];
|
|
311
|
-
case "not_configured":
|
|
312
|
-
return [
|
|
313
|
-
` ${formatStatusIcon("warning")} ${theme.fg("warning", "Authenticated (no default org)")}`,
|
|
314
|
-
` ${theme.fg("dim", "Run")} ${theme.fg("contentAccent", "sf_setup")} ${theme.fg("dim", "with action set_default")}`,
|
|
315
|
-
];
|
|
316
|
-
case "auth_error":
|
|
317
|
-
return [
|
|
318
|
-
` ${formatStatusIcon("error")} ${theme.fg("error", "Not authenticated")}`,
|
|
319
|
-
` ${theme.fg("dim", "Run")} ${theme.fg("contentAccent", "sf org login web --set-default --alias SFDC")}`,
|
|
320
|
-
];
|
|
321
|
-
case "session_expired":
|
|
322
|
-
return [
|
|
323
|
-
` ${formatStatusIcon("warning")} ${theme.fg("muted", orgAlias ?? "org")} ${theme.fg("warning", "— session expired")}`,
|
|
324
|
-
` ${theme.fg("dim", "Re-authenticate with")} ${theme.fg("contentAccent", "sf org login web --set-default")}`,
|
|
325
|
-
];
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
192
|
#f5ColorLine(line: string): string {
|
|
330
193
|
const red = "\x1b[38;5;160m";
|
|
331
194
|
const white = "\x1b[1;37m";
|
|
@@ -49,8 +49,15 @@ import type { HookSelectorComponent } from "./components/hook-selector";
|
|
|
49
49
|
import type { PythonExecutionComponent } from "./components/python-execution";
|
|
50
50
|
import { StatusLineComponent } from "./components/status-line";
|
|
51
51
|
import type { ToolExecutionHandle } from "./components/tool-execution";
|
|
52
|
-
import { type
|
|
53
|
-
import {
|
|
52
|
+
import { type UpdateStatus, WelcomeComponent } from "./components/welcome";
|
|
53
|
+
import {
|
|
54
|
+
checkGitLabStatus,
|
|
55
|
+
checkSalesforceStatus,
|
|
56
|
+
mapContextStatus,
|
|
57
|
+
mapGitLabStatus,
|
|
58
|
+
mapSalesforceStatus,
|
|
59
|
+
runWelcomeChecks,
|
|
60
|
+
} from "./components/welcome-checks";
|
|
54
61
|
import { BtwController } from "./controllers/btw-controller";
|
|
55
62
|
import { CommandController } from "./controllers/command-controller";
|
|
56
63
|
import { EventController } from "./controllers/event-controller";
|
|
@@ -161,7 +168,6 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
161
168
|
#pendingSlashCommands: SlashCommand[] = [];
|
|
162
169
|
#cleanupUnsubscribe?: () => void;
|
|
163
170
|
readonly #version: string;
|
|
164
|
-
readonly #changelogStatus: ChangelogStatus | undefined;
|
|
165
171
|
readonly #initialUpdateStatus: UpdateStatus | undefined;
|
|
166
172
|
#planModePreviousTools: string[] | undefined;
|
|
167
173
|
#planModePreviousModelState: { model: Model; thinkingLevel?: ThinkingLevel } | undefined;
|
|
@@ -193,7 +199,6 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
193
199
|
constructor(
|
|
194
200
|
session: AgentSession,
|
|
195
201
|
version: string,
|
|
196
|
-
changelogStatus: ChangelogStatus | undefined = undefined,
|
|
197
202
|
initialUpdateStatus: UpdateStatus | undefined = undefined,
|
|
198
203
|
setToolUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void = () => {},
|
|
199
204
|
lspServers?: import("../tools").LspStartupServerInfo[],
|
|
@@ -206,7 +211,6 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
206
211
|
this.keybindings = KeybindingsManager.inMemory();
|
|
207
212
|
this.agent = session.agent;
|
|
208
213
|
this.#version = version;
|
|
209
|
-
this.#changelogStatus = changelogStatus;
|
|
210
214
|
this.#initialUpdateStatus = initialUpdateStatus;
|
|
211
215
|
this.#toolUiContextSetter = setToolUIContext;
|
|
212
216
|
this.lspServers = lspServers;
|
|
@@ -329,15 +333,20 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
329
333
|
}
|
|
330
334
|
|
|
331
335
|
if (!startupQuiet) {
|
|
332
|
-
// Welcome box owns all startup notifications (model,
|
|
336
|
+
// Welcome box owns all startup notifications (model, services, update)
|
|
337
|
+
const services =
|
|
338
|
+
welcomeResult.model.state === "connected"
|
|
339
|
+
? [
|
|
340
|
+
mapContextStatus(welcomeResult.context ?? { state: "no_context" }),
|
|
341
|
+
mapGitLabStatus(gitlabStatus),
|
|
342
|
+
mapSalesforceStatus(salesforceStatus),
|
|
343
|
+
]
|
|
344
|
+
: [];
|
|
333
345
|
this.#welcomeComponent = new WelcomeComponent(
|
|
334
346
|
this.#version,
|
|
335
347
|
welcomeResult.model,
|
|
336
|
-
|
|
348
|
+
services,
|
|
337
349
|
this.#initialUpdateStatus,
|
|
338
|
-
this.#changelogStatus,
|
|
339
|
-
gitlabStatus,
|
|
340
|
-
salesforceStatus,
|
|
341
350
|
);
|
|
342
351
|
|
|
343
352
|
// Setup UI layout
|