@cspeach/cli 0.6.5 → 0.7.1
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/README.md +26 -0
- package/dist/agent/intent-system-prompt.js +46 -0
- package/dist/agent/loop.js +180 -18
- package/dist/agent/parallel-write-guard.js +71 -0
- package/dist/agent/repair-partial.js +88 -1
- package/dist/agent/retry-cap.js +121 -0
- package/dist/agent/summarise-via-provider.js +51 -0
- package/dist/approvals/jwt.js +33 -12
- package/dist/commands/auto-compact.js +94 -0
- package/dist/commands/compact.js +265 -0
- package/dist/commands/cost.js +56 -0
- package/dist/commands/help.js +21 -14
- package/dist/config/loader.js +39 -0
- package/dist/cost/cost-log.js +113 -0
- package/dist/cost/pricing.js +91 -0
- package/dist/one-shot.js +1 -1
- package/dist/renderer/markdown.js +7 -1
- package/dist/renderer/status-footer.js +37 -14
- package/dist/renderer/thinking-heartbeat.js +15 -3
- package/dist/renderer/tool-widget.js +6 -1
- package/dist/renderer/tty.js +27 -0
- package/dist/repl/cspeach-shell-detect.js +33 -0
- package/dist/repl/post-turn-status.js +68 -0
- package/dist/repl/slash-completer.js +2 -0
- package/dist/repl/slash-picker.js +2 -0
- package/dist/repl.js +371 -46
- package/dist/sap-errors/parse-adt-exception.js +149 -0
- package/dist/session/schema.js +2 -1
- package/dist/session/store.js +19 -0
- package/dist/tools/_filesystem-shared.js +9 -1
- package/dist/tools/ask-question.js +19 -0
- package/dist/tools/sap-read.js +56 -4
- package/dist/tools/sap-write.js +19 -0
- package/dist/tools/subagent/schedule_draft_create.js +137 -0
- package/dist/ui/alt-screen.js +120 -0
- package/dist/ui/app.js +47 -15
- package/dist/ui/ask-question-emitter.js +13 -0
- package/dist/ui/body.js +39 -23
- package/dist/ui/coaching-picker-classic.js +8 -1
- package/dist/ui/footer.js +10 -2
- package/dist/ui/header.js +19 -4
- package/dist/ui/sap-state-store.js +13 -1
- package/dist/ui/sidebar.js +5 -3
- package/dist/ui/status-emitter.js +19 -0
- package/dist/ui/status-row.js +30 -4
- package/dist/ui/widgets/ask-question-modal.js +132 -0
- package/dist/ui/widgets/coaching-picker.js +55 -8
- package/package.json +1 -1
|
@@ -4,16 +4,40 @@ import { Box, Text, useInput } from 'ink';
|
|
|
4
4
|
import { PICK_CANCELLED } from '../skill-picker.js';
|
|
5
5
|
const PEACH = '#FFCBA4';
|
|
6
6
|
/**
|
|
7
|
-
* Ink-mode coaching picker
|
|
8
|
-
* (App) mounts this component only when coachingPending !== null, so the
|
|
9
|
-
* component's useInput being always-active is safe — it can only fire
|
|
10
|
-
* while the overlay is visible.
|
|
7
|
+
* Ink-mode coaching picker — compact single-line-per-option layout.
|
|
11
8
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* Phase D3+ (2026-05-16): the prior layout used a bordered Box per
|
|
10
|
+
* option with 3 text rows each (skill+confidence, Does:, Pick if:).
|
|
11
|
+
* For 5 options that's ~25 lines — exceeded available vertical space
|
|
12
|
+
* once mounted inline between Body and Footer, and Ink overflow-
|
|
13
|
+
* clipped only the BOTTOM line of each option leaving a garbled
|
|
14
|
+
* picker (screenshot 71). This rewrite uses one line per option +
|
|
15
|
+
* a "details" line only for the highlighted entry, total height
|
|
16
|
+
* bounded to ~8 lines regardless of option count.
|
|
17
|
+
*
|
|
18
|
+
* Layout (example, 3 options):
|
|
19
|
+
* ╭ Pick a skill for: "What is the best part…?" ───────────╮
|
|
20
|
+
* │ ▸ /abap-explain 72% Plain-language code explainer │
|
|
21
|
+
* │ /abap-review 0% Code review vs quality criteria│
|
|
22
|
+
* │ /abap-document 0% Generate ABAP documentation │
|
|
23
|
+
* │ │
|
|
24
|
+
* │ ▸ /abap-explain — Pick if: pick this to teach code to a human │
|
|
25
|
+
* │ ↑/↓ navigate · Enter select · Esc cancel │
|
|
26
|
+
* ╰──────────────────────────────────────────────────────────╯
|
|
14
27
|
*/
|
|
15
28
|
export function CoachingPicker({ params, onResolve }) {
|
|
16
|
-
|
|
29
|
+
// 2026-05-17 — initial cursor position priority:
|
|
30
|
+
// 1. preferSkill (the just-used skill, if present in options) — lets
|
|
31
|
+
// the user confirm "same skill as last turn" with one Enter press
|
|
32
|
+
// 2. preSelect=true → top-1 (classifier's best guess)
|
|
33
|
+
// 3. -1 → no selection, user must arrow-key to a choice
|
|
34
|
+
const preferIdx = params.preferSkill
|
|
35
|
+
? params.options.findIndex((o) => o.skill === params.preferSkill)
|
|
36
|
+
: -1;
|
|
37
|
+
const initialCursor = preferIdx >= 0
|
|
38
|
+
? preferIdx
|
|
39
|
+
: params.preSelect ? 0 : -1;
|
|
40
|
+
const [cursor, setCursor] = useState(initialCursor);
|
|
17
41
|
useInput((_input, key) => {
|
|
18
42
|
if (key.escape) {
|
|
19
43
|
onResolve(PICK_CANCELLED);
|
|
@@ -37,5 +61,28 @@ export function CoachingPicker({ params, onResolve }) {
|
|
|
37
61
|
onResolve(chosen.skill);
|
|
38
62
|
}
|
|
39
63
|
}, { isActive: true });
|
|
40
|
-
|
|
64
|
+
const promptPreview = params.prompt.length > 60
|
|
65
|
+
? params.prompt.slice(0, 57) + '…'
|
|
66
|
+
: params.prompt;
|
|
67
|
+
const highlighted = cursor >= 0 ? params.options[cursor] : undefined;
|
|
68
|
+
return (
|
|
69
|
+
// flexShrink={0} (2026-05-17) — without this, Ink's default
|
|
70
|
+
// flexShrink: 1 lets the picker get squashed when vertical space is
|
|
71
|
+
// tight, and the TOP options clip off (only the bottom one remained
|
|
72
|
+
// visible — see screenshot 74). flexShrink={0} guarantees the picker
|
|
73
|
+
// claims its natural height; Body shrinks to make room (and Body
|
|
74
|
+
// content stays recoverable via PgUp/Ctrl+B scroll).
|
|
75
|
+
_jsxs(Box, { borderStyle: "round", borderColor: PEACH, flexDirection: "column", paddingX: 1, flexShrink: 0, children: [_jsxs(Text, { bold: true, children: ["Pick a skill for: ", _jsxs(Text, { color: "cyan", children: ["\"", promptPreview, "\""] })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: params.options.map((opt, i) => {
|
|
76
|
+
const isCursor = i === cursor;
|
|
77
|
+
const arrow = isCursor ? '▸ ' : ' ';
|
|
78
|
+
// 2026-05-17 — hide the "0%" cruft. Confidence is 0 for any
|
|
79
|
+
// alternate / fallback option (we never had a real score for
|
|
80
|
+
// them), AND for top-1 picks where the classifier itself
|
|
81
|
+
// returned 0. In both cases displaying "0%" looks broken.
|
|
82
|
+
// Show "%" only when there's a meaningful number.
|
|
83
|
+
const pctNum = Math.round(opt.confidence * 100);
|
|
84
|
+
const pct = pctNum > 0 ? `${pctNum.toString().padStart(3, ' ')}%` : ' ';
|
|
85
|
+
const name = `/${opt.skill}`.padEnd(20, ' ');
|
|
86
|
+
return (_jsxs(Text, { color: isCursor ? PEACH : undefined, bold: isCursor, children: [arrow, name, " ", pct, " ", opt.whatItDoes.slice(0, 60)] }, opt.skill));
|
|
87
|
+
}) }), highlighted && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Pick if: ", highlighted.whenToPick] }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate \u00B7 Enter select \u00B7 Esc cancel" }) })] }));
|
|
41
88
|
}
|