@axplusb/kepler 1.0.10 → 2.0.0
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/package.json +5 -2
- package/src/context/retriever.mjs +42 -4
- package/src/context/symbol-indexer.mjs +375 -0
- package/src/core/approval.mjs +154 -95
- package/src/core/backend-url.mjs +2 -2
- package/src/core/headless.mjs +5 -0
- package/src/core/risk-tier.mjs +239 -0
- package/src/core/tool-executor.mjs +49 -3
- package/src/onboarding/preflight.mjs +274 -0
- package/src/state/orbit.mjs +263 -0
- package/src/state/verbosity.mjs +99 -0
- package/src/terminal/ansi.mjs +44 -22
- package/src/terminal/repl.mjs +395 -108
- package/src/ui/approval.mjs +167 -0
- package/src/ui/banner.mjs +133 -122
- package/src/ui/dock.mjs +88 -0
- package/src/ui/icons.mjs +164 -0
- package/src/ui/mission-report.mjs +264 -0
- package/src/ui/palette.mjs +189 -0
- package/src/ui/spinner.mjs +116 -0
- package/src/ui/status-bar.mjs +275 -0
- package/src/ui/sub-agent.mjs +152 -0
- package/src/ui/term.mjs +159 -0
- package/src/ui/tool-card.mjs +314 -0
- package/src/ui/tool-details.mjs +277 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verbosity modes — Mission Control (PRD-055 §12).
|
|
3
|
+
*
|
|
4
|
+
* quiet Folded summary only. Sub-agent inner tools hidden.
|
|
5
|
+
* default Folded summary. Sub-agent header shown, inner tools folded.
|
|
6
|
+
* verbose Folded summary. Sub-agent inner tools shown.
|
|
7
|
+
* surgical Expanded tool details + raw model reasoning.
|
|
8
|
+
*
|
|
9
|
+
* Persisted to `~/.kepler/config.json` under the `verbosity` key so the
|
|
10
|
+
* choice survives across sessions.
|
|
11
|
+
*
|
|
12
|
+
* import { getVerbosity, setVerbosity, showSubAgentTools, showReasoning } from './verbosity.mjs';
|
|
13
|
+
*
|
|
14
|
+
* No imports from the REPL — this module is pure state + filesystem.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import fs from 'node:fs';
|
|
18
|
+
import os from 'node:os';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
|
|
21
|
+
export const MODES = Object.freeze({
|
|
22
|
+
QUIET: 'quiet',
|
|
23
|
+
DEFAULT: 'default',
|
|
24
|
+
VERBOSE: 'verbose',
|
|
25
|
+
SURGICAL: 'surgical',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const VALID = new Set(Object.values(MODES));
|
|
29
|
+
|
|
30
|
+
const CONFIG_DIR = process.env.KEPLER_HOME || path.join(os.homedir(), '.kepler');
|
|
31
|
+
const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
|
|
32
|
+
|
|
33
|
+
let _cached = null;
|
|
34
|
+
|
|
35
|
+
function readConfig() {
|
|
36
|
+
try { return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8')); }
|
|
37
|
+
catch { return {}; }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function writeConfig(obj) {
|
|
41
|
+
try {
|
|
42
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
43
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(obj, null, 2));
|
|
44
|
+
} catch { /* best effort */ }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Read the current mode (falls back to default). */
|
|
48
|
+
export function getVerbosity() {
|
|
49
|
+
if (_cached) return _cached;
|
|
50
|
+
const v = readConfig().verbosity;
|
|
51
|
+
_cached = VALID.has(v) ? v : MODES.DEFAULT;
|
|
52
|
+
return _cached;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Update the persisted mode. Returns the new mode. */
|
|
56
|
+
export function setVerbosity(mode) {
|
|
57
|
+
if (!VALID.has(mode)) throw new Error(`Unknown verbosity mode: ${mode}`);
|
|
58
|
+
const cfg = readConfig();
|
|
59
|
+
cfg.verbosity = mode;
|
|
60
|
+
writeConfig(cfg);
|
|
61
|
+
_cached = mode;
|
|
62
|
+
return mode;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Force-reload from disk (used by tests). */
|
|
66
|
+
export function _resetCache() { _cached = null; }
|
|
67
|
+
|
|
68
|
+
// ── Predicates — let other modules ask "should I render X?" ─────────────
|
|
69
|
+
|
|
70
|
+
/** Should sub-agent inner tool cards be printed? */
|
|
71
|
+
export function showSubAgentTools(mode = getVerbosity()) {
|
|
72
|
+
return mode === MODES.VERBOSE || mode === MODES.SURGICAL;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Should raw model reasoning be printed? */
|
|
76
|
+
export function showReasoning(mode = getVerbosity()) {
|
|
77
|
+
return mode === MODES.SURGICAL;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Should tool cards default to expanded instead of folded? */
|
|
81
|
+
export function defaultExpanded(mode = getVerbosity()) {
|
|
82
|
+
return mode === MODES.SURGICAL;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Should markdown be rendered? (only `surgical` shows raw, others render) */
|
|
86
|
+
export function renderMarkdown(mode = getVerbosity()) {
|
|
87
|
+
return mode !== MODES.SURGICAL;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Per-mode label for /help and status display. */
|
|
91
|
+
export function label(mode = getVerbosity()) {
|
|
92
|
+
switch (mode) {
|
|
93
|
+
case MODES.QUIET: return 'quiet (compact)';
|
|
94
|
+
case MODES.DEFAULT: return 'default';
|
|
95
|
+
case MODES.VERBOSE: return 'verbose (sub-agent tools visible)';
|
|
96
|
+
case MODES.SURGICAL: return 'surgical (everything shown)';
|
|
97
|
+
default: return String(mode || 'default');
|
|
98
|
+
}
|
|
99
|
+
}
|
package/src/terminal/ansi.mjs
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ANSI Terminal Renderer —
|
|
2
|
+
* ANSI Terminal Renderer — cursor control, box drawing, status bars.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Color helpers (the `c` object) now route through the semantic palette
|
|
5
|
+
* (`src/ui/palette.mjs`) so the entire CLI honors the Kepler brand and
|
|
6
|
+
* tier fallbacks (truecolor, ansi256, ansi16, none) without touching
|
|
7
|
+
* each call site. Hot-swap-friendly: external semantics like `c.red`,
|
|
8
|
+
* `c.bold`, `c.cyan` are preserved as the legacy contract; new code
|
|
9
|
+
* should prefer importing `paint` directly.
|
|
6
10
|
*/
|
|
7
11
|
|
|
12
|
+
import { paint } from '../ui/palette.mjs';
|
|
13
|
+
|
|
8
14
|
const ESC = '\x1b[';
|
|
9
15
|
const write = (s) => process.stderr.write(s);
|
|
10
16
|
|
|
@@ -27,27 +33,43 @@ export const cursor = {
|
|
|
27
33
|
};
|
|
28
34
|
|
|
29
35
|
// ── Colors ──
|
|
36
|
+
// Legacy color names re-mapped onto semantic palette tokens. The CLI's
|
|
37
|
+
// branding is centralized in palette.mjs; this object is preserved only
|
|
38
|
+
// so existing imports keep compiling. Internal Kepler color choices are
|
|
39
|
+
// documented next to each mapping for the next code review.
|
|
40
|
+
|
|
41
|
+
const identity = (s) => String(s ?? '');
|
|
30
42
|
|
|
31
43
|
export const c = {
|
|
32
|
-
reset:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
reset: identity, // palette already wraps with RESET
|
|
45
|
+
|
|
46
|
+
// Styles — work at every tier
|
|
47
|
+
bold: paint.bold,
|
|
48
|
+
dim: paint.dim,
|
|
49
|
+
italic: paint.italic,
|
|
50
|
+
underline: paint.underline,
|
|
51
|
+
|
|
52
|
+
// State semantics
|
|
53
|
+
red: paint.state.danger, // failure / hard error
|
|
54
|
+
green: paint.state.success, // pass / aligned
|
|
55
|
+
yellow: paint.state.warn, // soft warn / retry
|
|
56
|
+
|
|
57
|
+
// Brand semantics
|
|
58
|
+
blue: paint.brand.primary, // headers, primary brand
|
|
59
|
+
magenta: paint.brand.accent, // attention required
|
|
60
|
+
brand: paint.brand.primary, // primary brand surface
|
|
61
|
+
cyan: paint.brand.data, // code / file paths
|
|
62
|
+
cyanRegular: paint.brand.data,
|
|
63
|
+
cyanBold: (s) => paint.bold(paint.brand.data(s)),
|
|
64
|
+
|
|
65
|
+
// Text semantics
|
|
66
|
+
white: paint.text.primary, // primary text
|
|
67
|
+
gray: paint.text.dim, // hints, metadata, dim text
|
|
68
|
+
|
|
69
|
+
// Backgrounds — kept as raw ANSI; rarely used and have no palette analog
|
|
70
|
+
bgRed: (s) => `${ESC}41m${String(s ?? '')}${ESC}0m`,
|
|
71
|
+
bgGreen: (s) => `${ESC}42m${String(s ?? '')}${ESC}0m`,
|
|
72
|
+
bgCyan: (s) => `${ESC}46m${String(s ?? '')}${ESC}0m`,
|
|
51
73
|
};
|
|
52
74
|
|
|
53
75
|
// ── Box Drawing ──
|