@cspeach/cli 1.1.23 → 1.1.25
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 +124 -0
- package/dist/classifier/client.js +27 -2
- package/dist/commands/plan-continue.js +11 -1
- package/dist/commands/plan-resume.js +38 -1
- package/dist/lane/app-chain.js +297 -0
- package/dist/lane/app-flow.js +55 -0
- package/dist/lane/card.js +148 -0
- package/dist/lane/chain-token.js +59 -0
- package/dist/lane/inputs.js +459 -0
- package/dist/lane/paths.js +21 -0
- package/dist/lane/resolve.js +109 -0
- package/dist/lane/roots.js +113 -0
- package/dist/lane/signals.js +80 -0
- package/dist/lane/store.js +232 -0
- package/dist/lane/types.js +1 -0
- package/dist/one-shot.js +1 -0
- package/dist/projects/detail-path.js +117 -0
- package/dist/projects/extract-plan.js +46 -6
- package/dist/projects/merge-cca.js +19 -0
- package/dist/projects/merge-upgrade.js +19 -1
- package/dist/projects/plan-lane.js +214 -0
- package/dist/projects/plan-schema.js +10 -0
- package/dist/projects/promote-command.js +8 -2
- package/dist/projects/promote.js +7 -1
- package/dist/projects/save-command.js +71 -25
- package/dist/projects/workspace.js +10 -0
- package/dist/register/records.js +7 -2
- package/dist/renderer/tool-labels.js +2 -1
- package/dist/repl/resume-standalone.js +3 -0
- package/dist/repl.js +23 -2
- package/dist/skill-catalog.js +14 -6
- package/dist/skills/bundled-skills.js +61 -54
- package/dist/tools/_filesystem-shared.js +363 -33
- package/dist/tools/cap/metadata-import.js +10 -4
- package/dist/tools/filesystem/file-write.js +12 -39
- package/dist/tools/filesystem/glob.js +25 -2
- package/dist/tools/filesystem/grep.js +25 -2
- package/dist/tools/fiori/apply.js +30 -21
- package/dist/tools/fiori/commit-gate.js +58 -0
- package/dist/tools/fiori/fe-extend.js +6 -1
- package/dist/tools/fiori/fe-scaffold.js +6 -1
- package/dist/tools/fiori/path-params.js +78 -0
- package/dist/tools/fiori/scaffold.js +2 -1
- package/dist/tools/fiori/tools.js +53 -14
- package/dist/tools/lane/app-lane-resolve.js +329 -0
- package/dist/tools/local-build.js +4 -0
- package/dist/tools/project/_merge-shared.js +36 -1
- package/dist/tools/project/cca_merge.js +4 -0
- package/dist/tools/project/upgrade_merge_progress.js +21 -10
- package/dist/tools/tool-loading.js +2 -0
- package/package.json +1 -1
package/dist/repl.js
CHANGED
|
@@ -20,6 +20,7 @@ import { CLI_VERSION } from './lib/version.js';
|
|
|
20
20
|
import { createOfflineAdtClient } from './sap/offline-adt-client.js';
|
|
21
21
|
import { STANDALONE_ALIAS } from './tools/index.js';
|
|
22
22
|
import { resumeStandaloneDecision, applySystemSwitch } from './repl/resume-standalone.js';
|
|
23
|
+
import { clearAppFlow } from './lane/app-flow.js';
|
|
23
24
|
import { applyResumedSkill, isShortFollowUp } from './router/resume-routing.js';
|
|
24
25
|
import { readableInterruptReason, isUserStopReason } from './session/interrupt-reason.js';
|
|
25
26
|
import { getStore } from './auth/api-key.js';
|
|
@@ -152,6 +153,7 @@ import './tools/cap/service-catalog.js';
|
|
|
152
153
|
import './tools/cap/metadata-import.js';
|
|
153
154
|
import './tools/cap/sap-link-tool.js';
|
|
154
155
|
import './tools/cap/link-smoke.js';
|
|
156
|
+
import './tools/lane/app-lane-resolve.js';
|
|
155
157
|
import './tools/extend-model/tool.js';
|
|
156
158
|
import './tools/capability/tool.js';
|
|
157
159
|
import './tools/web/web_fetch.js';
|
|
@@ -1187,6 +1189,7 @@ export async function runRepl(opts) {
|
|
|
1187
1189
|
// list AND the live view, so Ctrl+T / --resume can't bring it back.
|
|
1188
1190
|
session.todos = [];
|
|
1189
1191
|
todoEmitter.emit('update', []);
|
|
1192
|
+
clearAppFlow(session); // Task 7 — /new ends an /abap-app flow
|
|
1190
1193
|
chunkEmitter.emit('chunk', '\n' + formatInfo('Fresh start · the next prompt picks a skill again'));
|
|
1191
1194
|
return;
|
|
1192
1195
|
}
|
|
@@ -1581,11 +1584,19 @@ export async function runRepl(opts) {
|
|
|
1581
1584
|
if (skill === 'abap-plan' && planResume === null && session.plan_in_flight) {
|
|
1582
1585
|
const marker = session.plan_in_flight;
|
|
1583
1586
|
const { preparePlanContinuation } = await import('./commands/plan-continue.js');
|
|
1584
|
-
const r = preparePlanContinuation({
|
|
1587
|
+
const r = await preparePlanContinuation({
|
|
1585
1588
|
marker,
|
|
1586
1589
|
sessionId: session.id,
|
|
1590
|
+
cwd: process.cwd(),
|
|
1587
1591
|
log: (...lines) => chunkEmitter.emit('chunk', lines.join('\n') + '\n'),
|
|
1588
1592
|
});
|
|
1593
|
+
// App lane routing — the plan's lane file changed or its phases do not
|
|
1594
|
+
// fit the lane: the plan is paused, no turn runs, the marker stays.
|
|
1595
|
+
if ('paused' in r && r.paused) {
|
|
1596
|
+
session.last_skill = previousSkill ?? null;
|
|
1597
|
+
session.last_object = extractedObject ?? previousObject ?? null;
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1589
1600
|
if (r.prepared) {
|
|
1590
1601
|
planContinue = { prepared: r.prepared, marker };
|
|
1591
1602
|
planPhaseStartedAt = marker.attemptStartedAt;
|
|
@@ -1675,6 +1686,7 @@ export async function runRepl(opts) {
|
|
|
1675
1686
|
ctx: { adt, sapAlias: selectedAlias, session, cwd: process.cwd(), provider, skillSource: provider.skillSource, previewHook: inkPreview, chunkEmitter, todoEmitter, currentTransport: currentTransportAccessor, pendingDispatch: pendingDispatchAccessor },
|
|
1676
1687
|
chunkEmitter,
|
|
1677
1688
|
pushSpend: true, // F-L2-2 — top-level REPL turn: live statusline spend
|
|
1689
|
+
explicitSlash: parsed.skill !== undefined, // Task 7 R11 — typed or queued slash command
|
|
1678
1690
|
signal: currentTurnAbort.signal,
|
|
1679
1691
|
suppressSaveHook: planResume !== null || planContinue !== null,
|
|
1680
1692
|
// Task 19 — auto-compact at turn end, except plan resume/continue
|
|
@@ -2839,6 +2851,7 @@ export async function runRepl(opts) {
|
|
|
2839
2851
|
if (trimmed === '/new' || trimmed === '/reset') {
|
|
2840
2852
|
session.awaitingSkillAnswer = false;
|
|
2841
2853
|
session.todos = []; // P2 — /new clears the plan (spec §4)
|
|
2854
|
+
clearAppFlow(session); // Task 7 — /new ends an /abap-app flow
|
|
2842
2855
|
console.log(formatInfo('Fresh start · the next prompt picks a skill again').trimEnd());
|
|
2843
2856
|
continue;
|
|
2844
2857
|
}
|
|
@@ -3295,11 +3308,18 @@ export async function runRepl(opts) {
|
|
|
3295
3308
|
if (skill === 'abap-plan' && planResume === null && session.plan_in_flight) {
|
|
3296
3309
|
const marker = session.plan_in_flight;
|
|
3297
3310
|
const { preparePlanContinuation } = await import('./commands/plan-continue.js');
|
|
3298
|
-
const r = preparePlanContinuation({
|
|
3311
|
+
const r = await preparePlanContinuation({
|
|
3299
3312
|
marker,
|
|
3300
3313
|
sessionId: session.id,
|
|
3314
|
+
cwd: process.cwd(),
|
|
3301
3315
|
log: (...lines) => lines.forEach((l) => console.log(l)),
|
|
3302
3316
|
});
|
|
3317
|
+
// App lane routing — paused plan: no turn, marker kept (Ink mirror).
|
|
3318
|
+
if ('paused' in r && r.paused) {
|
|
3319
|
+
session.last_skill = previousSkill ?? null;
|
|
3320
|
+
session.last_object = extractedObject ?? previousObject ?? null;
|
|
3321
|
+
continue;
|
|
3322
|
+
}
|
|
3303
3323
|
if (r.prepared) {
|
|
3304
3324
|
planContinue = { prepared: r.prepared, marker };
|
|
3305
3325
|
planPhaseStartedAt = marker.attemptStartedAt;
|
|
@@ -3403,6 +3423,7 @@ export async function runRepl(opts) {
|
|
|
3403
3423
|
skill: skill,
|
|
3404
3424
|
ctx: { adt, sapAlias: selectedAlias, session, cwd: process.cwd(), provider, skillSource: provider.skillSource, previewHook: replPreviewHook, chunkEmitter: classicOutputEmitter, todoEmitter, currentTransport: currentTransportAccessor, pendingDispatch: pendingDispatchAccessor },
|
|
3405
3425
|
pushSpend: true, // F-L2-2 — top-level REPL turn: live statusline spend
|
|
3426
|
+
explicitSlash: parsed.skill !== undefined, // Task 7 R11 — typed or queued slash command
|
|
3406
3427
|
signal: turnAbort.signal,
|
|
3407
3428
|
suppressSaveHook: planResume !== null || planContinue !== null,
|
|
3408
3429
|
// Task 19 — auto-compact at turn end, except plan resume/continue
|
package/dist/skill-catalog.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Static skill catalog for CSPeach CLI v0.2.
|
|
3
3
|
*
|
|
4
|
-
* STALENESS RISK (spec §3.3): This constant is hardcoded against the
|
|
4
|
+
* STALENESS RISK (spec §3.3): This constant is hardcoded against the 35 skills
|
|
5
5
|
* in .claude/skills/ as of 2026-07-03 (abap-dump-analyze + abap-dump-triage
|
|
6
6
|
* merged into abap-dump 2026-06-12; abap-extend-model added 2026-06-25;
|
|
7
7
|
* abap-radar/abap-document/abap-performance/abap-cloud-check merged into
|
|
8
8
|
* abap-explain/abap-handover/abap-review 2026-06-28 per
|
|
9
|
-
* plan 2026-06-28-skill-portfolio-merge; abap-clean-core added 2026-06-29
|
|
9
|
+
* plan 2026-06-28-skill-portfolio-merge; abap-clean-core added 2026-06-29; abap-cap added
|
|
10
|
+
* 2026-09-25; abap-app added 2026-10-01). It will drift if skills are added or
|
|
10
11
|
* removed. At Plan 4b kickoff decision the build-time generation option
|
|
11
12
|
* (scripts/generate-skill-catalog.ts reads SKILL.md frontmatter) or runtime
|
|
12
13
|
* fetch (/v1/skills endpoint) will be chosen to replace this file. Until then,
|
|
@@ -109,11 +110,18 @@ export const SKILL_CATALOG = [
|
|
|
109
110
|
{
|
|
110
111
|
name: 'abap-segw',
|
|
111
112
|
category: 'Modify / Fix',
|
|
112
|
-
description: 'Implement SEGW OData DPC_EXT method bodies — reads generated MPC/DPC base classes. SEGW project itself created in transaction SEGW. For S/4
|
|
113
|
-
whenToUse: `pick this for DPC_EXT method bodies on an EXISTING SEGW project (ECC / older S/4; not /abap-rap — that's S/4
|
|
113
|
+
description: 'Implement SEGW OData DPC_EXT method bodies — reads generated MPC/DPC base classes. SEGW project itself created in transaction SEGW. For S/4 2020+ RAP services use /abap-rap.',
|
|
114
|
+
whenToUse: `pick this for DPC_EXT method bodies on an EXISTING SEGW project (ECC / older S/4; not /abap-rap — that's S/4 2020+ RAP; SEGW project + MPC/DPC must already exist)`,
|
|
114
115
|
asks: 'which project and operation? e.g. "GET_ENTITYSET for ZORDER_SRV"',
|
|
115
116
|
},
|
|
116
117
|
// ── Create / Generate ────────────────────────────────────────────────────
|
|
118
|
+
{
|
|
119
|
+
name: 'abap-app',
|
|
120
|
+
category: 'Create / Generate',
|
|
121
|
+
description: 'One entry from a spec (Word, PDF, Excel or text) to a running app — spec gaps, then the app lane (backend + UI, picked by the CLI and confirmed on the lane card), then the plan and the build.',
|
|
122
|
+
whenToUse: `pick this to build an app FROM a spec document (not /abap-rap or /abap-cap — those build one stack you already chose)`,
|
|
123
|
+
asks: 'the spec file. e.g. "@specs/inspection-log.docx"',
|
|
124
|
+
},
|
|
117
125
|
{
|
|
118
126
|
name: 'abap-generate',
|
|
119
127
|
category: 'Create / Generate',
|
|
@@ -124,8 +132,8 @@ export const SKILL_CATALOG = [
|
|
|
124
132
|
{
|
|
125
133
|
name: 'abap-rap',
|
|
126
134
|
category: 'Create / Generate',
|
|
127
|
-
description: 'Scaffold a complete RAP stack on S/4HANA
|
|
128
|
-
whenToUse: `pick this for a full RAP stack on S/4
|
|
135
|
+
description: 'Scaffold a complete RAP stack on S/4HANA 2020+ — table, CDS interface, projection, BDEF, BP class, SRVD, SRVB, DDLX, DCL. ECC/older S/4 → use /abap-segw.',
|
|
136
|
+
whenToUse: `pick this for a full RAP stack on S/4 2020+ (10 objects, table → SRVB; not /abap-segw — that's ECC/older S/4 OData; not /abap-generate — that's one object)`,
|
|
129
137
|
asks: 'the business object. e.g. "maintenance requests with draft and an approve action"',
|
|
130
138
|
},
|
|
131
139
|
{
|