@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.
Files changed (232) hide show
  1. package/.cursorrules +32 -0
  2. package/.github/workflows/ci.yml +13 -0
  3. package/.github/workflows/deploy.yml +28 -0
  4. package/.github/workflows/docker-build.yml +25 -0
  5. package/.github/workflows/drift-check.yml +10 -0
  6. package/.github/workflows/profiles-validate.yml +16 -0
  7. package/.github/workflows/release.yml +8 -0
  8. package/.kb/devkit/agents/devkit-maintainer/context.globs +15 -0
  9. package/.kb/devkit/agents/devkit-maintainer/permissions.yml +17 -0
  10. package/.kb/devkit/agents/devkit-maintainer/prompt.md +28 -0
  11. package/.kb/devkit/agents/devkit-maintainer/runbook.md +31 -0
  12. package/.kb/devkit/agents/docs-crafter/prompt.md +24 -0
  13. package/.kb/devkit/agents/docs-crafter/runbook.md +18 -0
  14. package/.kb/devkit/agents/release-manager/context.globs +7 -0
  15. package/.kb/devkit/agents/release-manager/prompt.md +27 -0
  16. package/.kb/devkit/agents/release-manager/runbook.md +17 -0
  17. package/.kb/devkit/agents/test-generator/context.globs +7 -0
  18. package/.kb/devkit/agents/test-generator/prompt.md +27 -0
  19. package/.kb/devkit/agents/test-generator/runbook.md +18 -0
  20. package/.vscode/settings.json +23 -0
  21. package/CHANGELOG.md +33 -0
  22. package/CONTRIBUTING.md +117 -0
  23. package/LICENSE +21 -0
  24. package/README.md +306 -0
  25. package/docs/DECLARATIVE-FLAGS-AND-ENV.md +622 -0
  26. package/docs/DOCUMENTATION.md +70 -0
  27. package/docs/adr/0000-template.md +52 -0
  28. package/docs/adr/0001-architecture-and-repository-layout.md +31 -0
  29. package/docs/adr/0002-plugins-and-extensibility.md +44 -0
  30. package/docs/adr/0003-package-and-module-boundaries.md +35 -0
  31. package/docs/adr/0004-versioning-and-release-policy.md +36 -0
  32. package/docs/adr/0005-reactive-loader-pattern.md +179 -0
  33. package/docs/adr/0006-declarative-flags-and-env-systems.md +376 -0
  34. package/eslint.config.js +27 -0
  35. package/kb-labs.config.json +5 -0
  36. package/package.json +88 -0
  37. package/package.json.bin +25 -0
  38. package/package.json.lib +30 -0
  39. package/packages/shared-cli-ui/CHANGELOG.md +20 -0
  40. package/packages/shared-cli-ui/README.md +342 -0
  41. package/packages/shared-cli-ui/docs/ARCHITECTURE.md +105 -0
  42. package/packages/shared-cli-ui/eslint.config.js +27 -0
  43. package/packages/shared-cli-ui/package.json +72 -0
  44. package/packages/shared-cli-ui/src/__tests__/artifacts-display.spec.ts +89 -0
  45. package/packages/shared-cli-ui/src/__tests__/format.spec.ts +44 -0
  46. package/packages/shared-cli-ui/src/__tests__/loader-json-mode.test.ts +119 -0
  47. package/packages/shared-cli-ui/src/artifacts-display.ts +266 -0
  48. package/packages/shared-cli-ui/src/cli-auto-discovery.ts +120 -0
  49. package/packages/shared-cli-ui/src/colors.ts +142 -0
  50. package/packages/shared-cli-ui/src/command-discovery.ts +72 -0
  51. package/packages/shared-cli-ui/src/command-output.ts +153 -0
  52. package/packages/shared-cli-ui/src/command-result.ts +267 -0
  53. package/packages/shared-cli-ui/src/command-runner.ts +310 -0
  54. package/packages/shared-cli-ui/src/command-suggestions.ts +204 -0
  55. package/packages/shared-cli-ui/src/debug/components/output.ts +141 -0
  56. package/packages/shared-cli-ui/src/debug/components/trace.ts +101 -0
  57. package/packages/shared-cli-ui/src/debug/components/tree.ts +88 -0
  58. package/packages/shared-cli-ui/src/debug/formatters/ai.ts +17 -0
  59. package/packages/shared-cli-ui/src/debug/formatters/human.ts +98 -0
  60. package/packages/shared-cli-ui/src/debug/formatters/timeline.ts +94 -0
  61. package/packages/shared-cli-ui/src/debug/index.ts +56 -0
  62. package/packages/shared-cli-ui/src/debug/types.ts +57 -0
  63. package/packages/shared-cli-ui/src/debug/utilities.ts +203 -0
  64. package/packages/shared-cli-ui/src/dynamic-command-discovery.ts +131 -0
  65. package/packages/shared-cli-ui/src/format.ts +412 -0
  66. package/packages/shared-cli-ui/src/index.ts +34 -0
  67. package/packages/shared-cli-ui/src/loader.ts +196 -0
  68. package/packages/shared-cli-ui/src/manifest-parser.ts +151 -0
  69. package/packages/shared-cli-ui/src/modern-format.ts +271 -0
  70. package/packages/shared-cli-ui/src/multi-cli-suggestions.ts +159 -0
  71. package/packages/shared-cli-ui/src/table.ts +134 -0
  72. package/packages/shared-cli-ui/src/timing-tracker.ts +68 -0
  73. package/packages/shared-cli-ui/src/utils/context.ts +12 -0
  74. package/packages/shared-cli-ui/src/utils/env.ts +164 -0
  75. package/packages/shared-cli-ui/src/utils/flags.ts +269 -0
  76. package/packages/shared-cli-ui/src/utils/path.ts +8 -0
  77. package/packages/shared-cli-ui/tsconfig.build.json +15 -0
  78. package/packages/shared-cli-ui/tsconfig.json +9 -0
  79. package/packages/shared-cli-ui/tsup.config.ts +11 -0
  80. package/packages/shared-cli-ui/vitest.config.ts +15 -0
  81. package/packages/shared-command-kit/CHANGELOG.md +20 -0
  82. package/packages/shared-command-kit/LICENSE +22 -0
  83. package/packages/shared-command-kit/README.md +1030 -0
  84. package/packages/shared-command-kit/docs/HIGH-LEVEL-API.md +89 -0
  85. package/packages/shared-command-kit/docs/LOW-LEVEL-API.md +105 -0
  86. package/packages/shared-command-kit/docs/MIGRATION-GUIDE.md +135 -0
  87. package/packages/shared-command-kit/eslint.config.js +27 -0
  88. package/packages/shared-command-kit/eslint.config.ts +14 -0
  89. package/packages/shared-command-kit/package.json +76 -0
  90. package/packages/shared-command-kit/prettierrc.json +5 -0
  91. package/packages/shared-command-kit/src/__tests__/define-command.spec.ts +294 -0
  92. package/packages/shared-command-kit/src/__tests__/define-route.test.ts +285 -0
  93. package/packages/shared-command-kit/src/__tests__/define-system-command.spec.ts +508 -0
  94. package/packages/shared-command-kit/src/__tests__/define-webhook.test.ts +156 -0
  95. package/packages/shared-command-kit/src/__tests__/define-websocket.test.ts +316 -0
  96. package/packages/shared-command-kit/src/__tests__/errors.spec.ts +45 -0
  97. package/packages/shared-command-kit/src/__tests__/flags.spec.ts +353 -0
  98. package/packages/shared-command-kit/src/__tests__/platform-api.test.ts +135 -0
  99. package/packages/shared-command-kit/src/__tests__/plugin-context-v3.snapshot.spec.ts +240 -0
  100. package/packages/shared-command-kit/src/__tests__/ws-types.test.ts +359 -0
  101. package/packages/shared-command-kit/src/analytics/index.ts +6 -0
  102. package/packages/shared-command-kit/src/analytics/with-analytics.ts +195 -0
  103. package/packages/shared-command-kit/src/define-action.ts +100 -0
  104. package/packages/shared-command-kit/src/define-command.ts +113 -0
  105. package/packages/shared-command-kit/src/define-route.ts +113 -0
  106. package/packages/shared-command-kit/src/define-system-command.ts +362 -0
  107. package/packages/shared-command-kit/src/define-webhook.ts +115 -0
  108. package/packages/shared-command-kit/src/define-websocket.ts +308 -0
  109. package/packages/shared-command-kit/src/errors/factory.ts +282 -0
  110. package/packages/shared-command-kit/src/errors/format-validation.ts +144 -0
  111. package/packages/shared-command-kit/src/errors/format.ts +92 -0
  112. package/packages/shared-command-kit/src/errors/index.ts +9 -0
  113. package/packages/shared-command-kit/src/errors/types.ts +32 -0
  114. package/packages/shared-command-kit/src/flags/define.ts +92 -0
  115. package/packages/shared-command-kit/src/flags/index.ts +9 -0
  116. package/packages/shared-command-kit/src/flags/types.ts +153 -0
  117. package/packages/shared-command-kit/src/flags/validate.ts +358 -0
  118. package/packages/shared-command-kit/src/helpers/context.ts +8 -0
  119. package/packages/shared-command-kit/src/helpers/flags.ts +84 -0
  120. package/packages/shared-command-kit/src/helpers/index.ts +42 -0
  121. package/packages/shared-command-kit/src/helpers/patterns.ts +464 -0
  122. package/packages/shared-command-kit/src/helpers/platform.ts +335 -0
  123. package/packages/shared-command-kit/src/helpers/use-analytics.ts +95 -0
  124. package/packages/shared-command-kit/src/helpers/use-cache.ts +97 -0
  125. package/packages/shared-command-kit/src/helpers/use-config.ts +99 -0
  126. package/packages/shared-command-kit/src/helpers/use-embeddings.ts +49 -0
  127. package/packages/shared-command-kit/src/helpers/use-llm.ts +316 -0
  128. package/packages/shared-command-kit/src/helpers/use-logger.ts +77 -0
  129. package/packages/shared-command-kit/src/helpers/use-platform.ts +111 -0
  130. package/packages/shared-command-kit/src/helpers/use-resource-broker.ts +106 -0
  131. package/packages/shared-command-kit/src/helpers/use-storage.ts +71 -0
  132. package/packages/shared-command-kit/src/helpers/use-vector-store.ts +49 -0
  133. package/packages/shared-command-kit/src/helpers/validation.ts +398 -0
  134. package/packages/shared-command-kit/src/index.ts +410 -0
  135. package/packages/shared-command-kit/src/jobs.ts +132 -0
  136. package/packages/shared-command-kit/src/lifecycle/define-handlers.ts +366 -0
  137. package/packages/shared-command-kit/src/lifecycle/index.ts +6 -0
  138. package/packages/shared-command-kit/src/manifest.ts +127 -0
  139. package/packages/shared-command-kit/src/rest/define-handler.ts +187 -0
  140. package/packages/shared-command-kit/src/rest/index.ts +11 -0
  141. package/packages/shared-command-kit/src/studio/index.ts +12 -0
  142. package/packages/shared-command-kit/src/validation/index.ts +6 -0
  143. package/packages/shared-command-kit/src/validation/schema-builders.ts +409 -0
  144. package/packages/shared-command-kit/src/ws-types.ts +106 -0
  145. package/packages/shared-command-kit/tsconfig.build.json +15 -0
  146. package/packages/shared-command-kit/tsconfig.json +9 -0
  147. package/packages/shared-command-kit/tsup.config.ts +30 -0
  148. package/packages/shared-command-kit/vitest.config.ts +4 -0
  149. package/packages/shared-http/package.json +67 -0
  150. package/packages/shared-http/src/__tests__/log-correlation.test.ts +81 -0
  151. package/packages/shared-http/src/__tests__/operation-metrics-tracker.test.ts +55 -0
  152. package/packages/shared-http/src/http-observability-collector.ts +363 -0
  153. package/packages/shared-http/src/index.ts +36 -0
  154. package/packages/shared-http/src/log-correlation.ts +89 -0
  155. package/packages/shared-http/src/operation-metrics-tracker.ts +107 -0
  156. package/packages/shared-http/src/register-openapi.ts +108 -0
  157. package/packages/shared-http/src/resolve-schema-ref.ts +75 -0
  158. package/packages/shared-http/src/schemas.ts +29 -0
  159. package/packages/shared-http/src/service-observability.ts +63 -0
  160. package/packages/shared-http/tsconfig.build.json +15 -0
  161. package/packages/shared-http/tsconfig.json +9 -0
  162. package/packages/shared-http/tsup.config.ts +23 -0
  163. package/packages/shared-http/vitest.config.ts +13 -0
  164. package/packages/shared-perm-presets/CHANGELOG.md +20 -0
  165. package/packages/shared-perm-presets/README.md +78 -0
  166. package/packages/shared-perm-presets/eslint.config.js +27 -0
  167. package/packages/shared-perm-presets/package.json +45 -0
  168. package/packages/shared-perm-presets/src/__tests__/combine.test.ts +403 -0
  169. package/packages/shared-perm-presets/src/__tests__/presets.test.ts +205 -0
  170. package/packages/shared-perm-presets/src/combine.ts +278 -0
  171. package/packages/shared-perm-presets/src/index.ts +18 -0
  172. package/packages/shared-perm-presets/src/presets/ci-environment.ts +34 -0
  173. package/packages/shared-perm-presets/src/presets/full-env.ts +16 -0
  174. package/packages/shared-perm-presets/src/presets/git-workflow.ts +40 -0
  175. package/packages/shared-perm-presets/src/presets/index.ts +8 -0
  176. package/packages/shared-perm-presets/src/presets/kb-platform.ts +30 -0
  177. package/packages/shared-perm-presets/src/presets/llm-access.ts +29 -0
  178. package/packages/shared-perm-presets/src/presets/minimal.ts +21 -0
  179. package/packages/shared-perm-presets/src/presets/npm-publish.ts +48 -0
  180. package/packages/shared-perm-presets/src/presets/vector-store.ts +40 -0
  181. package/packages/shared-perm-presets/src/types.ts +192 -0
  182. package/packages/shared-perm-presets/tsconfig.build.json +15 -0
  183. package/packages/shared-perm-presets/tsconfig.json +9 -0
  184. package/packages/shared-perm-presets/tsup.config.ts +8 -0
  185. package/packages/shared-perm-presets/vitest.config.ts +9 -0
  186. package/packages/shared-testing/CHANGELOG.md +20 -0
  187. package/packages/shared-testing/README.md +430 -0
  188. package/packages/shared-testing/package.json +51 -0
  189. package/packages/shared-testing/src/__tests__/create-test-context.test.ts +199 -0
  190. package/packages/shared-testing/src/__tests__/mock-cache.test.ts +174 -0
  191. package/packages/shared-testing/src/__tests__/mock-llm.test.ts +212 -0
  192. package/packages/shared-testing/src/__tests__/setup-platform.test.ts +90 -0
  193. package/packages/shared-testing/src/__tests__/test-command.test.ts +557 -0
  194. package/packages/shared-testing/src/create-test-context.ts +550 -0
  195. package/packages/shared-testing/src/index.ts +77 -0
  196. package/packages/shared-testing/src/mock-cache.ts +179 -0
  197. package/packages/shared-testing/src/mock-llm.ts +319 -0
  198. package/packages/shared-testing/src/mock-logger.ts +97 -0
  199. package/packages/shared-testing/src/mock-storage.ts +108 -0
  200. package/packages/shared-testing/src/setup-platform.ts +101 -0
  201. package/packages/shared-testing/src/test-command.ts +288 -0
  202. package/packages/shared-testing/tsconfig.build.json +15 -0
  203. package/packages/shared-testing/tsconfig.json +9 -0
  204. package/packages/shared-testing/tsup.config.ts +20 -0
  205. package/packages/shared-testing/vitest.config.ts +3 -0
  206. package/packages/shared-tool-kit/CHANGELOG.md +20 -0
  207. package/packages/shared-tool-kit/package.json +47 -0
  208. package/packages/shared-tool-kit/src/__tests__/factory.test.ts +103 -0
  209. package/packages/shared-tool-kit/src/__tests__/mock-tool.test.ts +95 -0
  210. package/packages/shared-tool-kit/src/factory.ts +126 -0
  211. package/packages/shared-tool-kit/src/index.ts +32 -0
  212. package/packages/shared-tool-kit/src/testing/index.ts +84 -0
  213. package/packages/shared-tool-kit/tsconfig.build.json +15 -0
  214. package/packages/shared-tool-kit/tsconfig.json +9 -0
  215. package/packages/shared-tool-kit/tsup.config.ts +21 -0
  216. package/pnpm-workspace.yaml +11070 -0
  217. package/prettierrc.json +1 -0
  218. package/scripts/devkit-sync.mjs +37 -0
  219. package/scripts/hooks/post-push +9 -0
  220. package/scripts/hooks/pre-commit +9 -0
  221. package/scripts/hooks/pre-push +9 -0
  222. package/tsconfig.base.json +9 -0
  223. package/tsconfig.build.json +15 -0
  224. package/tsconfig.json +9 -0
  225. package/tsconfig.paths.json +50 -0
  226. package/tsconfig.tools.json +18 -0
  227. package/tsup.config.bin.ts +34 -0
  228. package/tsup.config.cli.ts +41 -0
  229. package/tsup.config.dual.ts +46 -0
  230. package/tsup.config.ts +36 -0
  231. package/tsup.external.json +104 -0
  232. package/vitest.config.ts +48 -0
@@ -0,0 +1,101 @@
1
+ import type { DebugEntry } from '../types';
2
+ import { formatTimelineWithSummary } from '../formatters/timeline';
3
+ import { DebugTree } from './tree';
4
+
5
+ export interface TraceOptions {
6
+ showSummary?: boolean;
7
+ groupByPlugin?: boolean;
8
+ maxDepth?: number;
9
+ }
10
+
11
+ export class DebugTrace {
12
+ private readonly entries: DebugEntry[] = [];
13
+ private readonly options: TraceOptions;
14
+
15
+ constructor(entries: DebugEntry[] = [], options: TraceOptions = {}) {
16
+ this.entries.push(...entries);
17
+ this.options = options;
18
+ }
19
+
20
+ add(entry: DebugEntry): void {
21
+ this.entries.push(entry);
22
+ }
23
+
24
+ addAll(entries: DebugEntry[]): void {
25
+ this.entries.push(...entries);
26
+ }
27
+
28
+ clear(): void {
29
+ this.entries.length = 0;
30
+ }
31
+
32
+ format(): string {
33
+ if (this.entries.length === 0) {
34
+ return '';
35
+ }
36
+
37
+ const sorted = [...this.entries].sort((a, b) => a.timestamp - b.timestamp);
38
+ if (this.options.groupByPlugin) {
39
+ return this.formatGrouped(sorted);
40
+ }
41
+
42
+ return formatTimelineWithSummary(sorted);
43
+ }
44
+
45
+ private formatGrouped(entries: DebugEntry[]): string {
46
+ const groups = new Map<string, DebugEntry[]>();
47
+ for (const entry of entries) {
48
+ const plugin = entry.namespace.split(':')[0] ?? entry.namespace;
49
+ if (!groups.has(plugin)) {
50
+ groups.set(plugin, []);
51
+ }
52
+ groups.get(plugin)!.push(entry);
53
+ }
54
+
55
+ const parts: string[] = [];
56
+ for (const [plugin, pluginEntries] of groups) {
57
+ const tree = new DebugTree(pluginEntries, {
58
+ showSummary: this.options.showSummary,
59
+ maxDepth: this.options.maxDepth,
60
+ });
61
+ const formatted = tree.format();
62
+ if (formatted) {
63
+ parts.push(`[${plugin}]`, formatted);
64
+ }
65
+ }
66
+ return parts.join('\n\n');
67
+ }
68
+
69
+ getStats(): {
70
+ totalEntries: number;
71
+ plugins: string[];
72
+ totalDuration: number;
73
+ errorCount: number;
74
+ warnCount: number;
75
+ } {
76
+ const plugins = new Set<string>();
77
+ let totalDuration = 0;
78
+ let errorCount = 0;
79
+ let warnCount = 0;
80
+
81
+ for (const entry of this.entries) {
82
+ const plugin = entry.namespace.split(':')[0] ?? entry.namespace;
83
+ plugins.add(plugin);
84
+ totalDuration += entry.duration ?? 0;
85
+ if (entry.level === 'error') {
86
+ errorCount += 1;
87
+ } else if (entry.level === 'warn') {
88
+ warnCount += 1;
89
+ }
90
+ }
91
+
92
+ return {
93
+ totalEntries: this.entries.length,
94
+ plugins: Array.from(plugins),
95
+ totalDuration,
96
+ errorCount,
97
+ warnCount,
98
+ };
99
+ }
100
+ }
101
+
@@ -0,0 +1,88 @@
1
+ import type { DebugEntry, DebugTreeNode } from '../types';
2
+ import { createDebugTree } from '../utilities';
3
+ import { formatTimelineNode } from '../formatters/timeline';
4
+
5
+ export interface DebugTreeOptions {
6
+ showSummary?: boolean;
7
+ maxDepth?: number;
8
+ }
9
+
10
+ interface DebugTreeStats {
11
+ totalDuration: number;
12
+ errorCount: number;
13
+ warnCount: number;
14
+ nodeCount: number;
15
+ }
16
+
17
+ export class DebugTree {
18
+ private tree: DebugTreeNode | null = null;
19
+ private readonly options: DebugTreeOptions;
20
+
21
+ constructor(entries: DebugEntry[], options: DebugTreeOptions = {}) {
22
+ this.options = options;
23
+ this.tree = createDebugTree(entries);
24
+ }
25
+
26
+ update(entries: DebugEntry[]): void {
27
+ this.tree = createDebugTree(entries);
28
+ }
29
+
30
+ format(): string {
31
+ if (!this.tree) {
32
+ return '';
33
+ }
34
+
35
+ const lines = formatTimelineNode(this.tree, true, '', this.options.maxDepth);
36
+ if (this.options.showSummary) {
37
+ const summary = this.getSummary();
38
+ if (summary) {
39
+ lines.push('', summary);
40
+ }
41
+ }
42
+ return lines.join('\n');
43
+ }
44
+
45
+ private getSummary(): string {
46
+ if (!this.tree) {
47
+ return '';
48
+ }
49
+
50
+ const stats = this.collectStats(this.tree);
51
+ const parts: string[] = [];
52
+
53
+ if (stats.totalDuration > 0) {
54
+ parts.push(`total ${stats.totalDuration}ms`);
55
+ }
56
+ if (stats.errorCount > 0) {
57
+ parts.push(`${stats.errorCount} errors`);
58
+ }
59
+ if (stats.warnCount > 0) {
60
+ parts.push(`${stats.warnCount} warnings`);
61
+ }
62
+ parts.push(`${stats.nodeCount} nodes`);
63
+
64
+ return `Summary: ${parts.join(', ')}`;
65
+ }
66
+
67
+ private collectStats(node: DebugTreeNode): DebugTreeStats {
68
+ let totalDuration = node.entry.duration ?? 0;
69
+ let errorCount = node.entry.level === 'error' ? 1 : 0;
70
+ let warnCount = node.entry.level === 'warn' ? 1 : 0;
71
+ let nodeCount = 1;
72
+
73
+ for (const child of node.children) {
74
+ const childStats = this.collectStats(child);
75
+ totalDuration += childStats.totalDuration;
76
+ errorCount += childStats.errorCount;
77
+ warnCount += childStats.warnCount;
78
+ nodeCount += childStats.nodeCount;
79
+ }
80
+
81
+ return { totalDuration, errorCount, warnCount, nodeCount };
82
+ }
83
+
84
+ get root(): DebugTreeNode | null {
85
+ return this.tree;
86
+ }
87
+ }
88
+
@@ -0,0 +1,17 @@
1
+ import type { DebugEntry, DebugFormat } from '../types';
2
+
3
+ export function formatDebugEntryAI(entry: DebugEntry): string {
4
+ return JSON.stringify(entry, null, 2);
5
+ }
6
+
7
+ export function formatDebugEntriesAI(entries: DebugEntry[]): string {
8
+ return JSON.stringify(entries, null, 2);
9
+ }
10
+
11
+ export function shouldUseAIFormat(format?: DebugFormat, jsonMode?: boolean): boolean {
12
+ if (jsonMode) {
13
+ return true;
14
+ }
15
+ return format === 'ai';
16
+ }
17
+
@@ -0,0 +1,98 @@
1
+ import { safeColors, safeSymbols } from '../../colors';
2
+ import type { DebugEntry } from '../types';
3
+
4
+ export interface HumanFormatterOptions {
5
+ showTimestamp?: boolean;
6
+ showDuration?: boolean;
7
+ groupBy?: 'namespace' | 'group' | 'none';
8
+ }
9
+
10
+ function formatTimestamp(timestamp: number): string {
11
+ const date = new Date(timestamp);
12
+ return date.toISOString();
13
+ }
14
+
15
+ function formatDuration(duration: number): string {
16
+ if (duration < 1000) {
17
+ return `${duration}ms`;
18
+ }
19
+ return `${(duration / 1000).toFixed(2)}s`;
20
+ }
21
+
22
+ export function formatDebugEntryHuman(entry: DebugEntry, options: HumanFormatterOptions = {}): string {
23
+ const parts: string[] = [];
24
+
25
+ if (options.showTimestamp) {
26
+ parts.push(safeColors.dim(formatTimestamp(entry.timestamp)));
27
+ }
28
+
29
+ parts.push(safeColors.bold(`[${entry.namespace}]`));
30
+ parts.push(entry.message);
31
+
32
+ if (options.showDuration && typeof entry.duration === 'number') {
33
+ parts.push(safeColors.dim(`(${formatDuration(entry.duration)})`));
34
+ }
35
+
36
+ if (entry.level === 'error') {
37
+ parts.push(safeColors.error(safeSymbols.error));
38
+ } else if (entry.level === 'warn') {
39
+ parts.push(safeColors.warning(safeSymbols.warning));
40
+ }
41
+
42
+ return parts.join(' ');
43
+ }
44
+
45
+ export function formatDebugEntriesHuman(entries: DebugEntry[], options: HumanFormatterOptions = {}): string {
46
+ if (entries.length === 0) {
47
+ return '';
48
+ }
49
+
50
+ const sorted = [...entries].sort((a, b) => a.timestamp - b.timestamp);
51
+ const lines: string[] = [];
52
+
53
+ if (options.groupBy === 'namespace') {
54
+ const namespaces = new Map<string, DebugEntry[]>();
55
+ for (const entry of sorted) {
56
+ if (!namespaces.has(entry.namespace)) {
57
+ namespaces.set(entry.namespace, []);
58
+ }
59
+ namespaces.get(entry.namespace)!.push(entry);
60
+ }
61
+
62
+ for (const [namespace, namespaceEntries] of namespaces) {
63
+ lines.push(safeColors.bold(namespace));
64
+ for (const entry of namespaceEntries) {
65
+ lines.push(` ${formatDebugEntryHuman(entry, options)}`);
66
+ }
67
+ lines.push('');
68
+ }
69
+ return lines.join('\n').trimEnd();
70
+ }
71
+
72
+ if (options.groupBy === 'group') {
73
+ const groups = new Map<string, DebugEntry[]>();
74
+ for (const entry of sorted) {
75
+ const groupName = entry.group ?? 'default';
76
+ if (!groups.has(groupName)) {
77
+ groups.set(groupName, []);
78
+ }
79
+ groups.get(groupName)!.push(entry);
80
+ }
81
+
82
+ for (const [groupName, groupEntries] of groups) {
83
+ lines.push(safeColors.bold(groupName));
84
+ for (const entry of groupEntries) {
85
+ lines.push(` ${formatDebugEntryHuman(entry, options)}`);
86
+ }
87
+ lines.push('');
88
+ }
89
+ return lines.join('\n').trimEnd();
90
+ }
91
+
92
+ for (const entry of sorted) {
93
+ lines.push(formatDebugEntryHuman(entry, options));
94
+ }
95
+
96
+ return lines.join('\n');
97
+ }
98
+
@@ -0,0 +1,94 @@
1
+ import { safeColors, safeSymbols } from '../../colors';
2
+ import type { DebugEntry, DebugTreeNode } from '../types';
3
+ import { createDebugTree } from '../utilities';
4
+
5
+ function formatDuration(duration: number): string {
6
+ if (duration < 1000) {
7
+ return `${duration}ms`;
8
+ }
9
+ return `${(duration / 1000).toFixed(2)}s`;
10
+ }
11
+
12
+ export function formatTimelineNode(
13
+ node: DebugTreeNode,
14
+ isLast: boolean,
15
+ prefix = '',
16
+ maxDepth?: number,
17
+ ): string[] {
18
+ const lines: string[] = [];
19
+ const connector = isLast ? '└─' : '├─';
20
+ const parts: string[] = [];
21
+
22
+ parts.push(safeColors.bold(`[${node.entry.namespace}]`));
23
+ parts.push(node.entry.message);
24
+
25
+ if (typeof node.entry.duration === 'number') {
26
+ parts.push(safeColors.dim(`(${formatDuration(node.entry.duration)})`));
27
+ }
28
+
29
+ if (node.entry.level === 'error') {
30
+ parts.push(safeColors.error(safeSymbols.error));
31
+ } else if (node.entry.level === 'warn') {
32
+ parts.push(safeColors.warning(safeSymbols.warning));
33
+ }
34
+
35
+ lines.push(`${prefix}${connector} ${parts.join(' ')}`.trimEnd());
36
+
37
+ if (maxDepth !== undefined && node.depth + 1 >= maxDepth) {
38
+ return lines;
39
+ }
40
+
41
+ const childPrefix = prefix + (isLast ? ' ' : '│ ');
42
+ for (let index = 0; index < node.children.length; index++) {
43
+ const child = node.children[index];
44
+ if (!child) {
45
+ continue;
46
+ }
47
+ const childIsLast = index === node.children.length - 1;
48
+ lines.push(...formatTimelineNode(child, childIsLast, childPrefix, maxDepth));
49
+ }
50
+
51
+ return lines;
52
+ }
53
+
54
+ export function formatTimeline(entries: DebugEntry[]): string {
55
+ if (entries.length === 0) {
56
+ return '';
57
+ }
58
+
59
+ const tree = createDebugTree(entries);
60
+ if (!tree) {
61
+ return '';
62
+ }
63
+
64
+ return formatTimelineNode(tree, true).join('\n');
65
+ }
66
+
67
+ export function formatTimelineWithSummary(entries: DebugEntry[]): string {
68
+ const timeline = formatTimeline(entries);
69
+ if (timeline.length === 0) {
70
+ return '';
71
+ }
72
+
73
+ const totalDuration = entries.reduce((acc, entry) => acc + (entry.duration ?? 0), 0);
74
+ const errorCount = entries.filter((entry) => entry.level === 'error').length;
75
+ const warnCount = entries.filter((entry) => entry.level === 'warn').length;
76
+
77
+ const summaryParts: string[] = [];
78
+ if (totalDuration > 0) {
79
+ summaryParts.push(`Total: ${formatDuration(totalDuration)}`);
80
+ }
81
+ if (errorCount > 0) {
82
+ summaryParts.push(safeColors.error(`${errorCount} errors`));
83
+ }
84
+ if (warnCount > 0) {
85
+ summaryParts.push(safeColors.warning(`${warnCount} warnings`));
86
+ }
87
+
88
+ if (summaryParts.length === 0) {
89
+ return timeline;
90
+ }
91
+
92
+ return `${timeline}\n\n${safeColors.bold('Summary:')} ${summaryParts.join(', ')}`;
93
+ }
94
+
@@ -0,0 +1,56 @@
1
+ export type {
2
+ DebugContext,
3
+ DebugDetailLevel,
4
+ DebugEntry,
5
+ DebugExportOptions,
6
+ DebugFilterOptions,
7
+ DebugFormat,
8
+ DebugLevel,
9
+ DebugMeta,
10
+ DebugTreeNode,
11
+ } from './types';
12
+
13
+ export {
14
+ formatDebugEntryAI,
15
+ formatDebugEntriesAI,
16
+ shouldUseAIFormat,
17
+ } from './formatters/ai';
18
+
19
+ export {
20
+ formatDebugEntryHuman,
21
+ formatDebugEntriesHuman,
22
+ type HumanFormatterOptions,
23
+ } from './formatters/human';
24
+
25
+ export { formatTimelineNode, formatTimeline, formatTimelineWithSummary } from './formatters/timeline';
26
+
27
+ export {
28
+ DebugOutput,
29
+ DebugSection,
30
+ formatDebugOutput,
31
+ formatDebugOutputs,
32
+ type DebugOutputOptions,
33
+ } from './components/output';
34
+
35
+ export { DebugTree, type DebugTreeOptions } from './components/tree';
36
+
37
+ export { DebugTrace, type TraceOptions } from './components/trace';
38
+
39
+ export {
40
+ createDebugTree,
41
+ describeEntriesAI,
42
+ describeEntriesHuman,
43
+ describeEntriesTimeline,
44
+ exportDebugEntries,
45
+ exportToChromeFormat,
46
+ exportToJSON,
47
+ exportToPlainText,
48
+ filterByLevel,
49
+ filterByNamespace,
50
+ filterByTimeRange,
51
+ filterDebugEntries,
52
+ groupByGroup,
53
+ groupByNamespace,
54
+ searchInLogs,
55
+ } from './utilities';
56
+
@@ -0,0 +1,57 @@
1
+ export type DebugLevel = 'debug' | 'info' | 'warn' | 'error';
2
+
3
+ export type DebugDetailLevel = 'debug' | 'verbose' | 'trace';
4
+
5
+ export type DebugFormat = 'ai' | 'human';
6
+
7
+ export type DebugMeta = Record<string, unknown>;
8
+
9
+ export interface DebugEntry {
10
+ timestamp: number;
11
+ namespace: string;
12
+ level: DebugLevel;
13
+ message: string;
14
+ meta?: DebugMeta;
15
+ traceId?: string;
16
+ spanId?: string;
17
+ parentSpanId?: string;
18
+ duration?: number;
19
+ group?: string;
20
+ groupDepth?: number;
21
+ }
22
+
23
+ export interface DebugContext {
24
+ format?: DebugFormat;
25
+ detailLevel?: DebugDetailLevel;
26
+ namespace?: string;
27
+ traceId?: string;
28
+ spanId?: string;
29
+ parentSpanId?: string;
30
+ groupDepth?: number;
31
+ enabled?: boolean;
32
+ }
33
+
34
+ export interface DebugTreeNode {
35
+ entry: DebugEntry;
36
+ children: DebugTreeNode[];
37
+ depth: number;
38
+ }
39
+
40
+ export interface DebugFilterOptions {
41
+ namespace?: string | RegExp;
42
+ level?: DebugLevel | DebugLevel[];
43
+ timeRange?: {
44
+ from?: number;
45
+ to?: number;
46
+ };
47
+ search?: string;
48
+ traceId?: string;
49
+ }
50
+
51
+ export interface DebugExportOptions {
52
+ format?: 'json' | 'chrome' | 'text';
53
+ path?: string;
54
+ filter?: DebugFilterOptions;
55
+ includeMeta?: boolean;
56
+ }
57
+