@kb-labs/shared 1.1.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/.cursorrules +32 -0
- package/.github/workflows/ci.yml +13 -0
- package/.github/workflows/deploy.yml +28 -0
- package/.github/workflows/docker-build.yml +25 -0
- package/.github/workflows/drift-check.yml +10 -0
- package/.github/workflows/profiles-validate.yml +16 -0
- package/.github/workflows/release.yml +8 -0
- package/.kb/devkit/agents/devkit-maintainer/context.globs +15 -0
- package/.kb/devkit/agents/devkit-maintainer/permissions.yml +17 -0
- package/.kb/devkit/agents/devkit-maintainer/prompt.md +28 -0
- package/.kb/devkit/agents/devkit-maintainer/runbook.md +31 -0
- package/.kb/devkit/agents/docs-crafter/prompt.md +24 -0
- package/.kb/devkit/agents/docs-crafter/runbook.md +18 -0
- package/.kb/devkit/agents/release-manager/context.globs +7 -0
- package/.kb/devkit/agents/release-manager/prompt.md +27 -0
- package/.kb/devkit/agents/release-manager/runbook.md +17 -0
- package/.kb/devkit/agents/test-generator/context.globs +7 -0
- package/.kb/devkit/agents/test-generator/prompt.md +27 -0
- package/.kb/devkit/agents/test-generator/runbook.md +18 -0
- package/.vscode/settings.json +23 -0
- package/CHANGELOG.md +33 -0
- package/CONTRIBUTING.md +117 -0
- package/LICENSE +21 -0
- package/README.md +306 -0
- package/docs/DECLARATIVE-FLAGS-AND-ENV.md +622 -0
- package/docs/DOCUMENTATION.md +70 -0
- package/docs/adr/0000-template.md +52 -0
- package/docs/adr/0001-architecture-and-repository-layout.md +31 -0
- package/docs/adr/0002-plugins-and-extensibility.md +44 -0
- package/docs/adr/0003-package-and-module-boundaries.md +35 -0
- package/docs/adr/0004-versioning-and-release-policy.md +36 -0
- package/docs/adr/0005-reactive-loader-pattern.md +179 -0
- package/docs/adr/0006-declarative-flags-and-env-systems.md +376 -0
- package/eslint.config.js +27 -0
- package/kb-labs.config.json +5 -0
- package/package.json +88 -0
- package/package.json.bin +25 -0
- package/package.json.lib +30 -0
- package/packages/shared-cli-ui/CHANGELOG.md +20 -0
- package/packages/shared-cli-ui/README.md +342 -0
- package/packages/shared-cli-ui/docs/ARCHITECTURE.md +105 -0
- package/packages/shared-cli-ui/eslint.config.js +27 -0
- package/packages/shared-cli-ui/package.json +72 -0
- package/packages/shared-cli-ui/src/__tests__/artifacts-display.spec.ts +89 -0
- package/packages/shared-cli-ui/src/__tests__/format.spec.ts +44 -0
- package/packages/shared-cli-ui/src/__tests__/loader-json-mode.test.ts +119 -0
- package/packages/shared-cli-ui/src/artifacts-display.ts +266 -0
- package/packages/shared-cli-ui/src/cli-auto-discovery.ts +120 -0
- package/packages/shared-cli-ui/src/colors.ts +142 -0
- package/packages/shared-cli-ui/src/command-discovery.ts +72 -0
- package/packages/shared-cli-ui/src/command-output.ts +153 -0
- package/packages/shared-cli-ui/src/command-result.ts +267 -0
- package/packages/shared-cli-ui/src/command-runner.ts +310 -0
- package/packages/shared-cli-ui/src/command-suggestions.ts +204 -0
- package/packages/shared-cli-ui/src/debug/components/output.ts +141 -0
- package/packages/shared-cli-ui/src/debug/components/trace.ts +101 -0
- package/packages/shared-cli-ui/src/debug/components/tree.ts +88 -0
- package/packages/shared-cli-ui/src/debug/formatters/ai.ts +17 -0
- package/packages/shared-cli-ui/src/debug/formatters/human.ts +98 -0
- package/packages/shared-cli-ui/src/debug/formatters/timeline.ts +94 -0
- package/packages/shared-cli-ui/src/debug/index.ts +56 -0
- package/packages/shared-cli-ui/src/debug/types.ts +57 -0
- package/packages/shared-cli-ui/src/debug/utilities.ts +203 -0
- package/packages/shared-cli-ui/src/dynamic-command-discovery.ts +131 -0
- package/packages/shared-cli-ui/src/format.ts +412 -0
- package/packages/shared-cli-ui/src/index.ts +34 -0
- package/packages/shared-cli-ui/src/loader.ts +196 -0
- package/packages/shared-cli-ui/src/manifest-parser.ts +151 -0
- package/packages/shared-cli-ui/src/modern-format.ts +271 -0
- package/packages/shared-cli-ui/src/multi-cli-suggestions.ts +159 -0
- package/packages/shared-cli-ui/src/table.ts +134 -0
- package/packages/shared-cli-ui/src/timing-tracker.ts +68 -0
- package/packages/shared-cli-ui/src/utils/context.ts +12 -0
- package/packages/shared-cli-ui/src/utils/env.ts +164 -0
- package/packages/shared-cli-ui/src/utils/flags.ts +269 -0
- package/packages/shared-cli-ui/src/utils/path.ts +8 -0
- package/packages/shared-cli-ui/tsconfig.build.json +15 -0
- package/packages/shared-cli-ui/tsconfig.json +9 -0
- package/packages/shared-cli-ui/tsup.config.ts +11 -0
- package/packages/shared-cli-ui/vitest.config.ts +15 -0
- package/packages/shared-command-kit/CHANGELOG.md +20 -0
- package/packages/shared-command-kit/LICENSE +22 -0
- package/packages/shared-command-kit/README.md +1030 -0
- package/packages/shared-command-kit/docs/HIGH-LEVEL-API.md +89 -0
- package/packages/shared-command-kit/docs/LOW-LEVEL-API.md +105 -0
- package/packages/shared-command-kit/docs/MIGRATION-GUIDE.md +135 -0
- package/packages/shared-command-kit/eslint.config.js +27 -0
- package/packages/shared-command-kit/eslint.config.ts +14 -0
- package/packages/shared-command-kit/package.json +76 -0
- package/packages/shared-command-kit/prettierrc.json +5 -0
- package/packages/shared-command-kit/src/__tests__/define-command.spec.ts +294 -0
- package/packages/shared-command-kit/src/__tests__/define-route.test.ts +285 -0
- package/packages/shared-command-kit/src/__tests__/define-system-command.spec.ts +508 -0
- package/packages/shared-command-kit/src/__tests__/define-webhook.test.ts +156 -0
- package/packages/shared-command-kit/src/__tests__/define-websocket.test.ts +316 -0
- package/packages/shared-command-kit/src/__tests__/errors.spec.ts +45 -0
- package/packages/shared-command-kit/src/__tests__/flags.spec.ts +353 -0
- package/packages/shared-command-kit/src/__tests__/platform-api.test.ts +135 -0
- package/packages/shared-command-kit/src/__tests__/plugin-context-v3.snapshot.spec.ts +240 -0
- package/packages/shared-command-kit/src/__tests__/ws-types.test.ts +359 -0
- package/packages/shared-command-kit/src/analytics/index.ts +6 -0
- package/packages/shared-command-kit/src/analytics/with-analytics.ts +195 -0
- package/packages/shared-command-kit/src/define-action.ts +100 -0
- package/packages/shared-command-kit/src/define-command.ts +113 -0
- package/packages/shared-command-kit/src/define-route.ts +113 -0
- package/packages/shared-command-kit/src/define-system-command.ts +362 -0
- package/packages/shared-command-kit/src/define-webhook.ts +115 -0
- package/packages/shared-command-kit/src/define-websocket.ts +308 -0
- package/packages/shared-command-kit/src/errors/factory.ts +282 -0
- package/packages/shared-command-kit/src/errors/format-validation.ts +144 -0
- package/packages/shared-command-kit/src/errors/format.ts +92 -0
- package/packages/shared-command-kit/src/errors/index.ts +9 -0
- package/packages/shared-command-kit/src/errors/types.ts +32 -0
- package/packages/shared-command-kit/src/flags/define.ts +92 -0
- package/packages/shared-command-kit/src/flags/index.ts +9 -0
- package/packages/shared-command-kit/src/flags/types.ts +153 -0
- package/packages/shared-command-kit/src/flags/validate.ts +358 -0
- package/packages/shared-command-kit/src/helpers/context.ts +8 -0
- package/packages/shared-command-kit/src/helpers/flags.ts +84 -0
- package/packages/shared-command-kit/src/helpers/index.ts +42 -0
- package/packages/shared-command-kit/src/helpers/patterns.ts +464 -0
- package/packages/shared-command-kit/src/helpers/platform.ts +335 -0
- package/packages/shared-command-kit/src/helpers/use-analytics.ts +95 -0
- package/packages/shared-command-kit/src/helpers/use-cache.ts +97 -0
- package/packages/shared-command-kit/src/helpers/use-config.ts +99 -0
- package/packages/shared-command-kit/src/helpers/use-embeddings.ts +49 -0
- package/packages/shared-command-kit/src/helpers/use-llm.ts +316 -0
- package/packages/shared-command-kit/src/helpers/use-logger.ts +77 -0
- package/packages/shared-command-kit/src/helpers/use-platform.ts +111 -0
- package/packages/shared-command-kit/src/helpers/use-resource-broker.ts +106 -0
- package/packages/shared-command-kit/src/helpers/use-storage.ts +71 -0
- package/packages/shared-command-kit/src/helpers/use-vector-store.ts +49 -0
- package/packages/shared-command-kit/src/helpers/validation.ts +398 -0
- package/packages/shared-command-kit/src/index.ts +410 -0
- package/packages/shared-command-kit/src/jobs.ts +132 -0
- package/packages/shared-command-kit/src/lifecycle/define-handlers.ts +366 -0
- package/packages/shared-command-kit/src/lifecycle/index.ts +6 -0
- package/packages/shared-command-kit/src/manifest.ts +127 -0
- package/packages/shared-command-kit/src/rest/define-handler.ts +187 -0
- package/packages/shared-command-kit/src/rest/index.ts +11 -0
- package/packages/shared-command-kit/src/studio/index.ts +12 -0
- package/packages/shared-command-kit/src/validation/index.ts +6 -0
- package/packages/shared-command-kit/src/validation/schema-builders.ts +409 -0
- package/packages/shared-command-kit/src/ws-types.ts +106 -0
- package/packages/shared-command-kit/tsconfig.build.json +15 -0
- package/packages/shared-command-kit/tsconfig.json +9 -0
- package/packages/shared-command-kit/tsup.config.ts +30 -0
- package/packages/shared-command-kit/vitest.config.ts +4 -0
- package/packages/shared-http/package.json +67 -0
- package/packages/shared-http/src/__tests__/log-correlation.test.ts +81 -0
- package/packages/shared-http/src/__tests__/operation-metrics-tracker.test.ts +55 -0
- package/packages/shared-http/src/http-observability-collector.ts +363 -0
- package/packages/shared-http/src/index.ts +36 -0
- package/packages/shared-http/src/log-correlation.ts +89 -0
- package/packages/shared-http/src/operation-metrics-tracker.ts +107 -0
- package/packages/shared-http/src/register-openapi.ts +108 -0
- package/packages/shared-http/src/resolve-schema-ref.ts +75 -0
- package/packages/shared-http/src/schemas.ts +29 -0
- package/packages/shared-http/src/service-observability.ts +63 -0
- package/packages/shared-http/tsconfig.build.json +15 -0
- package/packages/shared-http/tsconfig.json +9 -0
- package/packages/shared-http/tsup.config.ts +23 -0
- package/packages/shared-http/vitest.config.ts +13 -0
- package/packages/shared-perm-presets/CHANGELOG.md +20 -0
- package/packages/shared-perm-presets/README.md +78 -0
- package/packages/shared-perm-presets/eslint.config.js +27 -0
- package/packages/shared-perm-presets/package.json +45 -0
- package/packages/shared-perm-presets/src/__tests__/combine.test.ts +403 -0
- package/packages/shared-perm-presets/src/__tests__/presets.test.ts +205 -0
- package/packages/shared-perm-presets/src/combine.ts +278 -0
- package/packages/shared-perm-presets/src/index.ts +18 -0
- package/packages/shared-perm-presets/src/presets/ci-environment.ts +34 -0
- package/packages/shared-perm-presets/src/presets/full-env.ts +16 -0
- package/packages/shared-perm-presets/src/presets/git-workflow.ts +40 -0
- package/packages/shared-perm-presets/src/presets/index.ts +8 -0
- package/packages/shared-perm-presets/src/presets/kb-platform.ts +30 -0
- package/packages/shared-perm-presets/src/presets/llm-access.ts +29 -0
- package/packages/shared-perm-presets/src/presets/minimal.ts +21 -0
- package/packages/shared-perm-presets/src/presets/npm-publish.ts +48 -0
- package/packages/shared-perm-presets/src/presets/vector-store.ts +40 -0
- package/packages/shared-perm-presets/src/types.ts +192 -0
- package/packages/shared-perm-presets/tsconfig.build.json +15 -0
- package/packages/shared-perm-presets/tsconfig.json +9 -0
- package/packages/shared-perm-presets/tsup.config.ts +8 -0
- package/packages/shared-perm-presets/vitest.config.ts +9 -0
- package/packages/shared-testing/CHANGELOG.md +20 -0
- package/packages/shared-testing/README.md +430 -0
- package/packages/shared-testing/package.json +51 -0
- package/packages/shared-testing/src/__tests__/create-test-context.test.ts +199 -0
- package/packages/shared-testing/src/__tests__/mock-cache.test.ts +174 -0
- package/packages/shared-testing/src/__tests__/mock-llm.test.ts +212 -0
- package/packages/shared-testing/src/__tests__/setup-platform.test.ts +90 -0
- package/packages/shared-testing/src/__tests__/test-command.test.ts +557 -0
- package/packages/shared-testing/src/create-test-context.ts +550 -0
- package/packages/shared-testing/src/index.ts +77 -0
- package/packages/shared-testing/src/mock-cache.ts +179 -0
- package/packages/shared-testing/src/mock-llm.ts +319 -0
- package/packages/shared-testing/src/mock-logger.ts +97 -0
- package/packages/shared-testing/src/mock-storage.ts +108 -0
- package/packages/shared-testing/src/setup-platform.ts +101 -0
- package/packages/shared-testing/src/test-command.ts +288 -0
- package/packages/shared-testing/tsconfig.build.json +15 -0
- package/packages/shared-testing/tsconfig.json +9 -0
- package/packages/shared-testing/tsup.config.ts +20 -0
- package/packages/shared-testing/vitest.config.ts +3 -0
- package/packages/shared-tool-kit/CHANGELOG.md +20 -0
- package/packages/shared-tool-kit/package.json +47 -0
- package/packages/shared-tool-kit/src/__tests__/factory.test.ts +103 -0
- package/packages/shared-tool-kit/src/__tests__/mock-tool.test.ts +95 -0
- package/packages/shared-tool-kit/src/factory.ts +126 -0
- package/packages/shared-tool-kit/src/index.ts +32 -0
- package/packages/shared-tool-kit/src/testing/index.ts +84 -0
- package/packages/shared-tool-kit/tsconfig.build.json +15 -0
- package/packages/shared-tool-kit/tsconfig.json +9 -0
- package/packages/shared-tool-kit/tsup.config.ts +21 -0
- package/pnpm-workspace.yaml +11070 -0
- package/prettierrc.json +1 -0
- package/scripts/devkit-sync.mjs +37 -0
- package/scripts/hooks/post-push +9 -0
- package/scripts/hooks/pre-commit +9 -0
- package/scripts/hooks/pre-push +9 -0
- package/tsconfig.base.json +9 -0
- package/tsconfig.build.json +15 -0
- package/tsconfig.json +9 -0
- package/tsconfig.paths.json +50 -0
- package/tsconfig.tools.json +18 -0
- package/tsup.config.bin.ts +34 -0
- package/tsup.config.cli.ts +41 -0
- package/tsup.config.dual.ts +46 -0
- package/tsup.config.ts +36 -0
- package/tsup.external.json +104 -0
- package/vitest.config.ts +48 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command discovery utilities for CLI systems
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface CommandInfo {
|
|
6
|
+
id: string;
|
|
7
|
+
group: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
available: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Discover available commands from CLI manifest or registry
|
|
15
|
+
* This is a generic interface that can be implemented by different CLI systems
|
|
16
|
+
*/
|
|
17
|
+
export interface CommandDiscovery {
|
|
18
|
+
/**
|
|
19
|
+
* Get all available commands
|
|
20
|
+
*/
|
|
21
|
+
getAvailableCommands(): Promise<string[]>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get command info by ID
|
|
25
|
+
*/
|
|
26
|
+
getCommandInfo(commandId: string): Promise<CommandInfo | null>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Check if a command is available
|
|
30
|
+
*/
|
|
31
|
+
isCommandAvailable(commandId: string): Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Simple command discovery that works with a predefined list
|
|
36
|
+
* Can be extended to work with actual CLI registries
|
|
37
|
+
*/
|
|
38
|
+
export class StaticCommandDiscovery implements CommandDiscovery {
|
|
39
|
+
constructor(private commands: string[]) {}
|
|
40
|
+
|
|
41
|
+
async getAvailableCommands(): Promise<string[]> {
|
|
42
|
+
return [...this.commands];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async getCommandInfo(commandId: string): Promise<CommandInfo | null> {
|
|
46
|
+
if (!this.commands.includes(commandId)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const [group, name] = commandId.split(':');
|
|
51
|
+
return {
|
|
52
|
+
id: commandId,
|
|
53
|
+
group: group || 'unknown',
|
|
54
|
+
name: name || commandId,
|
|
55
|
+
description: `Execute ${commandId}`,
|
|
56
|
+
available: true
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async isCommandAvailable(commandId: string): Promise<boolean> {
|
|
61
|
+
return this.commands.includes(commandId);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Create a command discovery instance from a command list
|
|
69
|
+
*/
|
|
70
|
+
export function createCommandDiscovery(commands: string[]): CommandDiscovery {
|
|
71
|
+
return new StaticCommandDiscovery(commands);
|
|
72
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command output formatting utilities
|
|
3
|
+
* Provides consistent formatting for CLI command results
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { box, keyValue } from './format';
|
|
7
|
+
import { safeColors } from './colors';
|
|
8
|
+
|
|
9
|
+
export interface CommandResult {
|
|
10
|
+
title: string;
|
|
11
|
+
summary: Record<string, string | number>;
|
|
12
|
+
timing?: number | Record<string, number>;
|
|
13
|
+
diagnostics?: string[];
|
|
14
|
+
warnings?: string[];
|
|
15
|
+
errors?: string[];
|
|
16
|
+
suggestions?: string[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Format timing in milliseconds to human-readable string
|
|
21
|
+
*/
|
|
22
|
+
export function formatTiming(ms: number): string {
|
|
23
|
+
if (ms < 1000) {
|
|
24
|
+
return `${ms}ms`;
|
|
25
|
+
} else if (ms < 60000) {
|
|
26
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
27
|
+
} else {
|
|
28
|
+
const minutes = Math.floor(ms / 60000);
|
|
29
|
+
const seconds = ((ms % 60000) / 1000).toFixed(1);
|
|
30
|
+
return `${minutes}m ${seconds}s`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Format timing breakdown as array of strings
|
|
36
|
+
*/
|
|
37
|
+
export function formatTimingBreakdown(timings: Record<string, number>): string[] {
|
|
38
|
+
const lines: string[] = [];
|
|
39
|
+
|
|
40
|
+
// Sort timings by value (descending) for better readability
|
|
41
|
+
const sortedEntries = Object.entries(timings)
|
|
42
|
+
.filter(([key]) => key !== 'total')
|
|
43
|
+
.sort(([, a], [, b]) => b - a);
|
|
44
|
+
|
|
45
|
+
for (const [name, ms] of sortedEntries) {
|
|
46
|
+
const formattedName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
47
|
+
lines.push(`${formattedName}: ${formatTiming(ms)}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Always show total at the end
|
|
51
|
+
if (timings.total !== undefined) {
|
|
52
|
+
lines.push(`Total: ${formatTiming(timings.total)}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return lines;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Format complete command output with box, summary, timing, and additional info
|
|
60
|
+
*/
|
|
61
|
+
export function formatCommandOutput(result: CommandResult): string {
|
|
62
|
+
const sections: string[] = [];
|
|
63
|
+
|
|
64
|
+
// Add summary section
|
|
65
|
+
const summaryLines = keyValue(result.summary);
|
|
66
|
+
sections.push(...summaryLines);
|
|
67
|
+
|
|
68
|
+
// Add timing section
|
|
69
|
+
if (result.timing !== undefined) {
|
|
70
|
+
sections.push('');
|
|
71
|
+
|
|
72
|
+
if (typeof result.timing === 'number') {
|
|
73
|
+
sections.push(`Time: ${formatTiming(result.timing)}`);
|
|
74
|
+
} else {
|
|
75
|
+
const timingLines = formatTimingBreakdown(result.timing);
|
|
76
|
+
sections.push(...timingLines);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Add warnings section
|
|
81
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
82
|
+
sections.push('');
|
|
83
|
+
sections.push(safeColors.warning('Warnings:'));
|
|
84
|
+
result.warnings.forEach(warning =>
|
|
85
|
+
sections.push(` ${safeColors.dim('•')} ${warning}`)
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Add errors section
|
|
90
|
+
if (result.errors && result.errors.length > 0) {
|
|
91
|
+
sections.push('');
|
|
92
|
+
sections.push(safeColors.error('Errors:'));
|
|
93
|
+
result.errors.forEach(error =>
|
|
94
|
+
sections.push(` ${safeColors.dim('•')} ${error}`)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Add diagnostics section
|
|
99
|
+
if (result.diagnostics && result.diagnostics.length > 0) {
|
|
100
|
+
sections.push('');
|
|
101
|
+
sections.push(safeColors.info('Diagnostics:'));
|
|
102
|
+
result.diagnostics.forEach(diagnostic =>
|
|
103
|
+
sections.push(` ${safeColors.dim('•')} ${diagnostic}`)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Add suggestions section
|
|
108
|
+
if (result.suggestions && result.suggestions.length > 0) {
|
|
109
|
+
sections.push('');
|
|
110
|
+
sections.push(safeColors.info('Suggestions:'));
|
|
111
|
+
result.suggestions.forEach(suggestion =>
|
|
112
|
+
sections.push(` ${safeColors.dim('•')} ${suggestion}`)
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return box(result.title, sections);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Create a simple command result with just title, summary, and timing
|
|
121
|
+
*/
|
|
122
|
+
export function createSimpleResult(
|
|
123
|
+
title: string,
|
|
124
|
+
summary: Record<string, string | number>,
|
|
125
|
+
timing?: number
|
|
126
|
+
): CommandResult {
|
|
127
|
+
return {
|
|
128
|
+
title,
|
|
129
|
+
summary,
|
|
130
|
+
timing,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Create a detailed command result with all optional fields
|
|
136
|
+
*/
|
|
137
|
+
export function createDetailedResult(
|
|
138
|
+
title: string,
|
|
139
|
+
summary: Record<string, string | number>,
|
|
140
|
+
options: {
|
|
141
|
+
timing?: number | Record<string, number>;
|
|
142
|
+
diagnostics?: string[];
|
|
143
|
+
warnings?: string[];
|
|
144
|
+
errors?: string[];
|
|
145
|
+
suggestions?: string[];
|
|
146
|
+
} = {}
|
|
147
|
+
): CommandResult {
|
|
148
|
+
return {
|
|
149
|
+
title,
|
|
150
|
+
summary,
|
|
151
|
+
...options,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command result formatting utilities
|
|
3
|
+
* Provides high and low-level APIs for formatting command output
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
sideBorderBox,
|
|
8
|
+
metricsList,
|
|
9
|
+
bulletList,
|
|
10
|
+
type SectionContent,
|
|
11
|
+
} from './modern-format';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Command output with human and machine-readable formats
|
|
15
|
+
* Extends CommandResult contract from command-kit
|
|
16
|
+
*/
|
|
17
|
+
export interface CommandOutput {
|
|
18
|
+
/** Whether command executed successfully - required by CommandResult contract */
|
|
19
|
+
ok: boolean;
|
|
20
|
+
/** Execution status */
|
|
21
|
+
status?: 'success' | 'error' | 'warning' | 'info' | 'failed' | 'cancelled' | 'skipped';
|
|
22
|
+
/** Human-readable output (side border format) */
|
|
23
|
+
human: string;
|
|
24
|
+
/** Machine-readable output (JSON) */
|
|
25
|
+
json: object;
|
|
26
|
+
/** Agent-specific output (optional, for --agent flag) */
|
|
27
|
+
agent?: object;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Parameters for formatting command results
|
|
32
|
+
*/
|
|
33
|
+
export interface CommandResultParams {
|
|
34
|
+
title: string;
|
|
35
|
+
summary?: Record<string, string | number>;
|
|
36
|
+
details?: Array<{ section: string; items: string[] }>;
|
|
37
|
+
warnings?: string[];
|
|
38
|
+
errors?: string[];
|
|
39
|
+
timing?: number;
|
|
40
|
+
status: 'success' | 'error' | 'warning' | 'info';
|
|
41
|
+
/** Custom JSON data (optional) */
|
|
42
|
+
jsonData?: object;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Low-level: Format command result with full control
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const output = formatCommandResult({
|
|
51
|
+
* title: 'System Diagnostics',
|
|
52
|
+
* summary: { 'Total Checks': 4, 'OK': 3 },
|
|
53
|
+
* details: [
|
|
54
|
+
* { section: 'Environment', items: ['Node 20.11.0'] }
|
|
55
|
+
* ],
|
|
56
|
+
* warnings: ['Cache is old'],
|
|
57
|
+
* timing: 150,
|
|
58
|
+
* status: 'success',
|
|
59
|
+
* });
|
|
60
|
+
*
|
|
61
|
+
* console.log(output.human); // Pretty CLI output
|
|
62
|
+
* console.log(output.json); // JSON for --json flag
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function formatCommandResult(params: CommandResultParams): CommandOutput {
|
|
66
|
+
const {
|
|
67
|
+
title,
|
|
68
|
+
summary,
|
|
69
|
+
details = [],
|
|
70
|
+
warnings = [],
|
|
71
|
+
errors = [],
|
|
72
|
+
timing,
|
|
73
|
+
status,
|
|
74
|
+
jsonData,
|
|
75
|
+
} = params;
|
|
76
|
+
|
|
77
|
+
// Build sections for human output
|
|
78
|
+
const sections: SectionContent[] = [];
|
|
79
|
+
|
|
80
|
+
// Summary section
|
|
81
|
+
if (summary && Object.keys(summary).length > 0) {
|
|
82
|
+
sections.push({
|
|
83
|
+
header: 'Summary',
|
|
84
|
+
items: metricsList(summary),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Details sections
|
|
89
|
+
for (const detail of details) {
|
|
90
|
+
sections.push({
|
|
91
|
+
header: detail.section,
|
|
92
|
+
items: detail.items,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Warnings section
|
|
97
|
+
if (warnings.length > 0) {
|
|
98
|
+
sections.push({
|
|
99
|
+
header: '⚠ Warnings',
|
|
100
|
+
items: bulletList(warnings),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Errors section
|
|
105
|
+
if (errors.length > 0) {
|
|
106
|
+
sections.push({
|
|
107
|
+
header: '✗ Errors',
|
|
108
|
+
items: bulletList(errors),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Generate human-readable output
|
|
113
|
+
const human = sideBorderBox({
|
|
114
|
+
title,
|
|
115
|
+
sections,
|
|
116
|
+
status,
|
|
117
|
+
timing,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Generate JSON output
|
|
121
|
+
const json: any = {
|
|
122
|
+
ok: status === 'success',
|
|
123
|
+
status,
|
|
124
|
+
...(summary && { summary }),
|
|
125
|
+
...(details.length > 0 && {
|
|
126
|
+
details: details.reduce((acc, d) => {
|
|
127
|
+
acc[d.section] = d.items;
|
|
128
|
+
return acc;
|
|
129
|
+
}, {} as Record<string, string[]>),
|
|
130
|
+
}),
|
|
131
|
+
...(warnings.length > 0 && { warnings }),
|
|
132
|
+
...(errors.length > 0 && { errors }),
|
|
133
|
+
...(timing !== undefined && { timingMs: timing }),
|
|
134
|
+
...(jsonData && { data: jsonData }),
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
ok: status === 'success',
|
|
139
|
+
status,
|
|
140
|
+
human,
|
|
141
|
+
json
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* High-level: Quick success result
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* return successResult('Version Info', {
|
|
151
|
+
* summary: { 'CLI Version': '0.1.0' },
|
|
152
|
+
* timing: 5,
|
|
153
|
+
* });
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
export function successResult(
|
|
157
|
+
title: string,
|
|
158
|
+
data?: {
|
|
159
|
+
summary?: Record<string, string | number>;
|
|
160
|
+
details?: Array<{ section: string; items: string[] }>;
|
|
161
|
+
timing?: number;
|
|
162
|
+
json?: object;
|
|
163
|
+
}
|
|
164
|
+
): CommandOutput {
|
|
165
|
+
return formatCommandResult({
|
|
166
|
+
title,
|
|
167
|
+
summary: data?.summary,
|
|
168
|
+
details: data?.details,
|
|
169
|
+
timing: data?.timing,
|
|
170
|
+
status: 'success',
|
|
171
|
+
jsonData: data?.json,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* High-level: Quick error result
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* return errorResult('Command Failed', new Error('Something went wrong'), {
|
|
181
|
+
* timing: 100,
|
|
182
|
+
* suggestions: ['Try running with --debug flag'],
|
|
183
|
+
* });
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
export function errorResult(
|
|
187
|
+
title: string,
|
|
188
|
+
error: Error | string,
|
|
189
|
+
options?: {
|
|
190
|
+
timing?: number;
|
|
191
|
+
suggestions?: string[];
|
|
192
|
+
}
|
|
193
|
+
): CommandOutput {
|
|
194
|
+
const errorMessage = error instanceof Error ? error.message : error;
|
|
195
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
196
|
+
|
|
197
|
+
return formatCommandResult({
|
|
198
|
+
title,
|
|
199
|
+
errors: [errorMessage],
|
|
200
|
+
details: options?.suggestions
|
|
201
|
+
? [{ section: 'Suggestions', items: bulletList(options.suggestions) }]
|
|
202
|
+
: [],
|
|
203
|
+
timing: options?.timing,
|
|
204
|
+
status: 'error',
|
|
205
|
+
jsonData: {
|
|
206
|
+
error: errorMessage,
|
|
207
|
+
...(errorStack && { stack: errorStack }),
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* High-level: Quick warning result
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* return warningResult('Configuration Updated', ['Deprecated option used'], {
|
|
218
|
+
* summary: { 'Files Updated': 3 },
|
|
219
|
+
* timing: 50,
|
|
220
|
+
* });
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export function warningResult(
|
|
224
|
+
title: string,
|
|
225
|
+
warnings: string[],
|
|
226
|
+
options?: {
|
|
227
|
+
summary?: Record<string, string | number>;
|
|
228
|
+
timing?: number;
|
|
229
|
+
}
|
|
230
|
+
): CommandOutput {
|
|
231
|
+
return formatCommandResult({
|
|
232
|
+
title,
|
|
233
|
+
warnings,
|
|
234
|
+
summary: options?.summary,
|
|
235
|
+
timing: options?.timing,
|
|
236
|
+
status: 'warning',
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* High-level: Info result
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* return infoResult('Help Information', {
|
|
246
|
+
* details: [
|
|
247
|
+
* { section: 'Usage', items: ['kb command --flag'] }
|
|
248
|
+
* ],
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
export function infoResult(
|
|
253
|
+
title: string,
|
|
254
|
+
data?: {
|
|
255
|
+
summary?: Record<string, string | number>;
|
|
256
|
+
details?: Array<{ section: string; items: string[] }>;
|
|
257
|
+
timing?: number;
|
|
258
|
+
}
|
|
259
|
+
): CommandOutput {
|
|
260
|
+
return formatCommandResult({
|
|
261
|
+
title,
|
|
262
|
+
summary: data?.summary,
|
|
263
|
+
details: data?.details,
|
|
264
|
+
timing: data?.timing,
|
|
265
|
+
status: 'info',
|
|
266
|
+
});
|
|
267
|
+
}
|