@cspeach/cli 1.1.25 → 1.1.26
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/agent/loop.js +20 -8
- package/dist/agent/tool-dispatch.js +6 -0
- package/dist/auth/auth-file.js +173 -12
- package/dist/classifier/client.js +55 -30
- package/dist/cli.js +11 -0
- package/dist/commands/config-set.js +13 -0
- package/dist/commands/config-show.js +5 -1
- package/dist/commands/cost.js +24 -22
- package/dist/commands/deploy-card.js +135 -0
- package/dist/commands/login.js +31 -13
- package/dist/commands/plan-chain.js +31 -0
- package/dist/commands/plan-continue.js +1 -0
- package/dist/commands/plan-resume.js +49 -2
- package/dist/cost/cost-log.js +76 -4
- package/dist/cost/credits-wire.js +9 -0
- package/dist/cost/credits.js +24 -6
- package/dist/cost/router-spend.js +24 -0
- package/dist/cost/session-cost.js +16 -2
- package/dist/models/server-config.js +21 -1
- package/dist/one-shot.js +12 -2
- package/dist/projects/plan-lane.js +47 -0
- package/dist/projects/plan-run.js +8 -0
- package/dist/projects/plan-schema.js +2 -0
- package/dist/projects/save-command.js +3 -2
- package/dist/renderer/footer-line.js +10 -4
- package/dist/renderer/status-footer.js +5 -4
- package/dist/renderer/tool-labels.js +2 -1
- package/dist/repl.js +41 -8
- package/dist/router/byok-classifier.js +159 -0
- package/dist/router/classifier.js +130 -6
- package/dist/router/router-core.js +307 -0
- package/dist/router/router-prompt.js +121 -0
- package/dist/router/routing-failure.js +65 -3
- package/dist/skills/bundled-skills.js +45 -45
- package/dist/tools/fiori/deploy/existing-bsp.js +67 -0
- package/dist/tools/fiori/deploy/run.js +608 -0
- package/dist/tools/fiori/deploy/scope.js +8 -0
- package/dist/tools/fiori/deploy/yaml-read.js +236 -0
- package/dist/tools/fiori/deploy-config.js +24 -6
- package/dist/tools/fiori/tools.js +117 -5
- package/dist/tools/local-build.js +3 -0
- package/dist/tools/subagent/read_agent.js +4 -2
- package/dist/tools/tool-loading.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// cspeach-cli/src/tools/fiori/deploy/existing-bsp.ts
|
|
2
|
+
/**
|
|
3
|
+
* fiori_deploy pre-check — does the target BSP already exist, and whose app is it?
|
|
4
|
+
*
|
|
5
|
+
* `fiori deploy --yes` would silently overwrite a BSP that holds ANOTHER app
|
|
6
|
+
* (the tooling's HTTP 412 "different sap app id" handler auto-confirms with
|
|
7
|
+
* --yes), which could be another team's application. So before either mode
|
|
8
|
+
* runs, two read-only GETs over the alias's authenticated connection:
|
|
9
|
+
*
|
|
10
|
+
* 1. /sap/opu/odata/UI5/ABAP_REPOSITORY_SRV/Repositories('<BSP>') — the same
|
|
11
|
+
* OData service the deploy itself uploads through. 404 → a new app;
|
|
12
|
+
* 200 → it exists; anything else (401/403/500, no answer) → the check
|
|
13
|
+
* could not run, and the deploy is refused rather than guessed.
|
|
14
|
+
* 2. when it exists: /sap/bc/ui5_ui5/sap/<bsp>/manifest.json → sap.app.id.
|
|
15
|
+
* If that cannot be read, the app id is UNKNOWN, which is treated like a
|
|
16
|
+
* different app (never assumed to be ours).
|
|
17
|
+
*/
|
|
18
|
+
function repositoryPath(bsp) {
|
|
19
|
+
return `/sap/opu/odata/UI5/ABAP_REPOSITORY_SRV/Repositories('${encodeURIComponent(bsp)}')?$format=json`;
|
|
20
|
+
}
|
|
21
|
+
/** /sap/bc/ui5_ui5/sap/<bsp>/<file>, or /sap/bc/ui5_ui5/<ns>/<name>/<file> for a namespaced BSP. */
|
|
22
|
+
export function bspFilePath(bsp, file) {
|
|
23
|
+
const lower = bsp.toLowerCase();
|
|
24
|
+
const ns = /^\/([a-z0-9_]+)\/([a-z0-9_]+)$/.exec(lower);
|
|
25
|
+
return ns ? `/sap/bc/ui5_ui5/${ns[1]}/${ns[2]}/${file}` : `/sap/bc/ui5_ui5/sap/${lower}/${file}`;
|
|
26
|
+
}
|
|
27
|
+
export async function readExistingBsp(bsp, get) {
|
|
28
|
+
let repo;
|
|
29
|
+
try {
|
|
30
|
+
repo = await get(repositoryPath(bsp));
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
return { kind: 'unknown', reason: `the ABAP repository service did not answer (${e instanceof Error ? e.message : String(e)})` };
|
|
34
|
+
}
|
|
35
|
+
if (repo.status === 404)
|
|
36
|
+
return { kind: 'new' };
|
|
37
|
+
if (repo.status !== 200) {
|
|
38
|
+
return {
|
|
39
|
+
kind: 'unknown',
|
|
40
|
+
reason: `the ABAP repository service answered HTTP ${repo.status}` +
|
|
41
|
+
(repo.status === 401 || repo.status === 403 ? ' (the SAP user may lack authorisation for /UI5/ABAP_REPOSITORY_SRV)' : ''),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
let description;
|
|
45
|
+
let pkg;
|
|
46
|
+
try {
|
|
47
|
+
const d = JSON.parse(repo.body ?? '').d;
|
|
48
|
+
description = d?.Description || undefined;
|
|
49
|
+
pkg = d?.Package || undefined;
|
|
50
|
+
}
|
|
51
|
+
catch { /* the entry exists; its details are only for the message */ }
|
|
52
|
+
let appId = null;
|
|
53
|
+
try {
|
|
54
|
+
const m = await get(bspFilePath(bsp, 'manifest.json'));
|
|
55
|
+
if (m.status === 200) {
|
|
56
|
+
const id = JSON.parse(m.body ?? '')['sap.app']?.id;
|
|
57
|
+
if (typeof id === 'string' && id.trim() !== '')
|
|
58
|
+
appId = id.trim();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch { /* unknown app id — treated as a different app */ }
|
|
62
|
+
return { kind: 'existing', appId, ...(description ? { description } : {}), ...(pkg ? { package: pkg } : {}) };
|
|
63
|
+
}
|
|
64
|
+
/** The approval object an overwrite must carry: `<BSP> overwrites app id <id|unknown>`. */
|
|
65
|
+
export function overwriteApprovalObject(bsp, remoteAppId) {
|
|
66
|
+
return `${bsp} overwrites app id ${remoteAppId ?? 'unknown'}`;
|
|
67
|
+
}
|