@kb-labs/shared-cli-ui 2.94.0 → 2.98.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/dist/debug.cjs +19 -11
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.js +19 -11
- package/dist/debug.js.map +1 -1
- package/dist/index.cjs +905 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +239 -5
- package/dist/index.d.ts +239 -5
- package/dist/index.js +867 -105
- package/dist/index.js.map +1 -1
- package/dist/interactive/index.cjs +462 -0
- package/dist/interactive/index.cjs.map +1 -0
- package/dist/interactive/index.d.cts +74 -0
- package/dist/interactive/index.d.ts +74 -0
- package/dist/interactive/index.js +436 -0
- package/dist/interactive/index.js.map +1 -0
- package/package.json +12 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { DebugContext, DebugDetailLevel, DebugEntry, DebugExportOptions, DebugFilterOptions, DebugFormat, DebugLevel, DebugMeta, DebugOutput, DebugOutputOptions, DebugSection, DebugTrace, DebugTree, DebugTreeNode, DebugTreeOptions, HumanFormatterOptions, TraceOptions, createDebugTree, describeEntriesAI, describeEntriesHuman, describeEntriesTimeline, exportDebugEntries, exportToChromeFormat, exportToJSON, exportToPlainText, filterByLevel, filterByNamespace, filterByTimeRange, filterDebugEntries, formatDebugEntriesAI, formatDebugEntriesHuman, formatDebugEntryAI, formatDebugEntryHuman, formatDebugOutput, formatDebugOutputs, formatTimeline, formatTimelineNode, formatTimelineWithSummary, groupByGroup, groupByNamespace, searchInLogs, shouldUseAIFormat } from './debug.cjs';
|
|
2
|
+
export { ConfirmOptions, MultiSelectChoice, MultiSelectOptions, SelectChoice, SelectOptions, TextOptions, confirm, isInteractive, multiSelect, select, text } from './interactive/index.cjs';
|
|
3
|
+
import { SelectChoice, MultiSelectChoice, UIFacade } from '@kb-labs/plugin-contracts';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Minimalist color utilities for CLI output
|
|
@@ -32,6 +34,10 @@ declare const symbols: {
|
|
|
32
34
|
package: string;
|
|
33
35
|
pointer: string;
|
|
34
36
|
section: string;
|
|
37
|
+
step: string;
|
|
38
|
+
stepDone: string;
|
|
39
|
+
arrow: string;
|
|
40
|
+
diamond: string;
|
|
35
41
|
};
|
|
36
42
|
declare const supportsColor: boolean;
|
|
37
43
|
declare const safeColors: {
|
|
@@ -62,6 +68,10 @@ declare const safeSymbols: {
|
|
|
62
68
|
package: string;
|
|
63
69
|
pointer: string;
|
|
64
70
|
section: string;
|
|
71
|
+
step: string;
|
|
72
|
+
stepDone: string;
|
|
73
|
+
arrow: string;
|
|
74
|
+
diamond: string;
|
|
65
75
|
separator: string;
|
|
66
76
|
border: string;
|
|
67
77
|
topLeft: string;
|
|
@@ -845,22 +855,146 @@ interface RetryOptions {
|
|
|
845
855
|
}
|
|
846
856
|
declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
847
857
|
|
|
858
|
+
interface ErrorContext {
|
|
859
|
+
ui?: {
|
|
860
|
+
json?: (data: unknown) => void;
|
|
861
|
+
error?: (message: string, opts?: Record<string, unknown>) => void;
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Structured validation error — emits { ok: false, error: { code: 'INVALID_ARGS', ... } } in JSON mode.
|
|
866
|
+
* Call before try/catch, right before `return { exitCode: 1 }`.
|
|
867
|
+
*/
|
|
868
|
+
declare function validationError(ctx: ErrorContext, message: string, hint?: string, isJson?: boolean): void;
|
|
869
|
+
/**
|
|
870
|
+
* Structured runtime/API error — emits { ok: false, error: { code: 'INTERNAL_ERROR', ... } } in JSON mode.
|
|
871
|
+
* Call in catch blocks, right before `return { exitCode: 1 }`.
|
|
872
|
+
*/
|
|
873
|
+
declare function handleError(ctx: ErrorContext, err: unknown, isJson?: boolean): void;
|
|
874
|
+
/**
|
|
875
|
+
* Re-throws `err` as an HTTP-aware error for REST handlers.
|
|
876
|
+
* Envelope middleware reads `err.statusCode` to set HTTP status.
|
|
877
|
+
* If err already has statusCode — preserves it. Otherwise → 500.
|
|
878
|
+
*/
|
|
879
|
+
declare function rethrowForRest(err: unknown): never;
|
|
880
|
+
|
|
881
|
+
/**
|
|
882
|
+
* Destructive-action protocol (SOFT layer).
|
|
883
|
+
*
|
|
884
|
+
* A single, platform-wide way for a command to declare that an operation is
|
|
885
|
+
* destructive — how bad, how broad, and whether it can be undone — and to gate
|
|
886
|
+
* it behind explicit confirmation in EVERY mode (human and agent).
|
|
887
|
+
*
|
|
888
|
+
* This layer is intentionally SOFT: it informs and asks, it does not enforce.
|
|
889
|
+
* Physical enforcement (can-this-token-even-invoke-this) is the platform's
|
|
890
|
+
* future token/permission layer; it reads the SAME `severity`/`destructive`
|
|
891
|
+
* declaration on the command. So one declaration drives both:
|
|
892
|
+
* - now: this helper renders a clear signal + requires `--yes`;
|
|
893
|
+
* - later: the permission layer filters discovery + blocks invocation by right.
|
|
894
|
+
*
|
|
895
|
+
* Declaring it is OPTIONAL for external plugins (commands work without it) but
|
|
896
|
+
* strongly recommended — agents can only reason about blast radius they're told.
|
|
897
|
+
*/
|
|
898
|
+
type DestructiveSeverity = 'low' | 'medium' | 'high' | 'critical';
|
|
899
|
+
/**
|
|
900
|
+
* Severity rubric — worst-case blast radius weighed against recovery cost
|
|
901
|
+
* (keep consistent across plugins so agents can calibrate):
|
|
902
|
+
* - low narrow scope AND trivially auto-rebuilt from source (idempotent)
|
|
903
|
+
* - medium a bounded set is lost; rebuildable, but with effort/recompute
|
|
904
|
+
* - high a WHOLE collection is destroyed (entire index/corpus), OR recovery
|
|
905
|
+
* is slow / manual — even if rebuildable, the loss is large and
|
|
906
|
+
* easy to mis-target
|
|
907
|
+
* - critical irreversible, NO recovery (prod data, tenant wipe)
|
|
908
|
+
*/
|
|
909
|
+
interface DestructiveAction {
|
|
910
|
+
/** Command identity, e.g. "mind drop". */
|
|
911
|
+
action: string;
|
|
912
|
+
/** What is affected, e.g. 'index "code"'. */
|
|
913
|
+
resource: string;
|
|
914
|
+
/** Plain-language effect, e.g. "deletes all vectors + the manifest". */
|
|
915
|
+
effect: string;
|
|
916
|
+
/** Blast-radius tier. */
|
|
917
|
+
severity: DestructiveSeverity;
|
|
918
|
+
/** Whether the data can be recovered afterwards. */
|
|
919
|
+
reversible: boolean;
|
|
920
|
+
/** How to recover, if reversible (e.g. "re-run `kb mind index --full`"). */
|
|
921
|
+
recovery?: string;
|
|
922
|
+
/** Quantified scope — how much, of what, how broad. */
|
|
923
|
+
blastRadius?: {
|
|
924
|
+
count?: number;
|
|
925
|
+
unit?: string;
|
|
926
|
+
scope?: string;
|
|
927
|
+
};
|
|
928
|
+
/** Flag that confirms the action (default `--yes`). */
|
|
929
|
+
confirmFlag?: string;
|
|
930
|
+
}
|
|
931
|
+
/** The machine-readable signal an agent receives when confirmation is missing. */
|
|
932
|
+
interface ConfirmationRequired {
|
|
933
|
+
ok: false;
|
|
934
|
+
confirmationRequired: true;
|
|
935
|
+
destructive: true;
|
|
936
|
+
irreversible: boolean;
|
|
937
|
+
severity: DestructiveSeverity;
|
|
938
|
+
action: string;
|
|
939
|
+
resource: string;
|
|
940
|
+
effect: string;
|
|
941
|
+
reversible: boolean;
|
|
942
|
+
blastRadius?: {
|
|
943
|
+
count?: number;
|
|
944
|
+
unit?: string;
|
|
945
|
+
scope?: string;
|
|
946
|
+
};
|
|
947
|
+
recovery?: string;
|
|
948
|
+
confirmWith: string;
|
|
949
|
+
message: string;
|
|
950
|
+
}
|
|
951
|
+
interface ConfirmContext {
|
|
952
|
+
ui?: {
|
|
953
|
+
json?: (data: unknown) => void;
|
|
954
|
+
warn?: (message: string, opts?: Record<string, unknown>) => void;
|
|
955
|
+
error?: (message: string, opts?: Record<string, unknown>) => void;
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Build the machine-readable signal an agent receives when confirmation is
|
|
960
|
+
* missing in json mode. Exported so a non-CLI surface (REST 409, MCP) can reuse
|
|
961
|
+
* the exact shape instead of re-deriving it.
|
|
962
|
+
*/
|
|
963
|
+
declare function buildConfirmationSignal(a: DestructiveAction): ConfirmationRequired;
|
|
964
|
+
/** Render the one-line warning — leads with the scary part (irreversibility + severity). */
|
|
965
|
+
declare function renderDestructiveMessage(a: DestructiveAction): string;
|
|
966
|
+
/**
|
|
967
|
+
* Gate a destructive command. Returns the command result to return immediately
|
|
968
|
+
* when NOT confirmed (in every mode — agents get the structured signal, not a
|
|
969
|
+
* silent execution), or `null` when confirmed so the caller proceeds.
|
|
970
|
+
*
|
|
971
|
+
* const blocked = confirmDestructive(ctx, { confirmed: flags.yes, isJson, action });
|
|
972
|
+
* if (blocked) return blocked;
|
|
973
|
+
*/
|
|
974
|
+
declare function confirmDestructive(ctx: ConfirmContext, opts: {
|
|
975
|
+
confirmed: boolean;
|
|
976
|
+
isJson?: boolean;
|
|
977
|
+
action: DestructiveAction;
|
|
978
|
+
}): {
|
|
979
|
+
exitCode: number;
|
|
980
|
+
} | null;
|
|
981
|
+
|
|
848
982
|
/**
|
|
849
983
|
* Modern CLI formatting utilities with side border design
|
|
850
984
|
* Provides minimalist, modern UI components for CLI output
|
|
851
985
|
*/
|
|
852
986
|
|
|
853
987
|
/**
|
|
854
|
-
* Side border box -
|
|
988
|
+
* Side border box - Clack-style design
|
|
855
989
|
*
|
|
856
990
|
* @example
|
|
857
991
|
* ```
|
|
858
|
-
*
|
|
992
|
+
* ◆ Command Name
|
|
859
993
|
* │
|
|
860
|
-
* │
|
|
994
|
+
* │ Section Header
|
|
861
995
|
* │ Key: value
|
|
862
996
|
* │
|
|
863
|
-
*
|
|
997
|
+
* └ ✓ Success 84ms
|
|
864
998
|
* ```
|
|
865
999
|
*/
|
|
866
1000
|
interface SideBorderBoxOptions {
|
|
@@ -869,6 +1003,7 @@ interface SideBorderBoxOptions {
|
|
|
869
1003
|
footer?: string;
|
|
870
1004
|
status?: 'success' | 'error' | 'warning' | 'info';
|
|
871
1005
|
timing?: number;
|
|
1006
|
+
summary?: Record<string, string | number | boolean>;
|
|
872
1007
|
}
|
|
873
1008
|
interface RichSectionItem {
|
|
874
1009
|
text: string;
|
|
@@ -899,6 +1034,36 @@ declare function metricsList(metrics: Record<string, string | number>): string[]
|
|
|
899
1034
|
* Format status line for footer
|
|
900
1035
|
*/
|
|
901
1036
|
declare function statusLine(status: 'success' | 'error' | 'warning' | 'info', timing?: number): string;
|
|
1037
|
+
/**
|
|
1038
|
+
* A single block in a chained output — a title + sections with optional footer on the last block.
|
|
1039
|
+
*/
|
|
1040
|
+
interface SideBorderChainItem {
|
|
1041
|
+
title: string;
|
|
1042
|
+
sections: SectionContent[];
|
|
1043
|
+
summary?: Record<string, string | number | boolean>;
|
|
1044
|
+
status?: 'success' | 'error' | 'warning' | 'info';
|
|
1045
|
+
timing?: number;
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* Render multiple side-border blocks as a continuous visual chain.
|
|
1049
|
+
*
|
|
1050
|
+
* Every block opens with `◆ Title` on the shared rail.
|
|
1051
|
+
* Only the last block gets `└ status timing`.
|
|
1052
|
+
*
|
|
1053
|
+
* @example
|
|
1054
|
+
* ```
|
|
1055
|
+
* ◆ workflow metrics
|
|
1056
|
+
* │
|
|
1057
|
+
* │ Failed to fetch metrics
|
|
1058
|
+
* │
|
|
1059
|
+
* ◆ Warning
|
|
1060
|
+
* │
|
|
1061
|
+
* │ Make sure daemon is running
|
|
1062
|
+
* │
|
|
1063
|
+
* └ ✗ 12ms
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
declare function sideBorderChain(items: SideBorderChainItem[]): string;
|
|
902
1067
|
/**
|
|
903
1068
|
* Convert an Error or raw string into clean display lines for sideBorderBox items.
|
|
904
1069
|
* Splits on newlines, removes blank lines, and caps at maxLines with a "… N more" hint.
|
|
@@ -1066,4 +1231,73 @@ declare function infoResult(title: string, data?: {
|
|
|
1066
1231
|
timing?: number;
|
|
1067
1232
|
}): CommandOutput;
|
|
1068
1233
|
|
|
1069
|
-
|
|
1234
|
+
/**
|
|
1235
|
+
* Structured log display for CLI output (watch/run/stream commands).
|
|
1236
|
+
* Not a spinner — for rendering log lines with level, timestamp, and message.
|
|
1237
|
+
*/
|
|
1238
|
+
type LogLevel = 'info' | 'warn' | 'error' | 'debug' | 'verbose';
|
|
1239
|
+
declare function logLine(level: LogLevel, message: string): string;
|
|
1240
|
+
declare function logGroup(title: string, lines: string[]): string;
|
|
1241
|
+
declare function printLog(level: LogLevel, message: string): void;
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Inline status badges for CLI output.
|
|
1245
|
+
*
|
|
1246
|
+
* @example
|
|
1247
|
+
* badge('ONLINE', 'success') → green [ONLINE]
|
|
1248
|
+
* badge('FAILED', 'error') → red [FAILED]
|
|
1249
|
+
* badge('PENDING', 'neutral') → muted [PENDING]
|
|
1250
|
+
*/
|
|
1251
|
+
type BadgeVariant = 'success' | 'error' | 'warning' | 'info' | 'neutral';
|
|
1252
|
+
declare function badge(label: string, variant?: BadgeVariant): string;
|
|
1253
|
+
declare function statusBadge(status: string): string;
|
|
1254
|
+
|
|
1255
|
+
/**
|
|
1256
|
+
* Multi-step task runner with visual progress.
|
|
1257
|
+
* Each task shows as ○ pending → spinner running → ● done / ✗ failed.
|
|
1258
|
+
*
|
|
1259
|
+
* @example
|
|
1260
|
+
* await runTasks([
|
|
1261
|
+
* { title: 'Install dependencies', run: async () => { ... } },
|
|
1262
|
+
* { title: 'Build', run: async () => { ... } },
|
|
1263
|
+
* ])
|
|
1264
|
+
*/
|
|
1265
|
+
interface Task {
|
|
1266
|
+
title: string;
|
|
1267
|
+
run: (updateTitle: (t: string) => void) => Promise<void>;
|
|
1268
|
+
}
|
|
1269
|
+
declare function runTasks(tasks: Task[]): Promise<void>;
|
|
1270
|
+
|
|
1271
|
+
/**
|
|
1272
|
+
* All interactive prompt methods of UIFacade.
|
|
1273
|
+
* Required (not optional) so TypeScript catches missing implementations
|
|
1274
|
+
* when UIFacade gains a new prompt method.
|
|
1275
|
+
*/
|
|
1276
|
+
interface UIPrompts {
|
|
1277
|
+
confirm(msg: string, opts?: {
|
|
1278
|
+
defaultValue?: boolean;
|
|
1279
|
+
}): Promise<boolean>;
|
|
1280
|
+
prompt(msg: string, opts?: {
|
|
1281
|
+
default?: string;
|
|
1282
|
+
mask?: boolean;
|
|
1283
|
+
}): Promise<string>;
|
|
1284
|
+
select<T>(msg: string, choices: SelectChoice<T>[]): Promise<T>;
|
|
1285
|
+
multiSelect<T>(msg: string, choices: MultiSelectChoice<T>[]): Promise<T[]>;
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Safe-return prompts for non-interactive contexts (subprocess, sandbox).
|
|
1289
|
+
* All methods return the most sensible default without any I/O.
|
|
1290
|
+
*/
|
|
1291
|
+
declare const NOOP_PROMPTS: UIPrompts;
|
|
1292
|
+
/**
|
|
1293
|
+
* Shared stdout UIFacade factory for subprocess/worker contexts.
|
|
1294
|
+
*
|
|
1295
|
+
* Both params are required so TypeScript catches any new UIFacade interactive
|
|
1296
|
+
* method at the call site rather than silently inheriting a noop default.
|
|
1297
|
+
*
|
|
1298
|
+
* Uses `satisfies UIFacade` on the object literal — TypeScript will error here
|
|
1299
|
+
* (not just at the return type) if any UIFacade method is missing.
|
|
1300
|
+
*/
|
|
1301
|
+
declare function createBaseStdoutUI(prompts: UIPrompts, log: UIFacade['log']): UIFacade;
|
|
1302
|
+
|
|
1303
|
+
export { type AnalyticsConfig, type ArtifactDisplayOptions, type ArtifactInfo, type BadgeVariant, type BaseFlagSpec, type BooleanFlagSpec, type CLIPackage, type CommandContext, type CommandDiscovery, type CommandExecutionResult, type CommandInfo, type CommandManifest, type CommandOutput, type CommandPresenter, type CommandRegistry, type CommandResult, type CommandResultParams, type CommandRunnerOptions, type CommandSuggestion, type ConfirmationRequired, type DestructiveAction, type DestructiveSeverity, DynamicCommandDiscovery, type EnvDefinition, type EnvSchema, type FlagDefinition, type FlagSpec, type FlagType, type FlagsDefinition, type FlagsSchema, type FormatTimestampOptions, type InferFlagsType, type KeyValueOptions, Loader, type LoaderOptions, type LogLevel, type ManifestLoader, type MultiCLIContext, MultiCLISuggestions, NOOP_PROMPTS, type NumberFlagSpec, type RetryOptions, type RichSectionItem, type RuntimeLike, type SafeKeyValueOptions, type SectionContent, type SectionItem, type SideBorderBoxOptions, type SideBorderChainItem, StaticCommandDiscovery, type StringFlagSpec, type TableColumn, type TableOptions, type Task, TimingTracker, type UIPrompts, accentLabel, badge, box, buildConfirmationSignal, bulletList, colors, confirmDestructive, createBaseStdoutUI, createCommandDiscovery, createCommandRegistry, createCommandRunner, createDetailedResult, createKBLabsCommandDiscovery, createProgressBar, createSimpleResult, createSpinner, defineEnv, defineFlags, discoverArtifacts, displayArtifacts, displayArtifactsCompact, displaySingleArtifact, errorResult, extractCommandGroups, extractCommandIds, findCommandById, findCommandsByGroup, formatCommandHelp, formatCommandOutput, formatCommandResult, formatError, formatKeyValueTable, formatRelativeTime, formatSize, formatTable, formatTimestamp, formatTiming, formatTimingBreakdown, generateDevlinkSuggestions, generateGroupSuggestions, generateQuickActions, getCommandInfo, getContextCwd, handleError, hasAnsi, headline, indent, infoResult, isCommandAvailable, isJsonMode, keyValue, logGroup, logLine, mergeFlags, metricsList, muted, pad, parseBoolean, parseEnvFromRuntime, parseFlagsFromInput, parseNumber, parseNumberFlag, parseString, printLog, renderDestructiveMessage, rethrowForRest, runTasks, safeColors, safeKeyValue, safeSymbols, section, sectionHeader, setJsonMode, showError, showLoading, showSuccess, sideBorderBox, sideBorderChain, statusBadge, statusLine, stripAnsi, successResult, supportsColor, symbols, table, toPosixPath, truncate, useLoader, validateSuggestions, validationError, warningResult, withRetry };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { DebugContext, DebugDetailLevel, DebugEntry, DebugExportOptions, DebugFilterOptions, DebugFormat, DebugLevel, DebugMeta, DebugOutput, DebugOutputOptions, DebugSection, DebugTrace, DebugTree, DebugTreeNode, DebugTreeOptions, HumanFormatterOptions, TraceOptions, createDebugTree, describeEntriesAI, describeEntriesHuman, describeEntriesTimeline, exportDebugEntries, exportToChromeFormat, exportToJSON, exportToPlainText, filterByLevel, filterByNamespace, filterByTimeRange, filterDebugEntries, formatDebugEntriesAI, formatDebugEntriesHuman, formatDebugEntryAI, formatDebugEntryHuman, formatDebugOutput, formatDebugOutputs, formatTimeline, formatTimelineNode, formatTimelineWithSummary, groupByGroup, groupByNamespace, searchInLogs, shouldUseAIFormat } from './debug.js';
|
|
2
|
+
export { ConfirmOptions, MultiSelectChoice, MultiSelectOptions, SelectChoice, SelectOptions, TextOptions, confirm, isInteractive, multiSelect, select, text } from './interactive/index.js';
|
|
3
|
+
import { SelectChoice, MultiSelectChoice, UIFacade } from '@kb-labs/plugin-contracts';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Minimalist color utilities for CLI output
|
|
@@ -32,6 +34,10 @@ declare const symbols: {
|
|
|
32
34
|
package: string;
|
|
33
35
|
pointer: string;
|
|
34
36
|
section: string;
|
|
37
|
+
step: string;
|
|
38
|
+
stepDone: string;
|
|
39
|
+
arrow: string;
|
|
40
|
+
diamond: string;
|
|
35
41
|
};
|
|
36
42
|
declare const supportsColor: boolean;
|
|
37
43
|
declare const safeColors: {
|
|
@@ -62,6 +68,10 @@ declare const safeSymbols: {
|
|
|
62
68
|
package: string;
|
|
63
69
|
pointer: string;
|
|
64
70
|
section: string;
|
|
71
|
+
step: string;
|
|
72
|
+
stepDone: string;
|
|
73
|
+
arrow: string;
|
|
74
|
+
diamond: string;
|
|
65
75
|
separator: string;
|
|
66
76
|
border: string;
|
|
67
77
|
topLeft: string;
|
|
@@ -845,22 +855,146 @@ interface RetryOptions {
|
|
|
845
855
|
}
|
|
846
856
|
declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
847
857
|
|
|
858
|
+
interface ErrorContext {
|
|
859
|
+
ui?: {
|
|
860
|
+
json?: (data: unknown) => void;
|
|
861
|
+
error?: (message: string, opts?: Record<string, unknown>) => void;
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Structured validation error — emits { ok: false, error: { code: 'INVALID_ARGS', ... } } in JSON mode.
|
|
866
|
+
* Call before try/catch, right before `return { exitCode: 1 }`.
|
|
867
|
+
*/
|
|
868
|
+
declare function validationError(ctx: ErrorContext, message: string, hint?: string, isJson?: boolean): void;
|
|
869
|
+
/**
|
|
870
|
+
* Structured runtime/API error — emits { ok: false, error: { code: 'INTERNAL_ERROR', ... } } in JSON mode.
|
|
871
|
+
* Call in catch blocks, right before `return { exitCode: 1 }`.
|
|
872
|
+
*/
|
|
873
|
+
declare function handleError(ctx: ErrorContext, err: unknown, isJson?: boolean): void;
|
|
874
|
+
/**
|
|
875
|
+
* Re-throws `err` as an HTTP-aware error for REST handlers.
|
|
876
|
+
* Envelope middleware reads `err.statusCode` to set HTTP status.
|
|
877
|
+
* If err already has statusCode — preserves it. Otherwise → 500.
|
|
878
|
+
*/
|
|
879
|
+
declare function rethrowForRest(err: unknown): never;
|
|
880
|
+
|
|
881
|
+
/**
|
|
882
|
+
* Destructive-action protocol (SOFT layer).
|
|
883
|
+
*
|
|
884
|
+
* A single, platform-wide way for a command to declare that an operation is
|
|
885
|
+
* destructive — how bad, how broad, and whether it can be undone — and to gate
|
|
886
|
+
* it behind explicit confirmation in EVERY mode (human and agent).
|
|
887
|
+
*
|
|
888
|
+
* This layer is intentionally SOFT: it informs and asks, it does not enforce.
|
|
889
|
+
* Physical enforcement (can-this-token-even-invoke-this) is the platform's
|
|
890
|
+
* future token/permission layer; it reads the SAME `severity`/`destructive`
|
|
891
|
+
* declaration on the command. So one declaration drives both:
|
|
892
|
+
* - now: this helper renders a clear signal + requires `--yes`;
|
|
893
|
+
* - later: the permission layer filters discovery + blocks invocation by right.
|
|
894
|
+
*
|
|
895
|
+
* Declaring it is OPTIONAL for external plugins (commands work without it) but
|
|
896
|
+
* strongly recommended — agents can only reason about blast radius they're told.
|
|
897
|
+
*/
|
|
898
|
+
type DestructiveSeverity = 'low' | 'medium' | 'high' | 'critical';
|
|
899
|
+
/**
|
|
900
|
+
* Severity rubric — worst-case blast radius weighed against recovery cost
|
|
901
|
+
* (keep consistent across plugins so agents can calibrate):
|
|
902
|
+
* - low narrow scope AND trivially auto-rebuilt from source (idempotent)
|
|
903
|
+
* - medium a bounded set is lost; rebuildable, but with effort/recompute
|
|
904
|
+
* - high a WHOLE collection is destroyed (entire index/corpus), OR recovery
|
|
905
|
+
* is slow / manual — even if rebuildable, the loss is large and
|
|
906
|
+
* easy to mis-target
|
|
907
|
+
* - critical irreversible, NO recovery (prod data, tenant wipe)
|
|
908
|
+
*/
|
|
909
|
+
interface DestructiveAction {
|
|
910
|
+
/** Command identity, e.g. "mind drop". */
|
|
911
|
+
action: string;
|
|
912
|
+
/** What is affected, e.g. 'index "code"'. */
|
|
913
|
+
resource: string;
|
|
914
|
+
/** Plain-language effect, e.g. "deletes all vectors + the manifest". */
|
|
915
|
+
effect: string;
|
|
916
|
+
/** Blast-radius tier. */
|
|
917
|
+
severity: DestructiveSeverity;
|
|
918
|
+
/** Whether the data can be recovered afterwards. */
|
|
919
|
+
reversible: boolean;
|
|
920
|
+
/** How to recover, if reversible (e.g. "re-run `kb mind index --full`"). */
|
|
921
|
+
recovery?: string;
|
|
922
|
+
/** Quantified scope — how much, of what, how broad. */
|
|
923
|
+
blastRadius?: {
|
|
924
|
+
count?: number;
|
|
925
|
+
unit?: string;
|
|
926
|
+
scope?: string;
|
|
927
|
+
};
|
|
928
|
+
/** Flag that confirms the action (default `--yes`). */
|
|
929
|
+
confirmFlag?: string;
|
|
930
|
+
}
|
|
931
|
+
/** The machine-readable signal an agent receives when confirmation is missing. */
|
|
932
|
+
interface ConfirmationRequired {
|
|
933
|
+
ok: false;
|
|
934
|
+
confirmationRequired: true;
|
|
935
|
+
destructive: true;
|
|
936
|
+
irreversible: boolean;
|
|
937
|
+
severity: DestructiveSeverity;
|
|
938
|
+
action: string;
|
|
939
|
+
resource: string;
|
|
940
|
+
effect: string;
|
|
941
|
+
reversible: boolean;
|
|
942
|
+
blastRadius?: {
|
|
943
|
+
count?: number;
|
|
944
|
+
unit?: string;
|
|
945
|
+
scope?: string;
|
|
946
|
+
};
|
|
947
|
+
recovery?: string;
|
|
948
|
+
confirmWith: string;
|
|
949
|
+
message: string;
|
|
950
|
+
}
|
|
951
|
+
interface ConfirmContext {
|
|
952
|
+
ui?: {
|
|
953
|
+
json?: (data: unknown) => void;
|
|
954
|
+
warn?: (message: string, opts?: Record<string, unknown>) => void;
|
|
955
|
+
error?: (message: string, opts?: Record<string, unknown>) => void;
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Build the machine-readable signal an agent receives when confirmation is
|
|
960
|
+
* missing in json mode. Exported so a non-CLI surface (REST 409, MCP) can reuse
|
|
961
|
+
* the exact shape instead of re-deriving it.
|
|
962
|
+
*/
|
|
963
|
+
declare function buildConfirmationSignal(a: DestructiveAction): ConfirmationRequired;
|
|
964
|
+
/** Render the one-line warning — leads with the scary part (irreversibility + severity). */
|
|
965
|
+
declare function renderDestructiveMessage(a: DestructiveAction): string;
|
|
966
|
+
/**
|
|
967
|
+
* Gate a destructive command. Returns the command result to return immediately
|
|
968
|
+
* when NOT confirmed (in every mode — agents get the structured signal, not a
|
|
969
|
+
* silent execution), or `null` when confirmed so the caller proceeds.
|
|
970
|
+
*
|
|
971
|
+
* const blocked = confirmDestructive(ctx, { confirmed: flags.yes, isJson, action });
|
|
972
|
+
* if (blocked) return blocked;
|
|
973
|
+
*/
|
|
974
|
+
declare function confirmDestructive(ctx: ConfirmContext, opts: {
|
|
975
|
+
confirmed: boolean;
|
|
976
|
+
isJson?: boolean;
|
|
977
|
+
action: DestructiveAction;
|
|
978
|
+
}): {
|
|
979
|
+
exitCode: number;
|
|
980
|
+
} | null;
|
|
981
|
+
|
|
848
982
|
/**
|
|
849
983
|
* Modern CLI formatting utilities with side border design
|
|
850
984
|
* Provides minimalist, modern UI components for CLI output
|
|
851
985
|
*/
|
|
852
986
|
|
|
853
987
|
/**
|
|
854
|
-
* Side border box -
|
|
988
|
+
* Side border box - Clack-style design
|
|
855
989
|
*
|
|
856
990
|
* @example
|
|
857
991
|
* ```
|
|
858
|
-
*
|
|
992
|
+
* ◆ Command Name
|
|
859
993
|
* │
|
|
860
|
-
* │
|
|
994
|
+
* │ Section Header
|
|
861
995
|
* │ Key: value
|
|
862
996
|
* │
|
|
863
|
-
*
|
|
997
|
+
* └ ✓ Success 84ms
|
|
864
998
|
* ```
|
|
865
999
|
*/
|
|
866
1000
|
interface SideBorderBoxOptions {
|
|
@@ -869,6 +1003,7 @@ interface SideBorderBoxOptions {
|
|
|
869
1003
|
footer?: string;
|
|
870
1004
|
status?: 'success' | 'error' | 'warning' | 'info';
|
|
871
1005
|
timing?: number;
|
|
1006
|
+
summary?: Record<string, string | number | boolean>;
|
|
872
1007
|
}
|
|
873
1008
|
interface RichSectionItem {
|
|
874
1009
|
text: string;
|
|
@@ -899,6 +1034,36 @@ declare function metricsList(metrics: Record<string, string | number>): string[]
|
|
|
899
1034
|
* Format status line for footer
|
|
900
1035
|
*/
|
|
901
1036
|
declare function statusLine(status: 'success' | 'error' | 'warning' | 'info', timing?: number): string;
|
|
1037
|
+
/**
|
|
1038
|
+
* A single block in a chained output — a title + sections with optional footer on the last block.
|
|
1039
|
+
*/
|
|
1040
|
+
interface SideBorderChainItem {
|
|
1041
|
+
title: string;
|
|
1042
|
+
sections: SectionContent[];
|
|
1043
|
+
summary?: Record<string, string | number | boolean>;
|
|
1044
|
+
status?: 'success' | 'error' | 'warning' | 'info';
|
|
1045
|
+
timing?: number;
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* Render multiple side-border blocks as a continuous visual chain.
|
|
1049
|
+
*
|
|
1050
|
+
* Every block opens with `◆ Title` on the shared rail.
|
|
1051
|
+
* Only the last block gets `└ status timing`.
|
|
1052
|
+
*
|
|
1053
|
+
* @example
|
|
1054
|
+
* ```
|
|
1055
|
+
* ◆ workflow metrics
|
|
1056
|
+
* │
|
|
1057
|
+
* │ Failed to fetch metrics
|
|
1058
|
+
* │
|
|
1059
|
+
* ◆ Warning
|
|
1060
|
+
* │
|
|
1061
|
+
* │ Make sure daemon is running
|
|
1062
|
+
* │
|
|
1063
|
+
* └ ✗ 12ms
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
declare function sideBorderChain(items: SideBorderChainItem[]): string;
|
|
902
1067
|
/**
|
|
903
1068
|
* Convert an Error or raw string into clean display lines for sideBorderBox items.
|
|
904
1069
|
* Splits on newlines, removes blank lines, and caps at maxLines with a "… N more" hint.
|
|
@@ -1066,4 +1231,73 @@ declare function infoResult(title: string, data?: {
|
|
|
1066
1231
|
timing?: number;
|
|
1067
1232
|
}): CommandOutput;
|
|
1068
1233
|
|
|
1069
|
-
|
|
1234
|
+
/**
|
|
1235
|
+
* Structured log display for CLI output (watch/run/stream commands).
|
|
1236
|
+
* Not a spinner — for rendering log lines with level, timestamp, and message.
|
|
1237
|
+
*/
|
|
1238
|
+
type LogLevel = 'info' | 'warn' | 'error' | 'debug' | 'verbose';
|
|
1239
|
+
declare function logLine(level: LogLevel, message: string): string;
|
|
1240
|
+
declare function logGroup(title: string, lines: string[]): string;
|
|
1241
|
+
declare function printLog(level: LogLevel, message: string): void;
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Inline status badges for CLI output.
|
|
1245
|
+
*
|
|
1246
|
+
* @example
|
|
1247
|
+
* badge('ONLINE', 'success') → green [ONLINE]
|
|
1248
|
+
* badge('FAILED', 'error') → red [FAILED]
|
|
1249
|
+
* badge('PENDING', 'neutral') → muted [PENDING]
|
|
1250
|
+
*/
|
|
1251
|
+
type BadgeVariant = 'success' | 'error' | 'warning' | 'info' | 'neutral';
|
|
1252
|
+
declare function badge(label: string, variant?: BadgeVariant): string;
|
|
1253
|
+
declare function statusBadge(status: string): string;
|
|
1254
|
+
|
|
1255
|
+
/**
|
|
1256
|
+
* Multi-step task runner with visual progress.
|
|
1257
|
+
* Each task shows as ○ pending → spinner running → ● done / ✗ failed.
|
|
1258
|
+
*
|
|
1259
|
+
* @example
|
|
1260
|
+
* await runTasks([
|
|
1261
|
+
* { title: 'Install dependencies', run: async () => { ... } },
|
|
1262
|
+
* { title: 'Build', run: async () => { ... } },
|
|
1263
|
+
* ])
|
|
1264
|
+
*/
|
|
1265
|
+
interface Task {
|
|
1266
|
+
title: string;
|
|
1267
|
+
run: (updateTitle: (t: string) => void) => Promise<void>;
|
|
1268
|
+
}
|
|
1269
|
+
declare function runTasks(tasks: Task[]): Promise<void>;
|
|
1270
|
+
|
|
1271
|
+
/**
|
|
1272
|
+
* All interactive prompt methods of UIFacade.
|
|
1273
|
+
* Required (not optional) so TypeScript catches missing implementations
|
|
1274
|
+
* when UIFacade gains a new prompt method.
|
|
1275
|
+
*/
|
|
1276
|
+
interface UIPrompts {
|
|
1277
|
+
confirm(msg: string, opts?: {
|
|
1278
|
+
defaultValue?: boolean;
|
|
1279
|
+
}): Promise<boolean>;
|
|
1280
|
+
prompt(msg: string, opts?: {
|
|
1281
|
+
default?: string;
|
|
1282
|
+
mask?: boolean;
|
|
1283
|
+
}): Promise<string>;
|
|
1284
|
+
select<T>(msg: string, choices: SelectChoice<T>[]): Promise<T>;
|
|
1285
|
+
multiSelect<T>(msg: string, choices: MultiSelectChoice<T>[]): Promise<T[]>;
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Safe-return prompts for non-interactive contexts (subprocess, sandbox).
|
|
1289
|
+
* All methods return the most sensible default without any I/O.
|
|
1290
|
+
*/
|
|
1291
|
+
declare const NOOP_PROMPTS: UIPrompts;
|
|
1292
|
+
/**
|
|
1293
|
+
* Shared stdout UIFacade factory for subprocess/worker contexts.
|
|
1294
|
+
*
|
|
1295
|
+
* Both params are required so TypeScript catches any new UIFacade interactive
|
|
1296
|
+
* method at the call site rather than silently inheriting a noop default.
|
|
1297
|
+
*
|
|
1298
|
+
* Uses `satisfies UIFacade` on the object literal — TypeScript will error here
|
|
1299
|
+
* (not just at the return type) if any UIFacade method is missing.
|
|
1300
|
+
*/
|
|
1301
|
+
declare function createBaseStdoutUI(prompts: UIPrompts, log: UIFacade['log']): UIFacade;
|
|
1302
|
+
|
|
1303
|
+
export { type AnalyticsConfig, type ArtifactDisplayOptions, type ArtifactInfo, type BadgeVariant, type BaseFlagSpec, type BooleanFlagSpec, type CLIPackage, type CommandContext, type CommandDiscovery, type CommandExecutionResult, type CommandInfo, type CommandManifest, type CommandOutput, type CommandPresenter, type CommandRegistry, type CommandResult, type CommandResultParams, type CommandRunnerOptions, type CommandSuggestion, type ConfirmationRequired, type DestructiveAction, type DestructiveSeverity, DynamicCommandDiscovery, type EnvDefinition, type EnvSchema, type FlagDefinition, type FlagSpec, type FlagType, type FlagsDefinition, type FlagsSchema, type FormatTimestampOptions, type InferFlagsType, type KeyValueOptions, Loader, type LoaderOptions, type LogLevel, type ManifestLoader, type MultiCLIContext, MultiCLISuggestions, NOOP_PROMPTS, type NumberFlagSpec, type RetryOptions, type RichSectionItem, type RuntimeLike, type SafeKeyValueOptions, type SectionContent, type SectionItem, type SideBorderBoxOptions, type SideBorderChainItem, StaticCommandDiscovery, type StringFlagSpec, type TableColumn, type TableOptions, type Task, TimingTracker, type UIPrompts, accentLabel, badge, box, buildConfirmationSignal, bulletList, colors, confirmDestructive, createBaseStdoutUI, createCommandDiscovery, createCommandRegistry, createCommandRunner, createDetailedResult, createKBLabsCommandDiscovery, createProgressBar, createSimpleResult, createSpinner, defineEnv, defineFlags, discoverArtifacts, displayArtifacts, displayArtifactsCompact, displaySingleArtifact, errorResult, extractCommandGroups, extractCommandIds, findCommandById, findCommandsByGroup, formatCommandHelp, formatCommandOutput, formatCommandResult, formatError, formatKeyValueTable, formatRelativeTime, formatSize, formatTable, formatTimestamp, formatTiming, formatTimingBreakdown, generateDevlinkSuggestions, generateGroupSuggestions, generateQuickActions, getCommandInfo, getContextCwd, handleError, hasAnsi, headline, indent, infoResult, isCommandAvailable, isJsonMode, keyValue, logGroup, logLine, mergeFlags, metricsList, muted, pad, parseBoolean, parseEnvFromRuntime, parseFlagsFromInput, parseNumber, parseNumberFlag, parseString, printLog, renderDestructiveMessage, rethrowForRest, runTasks, safeColors, safeKeyValue, safeSymbols, section, sectionHeader, setJsonMode, showError, showLoading, showSuccess, sideBorderBox, sideBorderChain, statusBadge, statusLine, stripAnsi, successResult, supportsColor, symbols, table, toPosixPath, truncate, useLoader, validateSuggestions, validationError, warningResult, withRetry };
|