@cspeach/cli 1.1.7 → 1.1.9
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/providers/ai-hub-provider.js +3 -3
- package/dist/agent/providers/byok-provider.js +3 -3
- package/dist/auth/api-key.js +9 -9
- package/dist/auth/keychain.js +0 -0
- package/dist/cli.js +27 -27
- package/dist/commands/config-set.js +3 -3
- package/dist/commands/login.js +2 -2
- package/dist/commands/logout.js +1 -1
- package/dist/commands/whoami.js +1 -1
- package/dist/doctor/checks/keychain.js +4 -4
- package/dist/doctor/checks/zcspeach.js +2 -2
- package/dist/repl.js +24 -5
- package/dist/sap/connection-manager.js +2 -2
- package/dist/sap/first-run-choice.js +34 -0
- package/dist/sap/onboarding.js +4 -4
- package/dist/skills/bundled-skills.js +1 -1
- package/package.json +2 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
-
import
|
|
2
|
+
import keychain from '../../auth/keychain.js';
|
|
3
3
|
import { createManifestSkillSource } from '../../skills/source-manifest.js';
|
|
4
4
|
import { DEFAULT_MANIFEST_URL } from '../../skills/manifest-client.js';
|
|
5
5
|
const KEYCHAIN_SERVICE = 'cspeach.ai-hub';
|
|
@@ -26,7 +26,7 @@ export function createAiHubProvider(cfg) {
|
|
|
26
26
|
return sdk.messages.stream({ ...params, model: modelAlias }, options.signal ? { signal: options.signal } : undefined);
|
|
27
27
|
},
|
|
28
28
|
async healthCheck() {
|
|
29
|
-
const token = await
|
|
29
|
+
const token = await keychain.getPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);
|
|
30
30
|
if (!token)
|
|
31
31
|
return { ok: false, message: 'AI Hub token not in keychain', hint: 'Run: cspeach config set llm.ai_hub_token <token>' };
|
|
32
32
|
try {
|
|
@@ -51,7 +51,7 @@ export function createAiHubProvider(cfg) {
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
async function getToken() {
|
|
54
|
-
const t = await
|
|
54
|
+
const t = await keychain.getPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);
|
|
55
55
|
if (!t)
|
|
56
56
|
throw new Error('AI Hub token not configured');
|
|
57
57
|
return t;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
-
import
|
|
2
|
+
import keychain from '../../auth/keychain.js';
|
|
3
3
|
import { createManifestSkillSource } from '../../skills/source-manifest.js';
|
|
4
4
|
import { DEFAULT_MANIFEST_URL } from '../../skills/manifest-client.js';
|
|
5
5
|
const KEYCHAIN_SERVICE = 'cspeach.anthropic';
|
|
@@ -21,7 +21,7 @@ export function createByokProvider(_cfg) {
|
|
|
21
21
|
return sdk.messages.stream(params, options.signal ? { signal: options.signal } : undefined);
|
|
22
22
|
},
|
|
23
23
|
async healthCheck() {
|
|
24
|
-
const key = await
|
|
24
|
+
const key = await keychain.getPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);
|
|
25
25
|
if (!key)
|
|
26
26
|
return { ok: false, message: 'Anthropic API key not in keychain', hint: 'Run: cspeach config set llm.byok_key <your-anthropic-key>' };
|
|
27
27
|
try {
|
|
@@ -46,7 +46,7 @@ export function createByokProvider(_cfg) {
|
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
async function getKey() {
|
|
49
|
-
const key = await
|
|
49
|
+
const key = await keychain.getPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);
|
|
50
50
|
if (!key)
|
|
51
51
|
throw new Error('BYOK Anthropic API key not configured — run: cspeach config set llm.byok_key <key>');
|
|
52
52
|
return key;
|
package/dist/auth/api-key.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import keychain from './keychain.js';
|
|
2
2
|
const SERVICE = 'cspeach';
|
|
3
3
|
const ACCOUNT = 'api-key';
|
|
4
|
-
class
|
|
5
|
-
async get() { return
|
|
6
|
-
async set(key) { await
|
|
7
|
-
async delete() { await
|
|
4
|
+
class KeychainStore {
|
|
5
|
+
async get() { return keychain.getPassword(SERVICE, ACCOUNT); }
|
|
6
|
+
async set(key) { await keychain.setPassword(SERVICE, ACCOUNT, key); }
|
|
7
|
+
async delete() { await keychain.deletePassword(SERVICE, ACCOUNT); }
|
|
8
8
|
async isKeychainAvailable() {
|
|
9
9
|
try {
|
|
10
10
|
const probe = `probe-${Date.now()}`;
|
|
11
|
-
await
|
|
12
|
-
const ok = (await
|
|
13
|
-
await
|
|
11
|
+
await keychain.setPassword(SERVICE, 'probe', probe);
|
|
12
|
+
const ok = (await keychain.getPassword(SERVICE, 'probe')) === probe;
|
|
13
|
+
await keychain.deletePassword(SERVICE, 'probe');
|
|
14
14
|
return ok;
|
|
15
15
|
}
|
|
16
16
|
catch {
|
|
@@ -29,7 +29,7 @@ let store;
|
|
|
29
29
|
export async function getStore() {
|
|
30
30
|
if (store)
|
|
31
31
|
return store;
|
|
32
|
-
const ktr = new
|
|
32
|
+
const ktr = new KeychainStore();
|
|
33
33
|
if (await ktr.isKeychainAvailable()) {
|
|
34
34
|
store = ktr;
|
|
35
35
|
}
|
|
Binary file
|
package/dist/cli.js
CHANGED
|
@@ -162,32 +162,32 @@ export async function main(argv) {
|
|
|
162
162
|
return runRepl({ sapAlias, noSap });
|
|
163
163
|
}
|
|
164
164
|
function printHelp() {
|
|
165
|
-
console.log(`
|
|
166
|
-
CSPeach — AI-assisted ABAP development CLI
|
|
167
|
-
|
|
168
|
-
Usage:
|
|
169
|
-
cspeach Start interactive REPL
|
|
170
|
-
cspeach "<prompt>" One-shot — runs one turn and exits
|
|
171
|
-
cspeach --one-shot "<prompt>" Same as above, explicit flag
|
|
172
|
-
cspeach --sap-alias <name> Use a specific SAP alias (overrides default)
|
|
173
|
-
cspeach --no-sap Start without a SAP system (paste-mode skills only)
|
|
174
|
-
cspeach --resume [id] Resume a previous session (list if no id)
|
|
175
|
-
cspeach config add-sap Add a SAP system interactively
|
|
176
|
-
cspeach config standalone Set the standalone SAP profile (no system)
|
|
177
|
-
cspeach standards init Capture your team's ABAP development standards
|
|
178
|
-
cspeach configure Alias for \`cspeach config add-sap\`
|
|
179
|
-
cspeach config set <key> <value> Update a config key
|
|
180
|
-
cspeach config unset <key> Remove a config key (revert to default)
|
|
181
|
-
cspeach config show [key] Show config (full or single key)
|
|
182
|
-
cspeach doctor Diagnose install + connectivity
|
|
183
|
-
cspeach login Sign in via device-code flow
|
|
184
|
-
cspeach logout Sign out (keep
|
|
185
|
-
cspeach whoami Print current account info
|
|
186
|
-
cspeach analyze project-context Compare flag-on vs flag-off session metrics
|
|
187
|
-
cspeach --upgrade Upgrade to latest via npm
|
|
188
|
-
cspeach --version Print version
|
|
189
|
-
cspeach --help Show this help
|
|
190
|
-
|
|
191
|
-
Docs: https://cspeach.dev
|
|
165
|
+
console.log(`
|
|
166
|
+
CSPeach — AI-assisted ABAP development CLI
|
|
167
|
+
|
|
168
|
+
Usage:
|
|
169
|
+
cspeach Start interactive REPL
|
|
170
|
+
cspeach "<prompt>" One-shot — runs one turn and exits
|
|
171
|
+
cspeach --one-shot "<prompt>" Same as above, explicit flag
|
|
172
|
+
cspeach --sap-alias <name> Use a specific SAP alias (overrides default)
|
|
173
|
+
cspeach --no-sap Start without a SAP system (paste-mode skills only)
|
|
174
|
+
cspeach --resume [id] Resume a previous session (list if no id)
|
|
175
|
+
cspeach config add-sap Add a SAP system interactively
|
|
176
|
+
cspeach config standalone Set the standalone SAP profile (no system)
|
|
177
|
+
cspeach standards init Capture your team's ABAP development standards
|
|
178
|
+
cspeach configure Alias for \`cspeach config add-sap\`
|
|
179
|
+
cspeach config set <key> <value> Update a config key
|
|
180
|
+
cspeach config unset <key> Remove a config key (revert to default)
|
|
181
|
+
cspeach config show [key] Show config (full or single key)
|
|
182
|
+
cspeach doctor Diagnose install + connectivity
|
|
183
|
+
cspeach login Sign in via device-code flow
|
|
184
|
+
cspeach logout Sign out (keep keychain key, if any)
|
|
185
|
+
cspeach whoami Print current account info
|
|
186
|
+
cspeach analyze project-context Compare flag-on vs flag-off session metrics
|
|
187
|
+
cspeach --upgrade Upgrade to latest via npm
|
|
188
|
+
cspeach --version Print version
|
|
189
|
+
cspeach --help Show this help
|
|
190
|
+
|
|
191
|
+
Docs: https://cspeach.dev
|
|
192
192
|
`);
|
|
193
193
|
}
|
|
@@ -400,12 +400,12 @@ export async function runConfigSet(args) {
|
|
|
400
400
|
else {
|
|
401
401
|
console.log(chalk.yellow(`WARN: secret passed as shell argument — will land in shell history. Prefer: cat key.txt | cspeach config set ${key} -`));
|
|
402
402
|
}
|
|
403
|
-
const { default:
|
|
403
|
+
const { default: keychain } = await import('../auth/keychain.js');
|
|
404
404
|
if (key === 'llm.byok_key') {
|
|
405
|
-
await
|
|
405
|
+
await keychain.setPassword('cspeach.anthropic', 'api-key', secret);
|
|
406
406
|
}
|
|
407
407
|
else {
|
|
408
|
-
await
|
|
408
|
+
await keychain.setPassword('cspeach.ai-hub', 'token', secret);
|
|
409
409
|
}
|
|
410
410
|
console.log(chalk.green(`✓ Secret stored in OS keychain (service: ${key === 'llm.byok_key' ? 'cspeach.anthropic' : 'cspeach.ai-hub'})`));
|
|
411
411
|
return;
|
package/dist/commands/login.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* Dependencies (open, print, prompt) are injected so the command is
|
|
14
14
|
* unit-testable without stubbing platform globals.
|
|
15
15
|
*/
|
|
16
|
-
import
|
|
16
|
+
import keychain from '../auth/keychain.js';
|
|
17
17
|
import { writeAuthFile } from '../auth/auth-file.js';
|
|
18
18
|
import { fetchOrgAnthropicKey } from '../auth/org-anthropic-key.js';
|
|
19
19
|
const ANTHROPIC_KEYCHAIN_SERVICE = 'cspeach.anthropic';
|
|
@@ -101,7 +101,7 @@ export async function runLoginCommand(deps) {
|
|
|
101
101
|
fetchImpl: deps.fetchImpl,
|
|
102
102
|
});
|
|
103
103
|
const setKey = deps.setKeychainKey ??
|
|
104
|
-
((svc, acct, k) =>
|
|
104
|
+
((svc, acct, k) => keychain.setPassword(svc, acct, k));
|
|
105
105
|
if (orgKey !== null) {
|
|
106
106
|
await setKey(ANTHROPIC_KEYCHAIN_SERVICE, ANTHROPIC_KEYCHAIN_ACCOUNT, orgKey);
|
|
107
107
|
deps.print('Using your organization\'s Anthropic key.');
|
package/dist/commands/logout.js
CHANGED
|
@@ -8,7 +8,7 @@ export async function runLogoutCommand(deps) {
|
|
|
8
8
|
await deleteAuthFile();
|
|
9
9
|
if (before) {
|
|
10
10
|
deps.print('✓ Signed out — removed ~/.cspeach/auth.json');
|
|
11
|
-
deps.print(' (the REPL will use the
|
|
11
|
+
deps.print(' (the REPL will use the keychain-stored key if you have one)');
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
14
|
deps.print('Already signed out — no auth.json present.');
|
package/dist/commands/whoami.js
CHANGED
|
@@ -10,7 +10,7 @@ export async function runWhoamiCommand(deps) {
|
|
|
10
10
|
const auth = await readAuthFile();
|
|
11
11
|
if (!auth) {
|
|
12
12
|
deps.print('Not signed in via cspeach login (no ~/.cspeach/auth.json).');
|
|
13
|
-
deps.print('Your REPL may still authenticate via the
|
|
13
|
+
deps.print('Your REPL may still authenticate via the keychain-stored key — run `cspeach` to check.');
|
|
14
14
|
return 0;
|
|
15
15
|
}
|
|
16
16
|
const me = await fetchMe({ proxyUrl: deps.proxyUrl, apiKey: auth.apiKey });
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import keychain from '../../auth/keychain.js';
|
|
2
2
|
export async function checkKeychain() {
|
|
3
3
|
try {
|
|
4
4
|
const probe = `probe-${Date.now()}`;
|
|
5
|
-
await
|
|
6
|
-
const ok = (await
|
|
7
|
-
await
|
|
5
|
+
await keychain.setPassword('cspeach', 'probe', probe);
|
|
6
|
+
const ok = (await keychain.getPassword('cspeach', 'probe')) === probe;
|
|
7
|
+
await keychain.deletePassword('cspeach', 'probe');
|
|
8
8
|
if (ok)
|
|
9
9
|
return { name: 'keychain', ok: true, message: 'OS keychain working' };
|
|
10
10
|
return { name: 'keychain', ok: false, message: 'probe write/read mismatch', hint: 'Per-session fallback mode will be used' };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import keychain from '../../auth/keychain.js';
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { loadConfig, resolveSapTls } from '../../config/loader.js';
|
|
4
4
|
import { probeGet } from './_http-probe.js';
|
|
@@ -26,7 +26,7 @@ export async function checkZcspeach() {
|
|
|
26
26
|
const url = `${protocol}://${sys.host}:${sys.port}/sap/bc/zcspeach/discovery`;
|
|
27
27
|
let pwd = null;
|
|
28
28
|
try {
|
|
29
|
-
pwd = await
|
|
29
|
+
pwd = await keychain.getPassword(SAP_SERVICE, alias);
|
|
30
30
|
}
|
|
31
31
|
catch {
|
|
32
32
|
// keychain unavailable — fall through, will be skipped below
|
package/dist/repl.js
CHANGED
|
@@ -384,9 +384,9 @@ export async function runRepl(opts) {
|
|
|
384
384
|
// Having aliases configured does NOT override the request.
|
|
385
385
|
// A session that WAS standalone stays standalone on `--resume`: its
|
|
386
386
|
// sap_system is the reserved 'none' alias, which has no entry in cfg.sap.
|
|
387
|
-
|
|
387
|
+
let standalone = resolveStandalone(cfg, opts?.noSap === true) ||
|
|
388
388
|
opts?.resumedSession?.sap_system === STANDALONE_ALIAS;
|
|
389
|
-
|
|
389
|
+
const enterStandalone = async () => {
|
|
390
390
|
console.log(chalk.dim('\nStandalone mode: no SAP system connected — skills work from pasted code. ' +
|
|
391
391
|
'Connect later with: cspeach config add-sap'));
|
|
392
392
|
// Ask the profile questions ONCE — they become the <sap_system> element
|
|
@@ -396,11 +396,30 @@ export async function runRepl(opts) {
|
|
|
396
396
|
await runStandaloneProfileWizard({ cwd: process.cwd() });
|
|
397
397
|
cfg = await loadConfig();
|
|
398
398
|
}
|
|
399
|
+
};
|
|
400
|
+
if (standalone) {
|
|
401
|
+
await enterStandalone();
|
|
399
402
|
}
|
|
400
403
|
else if (Object.keys(cfg.sap).length === 0) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
+
// First run with nothing configured (2026-09-17): let the user choose.
|
|
405
|
+
// Someone without SAP access used to be pushed into the SAP wizard with
|
|
406
|
+
// no way out except knowing --no-sap. Non-TTY runs skip the question and
|
|
407
|
+
// keep the previous behaviour exactly.
|
|
408
|
+
const { chooseFirstRunMode } = await import('./sap/first-run-choice.js');
|
|
409
|
+
const mode = await chooseFirstRunMode();
|
|
410
|
+
if (mode === 'standalone') {
|
|
411
|
+
// Persist so the next plain `cspeach` is standalone too — same effect
|
|
412
|
+
// as `cspeach config set no_sap on`, which the user can undo any time.
|
|
413
|
+
cfg.no_sap = true;
|
|
414
|
+
await saveConfig(cfg);
|
|
415
|
+
standalone = true;
|
|
416
|
+
await enterStandalone();
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
console.log(chalk.yellow('\nNo SAP systems configured. Starting onboarding wizard.'));
|
|
420
|
+
await runAddSapWizard();
|
|
421
|
+
cfg = await loadConfig();
|
|
422
|
+
}
|
|
404
423
|
}
|
|
405
424
|
// model-governance step 2d — fire-and-forget fetch of the served model-config
|
|
406
425
|
// (managed mode only). NEVER blocks startup: a turn that starts before the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import keychain from '../auth/keychain.js';
|
|
2
2
|
import { SapConnection } from '@cspeach/sap-client';
|
|
3
3
|
import { resolveSapTls } from '../config/loader.js';
|
|
4
4
|
import { password as promptPassword } from '@inquirer/prompts';
|
|
@@ -12,7 +12,7 @@ export async function getConnection(alias, cfg) {
|
|
|
12
12
|
let passwordValue;
|
|
13
13
|
if (cfg.authType === 'basic') {
|
|
14
14
|
try {
|
|
15
|
-
passwordValue = (await
|
|
15
|
+
passwordValue = (await keychain.getPassword(SAP_SERVICE, alias)) ?? undefined;
|
|
16
16
|
}
|
|
17
17
|
catch { /* keychain unavailable */ }
|
|
18
18
|
if (!passwordValue) {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-run choice (2026-09-17). Before this, a fresh install that started
|
|
3
|
+
* with plain `cspeach` (no --no-sap flag, no persisted no_sap) was pushed
|
|
4
|
+
* straight into the "Add SAP system" wizard — someone with no SAP access had
|
|
5
|
+
* no way forward except to know the flag. Seen live on Laeeq's dry run.
|
|
6
|
+
*
|
|
7
|
+
* Now, when no SAP alias is configured, the user picks how to start. The
|
|
8
|
+
* standalone answer is listed first: it needs nothing, and it is the path a
|
|
9
|
+
* trial user is on. Non-interactive runs (piped stdin, CI) never see the
|
|
10
|
+
* prompt and keep the exact pre-existing behaviour (the SAP wizard branch).
|
|
11
|
+
*/
|
|
12
|
+
import { select } from '@inquirer/prompts';
|
|
13
|
+
export const FIRST_RUN_CHOICES = [
|
|
14
|
+
{
|
|
15
|
+
name: 'Work standalone — no SAP connection',
|
|
16
|
+
value: 'standalone',
|
|
17
|
+
description: 'Paste code or a requirement in; get code, reviews, designs and step-by-step implementation guides out. Connect a system later with: cspeach config add-sap',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Connect to an SAP system now',
|
|
21
|
+
value: 'sap',
|
|
22
|
+
description: 'Host, client, user and password for an SAP system CSPeach may read and write through ADT.',
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
export async function chooseFirstRunMode(deps = {}) {
|
|
26
|
+
const isTTY = deps.isTTY ?? process.stdin.isTTY === true;
|
|
27
|
+
if (!isTTY)
|
|
28
|
+
return 'sap';
|
|
29
|
+
const ask = deps.select ?? select;
|
|
30
|
+
return ask({
|
|
31
|
+
message: 'No SAP system is set up yet. How do you want to start?',
|
|
32
|
+
choices: FIRST_RUN_CHOICES,
|
|
33
|
+
});
|
|
34
|
+
}
|
package/dist/sap/onboarding.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { input, select, password, confirm } from '@inquirer/prompts';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import
|
|
3
|
+
import keychain from '../auth/keychain.js';
|
|
4
4
|
import { loadConfig, saveConfig } from '../config/loader.js';
|
|
5
5
|
const SAP_SERVICE = 'cspeach-sap';
|
|
6
6
|
export async function runAddSapWizard() {
|
|
@@ -87,7 +87,7 @@ export async function runAddSapWizard() {
|
|
|
87
87
|
mask: '*',
|
|
88
88
|
});
|
|
89
89
|
try {
|
|
90
|
-
await
|
|
90
|
+
await keychain.setPassword(SAP_SERVICE, alias, pwd);
|
|
91
91
|
}
|
|
92
92
|
catch {
|
|
93
93
|
console.log(chalk.yellow('Warning: keychain unavailable; password will be prompted per session.'));
|
|
@@ -166,7 +166,7 @@ export async function runAddSapWizard() {
|
|
|
166
166
|
mask: '*',
|
|
167
167
|
});
|
|
168
168
|
try {
|
|
169
|
-
await
|
|
169
|
+
await keychain.setPassword('cspeach.ai-hub', 'token', aiHubToken);
|
|
170
170
|
}
|
|
171
171
|
catch {
|
|
172
172
|
console.log(chalk.yellow('Warning: keychain unavailable; AI Hub token will be prompted per session.'));
|
|
@@ -188,7 +188,7 @@ export async function runAddSapWizard() {
|
|
|
188
188
|
mask: '*',
|
|
189
189
|
});
|
|
190
190
|
try {
|
|
191
|
-
await
|
|
191
|
+
await keychain.setPassword('cspeach.anthropic', 'api-key', byokKey);
|
|
192
192
|
}
|
|
193
193
|
catch {
|
|
194
194
|
console.log(chalk.yellow('Warning: keychain unavailable; Anthropic key will be prompted per session.'));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// GENERATED FILE — bundled skills for local mode.
|
|
2
2
|
// Source: https://manifest.cspeach.dev/v1.json
|
|
3
|
-
// Generated: 2026-09-
|
|
3
|
+
// Generated: 2026-09-17T16:36:01.136Z
|
|
4
4
|
// Manifest signature verified at build time.
|
|
5
5
|
export const BUNDLED_SKILLS = {
|
|
6
6
|
"abap-atc-fix": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cspeach/cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "CSPeach — AI-assisted ABAP development CLI. Direct SAP access, 34 skills, safety gates.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"abap",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"ink": "^5.0.0",
|
|
72
72
|
"ink-text-input": "^6.0.0",
|
|
73
73
|
"jose": "^5.9.0",
|
|
74
|
-
"
|
|
74
|
+
"@napi-rs/keyring": "2.1.0",
|
|
75
75
|
"mammoth": "^1.8.0",
|
|
76
76
|
"marked": "^11.2.0",
|
|
77
77
|
"marked-terminal": "^6.2.0",
|
|
@@ -102,7 +102,6 @@
|
|
|
102
102
|
},
|
|
103
103
|
"pnpm": {
|
|
104
104
|
"onlyBuiltDependencies": [
|
|
105
|
-
"keytar",
|
|
106
105
|
"esbuild"
|
|
107
106
|
]
|
|
108
107
|
}
|