@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,622 @@
1
+ # Declarative Flags and Environment Variables
2
+
3
+ **For Plugin Developers**: Type-safe CLI flags and environment variables with automatic validation.
4
+
5
+ ## Overview
6
+
7
+ KB Labs provides declarative systems for defining CLI flags and environment variables with:
8
+
9
+ ✅ **Type Safety** — Automatic type inference from schema
10
+ ✅ **Validation** — Built-in type checking + custom validators
11
+ ✅ **DX** — 1 line of code instead of 5+
12
+ ✅ **Self-Documenting** — Schema serves as documentation
13
+
14
+ ## Quick Start
15
+
16
+ ### CLI Flags
17
+
18
+ ```typescript
19
+ // In your-plugin-contracts/src/flags.ts
20
+ import { defineFlags } from '@kb-labs/sdk';
21
+
22
+ export const myFlags = defineFlags({
23
+ scope: {
24
+ type: 'string',
25
+ description: 'Limit to package or path',
26
+ examples: ['@kb-labs/core', 'packages/**'],
27
+ },
28
+ 'dry-run': {
29
+ type: 'boolean',
30
+ description: 'Preview without applying',
31
+ default: false,
32
+ },
33
+ timeout: {
34
+ type: 'number',
35
+ description: 'Timeout in milliseconds',
36
+ default: 5000,
37
+ validate: (v) => {
38
+ if (v < 0) throw new Error('Timeout must be positive');
39
+ },
40
+ },
41
+ });
42
+
43
+ export type MyFlags = typeof myFlags.type;
44
+ // Result: { scope?: string; 'dry-run': boolean; timeout: number }
45
+ ```
46
+
47
+ ```typescript
48
+ // In your command
49
+ import { defineCommand } from '@kb-labs/sdk';
50
+ import { type MyFlags } from './contracts';
51
+
52
+ export default defineCommand({
53
+ handler: {
54
+ async execute(ctx, input: MyFlags) {
55
+ const { scope, 'dry-run': dryRun, timeout } = input;
56
+ // ✅ Fully typed, no manual parsing needed
57
+ }
58
+ }
59
+ });
60
+ ```
61
+
62
+ ### Environment Variables
63
+
64
+ ```typescript
65
+ // In your-plugin-contracts/src/env.ts
66
+ import { defineEnv } from '@kb-labs/sdk';
67
+
68
+ export const myEnv = defineEnv({
69
+ MY_API_KEY: {
70
+ type: 'string',
71
+ description: 'API key for service',
72
+ },
73
+ MY_ENABLED: {
74
+ type: 'boolean',
75
+ default: true,
76
+ description: 'Enable feature',
77
+ },
78
+ MY_TIMEOUT: {
79
+ type: 'number',
80
+ default: 5000,
81
+ description: 'Timeout in ms',
82
+ validate: (v) => {
83
+ if (v < 0) throw new Error('Timeout must be positive');
84
+ },
85
+ },
86
+ });
87
+
88
+ export type MyEnv = typeof myEnv.type;
89
+ // Result: { MY_API_KEY?: string; MY_ENABLED: boolean; MY_TIMEOUT: number }
90
+ ```
91
+
92
+ ```typescript
93
+ // In your command
94
+ const env = myEnv.parse(ctx.runtime);
95
+ // ✅ One line! Fully typed and validated
96
+ // env.MY_API_KEY → string | undefined
97
+ // env.MY_ENABLED → boolean
98
+ // env.MY_TIMEOUT → number
99
+ ```
100
+
101
+ ## Flag Types
102
+
103
+ ### String Flags
104
+
105
+ ```typescript
106
+ export const flags = defineFlags({
107
+ name: {
108
+ type: 'string',
109
+ description: 'User name',
110
+ examples: ['john', 'jane'],
111
+ },
112
+ email: {
113
+ type: 'string',
114
+ default: 'noreply@example.com',
115
+ validate: (v) => {
116
+ if (!v.includes('@')) throw new Error('Invalid email');
117
+ },
118
+ },
119
+ });
120
+
121
+ type Result = typeof flags.type;
122
+ // { name?: string; email: string }
123
+ ```
124
+
125
+ **Key points**:
126
+ - Without `default`: optional (`string | undefined`)
127
+ - With `default`: required (`string`)
128
+ - Custom validation via `validate` function
129
+
130
+ ### Boolean Flags
131
+
132
+ ```typescript
133
+ export const flags = defineFlags({
134
+ verbose: {
135
+ type: 'boolean',
136
+ description: 'Enable verbose logging',
137
+ default: false,
138
+ },
139
+ force: {
140
+ type: 'boolean',
141
+ description: 'Force operation',
142
+ },
143
+ });
144
+
145
+ type Result = typeof flags.type;
146
+ // { verbose: boolean; force?: boolean }
147
+ ```
148
+
149
+ **Parsing**:
150
+ - `true`, `'true'`, `'1'`, `'yes'` → `true`
151
+ - `false`, `'false'`, `'0'`, `'no'` → `false`
152
+
153
+ ### Number Flags
154
+
155
+ ```typescript
156
+ export const flags = defineFlags({
157
+ port: {
158
+ type: 'number',
159
+ default: 3000,
160
+ description: 'Server port',
161
+ validate: (v) => {
162
+ if (v < 1024 || v > 65535) {
163
+ throw new Error('Port must be 1024-65535');
164
+ }
165
+ },
166
+ },
167
+ retries: {
168
+ type: 'number',
169
+ description: 'Number of retries',
170
+ },
171
+ });
172
+
173
+ type Result = typeof flags.type;
174
+ // { port: number; retries?: number }
175
+ ```
176
+
177
+ **Parsing**:
178
+ - Numbers: `3000` → `3000`
179
+ - Strings: `'3000'` → `3000`
180
+ - Invalid: `'abc'` → throws error
181
+
182
+ ## Type Inference
183
+
184
+ The type system automatically infers correct types:
185
+
186
+ ```typescript
187
+ export const flags = defineFlags({
188
+ // Without default → optional
189
+ scope: { type: 'string' },
190
+
191
+ // With default → required
192
+ verbose: { type: 'boolean', default: false },
193
+ });
194
+
195
+ type Inferred = typeof flags.type;
196
+ // { scope?: string; verbose: boolean }
197
+ // ^^^^^ optional ^^^^^^^ required
198
+ ```
199
+
200
+ ### Why This Matters
201
+
202
+ ```typescript
203
+ function doSomething(input: MyFlags) {
204
+ // ✅ TypeScript knows this might be undefined
205
+ if (input.scope) {
206
+ console.log(input.scope.toUpperCase());
207
+ }
208
+
209
+ // ✅ TypeScript knows this is always boolean
210
+ if (input.verbose) {
211
+ console.log('Verbose mode enabled');
212
+ }
213
+ }
214
+ ```
215
+
216
+ ## Validation
217
+
218
+ ### Built-in Type Validation
219
+
220
+ Automatic for all types:
221
+
222
+ ```typescript
223
+ // ❌ Runtime error: "Flag 'port' must be number, got string"
224
+ const flags = { port: 'invalid' };
225
+ myFlags.parse(flags);
226
+ ```
227
+
228
+ ### Custom Validation
229
+
230
+ Add business logic validation:
231
+
232
+ ```typescript
233
+ export const flags = defineFlags({
234
+ temperature: {
235
+ type: 'number',
236
+ default: 0.3,
237
+ validate: (v) => {
238
+ if (v < 0 || v > 1) {
239
+ throw new Error('Temperature must be 0-1');
240
+ }
241
+ },
242
+ },
243
+ email: {
244
+ type: 'string',
245
+ validate: (v) => {
246
+ if (!v.includes('@')) {
247
+ throw new Error('Invalid email format');
248
+ }
249
+ },
250
+ },
251
+ });
252
+ ```
253
+
254
+ **Validation happens**:
255
+ - After type coercion
256
+ - Before returning to command
257
+ - Only if value is present (not for `undefined`)
258
+
259
+ ## Environment Variables
260
+
261
+ ### Basic Usage
262
+
263
+ ```typescript
264
+ // In contracts
265
+ export const myEnv = defineEnv({
266
+ MY_VAR: { type: 'boolean', default: true },
267
+ });
268
+
269
+ // In command
270
+ const env = myEnv.parse(ctx.runtime);
271
+ console.log(env.MY_VAR); // boolean
272
+ ```
273
+
274
+ ### With Validation
275
+
276
+ ```typescript
277
+ export const myEnv = defineEnv({
278
+ MY_TEMPERATURE: {
279
+ type: 'number',
280
+ default: 0.3,
281
+ validate: (v) => {
282
+ if (v < 0 || v > 1) {
283
+ throw new Error('MY_TEMPERATURE must be 0-1');
284
+ }
285
+ },
286
+ },
287
+ });
288
+
289
+ // Usage
290
+ MY_TEMPERATURE=1.5 pnpm kb my-command
291
+ // ❌ Error: MY_TEMPERATURE must be 0-1
292
+ ```
293
+
294
+ ### Real-World Example
295
+
296
+ ```typescript
297
+ // commit-contracts/src/env.ts
298
+ export const commitEnv = defineEnv({
299
+ KB_COMMIT_LLM_ENABLED: {
300
+ type: 'boolean',
301
+ default: true,
302
+ description: 'Enable LLM-powered commit analysis',
303
+ },
304
+ KB_COMMIT_LLM_TEMPERATURE: {
305
+ type: 'number',
306
+ default: 0.3,
307
+ description: 'LLM temperature (0-1)',
308
+ validate: (v) => {
309
+ if (v < 0 || v > 1) {
310
+ throw new Error('Temperature must be 0-1');
311
+ }
312
+ },
313
+ },
314
+ KB_COMMIT_LLM_MAX_TOKENS: {
315
+ type: 'number',
316
+ default: 2000,
317
+ description: 'Maximum tokens for LLM',
318
+ },
319
+ });
320
+
321
+ // In command
322
+ const env = commitEnv.parse(ctx.runtime);
323
+ // env.KB_COMMIT_LLM_ENABLED → boolean
324
+ // env.KB_COMMIT_LLM_TEMPERATURE → number (validated 0-1)
325
+ // env.KB_COMMIT_LLM_MAX_TOKENS → number
326
+ ```
327
+
328
+ ## Migration Guide
329
+
330
+ ### Before (Manual)
331
+
332
+ ```typescript
333
+ // ❌ OLD: Lots of boilerplate, no type safety
334
+ type MyInput = {
335
+ scope?: string;
336
+ 'dry-run'?: boolean;
337
+ };
338
+
339
+ const env = {
340
+ MY_ENABLED: ctx.runtime.env('MY_ENABLED'),
341
+ MY_TEMPERATURE: ctx.runtime.env('MY_TEMPERATURE'),
342
+ MY_MAX_TOKENS: ctx.runtime.env('MY_MAX_TOKENS'),
343
+ };
344
+
345
+ // Manual parsing
346
+ let enabled = true;
347
+ if (env.MY_ENABLED !== undefined) {
348
+ enabled = env.MY_ENABLED === 'true';
349
+ }
350
+
351
+ let temperature = 0.3;
352
+ if (env.MY_TEMPERATURE !== undefined) {
353
+ const temp = parseFloat(env.MY_TEMPERATURE);
354
+ if (!isNaN(temp) && temp >= 0 && temp <= 1) {
355
+ temperature = temp;
356
+ }
357
+ }
358
+
359
+ // Use values
360
+ const dryRun = input['dry-run'] ?? false;
361
+ ```
362
+
363
+ ### After (Declarative)
364
+
365
+ ```typescript
366
+ // ✅ NEW: Clean, type-safe, validated
367
+ export const myFlags = defineFlags({
368
+ scope: { type: 'string' },
369
+ 'dry-run': { type: 'boolean', default: false },
370
+ });
371
+
372
+ export const myEnv = defineEnv({
373
+ MY_ENABLED: { type: 'boolean', default: true },
374
+ MY_TEMPERATURE: {
375
+ type: 'number',
376
+ default: 0.3,
377
+ validate: (v) => {
378
+ if (v < 0 || v > 1) throw new Error('Must be 0-1');
379
+ },
380
+ },
381
+ });
382
+
383
+ // In command
384
+ const env = myEnv.parse(ctx.runtime);
385
+ const { scope, 'dry-run': dryRun } = input;
386
+
387
+ // ✅ 2 lines instead of 20+, fully typed
388
+ ```
389
+
390
+ ## Best Practices
391
+
392
+ ### 1. Always Add Descriptions
393
+
394
+ ```typescript
395
+ // ✅ GOOD: Self-documenting
396
+ export const flags = defineFlags({
397
+ scope: {
398
+ type: 'string',
399
+ description: 'Limit operation to specific scope',
400
+ examples: ['@kb-labs/core', 'packages/**'],
401
+ },
402
+ });
403
+
404
+ // ❌ BAD: No documentation
405
+ export const flags = defineFlags({
406
+ scope: { type: 'string' },
407
+ });
408
+ ```
409
+
410
+ ### 2. Use Defaults for Required Values
411
+
412
+ ```typescript
413
+ // ✅ GOOD: Required boolean with default
414
+ export const flags = defineFlags({
415
+ verbose: {
416
+ type: 'boolean',
417
+ default: false, // Always boolean, never undefined
418
+ },
419
+ });
420
+
421
+ // ⚠️ CAUTION: Optional boolean
422
+ export const flags = defineFlags({
423
+ verbose: { type: 'boolean' }, // boolean | undefined
424
+ });
425
+ ```
426
+
427
+ ### 3. Validate Business Logic
428
+
429
+ ```typescript
430
+ // ✅ GOOD: Domain validation
431
+ export const flags = defineFlags({
432
+ port: {
433
+ type: 'number',
434
+ validate: (v) => {
435
+ if (v < 1024 || v > 65535) {
436
+ throw new Error('Port must be 1024-65535');
437
+ }
438
+ },
439
+ },
440
+ });
441
+
442
+ // ❌ BAD: No validation, runtime errors possible
443
+ export const flags = defineFlags({
444
+ port: { type: 'number' },
445
+ });
446
+ ```
447
+
448
+ ### 4. Group Related Flags
449
+
450
+ ```typescript
451
+ // ✅ GOOD: Organized by feature
452
+ export const llmFlags = defineFlags({
453
+ 'llm-temperature': { type: 'number', default: 0.3 },
454
+ 'llm-max-tokens': { type: 'number', default: 2000 },
455
+ 'llm-enabled': { type: 'boolean', default: true },
456
+ });
457
+
458
+ export const gitFlags = defineFlags({
459
+ 'git-auto-stage': { type: 'boolean', default: false },
460
+ 'git-push': { type: 'boolean', default: false },
461
+ });
462
+ ```
463
+
464
+ ## Error Handling
465
+
466
+ ### Type Errors
467
+
468
+ ```typescript
469
+ const flags = defineFlags({
470
+ port: { type: 'number' },
471
+ });
472
+
473
+ // ❌ Error: Flag "port" must be number, got string
474
+ flags.parse({ port: 'invalid' });
475
+ ```
476
+
477
+ ### Validation Errors
478
+
479
+ ```typescript
480
+ const flags = defineFlags({
481
+ temperature: {
482
+ type: 'number',
483
+ validate: (v) => {
484
+ if (v < 0 || v > 1) {
485
+ throw new Error('Temperature must be 0-1');
486
+ }
487
+ },
488
+ },
489
+ });
490
+
491
+ // ❌ Error: Temperature must be 0-1
492
+ flags.parse({ temperature: 1.5 });
493
+ ```
494
+
495
+ ### Graceful Handling
496
+
497
+ ```typescript
498
+ try {
499
+ const env = myEnv.parse(ctx.runtime);
500
+ // Use env
501
+ } catch (error) {
502
+ ctx.ui?.error?.(`Invalid environment: ${error.message}`);
503
+ return { exitCode: 1 };
504
+ }
505
+ ```
506
+
507
+ ## Advanced Patterns
508
+
509
+ ### Combining Flags and Env
510
+
511
+ ```typescript
512
+ // Flags for CLI args
513
+ export const myFlags = defineFlags({
514
+ scope: { type: 'string' },
515
+ verbose: { type: 'boolean', default: false },
516
+ });
517
+
518
+ // Env for configuration
519
+ export const myEnv = defineEnv({
520
+ MY_API_KEY: { type: 'string' },
521
+ MY_ENABLED: { type: 'boolean', default: true },
522
+ });
523
+
524
+ // In command
525
+ const env = myEnv.parse(ctx.runtime);
526
+ const { scope, verbose } = input;
527
+
528
+ // Merge: flags override env
529
+ const enabled = input.enabled ?? env.MY_ENABLED;
530
+ ```
531
+
532
+ ### Conditional Validation
533
+
534
+ ```typescript
535
+ export const flags = defineFlags({
536
+ mode: { type: 'string', default: 'auto' },
537
+ temperature: {
538
+ type: 'number',
539
+ default: 0.3,
540
+ validate: (v) => {
541
+ // Only validate if mode is 'thinking'
542
+ // (actual check done in command)
543
+ if (v < 0 || v > 1) {
544
+ throw new Error('Temperature must be 0-1');
545
+ }
546
+ },
547
+ },
548
+ });
549
+ ```
550
+
551
+ ### Dynamic Defaults
552
+
553
+ ```typescript
554
+ export const flags = defineFlags({
555
+ output: {
556
+ type: 'string',
557
+ // No default here - set dynamically in command
558
+ },
559
+ });
560
+
561
+ // In command
562
+ const output = input.output ?? `.kb/output-${Date.now()}.json`;
563
+ ```
564
+
565
+ ## Reference
566
+
567
+ ### Flag Spec
568
+
569
+ ```typescript
570
+ interface StringFlagSpec {
571
+ type: 'string';
572
+ description?: string;
573
+ examples?: string[];
574
+ deprecated?: boolean | string;
575
+ default?: string;
576
+ validate?: (value: string) => void | Promise<void>;
577
+ }
578
+
579
+ interface BooleanFlagSpec {
580
+ type: 'boolean';
581
+ description?: string;
582
+ deprecated?: boolean | string;
583
+ default?: boolean;
584
+ }
585
+
586
+ interface NumberFlagSpec {
587
+ type: 'number';
588
+ description?: string;
589
+ deprecated?: boolean | string;
590
+ default?: number;
591
+ validate?: (value: number) => void | Promise<void>;
592
+ }
593
+ ```
594
+
595
+ ### API
596
+
597
+ ```typescript
598
+ // Define flags
599
+ const flags = defineFlags({ ... });
600
+ // → FlagsDefinition<T>
601
+
602
+ // Get inferred type
603
+ type MyFlags = typeof flags.type;
604
+ // → InferFlagsType<T>
605
+
606
+ // Parse flags
607
+ const parsed = flags.parse(input);
608
+ // → InferFlagsType<T>
609
+
610
+ // Define env
611
+ const env = defineEnv({ ... });
612
+ // → EnvDefinition<T>
613
+
614
+ // Parse env
615
+ const parsed = env.parse(runtime);
616
+ // → InferFlagsType<T>
617
+ ```
618
+
619
+ ## See Also
620
+
621
+ - [ADR-0006: Declarative Flags and Env Systems](./adr/0006-declarative-flags-and-env-systems.md)
622
+ - [V3 Plugin System Spec](../../docs/V3-IMPLEMENTATION-SPEC.md)
@@ -0,0 +1,70 @@
1
+ # KB Labs Shared Documentation Standard
2
+
3
+ > **This document is a project-specific copy of the KB Labs Documentation Standard.**
4
+ > See [Main Documentation Standard](https://github.com/KirillBaranov/kb-labs/blob/main/docs/DOCUMENTATION.md) for the complete ecosystem standard.
5
+
6
+ This document defines the documentation standards for **KB Labs Shared**. This project follows the [KB Labs Documentation Standard](https://github.com/KirillBaranov/kb-labs/blob/main/docs/DOCUMENTATION.md) with the following project-specific customizations:
7
+
8
+ ## Project-Specific Customizations
9
+
10
+ KB Labs Shared provides building blocks for all KB Labs plugins. Documentation should focus on:
11
+
12
+ - Platform composables and command definitions (`shared-command-kit`)
13
+ - CLI UI formatting utilities (`shared-cli-ui`)
14
+ - Permission presets for plugin manifests (`perm-presets`)
15
+ - Mock builders and test helpers (`shared-testing`)
16
+ - Tool factory for agent tools (`shared-tool-kit`)
17
+
18
+ ## Project Documentation Structure
19
+
20
+ ```
21
+ docs/
22
+ ├── DOCUMENTATION.md # This standard (REQUIRED)
23
+ └── adr/ # Architecture Decision Records
24
+ ├── 0000-template.md # ADR template
25
+ └── *.md # ADR files
26
+ ```
27
+
28
+ ## Required Documentation
29
+
30
+ This project requires:
31
+
32
+ - [x] `README.md` in root with all required sections
33
+ - [x] `CONTRIBUTING.md` in root with development guidelines
34
+ - [x] `docs/DOCUMENTATION.md` (this file)
35
+ - [ ] `docs/adr/0000-template.md` (ADR template - should be created from main standard)
36
+ - [x] `LICENSE` in root
37
+
38
+ ## ADR Requirements
39
+
40
+ All ADRs must follow the format defined in the [main standard](https://github.com/KirillBaranov/kb-labs/blob/main/docs/DOCUMENTATION.md#architecture-decision-records-adr) with:
41
+
42
+ - Required metadata: Date, Status, Deciders, Last Reviewed, Tags
43
+ - Minimum 1 tag, maximum 5 tags
44
+ - Tags from approved list
45
+ - See main standard `docs/templates/ADR.template.md` for template
46
+
47
+ ## Cross-Linking
48
+
49
+ This project links to:
50
+
51
+ **Dependencies:**
52
+ - None (shared utilities only)
53
+
54
+ **Used By:**
55
+ - [@kb-labs/core](https://github.com/KirillBaranov/kb-labs-core) - Core utilities
56
+ - [@kb-labs/cli](https://github.com/KirillBaranov/kb-labs-cli) - CLI wrapper
57
+ - [@kb-labs/ai-review](https://github.com/KirillBaranov/kb-labs-ai-review) - AI Review
58
+ - All other KB Labs products
59
+
60
+ **Ecosystem:**
61
+ - [KB Labs](https://github.com/KirillBaranov/kb-labs) - Main ecosystem repository
62
+
63
+ ---
64
+
65
+ **Last Updated:** 2026-02-24
66
+ **Standard Version:** 1.0 (following KB Labs ecosystem standard)
67
+ **See Main Standard:** [KB Labs Documentation Standard](https://github.com/KirillBaranov/kb-labs/blob/main/docs/DOCUMENTATION.md)
68
+
69
+
70
+