@f5xc-salesdemos/xcsh 18.24.0 → 18.25.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.25.2",
|
|
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",
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@agentclientprotocol/sdk": "0.16.1",
|
|
49
49
|
"@mozilla/readability": "^0.6",
|
|
50
|
-
"@f5xc-salesdemos/xcsh-stats": "18.
|
|
51
|
-
"@f5xc-salesdemos/pi-agent-core": "18.
|
|
52
|
-
"@f5xc-salesdemos/pi-ai": "18.
|
|
53
|
-
"@f5xc-salesdemos/pi-natives": "18.
|
|
54
|
-
"@f5xc-salesdemos/pi-tui": "18.
|
|
55
|
-
"@f5xc-salesdemos/pi-utils": "18.
|
|
50
|
+
"@f5xc-salesdemos/xcsh-stats": "18.25.2",
|
|
51
|
+
"@f5xc-salesdemos/pi-agent-core": "18.25.2",
|
|
52
|
+
"@f5xc-salesdemos/pi-ai": "18.25.2",
|
|
53
|
+
"@f5xc-salesdemos/pi-natives": "18.25.2",
|
|
54
|
+
"@f5xc-salesdemos/pi-tui": "18.25.2",
|
|
55
|
+
"@f5xc-salesdemos/pi-utils": "18.25.2",
|
|
56
56
|
"@sinclair/typebox": "^0.34",
|
|
57
57
|
"@xterm/headless": "^6.0",
|
|
58
58
|
"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.25.2",
|
|
21
|
+
"commit": "abd4234179059ccda04559a3a8611a93ce52f98b",
|
|
22
|
+
"shortCommit": "abd4234",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v18.
|
|
25
|
-
"commitDate": "2026-04-
|
|
26
|
-
"buildDate": "2026-04-
|
|
24
|
+
"tag": "v18.25.2",
|
|
25
|
+
"commitDate": "2026-04-29T07:33:34Z",
|
|
26
|
+
"buildDate": "2026-04-29T07:59:50.398Z",
|
|
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/abd4234179059ccda04559a3a8611a93ce52f98b",
|
|
32
|
+
"releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.25.2"
|
|
33
33
|
};
|
|
@@ -180,6 +180,7 @@ export class ContextService {
|
|
|
180
180
|
#apiClient: F5XCApiClient | null = null;
|
|
181
181
|
#revalidationTimer: NodeJS.Timeout | null = null;
|
|
182
182
|
#lastTokenHealth: TokenHealth = "ok";
|
|
183
|
+
#previousContextName: string | null = null;
|
|
183
184
|
|
|
184
185
|
private constructor(configDir: string) {
|
|
185
186
|
this.#configDir = configDir;
|
|
@@ -330,6 +331,7 @@ export class ContextService {
|
|
|
330
331
|
ContextService.#instance.#apiClient = null;
|
|
331
332
|
ContextService.#instance.#lastTokenHealth = "ok";
|
|
332
333
|
ContextService.#instance.stopRevalidation();
|
|
334
|
+
ContextService.#instance.#previousContextName = null;
|
|
333
335
|
}
|
|
334
336
|
ContextService.#instance = null;
|
|
335
337
|
// Clear listeners to prevent cross-test contamination. Each createAgentSession() call
|
|
@@ -340,6 +342,10 @@ export class ContextService {
|
|
|
340
342
|
ContextService.#onTokenHealthChangeListeners = [];
|
|
341
343
|
}
|
|
342
344
|
|
|
345
|
+
get previousContextName(): string | null {
|
|
346
|
+
return this.#previousContextName;
|
|
347
|
+
}
|
|
348
|
+
|
|
343
349
|
get contextsDir(): string {
|
|
344
350
|
return path.join(this.#configDir, "contexts");
|
|
345
351
|
}
|
|
@@ -439,6 +445,9 @@ export class ContextService {
|
|
|
439
445
|
// NFR-402: write active_context first — if it fails, don't update settings
|
|
440
446
|
this.#atomicWrite(this.activeContextPath, name);
|
|
441
447
|
|
|
448
|
+
if (this.#activeContext && this.#activeContext.name !== name) {
|
|
449
|
+
this.#previousContextName = this.#activeContext.name;
|
|
450
|
+
}
|
|
442
451
|
this.#activeContext = context;
|
|
443
452
|
this.#applyToSettings(context);
|
|
444
453
|
this.#credentialSource = hasEnvOverride() ? "mixed" : "context";
|
|
@@ -456,6 +465,13 @@ export class ContextService {
|
|
|
456
465
|
return context;
|
|
457
466
|
}
|
|
458
467
|
|
|
468
|
+
async activatePrevious(): Promise<F5XCContext> {
|
|
469
|
+
if (!this.#previousContextName) {
|
|
470
|
+
throw new ContextError("No previous context. Switch contexts first with /context activate <name>.");
|
|
471
|
+
}
|
|
472
|
+
return this.activate(this.#previousContextName);
|
|
473
|
+
}
|
|
474
|
+
|
|
459
475
|
async listContexts(): Promise<F5XCContext[]> {
|
|
460
476
|
const files = this.#listContextFiles();
|
|
461
477
|
const contexts: F5XCContext[] = [];
|
|
@@ -506,6 +522,9 @@ export class ContextService {
|
|
|
506
522
|
}
|
|
507
523
|
fs.unlinkSync(contextPath);
|
|
508
524
|
this.#contextsCache = this.#contextsCache.filter(p => p.name !== name);
|
|
525
|
+
if (this.#previousContextName === name) {
|
|
526
|
+
this.#previousContextName = null;
|
|
527
|
+
}
|
|
509
528
|
}
|
|
510
529
|
|
|
511
530
|
/**
|
|
@@ -806,6 +825,9 @@ export class ContextService {
|
|
|
806
825
|
this.#contextsCache = this.#contextsCache
|
|
807
826
|
.map(p => (p.name === oldName ? { ...p, name: newName } : p))
|
|
808
827
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
828
|
+
if (this.#previousContextName === oldName) {
|
|
829
|
+
this.#previousContextName = newName;
|
|
830
|
+
}
|
|
809
831
|
if (wasActive && this.#activeContext) {
|
|
810
832
|
this.#activeContext = { ...this.#activeContext, name: newName };
|
|
811
833
|
for (const cb of ContextService.#onContextChangeListeners) {
|