@cspeach/cli 1.1.20 → 1.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sap/standalone-profile.js +1 -1
- package/dist/sap/system-info.js +50 -27
- package/dist/skills/bundled-skills.js +118 -118
- package/dist/upgrade.js +4 -2
- package/package.json +121 -121
- package/dist/commands/project.js +0 -301
- package/dist/tools/local-files.js +0 -31
- package/dist/tools/subagent/schedule_create.js +0 -131
- package/dist/ui/error-emitter.js +0 -21
- package/dist/ui/header.js +0 -41
- package/dist/ui/ink-classifier-route.js +0 -19
- package/dist/ui/rich-error-box.js +0 -9
- package/dist/ui/sidebar.js +0 -12
- package/dist/ui/status-emitter.js +0 -19
- package/dist/ui/status-line.js +0 -62
- package/dist/ui/status-row.js +0 -38
- package/dist/ui/todo-panel.js +0 -85
- package/dist/ui/widgets/ask-form.js +0 -250
- package/dist/ui/widgets/ask-question-modal.js +0 -178
- package/fiori/zlas-inspection-lr/package.json +0 -26
- package/fiori/zlas-inspection-lr/ui5-local.yaml +0 -45
- package/fiori/zlas-inspection-lr/ui5.yaml +0 -41
- package/fiori/zlas-inspection-lr/webapp/Component.js +0 -12
- package/fiori/zlas-inspection-lr/webapp/i18n/i18n.properties +0 -9
- package/fiori/zlas-inspection-lr/webapp/index.html +0 -35
- package/fiori/zlas-inspection-lr/webapp/manifest.json +0 -145
|
@@ -90,7 +90,7 @@ const S4_YEAR_TO_ABAP = {
|
|
|
90
90
|
'2021': '7.56',
|
|
91
91
|
'2022': '7.57',
|
|
92
92
|
'2023': '7.58',
|
|
93
|
-
'2025': '
|
|
93
|
+
'2025': '8.16', // ABAP Platform 2025 = SAP_BASIS 816 (matches system-info.ts abapVersionFor)
|
|
94
94
|
};
|
|
95
95
|
function releaseYear(release) {
|
|
96
96
|
for (const year of Object.keys(S4_YEAR_TO_ABAP)) {
|
package/dist/sap/system-info.js
CHANGED
|
@@ -19,6 +19,12 @@ import { join } from 'node:path';
|
|
|
19
19
|
import { auditLog, xmlParser } from '@cspeach/sap-client';
|
|
20
20
|
import { cspeachRoot } from '../config/paths.js';
|
|
21
21
|
const CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
22
|
+
/**
|
|
23
|
+
* Bump when the cached shape or its meaning changes, so files written by
|
|
24
|
+
* an older CLI are re-queried instead of served. v2 (2026-09-29): CVERS
|
|
25
|
+
* now includes SAP_APPL; v1 files classified ECC EHP8 as NetWeaver.
|
|
26
|
+
*/
|
|
27
|
+
const CACHE_VERSION = 2;
|
|
22
28
|
const memCache = new Map();
|
|
23
29
|
/**
|
|
24
30
|
* Top-level entry point. Returns cached info when available, queries
|
|
@@ -68,7 +74,8 @@ export function _resetSystemInfoCache() {
|
|
|
68
74
|
async function queryLive(adt, alias) {
|
|
69
75
|
// S4FND covers some private-cloud variants where S4CORE isn't shipped
|
|
70
76
|
// — including both broadens detection without extra cost.
|
|
71
|
-
|
|
77
|
+
// SAP_APPL tells ECC apart from plain NetWeaver (see classify()).
|
|
78
|
+
const sql = `SELECT COMPONENT, RELEASE FROM CVERS WHERE COMPONENT IN ('SAP_BASIS', 'S4CORE', 'S4FND', 'SAP_ABA', 'SAP_APPL')`;
|
|
72
79
|
// Dispatch order is INTENTIONALLY connection-first: AdtClient.sqlQuery
|
|
73
80
|
// internally uses parseDataPreview which silently returns empty rows on
|
|
74
81
|
// shapes it doesn't recognise — exactly the failure mode that surfaced
|
|
@@ -380,11 +387,17 @@ export async function parseCversTree(xml) {
|
|
|
380
387
|
*/
|
|
381
388
|
export function classify(alias, components) {
|
|
382
389
|
const sapBasis = components['SAP_BASIS'];
|
|
390
|
+
// SAP_APPL is the ERP application component: present on ECC, replaced by
|
|
391
|
+
// S4CORE on S/4, absent on BW / SolMan / PI. It — not the SAP_BASIS
|
|
392
|
+
// number — is what tells ECC apart from a plain NetWeaver system
|
|
393
|
+
// (ECC EHP8 runs on SAP_BASIS 750).
|
|
394
|
+
const sapAppl = components['SAP_APPL'];
|
|
383
395
|
const s4Core = components['S4CORE'] || components['S4FND'];
|
|
384
396
|
const platform = s4Core ? 'S/4HANA'
|
|
385
|
-
:
|
|
386
|
-
: '
|
|
387
|
-
|
|
397
|
+
: sapAppl ? 'ECC'
|
|
398
|
+
: sapBasis ? 'NetWeaver'
|
|
399
|
+
: 'unknown';
|
|
400
|
+
const release = humanReadableRelease(platform, sapBasis, s4Core, sapAppl);
|
|
388
401
|
const abapVersion = abapVersionFor(sapBasis);
|
|
389
402
|
return {
|
|
390
403
|
alias,
|
|
@@ -405,38 +418,42 @@ export function classify(alias, components) {
|
|
|
405
418
|
* so we anchor on S4CORE when present and fall back to SAP_BASIS only
|
|
406
419
|
* for ECC/NW systems.
|
|
407
420
|
*/
|
|
408
|
-
function humanReadableRelease(platform, sapBasis, s4Core) {
|
|
421
|
+
function humanReadableRelease(platform, sapBasis, s4Core, sapAppl) {
|
|
409
422
|
if (platform === 'S/4HANA' && s4Core) {
|
|
423
|
+
// S4CORE release → S/4HANA edition. FPS/SPS levels do not change the
|
|
424
|
+
// S4CORE release, so there are no "FPS" entries here.
|
|
410
425
|
const map = {
|
|
411
|
-
'100': 'S/4HANA
|
|
412
|
-
'101': 'S/4HANA
|
|
413
|
-
'102': 'S/4HANA
|
|
414
|
-
'103': 'S/4HANA
|
|
415
|
-
'104': 'S/4HANA
|
|
416
|
-
'105': 'S/4HANA
|
|
417
|
-
'106': 'S/4HANA
|
|
426
|
+
'100': 'S/4HANA 1511',
|
|
427
|
+
'101': 'S/4HANA 1610',
|
|
428
|
+
'102': 'S/4HANA 1709',
|
|
429
|
+
'103': 'S/4HANA 1809',
|
|
430
|
+
'104': 'S/4HANA 1909',
|
|
431
|
+
'105': 'S/4HANA 2020',
|
|
432
|
+
'106': 'S/4HANA 2021',
|
|
418
433
|
'107': 'S/4HANA 2022',
|
|
419
434
|
'108': 'S/4HANA 2023',
|
|
420
|
-
'109': 'S/4HANA
|
|
421
|
-
'110': 'S/4HANA 2025',
|
|
435
|
+
'109': 'S/4HANA 2025',
|
|
422
436
|
};
|
|
423
437
|
return map[s4Core] ?? `S/4HANA (S4CORE ${s4Core})`;
|
|
424
438
|
}
|
|
425
439
|
if (platform === 'NetWeaver' && sapBasis) {
|
|
426
|
-
return `NetWeaver
|
|
440
|
+
return `NetWeaver (SAP_BASIS ${sapBasis})`;
|
|
427
441
|
}
|
|
428
|
-
if (platform === 'ECC' &&
|
|
442
|
+
if (platform === 'ECC' && sapAppl) {
|
|
443
|
+
// Enhancement pack is read from SAP_APPL: SAP_BASIS is ambiguous
|
|
444
|
+
// (730 covers EHP5 and EHP6; 750 is EHP8 but also plain NW 7.50).
|
|
429
445
|
const map = {
|
|
430
|
-
'
|
|
431
|
-
'
|
|
432
|
-
'
|
|
433
|
-
'
|
|
434
|
-
'
|
|
435
|
-
'
|
|
436
|
-
'
|
|
437
|
-
'
|
|
446
|
+
'600': 'ECC 6.0',
|
|
447
|
+
'602': 'ECC 6.0 EHP2',
|
|
448
|
+
'603': 'ECC 6.0 EHP3',
|
|
449
|
+
'604': 'ECC 6.0 EHP4',
|
|
450
|
+
'605': 'ECC 6.0 EHP5',
|
|
451
|
+
'606': 'ECC 6.0 EHP6',
|
|
452
|
+
'616': 'ECC 6.0 EHP6 (HANA)',
|
|
453
|
+
'617': 'ECC 6.0 EHP7',
|
|
454
|
+
'618': 'ECC 6.0 EHP8',
|
|
438
455
|
};
|
|
439
|
-
return map[
|
|
456
|
+
return map[sapAppl] ?? `ECC 6.0 (SAP_APPL ${sapAppl})`;
|
|
440
457
|
}
|
|
441
458
|
return 'unknown';
|
|
442
459
|
}
|
|
@@ -455,6 +472,9 @@ function abapVersionFor(sapBasis) {
|
|
|
455
472
|
// Modern releases — return as N.NN (e.g. 757 → 7.57).
|
|
456
473
|
if (n >= 740 && n < 800)
|
|
457
474
|
return `7.${n - 700}`;
|
|
475
|
+
// ABAP Platform 2025 moved to 8.xx (SAP_BASIS 816 → 8.16).
|
|
476
|
+
if (n >= 800 && n < 900)
|
|
477
|
+
return `8.${String(n - 800).padStart(2, '0')}`;
|
|
458
478
|
return sapBasis;
|
|
459
479
|
}
|
|
460
480
|
// ── Disk cache ─────────────────────────────────────────────────────────────
|
|
@@ -473,12 +493,15 @@ function readDiskCache(alias) {
|
|
|
473
493
|
if (!existsSync(path))
|
|
474
494
|
return null;
|
|
475
495
|
const raw = JSON.parse(readFileSync(path, 'utf8'));
|
|
496
|
+
if (raw.cacheVersion !== CACHE_VERSION)
|
|
497
|
+
return null;
|
|
476
498
|
if (!raw.queriedAt)
|
|
477
499
|
return null;
|
|
478
500
|
const age = Date.now() - new Date(raw.queriedAt).getTime();
|
|
479
501
|
if (age > CACHE_TTL_MS)
|
|
480
502
|
return null;
|
|
481
|
-
|
|
503
|
+
const { cacheVersion: _v, ...info } = raw;
|
|
504
|
+
return info;
|
|
482
505
|
}
|
|
483
506
|
catch {
|
|
484
507
|
return null;
|
|
@@ -489,7 +512,7 @@ function writeDiskCache(alias, info) {
|
|
|
489
512
|
const dir = cacheDir();
|
|
490
513
|
if (!existsSync(dir))
|
|
491
514
|
mkdirSync(dir, { recursive: true });
|
|
492
|
-
writeFileSync(cacheFile(alias), JSON.stringify(info, null, 2), 'utf8');
|
|
515
|
+
writeFileSync(cacheFile(alias), JSON.stringify({ ...info, cacheVersion: CACHE_VERSION }, null, 2), 'utf8');
|
|
493
516
|
}
|
|
494
517
|
catch {
|
|
495
518
|
// best-effort — we still return the in-memory result
|