@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,144 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/errors/format-validation
3
+ * User-friendly formatting for flag validation errors
4
+ */
5
+
6
+ import type { FlagValidationError, StringFlagSchema } from '../flags/types';
7
+ import type { FlagSchemaDefinition } from '../flags/types';
8
+
9
+ /**
10
+ * Format a validation error into a user-friendly message
11
+ *
12
+ * @example
13
+ * ```
14
+ * ❌ Missing required flag: --text
15
+ *
16
+ * Usage: kb mind rag-query --text <query>
17
+ * Hint: Try kb mind rag-query --help
18
+ * ```
19
+ */
20
+ export function formatValidationError(
21
+ error: FlagValidationError,
22
+ options: {
23
+ commandName?: string;
24
+ schema?: FlagSchemaDefinition;
25
+ } = {}
26
+ ): string {
27
+ const { commandName, schema } = options;
28
+ const lines: string[] = [];
29
+
30
+ // Main error message with emoji
31
+ const errorMsg = error.message;
32
+
33
+ // Determine error type and format accordingly
34
+ if (errorMsg.includes('is required')) {
35
+ lines.push(`❌ Missing required flag: --${error.flag}`);
36
+ } else if (errorMsg.includes('must be one of')) {
37
+ // Extract the invalid value if available
38
+ const valueStr = error.value !== undefined ? ` ${error.value}` : '';
39
+ lines.push(`❌ Invalid value for --${error.flag}:${valueStr}`);
40
+ } else if (errorMsg.includes('must be a')) {
41
+ lines.push(`❌ Invalid type for --${error.flag}`);
42
+ } else if (errorMsg.includes('conflicts with')) {
43
+ lines.push(`❌ Flag conflict: --${error.flag}`);
44
+ } else if (errorMsg.includes('depends on')) {
45
+ lines.push(`❌ Missing dependency for --${error.flag}`);
46
+ } else {
47
+ // Fallback: use the original message
48
+ lines.push(`❌ ${errorMsg}`);
49
+ }
50
+
51
+ lines.push(''); // Empty line for spacing
52
+
53
+ // Generate usage hint if we have schema and command name
54
+ if (commandName && schema) {
55
+ const usageLine = generateUsageLine(commandName, schema, error.flag);
56
+ if (usageLine) {
57
+ lines.push(`Usage: ${usageLine}`);
58
+ }
59
+ }
60
+
61
+ // Add help hint
62
+ if (commandName) {
63
+ lines.push(`Hint: Try ${commandName} --help`);
64
+ } else {
65
+ lines.push('Hint: Try --help for more information');
66
+ }
67
+
68
+ return lines.join('\n');
69
+ }
70
+
71
+ /**
72
+ * Generate a usage line from command name and schema
73
+ *
74
+ * @example
75
+ * generateUsageLine('kb mind rag-query', schema, 'text')
76
+ * // Returns: 'kb mind rag-query --text <query> [options]'
77
+ */
78
+ function generateUsageLine(
79
+ commandName: string,
80
+ schema: FlagSchemaDefinition,
81
+ errorFlag: string
82
+ ): string {
83
+ const parts: string[] = [commandName];
84
+
85
+ // Add the flag that caused the error first
86
+ const errorFlagSchema = schema[errorFlag];
87
+ if (errorFlagSchema) {
88
+ const flagStr = formatFlagForUsage(errorFlag, errorFlagSchema);
89
+ parts.push(flagStr);
90
+ }
91
+
92
+ // Check if there are other required flags
93
+ const otherRequiredFlags = Object.entries(schema)
94
+ .filter(([name, flagSchema]) =>
95
+ name !== errorFlag && flagSchema.required
96
+ );
97
+
98
+ if (otherRequiredFlags.length > 0) {
99
+ // Add other required flags
100
+ for (const [name, flagSchema] of otherRequiredFlags) {
101
+ parts.push(formatFlagForUsage(name, flagSchema));
102
+ }
103
+ }
104
+
105
+ // Add [options] if there are optional flags
106
+ const hasOptionalFlags = Object.values(schema).some(s => !s.required);
107
+ if (hasOptionalFlags) {
108
+ parts.push('[options]');
109
+ }
110
+
111
+ return parts.join(' ');
112
+ }
113
+
114
+ /**
115
+ * Format a single flag for usage display
116
+ *
117
+ * @example
118
+ * formatFlagForUsage('text', { type: 'string', required: true })
119
+ * // Returns: '--text <text>'
120
+ *
121
+ * formatFlagForUsage('mode', { type: 'string', choices: ['local', 'auto'] })
122
+ * // Returns: '[--mode <local|auto>]'
123
+ */
124
+ function formatFlagForUsage(
125
+ name: string,
126
+ schema: FlagSchemaDefinition[string]
127
+ ): string {
128
+ let valueHint: string;
129
+
130
+ if ('choices' in schema && (schema as StringFlagSchema).choices && (schema as StringFlagSchema).choices!.length > 0) {
131
+ // Show choices: <local|auto>
132
+ valueHint = `<${(schema as StringFlagSchema).choices!.join('|')}>`;
133
+ } else if (schema.type === 'boolean') {
134
+ // Boolean flags don't need a value hint
135
+ return schema.required ? `--${name}` : `[--${name}]`;
136
+ } else {
137
+ // Generic type hint: <text>, <number>, etc.
138
+ valueHint = `<${name}>`;
139
+ }
140
+
141
+ const flagPart = `--${name} ${valueHint}`;
142
+
143
+ return schema.required ? flagPart : `[${flagPart}]`;
144
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/errors/format
3
+ * Error formatting utilities
4
+ */
5
+
6
+ import type { FormattedError, FormatErrorOptions } from './types';
7
+ import { FlagValidationError } from '../flags/types';
8
+ import { formatValidationError } from './format-validation';
9
+
10
+ /**
11
+ * Format error for display
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const formatted = formatError(error, {
16
+ * jsonMode: Boolean(flags.json),
17
+ * showStack: Boolean(flags.debug),
18
+ * timingMs: tracker.total(),
19
+ * });
20
+ *
21
+ * if (flags.json) {
22
+ * ctx.output?.json(formatted.json);
23
+ * } else {
24
+ * ctx.output?.error(formatted.message);
25
+ * }
26
+ * ```
27
+ */
28
+ export function formatError(
29
+ error: unknown,
30
+ options: FormatErrorOptions = {}
31
+ ): FormattedError {
32
+ const { showStack = false, timingMs } = options;
33
+
34
+ // Special handling for FlagValidationError
35
+ if (error instanceof FlagValidationError) {
36
+ const friendlyMessage = formatValidationError(error, {
37
+ commandName: error.commandName,
38
+ schema: error.schema,
39
+ });
40
+
41
+ const json: FormattedError['json'] = {
42
+ ok: false,
43
+ error: error.message,
44
+ };
45
+
46
+ if (timingMs !== undefined) {
47
+ json.timingMs = timingMs;
48
+ }
49
+
50
+ if (showStack && error.stack) {
51
+ json.stack = error.stack;
52
+ }
53
+
54
+ let message = friendlyMessage;
55
+ if (showStack && error.stack) {
56
+ message = `${friendlyMessage}\n\nStack trace:\n${error.stack}`;
57
+ }
58
+
59
+ return {
60
+ message,
61
+ json,
62
+ };
63
+ }
64
+
65
+ // Standard error formatting for other errors
66
+ const errorMessage = error instanceof Error ? error.message : String(error);
67
+ const errorStack = error instanceof Error ? error.stack : undefined;
68
+
69
+ const json: FormattedError['json'] = {
70
+ ok: false,
71
+ error: errorMessage,
72
+ };
73
+
74
+ if (timingMs !== undefined) {
75
+ json.timingMs = timingMs;
76
+ }
77
+
78
+ if (showStack && errorStack) {
79
+ json.stack = errorStack;
80
+ }
81
+
82
+ let message = errorMessage;
83
+ if (showStack && errorStack) {
84
+ message = `${errorMessage}\n\n${errorStack}`;
85
+ }
86
+
87
+ return {
88
+ message,
89
+ json,
90
+ };
91
+ }
92
+
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/errors
3
+ * Error formatting utilities and error factory
4
+ */
5
+
6
+ export * from './types';
7
+ export * from './format';
8
+ export * from './factory';
9
+
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/errors/types
3
+ * Types for error formatting
4
+ */
5
+
6
+ /**
7
+ * Formatted error result
8
+ */
9
+ export interface FormattedError {
10
+ /** Human-readable error message */
11
+ message: string;
12
+ /** JSON representation */
13
+ json: {
14
+ ok: false;
15
+ error: string;
16
+ timingMs?: number;
17
+ stack?: string;
18
+ };
19
+ }
20
+
21
+ /**
22
+ * Error formatting options
23
+ */
24
+ export interface FormatErrorOptions {
25
+ /** Output in JSON format */
26
+ jsonMode?: boolean;
27
+ /** Include stack trace */
28
+ showStack?: boolean;
29
+ /** Timing information */
30
+ timingMs?: number;
31
+ }
32
+
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/flags/define
3
+ * Define flag schemas with automatic type inference
4
+ */
5
+
6
+ import type {
7
+ FlagSchemaDefinition,
8
+ BooleanFlagSchema,
9
+ StringFlagSchema,
10
+ NumberFlagSchema,
11
+ ArrayFlagSchema,
12
+ } from './types';
13
+
14
+ /**
15
+ * Flag schema with type inference
16
+ */
17
+ export interface FlagSchemaWithInfer<T extends FlagSchemaDefinition> {
18
+ /** Original schema definition */
19
+ readonly schema: T;
20
+ /** Infer TypeScript type from schema */
21
+ infer: InferFlags<T>;
22
+ }
23
+
24
+ /**
25
+ * Infer TypeScript type from flag schema definition
26
+ */
27
+ export type InferFlags<T extends FlagSchemaDefinition> = {
28
+ [K in keyof T]: T[K] extends BooleanFlagSchema
29
+ ? T[K]['default'] extends boolean
30
+ ? boolean
31
+ : T[K]['required'] extends true
32
+ ? boolean
33
+ : boolean | undefined
34
+ : T[K] extends StringFlagSchema
35
+ ? T[K]['choices'] extends readonly string[]
36
+ ? T[K]['required'] extends true
37
+ ? T[K]['choices'][number]
38
+ : T[K]['default'] extends string
39
+ ? T[K]['choices'][number]
40
+ : T[K]['choices'][number] | undefined
41
+ : T[K]['required'] extends true
42
+ ? string
43
+ : T[K]['default'] extends string
44
+ ? string
45
+ : string | undefined
46
+ : T[K] extends NumberFlagSchema
47
+ ? T[K]['required'] extends true
48
+ ? number
49
+ : T[K]['default'] extends number
50
+ ? number
51
+ : number | undefined
52
+ : T[K] extends ArrayFlagSchema
53
+ ? T[K]['items'] extends 'string'
54
+ ? string[]
55
+ : T[K]['items'] extends 'number'
56
+ ? number[]
57
+ : T[K]['items'] extends 'boolean'
58
+ ? boolean[]
59
+ : unknown[]
60
+ : unknown;
61
+ };
62
+
63
+ /**
64
+ * Define a flag schema with automatic type inference
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const schema = defineFlags({
69
+ * scope: {
70
+ * type: 'string',
71
+ * required: true,
72
+ * pattern: /^[@a-z0-9-/]+$/i,
73
+ * },
74
+ * 'dry-run': {
75
+ * type: 'boolean',
76
+ * default: false,
77
+ * },
78
+ * });
79
+ *
80
+ * type Flags = typeof schema.infer;
81
+ * // Flags = { scope: string; 'dry-run': boolean }
82
+ * ```
83
+ */
84
+ export function defineFlags<T extends FlagSchemaDefinition>(
85
+ definition: T
86
+ ): FlagSchemaWithInfer<T> {
87
+ return {
88
+ schema: definition,
89
+ infer: {} as InferFlags<T>,
90
+ };
91
+ }
92
+
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/flags
3
+ * Flag validation and schema definition
4
+ */
5
+
6
+ export * from './types';
7
+ export * from './define';
8
+ export * from './validate';
9
+
@@ -0,0 +1,153 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/flags/types
3
+ * Types for flag validation and schema definition
4
+ */
5
+
6
+ /**
7
+ * Flag type definition
8
+ */
9
+ export type FlagType = 'boolean' | 'string' | 'number' | 'array';
10
+
11
+ /**
12
+ * Base flag schema definition
13
+ */
14
+ export interface BaseFlagSchema<T extends FlagType = FlagType> {
15
+ /** Flag name */
16
+ name?: string;
17
+ /** Flag type */
18
+ type: T;
19
+ /** Short alias (e.g., 'n' for 'dry-run') */
20
+ alias?: string;
21
+ /** Description for help text */
22
+ description?: string;
23
+ /** Default value if flag is not provided */
24
+ default?: unknown;
25
+ /** Whether flag is required */
26
+ required?: boolean;
27
+ /** Flags that conflict with this flag */
28
+ conflicts?: string[];
29
+ /** Flags that this flag depends on */
30
+ dependsOn?: string[];
31
+ /** Flags that are implied when this flag is set */
32
+ implies?: string[] | [string, unknown][];
33
+ // Note: transform is defined in child interfaces with specific types
34
+ }
35
+
36
+ /**
37
+ * Boolean flag schema
38
+ */
39
+ export interface BooleanFlagSchema extends BaseFlagSchema<'boolean'> {
40
+ type: 'boolean';
41
+ default?: boolean;
42
+ /** Transform function to apply to the value */
43
+ transform?: (value: boolean) => boolean | Promise<boolean>;
44
+ }
45
+
46
+ /**
47
+ * String flag schema
48
+ */
49
+ export interface StringFlagSchema extends BaseFlagSchema<'string'> {
50
+ type: 'string';
51
+ default?: string;
52
+ /** Allowed values (enum) */
53
+ choices?: readonly string[];
54
+ /** Regex pattern for validation */
55
+ pattern?: RegExp;
56
+ /** Minimum string length */
57
+ minLength?: number;
58
+ /** Maximum string length */
59
+ maxLength?: number;
60
+ /** Custom validation function */
61
+ validate?: (value: string) => true | string | Promise<true | string>;
62
+ /** Transform function to apply to the value */
63
+ transform?: (value: string) => string | Promise<string>;
64
+ }
65
+
66
+ /**
67
+ * Number flag schema
68
+ */
69
+ export interface NumberFlagSchema extends BaseFlagSchema<'number'> {
70
+ type: 'number';
71
+ default?: number;
72
+ /** Minimum value */
73
+ min?: number;
74
+ /** Maximum value */
75
+ max?: number;
76
+ /** Custom validation function */
77
+ validate?: (value: number) => true | string | Promise<true | string>;
78
+ /** Transform function to apply to the value */
79
+ transform?: (value: number) => number | Promise<number>;
80
+ }
81
+
82
+ /**
83
+ * Array flag schema
84
+ */
85
+ export interface ArrayFlagSchema extends BaseFlagSchema<'array'> {
86
+ type: 'array';
87
+ default?: unknown[];
88
+ /** Type of array items */
89
+ items?: 'string' | 'number' | 'boolean';
90
+ /** Minimum array length */
91
+ minLength?: number;
92
+ /** Maximum array length */
93
+ maxLength?: number;
94
+ /** Transform function to apply to the value */
95
+ transform?: (value: unknown[]) => unknown[] | Promise<unknown[]>;
96
+ }
97
+
98
+ /**
99
+ * Union of all flag schema types
100
+ */
101
+ export type FlagSchema =
102
+ | BooleanFlagSchema
103
+ | StringFlagSchema
104
+ | NumberFlagSchema
105
+ | ArrayFlagSchema;
106
+
107
+ /**
108
+ * Flag schema definition object (for defineFlags)
109
+ */
110
+ export type FlagSchemaDefinition = Record<string, Omit<FlagSchema, 'name'>>;
111
+
112
+ /**
113
+ * Validation error
114
+ */
115
+ export class FlagValidationError extends Error {
116
+ constructor(
117
+ public readonly flag: string,
118
+ message: string,
119
+ public readonly value?: unknown,
120
+ public readonly schema?: FlagSchemaDefinition,
121
+ public readonly commandName?: string
122
+ ) {
123
+ super(message);
124
+ this.name = 'FlagValidationError';
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Validation result
130
+ */
131
+ export interface ValidationResult<T = Record<string, unknown>> {
132
+ success: boolean;
133
+ data?: T;
134
+ errors?: Array<{
135
+ flag: string;
136
+ message: string;
137
+ value?: unknown;
138
+ }>;
139
+ }
140
+
141
+ /**
142
+ * Safe validation result (doesn't throw)
143
+ */
144
+ export interface SafeValidationResult<T = Record<string, unknown>> {
145
+ success: boolean;
146
+ data?: T;
147
+ errors: Array<{
148
+ flag: string;
149
+ message: string;
150
+ value?: unknown;
151
+ }>;
152
+ }
153
+