@kb-labs/shared 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursorrules +32 -0
- package/.github/workflows/ci.yml +13 -0
- package/.github/workflows/deploy.yml +28 -0
- package/.github/workflows/docker-build.yml +25 -0
- package/.github/workflows/drift-check.yml +10 -0
- package/.github/workflows/profiles-validate.yml +16 -0
- package/.github/workflows/release.yml +8 -0
- package/.kb/devkit/agents/devkit-maintainer/context.globs +15 -0
- package/.kb/devkit/agents/devkit-maintainer/permissions.yml +17 -0
- package/.kb/devkit/agents/devkit-maintainer/prompt.md +28 -0
- package/.kb/devkit/agents/devkit-maintainer/runbook.md +31 -0
- package/.kb/devkit/agents/docs-crafter/prompt.md +24 -0
- package/.kb/devkit/agents/docs-crafter/runbook.md +18 -0
- package/.kb/devkit/agents/release-manager/context.globs +7 -0
- package/.kb/devkit/agents/release-manager/prompt.md +27 -0
- package/.kb/devkit/agents/release-manager/runbook.md +17 -0
- package/.kb/devkit/agents/test-generator/context.globs +7 -0
- package/.kb/devkit/agents/test-generator/prompt.md +27 -0
- package/.kb/devkit/agents/test-generator/runbook.md +18 -0
- package/.vscode/settings.json +23 -0
- package/CHANGELOG.md +33 -0
- package/CONTRIBUTING.md +117 -0
- package/LICENSE +21 -0
- package/README.md +306 -0
- package/docs/DECLARATIVE-FLAGS-AND-ENV.md +622 -0
- package/docs/DOCUMENTATION.md +70 -0
- package/docs/adr/0000-template.md +52 -0
- package/docs/adr/0001-architecture-and-repository-layout.md +31 -0
- package/docs/adr/0002-plugins-and-extensibility.md +44 -0
- package/docs/adr/0003-package-and-module-boundaries.md +35 -0
- package/docs/adr/0004-versioning-and-release-policy.md +36 -0
- package/docs/adr/0005-reactive-loader-pattern.md +179 -0
- package/docs/adr/0006-declarative-flags-and-env-systems.md +376 -0
- package/eslint.config.js +27 -0
- package/kb-labs.config.json +5 -0
- package/package.json +88 -0
- package/package.json.bin +25 -0
- package/package.json.lib +30 -0
- package/packages/shared-cli-ui/CHANGELOG.md +20 -0
- package/packages/shared-cli-ui/README.md +342 -0
- package/packages/shared-cli-ui/docs/ARCHITECTURE.md +105 -0
- package/packages/shared-cli-ui/eslint.config.js +27 -0
- package/packages/shared-cli-ui/package.json +72 -0
- package/packages/shared-cli-ui/src/__tests__/artifacts-display.spec.ts +89 -0
- package/packages/shared-cli-ui/src/__tests__/format.spec.ts +44 -0
- package/packages/shared-cli-ui/src/__tests__/loader-json-mode.test.ts +119 -0
- package/packages/shared-cli-ui/src/artifacts-display.ts +266 -0
- package/packages/shared-cli-ui/src/cli-auto-discovery.ts +120 -0
- package/packages/shared-cli-ui/src/colors.ts +142 -0
- package/packages/shared-cli-ui/src/command-discovery.ts +72 -0
- package/packages/shared-cli-ui/src/command-output.ts +153 -0
- package/packages/shared-cli-ui/src/command-result.ts +267 -0
- package/packages/shared-cli-ui/src/command-runner.ts +310 -0
- package/packages/shared-cli-ui/src/command-suggestions.ts +204 -0
- package/packages/shared-cli-ui/src/debug/components/output.ts +141 -0
- package/packages/shared-cli-ui/src/debug/components/trace.ts +101 -0
- package/packages/shared-cli-ui/src/debug/components/tree.ts +88 -0
- package/packages/shared-cli-ui/src/debug/formatters/ai.ts +17 -0
- package/packages/shared-cli-ui/src/debug/formatters/human.ts +98 -0
- package/packages/shared-cli-ui/src/debug/formatters/timeline.ts +94 -0
- package/packages/shared-cli-ui/src/debug/index.ts +56 -0
- package/packages/shared-cli-ui/src/debug/types.ts +57 -0
- package/packages/shared-cli-ui/src/debug/utilities.ts +203 -0
- package/packages/shared-cli-ui/src/dynamic-command-discovery.ts +131 -0
- package/packages/shared-cli-ui/src/format.ts +412 -0
- package/packages/shared-cli-ui/src/index.ts +34 -0
- package/packages/shared-cli-ui/src/loader.ts +196 -0
- package/packages/shared-cli-ui/src/manifest-parser.ts +151 -0
- package/packages/shared-cli-ui/src/modern-format.ts +271 -0
- package/packages/shared-cli-ui/src/multi-cli-suggestions.ts +159 -0
- package/packages/shared-cli-ui/src/table.ts +134 -0
- package/packages/shared-cli-ui/src/timing-tracker.ts +68 -0
- package/packages/shared-cli-ui/src/utils/context.ts +12 -0
- package/packages/shared-cli-ui/src/utils/env.ts +164 -0
- package/packages/shared-cli-ui/src/utils/flags.ts +269 -0
- package/packages/shared-cli-ui/src/utils/path.ts +8 -0
- package/packages/shared-cli-ui/tsconfig.build.json +15 -0
- package/packages/shared-cli-ui/tsconfig.json +9 -0
- package/packages/shared-cli-ui/tsup.config.ts +11 -0
- package/packages/shared-cli-ui/vitest.config.ts +15 -0
- package/packages/shared-command-kit/CHANGELOG.md +20 -0
- package/packages/shared-command-kit/LICENSE +22 -0
- package/packages/shared-command-kit/README.md +1030 -0
- package/packages/shared-command-kit/docs/HIGH-LEVEL-API.md +89 -0
- package/packages/shared-command-kit/docs/LOW-LEVEL-API.md +105 -0
- package/packages/shared-command-kit/docs/MIGRATION-GUIDE.md +135 -0
- package/packages/shared-command-kit/eslint.config.js +27 -0
- package/packages/shared-command-kit/eslint.config.ts +14 -0
- package/packages/shared-command-kit/package.json +76 -0
- package/packages/shared-command-kit/prettierrc.json +5 -0
- package/packages/shared-command-kit/src/__tests__/define-command.spec.ts +294 -0
- package/packages/shared-command-kit/src/__tests__/define-route.test.ts +285 -0
- package/packages/shared-command-kit/src/__tests__/define-system-command.spec.ts +508 -0
- package/packages/shared-command-kit/src/__tests__/define-webhook.test.ts +156 -0
- package/packages/shared-command-kit/src/__tests__/define-websocket.test.ts +316 -0
- package/packages/shared-command-kit/src/__tests__/errors.spec.ts +45 -0
- package/packages/shared-command-kit/src/__tests__/flags.spec.ts +353 -0
- package/packages/shared-command-kit/src/__tests__/platform-api.test.ts +135 -0
- package/packages/shared-command-kit/src/__tests__/plugin-context-v3.snapshot.spec.ts +240 -0
- package/packages/shared-command-kit/src/__tests__/ws-types.test.ts +359 -0
- package/packages/shared-command-kit/src/analytics/index.ts +6 -0
- package/packages/shared-command-kit/src/analytics/with-analytics.ts +195 -0
- package/packages/shared-command-kit/src/define-action.ts +100 -0
- package/packages/shared-command-kit/src/define-command.ts +113 -0
- package/packages/shared-command-kit/src/define-route.ts +113 -0
- package/packages/shared-command-kit/src/define-system-command.ts +362 -0
- package/packages/shared-command-kit/src/define-webhook.ts +115 -0
- package/packages/shared-command-kit/src/define-websocket.ts +308 -0
- package/packages/shared-command-kit/src/errors/factory.ts +282 -0
- package/packages/shared-command-kit/src/errors/format-validation.ts +144 -0
- package/packages/shared-command-kit/src/errors/format.ts +92 -0
- package/packages/shared-command-kit/src/errors/index.ts +9 -0
- package/packages/shared-command-kit/src/errors/types.ts +32 -0
- package/packages/shared-command-kit/src/flags/define.ts +92 -0
- package/packages/shared-command-kit/src/flags/index.ts +9 -0
- package/packages/shared-command-kit/src/flags/types.ts +153 -0
- package/packages/shared-command-kit/src/flags/validate.ts +358 -0
- package/packages/shared-command-kit/src/helpers/context.ts +8 -0
- package/packages/shared-command-kit/src/helpers/flags.ts +84 -0
- package/packages/shared-command-kit/src/helpers/index.ts +42 -0
- package/packages/shared-command-kit/src/helpers/patterns.ts +464 -0
- package/packages/shared-command-kit/src/helpers/platform.ts +335 -0
- package/packages/shared-command-kit/src/helpers/use-analytics.ts +95 -0
- package/packages/shared-command-kit/src/helpers/use-cache.ts +97 -0
- package/packages/shared-command-kit/src/helpers/use-config.ts +99 -0
- package/packages/shared-command-kit/src/helpers/use-embeddings.ts +49 -0
- package/packages/shared-command-kit/src/helpers/use-llm.ts +316 -0
- package/packages/shared-command-kit/src/helpers/use-logger.ts +77 -0
- package/packages/shared-command-kit/src/helpers/use-platform.ts +111 -0
- package/packages/shared-command-kit/src/helpers/use-resource-broker.ts +106 -0
- package/packages/shared-command-kit/src/helpers/use-storage.ts +71 -0
- package/packages/shared-command-kit/src/helpers/use-vector-store.ts +49 -0
- package/packages/shared-command-kit/src/helpers/validation.ts +398 -0
- package/packages/shared-command-kit/src/index.ts +410 -0
- package/packages/shared-command-kit/src/jobs.ts +132 -0
- package/packages/shared-command-kit/src/lifecycle/define-handlers.ts +366 -0
- package/packages/shared-command-kit/src/lifecycle/index.ts +6 -0
- package/packages/shared-command-kit/src/manifest.ts +127 -0
- package/packages/shared-command-kit/src/rest/define-handler.ts +187 -0
- package/packages/shared-command-kit/src/rest/index.ts +11 -0
- package/packages/shared-command-kit/src/studio/index.ts +12 -0
- package/packages/shared-command-kit/src/validation/index.ts +6 -0
- package/packages/shared-command-kit/src/validation/schema-builders.ts +409 -0
- package/packages/shared-command-kit/src/ws-types.ts +106 -0
- package/packages/shared-command-kit/tsconfig.build.json +15 -0
- package/packages/shared-command-kit/tsconfig.json +9 -0
- package/packages/shared-command-kit/tsup.config.ts +30 -0
- package/packages/shared-command-kit/vitest.config.ts +4 -0
- package/packages/shared-http/package.json +67 -0
- package/packages/shared-http/src/__tests__/log-correlation.test.ts +81 -0
- package/packages/shared-http/src/__tests__/operation-metrics-tracker.test.ts +55 -0
- package/packages/shared-http/src/http-observability-collector.ts +363 -0
- package/packages/shared-http/src/index.ts +36 -0
- package/packages/shared-http/src/log-correlation.ts +89 -0
- package/packages/shared-http/src/operation-metrics-tracker.ts +107 -0
- package/packages/shared-http/src/register-openapi.ts +108 -0
- package/packages/shared-http/src/resolve-schema-ref.ts +75 -0
- package/packages/shared-http/src/schemas.ts +29 -0
- package/packages/shared-http/src/service-observability.ts +63 -0
- package/packages/shared-http/tsconfig.build.json +15 -0
- package/packages/shared-http/tsconfig.json +9 -0
- package/packages/shared-http/tsup.config.ts +23 -0
- package/packages/shared-http/vitest.config.ts +13 -0
- package/packages/shared-perm-presets/CHANGELOG.md +20 -0
- package/packages/shared-perm-presets/README.md +78 -0
- package/packages/shared-perm-presets/eslint.config.js +27 -0
- package/packages/shared-perm-presets/package.json +45 -0
- package/packages/shared-perm-presets/src/__tests__/combine.test.ts +403 -0
- package/packages/shared-perm-presets/src/__tests__/presets.test.ts +205 -0
- package/packages/shared-perm-presets/src/combine.ts +278 -0
- package/packages/shared-perm-presets/src/index.ts +18 -0
- package/packages/shared-perm-presets/src/presets/ci-environment.ts +34 -0
- package/packages/shared-perm-presets/src/presets/full-env.ts +16 -0
- package/packages/shared-perm-presets/src/presets/git-workflow.ts +40 -0
- package/packages/shared-perm-presets/src/presets/index.ts +8 -0
- package/packages/shared-perm-presets/src/presets/kb-platform.ts +30 -0
- package/packages/shared-perm-presets/src/presets/llm-access.ts +29 -0
- package/packages/shared-perm-presets/src/presets/minimal.ts +21 -0
- package/packages/shared-perm-presets/src/presets/npm-publish.ts +48 -0
- package/packages/shared-perm-presets/src/presets/vector-store.ts +40 -0
- package/packages/shared-perm-presets/src/types.ts +192 -0
- package/packages/shared-perm-presets/tsconfig.build.json +15 -0
- package/packages/shared-perm-presets/tsconfig.json +9 -0
- package/packages/shared-perm-presets/tsup.config.ts +8 -0
- package/packages/shared-perm-presets/vitest.config.ts +9 -0
- package/packages/shared-testing/CHANGELOG.md +20 -0
- package/packages/shared-testing/README.md +430 -0
- package/packages/shared-testing/package.json +51 -0
- package/packages/shared-testing/src/__tests__/create-test-context.test.ts +199 -0
- package/packages/shared-testing/src/__tests__/mock-cache.test.ts +174 -0
- package/packages/shared-testing/src/__tests__/mock-llm.test.ts +212 -0
- package/packages/shared-testing/src/__tests__/setup-platform.test.ts +90 -0
- package/packages/shared-testing/src/__tests__/test-command.test.ts +557 -0
- package/packages/shared-testing/src/create-test-context.ts +550 -0
- package/packages/shared-testing/src/index.ts +77 -0
- package/packages/shared-testing/src/mock-cache.ts +179 -0
- package/packages/shared-testing/src/mock-llm.ts +319 -0
- package/packages/shared-testing/src/mock-logger.ts +97 -0
- package/packages/shared-testing/src/mock-storage.ts +108 -0
- package/packages/shared-testing/src/setup-platform.ts +101 -0
- package/packages/shared-testing/src/test-command.ts +288 -0
- package/packages/shared-testing/tsconfig.build.json +15 -0
- package/packages/shared-testing/tsconfig.json +9 -0
- package/packages/shared-testing/tsup.config.ts +20 -0
- package/packages/shared-testing/vitest.config.ts +3 -0
- package/packages/shared-tool-kit/CHANGELOG.md +20 -0
- package/packages/shared-tool-kit/package.json +47 -0
- package/packages/shared-tool-kit/src/__tests__/factory.test.ts +103 -0
- package/packages/shared-tool-kit/src/__tests__/mock-tool.test.ts +95 -0
- package/packages/shared-tool-kit/src/factory.ts +126 -0
- package/packages/shared-tool-kit/src/index.ts +32 -0
- package/packages/shared-tool-kit/src/testing/index.ts +84 -0
- package/packages/shared-tool-kit/tsconfig.build.json +15 -0
- package/packages/shared-tool-kit/tsconfig.json +9 -0
- package/packages/shared-tool-kit/tsup.config.ts +21 -0
- package/pnpm-workspace.yaml +11070 -0
- package/prettierrc.json +1 -0
- package/scripts/devkit-sync.mjs +37 -0
- package/scripts/hooks/post-push +9 -0
- package/scripts/hooks/pre-commit +9 -0
- package/scripts/hooks/pre-push +9 -0
- package/tsconfig.base.json +9 -0
- package/tsconfig.build.json +15 -0
- package/tsconfig.json +9 -0
- package/tsconfig.paths.json +50 -0
- package/tsconfig.tools.json +18 -0
- package/tsup.config.bin.ts +34 -0
- package/tsup.config.cli.ts +41 -0
- package/tsup.config.dual.ts +46 -0
- package/tsup.config.ts +36 -0
- package/tsup.external.json +104 -0
- package/vitest.config.ts +48 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# ADR-0006: Declarative Flags and Environment Variables Systems
|
|
2
|
+
|
|
3
|
+
**Date:** 2025-12-19
|
|
4
|
+
**Status:** Accepted
|
|
5
|
+
**Deciders:** KB Labs Team
|
|
6
|
+
**Last Reviewed:** 2025-12-19
|
|
7
|
+
**Tags:** dx, type-safety, plugin-system, v3, developer-experience
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
V3 plugin commands had to manually extract and parse CLI flags and environment variables, leading to significant developer friction:
|
|
12
|
+
|
|
13
|
+
### Problems
|
|
14
|
+
|
|
15
|
+
1. **Excessive Boilerplate**: 5+ lines per command to extract env vars
|
|
16
|
+
2. **No Type Safety**: Manual casting and parsing without compile-time checks
|
|
17
|
+
3. **Inconsistent Patterns**: Different commands used different extraction approaches
|
|
18
|
+
4. **Error-Prone**: Easy to forget validation or default values
|
|
19
|
+
5. **Poor Maintainability**: Repetitive code across all commands
|
|
20
|
+
|
|
21
|
+
### Example of Manual Approach
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// ❌ OLD: Manual extraction and parsing (5+ lines)
|
|
25
|
+
const env: CommitEnv = {
|
|
26
|
+
KB_COMMIT_LLM_ENABLED: ctx.runtime.env('KB_COMMIT_LLM_ENABLED'),
|
|
27
|
+
KB_COMMIT_LLM_TEMPERATURE: ctx.runtime.env('KB_COMMIT_LLM_TEMPERATURE'),
|
|
28
|
+
KB_COMMIT_LLM_MAX_TOKENS: ctx.runtime.env('KB_COMMIT_LLM_MAX_TOKENS'),
|
|
29
|
+
KB_COMMIT_STORAGE_DIR: ctx.runtime.env('KB_COMMIT_STORAGE_DIR'),
|
|
30
|
+
KB_COMMIT_AUTO_STAGE: ctx.runtime.env('KB_COMMIT_AUTO_STAGE'),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Manual parsing in config resolver (20+ lines)
|
|
34
|
+
if (env.KB_COMMIT_LLM_TEMPERATURE !== undefined) {
|
|
35
|
+
const temp = parseFloat(env.KB_COMMIT_LLM_TEMPERATURE);
|
|
36
|
+
if (!isNaN(temp) && temp >= 0 && temp <= 1) {
|
|
37
|
+
config.llm.temperature = temp;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// ... repeat for every env var
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Impact
|
|
44
|
+
|
|
45
|
+
- **Developer Velocity**: Slowed down plugin development
|
|
46
|
+
- **Code Quality**: Inconsistent validation across commands
|
|
47
|
+
- **Type Safety**: Runtime errors from incorrect parsing
|
|
48
|
+
- **Maintenance**: Hard to refactor when changing env var types
|
|
49
|
+
|
|
50
|
+
### Constraints
|
|
51
|
+
|
|
52
|
+
- Must integrate with existing V3 plugin system
|
|
53
|
+
- Must maintain backward compatibility
|
|
54
|
+
- Cannot introduce heavy dependencies (Zod, class-validator, etc.)
|
|
55
|
+
- Must support type inference for excellent IDE experience
|
|
56
|
+
|
|
57
|
+
## Decision
|
|
58
|
+
|
|
59
|
+
Implement two declarative systems for type-safe flag and env variable handling:
|
|
60
|
+
|
|
61
|
+
### 1. `defineFlags()` — CLI Flags System
|
|
62
|
+
|
|
63
|
+
Declarative CLI flag definitions with automatic type inference.
|
|
64
|
+
|
|
65
|
+
**Location**: `@kb-labs/shared-cli-ui/src/utils/flags.ts`
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
export const commitFlags = defineFlags({
|
|
69
|
+
scope: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
description: 'Limit to package or path',
|
|
72
|
+
examples: ['@kb-labs/core', 'packages/**'],
|
|
73
|
+
},
|
|
74
|
+
'dry-run': {
|
|
75
|
+
type: 'boolean',
|
|
76
|
+
description: 'Preview without applying',
|
|
77
|
+
default: false,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export type CommitFlags = typeof commitFlags.type;
|
|
82
|
+
// → { scope?: string; 'dry-run': boolean }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. `defineEnv()` — Environment Variables System
|
|
86
|
+
|
|
87
|
+
Declarative environment variable definitions with automatic type inference.
|
|
88
|
+
|
|
89
|
+
**Location**: `@kb-labs/shared-cli-ui/src/utils/env.ts`
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
export const commitEnv = defineEnv({
|
|
93
|
+
KB_COMMIT_LLM_TEMPERATURE: {
|
|
94
|
+
type: 'number',
|
|
95
|
+
default: 0.3,
|
|
96
|
+
description: 'LLM temperature (0-1)',
|
|
97
|
+
validate: (v) => {
|
|
98
|
+
if (v < 0 || v > 1) throw new Error('Must be 0-1');
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
export type CommitEnv = typeof commitEnv.type;
|
|
104
|
+
// → { KB_COMMIT_LLM_TEMPERATURE: number }
|
|
105
|
+
|
|
106
|
+
// Usage (1 line instead of 5+)
|
|
107
|
+
const env = commitEnv.parse(ctx.runtime);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Key Features
|
|
111
|
+
|
|
112
|
+
**Type System**:
|
|
113
|
+
- Supports `string`, `boolean`, `number` primitive types
|
|
114
|
+
- Automatic type inference via TypeScript mapped types
|
|
115
|
+
- Optional vs required based on `default` presence
|
|
116
|
+
- Custom validation functions for strings and numbers
|
|
117
|
+
|
|
118
|
+
**Runtime Parsing**:
|
|
119
|
+
- Automatic type coercion and validation
|
|
120
|
+
- Helpful error messages on parse failures
|
|
121
|
+
- Default value application
|
|
122
|
+
- Validation function execution
|
|
123
|
+
|
|
124
|
+
**Shared Infrastructure**:
|
|
125
|
+
- Both systems reuse same type parsers (`parseBoolean`, `parseString`, `parseNumber`)
|
|
126
|
+
- Consistent API surface
|
|
127
|
+
- No dependency duplication
|
|
128
|
+
|
|
129
|
+
### Architecture
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
┌─────────────────────────────────────────────────────┐
|
|
133
|
+
│ defineFlags / defineEnv │
|
|
134
|
+
│ Declarative schema with automatic type inference │
|
|
135
|
+
└─────────────────────────────────────────────────────┘
|
|
136
|
+
│
|
|
137
|
+
┌───────────────┴───────────────┐
|
|
138
|
+
│ │
|
|
139
|
+
▼ ▼
|
|
140
|
+
┌───────────────┐ ┌──────────────┐
|
|
141
|
+
│ parseFlagsFrom│ │parseEnvFrom │
|
|
142
|
+
│ Input │ │ Runtime │
|
|
143
|
+
└───────────────┘ └──────────────┘
|
|
144
|
+
│ │
|
|
145
|
+
└───────────┬───────────────────┘
|
|
146
|
+
▼
|
|
147
|
+
┌───────────────────────┐
|
|
148
|
+
│ Shared Type Parsers │
|
|
149
|
+
│ - parseBoolean │
|
|
150
|
+
│ - parseString │
|
|
151
|
+
│ - parseNumber │
|
|
152
|
+
└───────────────────────┘
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Type Inference
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// Flags with defaults are non-optional
|
|
159
|
+
type InferFlagType<T extends FlagSpec> =
|
|
160
|
+
T extends StringFlagSpec
|
|
161
|
+
? T extends { default: string } ? string : string | undefined
|
|
162
|
+
: T extends BooleanFlagSpec
|
|
163
|
+
? T extends { default: boolean } ? boolean : boolean | undefined
|
|
164
|
+
: T extends NumberFlagSpec
|
|
165
|
+
? T extends { default: number } ? number : number | undefined
|
|
166
|
+
: never;
|
|
167
|
+
|
|
168
|
+
export type InferFlagsType<T extends FlagsSchema> = {
|
|
169
|
+
[K in keyof T]: InferFlagType<T[K]>;
|
|
170
|
+
};
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Result**: Flags with defaults become `string`, without defaults become `string | undefined`.
|
|
174
|
+
|
|
175
|
+
### Avoiding Circular Dependencies
|
|
176
|
+
|
|
177
|
+
Problem: `shared-cli-ui` cannot depend on `@kb-labs/plugin-contracts`.
|
|
178
|
+
|
|
179
|
+
Solution: Minimal `RuntimeLike` interface:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
/**
|
|
183
|
+
* Avoids dependency on @kb-labs/plugin-contracts
|
|
184
|
+
*/
|
|
185
|
+
export interface RuntimeLike {
|
|
186
|
+
env(key: string): string | undefined;
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Consequences
|
|
191
|
+
|
|
192
|
+
### Positive
|
|
193
|
+
|
|
194
|
+
✅ **5+ lines → 1 line**: Massive reduction in boilerplate
|
|
195
|
+
✅ **Type safety**: Automatic type inference, compile-time checks
|
|
196
|
+
✅ **Validation**: Built-in type validation + custom validators
|
|
197
|
+
✅ **Defaults**: Declarative defaults with proper type narrowing
|
|
198
|
+
✅ **Consistency**: Same pattern across all commands
|
|
199
|
+
✅ **Self-documenting**: Schema serves as documentation
|
|
200
|
+
✅ **DX**: Excellent IDE autocomplete and type hints
|
|
201
|
+
✅ **Backward compatible**: V3 bootstrap auto-merges `input.flags`
|
|
202
|
+
|
|
203
|
+
### Negative
|
|
204
|
+
|
|
205
|
+
⚠️ **Migration effort**: Existing commands need updating
|
|
206
|
+
⚠️ **Learning curve**: Developers need to learn new pattern
|
|
207
|
+
⚠️ **Schema duplication**: Flags in contracts + manifest (acceptable tradeoff)
|
|
208
|
+
|
|
209
|
+
### Neutral
|
|
210
|
+
|
|
211
|
+
🔹 **New dependency**: Commands depend on `@kb-labs/sdk` for `defineEnv()`
|
|
212
|
+
🔹 **Type complexity**: Uses advanced TypeScript (mapped types, conditional types)
|
|
213
|
+
🔹 **Runtime overhead**: Minimal (parsing happens once per command)
|
|
214
|
+
|
|
215
|
+
### Before/After Comparison
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
// ❌ BEFORE: Manual, error-prone, no type safety (25+ lines)
|
|
219
|
+
const env: CommitEnv = {
|
|
220
|
+
KB_COMMIT_LLM_ENABLED: ctx.runtime.env('KB_COMMIT_LLM_ENABLED'),
|
|
221
|
+
KB_COMMIT_LLM_TEMPERATURE: ctx.runtime.env('KB_COMMIT_LLM_TEMPERATURE'),
|
|
222
|
+
KB_COMMIT_LLM_MAX_TOKENS: ctx.runtime.env('KB_COMMIT_LLM_MAX_TOKENS'),
|
|
223
|
+
KB_COMMIT_STORAGE_DIR: ctx.runtime.env('KB_COMMIT_STORAGE_DIR'),
|
|
224
|
+
KB_COMMIT_AUTO_STAGE: ctx.runtime.env('KB_COMMIT_AUTO_STAGE'),
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// Manual parsing
|
|
228
|
+
if (env.KB_COMMIT_LLM_TEMPERATURE !== undefined) {
|
|
229
|
+
const temp = parseFloat(env.KB_COMMIT_LLM_TEMPERATURE);
|
|
230
|
+
if (!isNaN(temp) && temp >= 0 && temp <= 1) {
|
|
231
|
+
config.llm.temperature = temp;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// ✅ AFTER: Declarative, type-safe, DRY (1 line)
|
|
238
|
+
const env = commitEnv.parse(ctx.runtime);
|
|
239
|
+
// env.KB_COMMIT_LLM_TEMPERATURE → number (fully typed, validated)
|
|
240
|
+
|
|
241
|
+
// Clean config resolution
|
|
242
|
+
const config: CommitPluginConfig = {
|
|
243
|
+
llm: {
|
|
244
|
+
temperature: env.KB_COMMIT_LLM_TEMPERATURE ?? fileConfig.llm?.temperature ?? 0.3,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Alternatives Considered
|
|
250
|
+
|
|
251
|
+
### 1. Zod Schemas
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
const commitEnvSchema = z.object({
|
|
255
|
+
KB_COMMIT_LLM_TEMPERATURE: z.number().min(0).max(1).default(0.3),
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Rejected**:
|
|
260
|
+
- Too heavy (adds 14KB Zod dependency to shared-cli-ui)
|
|
261
|
+
- Overkill for simple primitive types
|
|
262
|
+
- More complex API surface
|
|
263
|
+
|
|
264
|
+
### 2. Class-based Validators
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
class CommitEnv {
|
|
268
|
+
@IsBoolean() KB_COMMIT_LLM_ENABLED = true;
|
|
269
|
+
@IsNumber() @Min(0) @Max(1) KB_COMMIT_LLM_TEMPERATURE = 0.3;
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Rejected**:
|
|
274
|
+
- Requires decorators (experimental TypeScript feature)
|
|
275
|
+
- More boilerplate than declarative approach
|
|
276
|
+
- Runtime reflection overhead
|
|
277
|
+
|
|
278
|
+
### 3. Manual Helper Functions
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
function useEnv<T>(schema: EnvSchema<T>): T {
|
|
282
|
+
// ...
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Rejected**:
|
|
287
|
+
- Similar complexity to our solution
|
|
288
|
+
- Less declarative
|
|
289
|
+
- Doesn't enable schema reuse for documentation
|
|
290
|
+
|
|
291
|
+
## Implementation
|
|
292
|
+
|
|
293
|
+
### Changes Made
|
|
294
|
+
|
|
295
|
+
1. **`@kb-labs/shared-cli-ui`**:
|
|
296
|
+
- Added `src/utils/flags.ts` — `defineFlags()` system
|
|
297
|
+
- Added `src/utils/env.ts` — `defineEnv()` system
|
|
298
|
+
- Exported parsers for reuse
|
|
299
|
+
|
|
300
|
+
2. **`@kb-labs/sdk`**:
|
|
301
|
+
- Re-exported `defineFlags`, `defineEnv`, and related types
|
|
302
|
+
- Added to public API for plugin developers
|
|
303
|
+
|
|
304
|
+
3. **`@kb-labs/commit-contracts`**:
|
|
305
|
+
- Added `src/flags.ts` — flag definitions
|
|
306
|
+
- Added `src/env.ts` — env definitions
|
|
307
|
+
- Removed old `CommitEnv` interface
|
|
308
|
+
- Updated `resolveCommitConfig()` to use typed values
|
|
309
|
+
|
|
310
|
+
4. **`@kb-labs/commit-cli`**:
|
|
311
|
+
- Migrated `run.ts` to use `commitEnv.parse()`
|
|
312
|
+
- Migrated `generate.ts` to use `commitEnv.parse()`
|
|
313
|
+
- Reduced boilerplate from 5+ lines to 1 line per command
|
|
314
|
+
|
|
315
|
+
### Migration Path
|
|
316
|
+
|
|
317
|
+
For existing plugins:
|
|
318
|
+
|
|
319
|
+
1. Create flag definitions in contracts:
|
|
320
|
+
```typescript
|
|
321
|
+
export const myFlags = defineFlags({
|
|
322
|
+
scope: { type: 'string', description: '...' },
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
2. Create env definitions in contracts:
|
|
327
|
+
```typescript
|
|
328
|
+
export const myEnv = defineEnv({
|
|
329
|
+
MY_VAR: { type: 'boolean', default: true },
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
3. Update commands:
|
|
334
|
+
```typescript
|
|
335
|
+
const env = myEnv.parse(ctx.runtime); // 1 line
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Testing
|
|
339
|
+
|
|
340
|
+
Verified with commit plugin:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
KB_COMMIT_LLM_TEMPERATURE=0.5 KB_COMMIT_LLM_MAX_TOKENS=3000 \
|
|
344
|
+
pnpm kb commit generate --scope="kb-labs-commit-plugin"
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Results:
|
|
348
|
+
- ✅ Env vars parsed correctly
|
|
349
|
+
- ✅ Type validation passed
|
|
350
|
+
- ✅ Command executed without errors
|
|
351
|
+
- ✅ No runtime performance impact
|
|
352
|
+
|
|
353
|
+
## Future Improvements
|
|
354
|
+
|
|
355
|
+
1. **Auto-generate manifest**: Extract flag definitions for plugin manifest
|
|
356
|
+
2. **CLI help generation**: Auto-generate `--help` text from flag descriptions
|
|
357
|
+
3. **Env var docs**: Auto-generate documentation from env schema
|
|
358
|
+
4. **Deprecation warnings**: Built-in support for deprecated flags/env vars
|
|
359
|
+
5. **Schema validation**: Validate manifest against flag schema at build time
|
|
360
|
+
|
|
361
|
+
## References
|
|
362
|
+
|
|
363
|
+
- TypeScript: [Mapped Types](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html)
|
|
364
|
+
- TypeScript: [Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html)
|
|
365
|
+
- V3 Plugin System: [docs/V3-IMPLEMENTATION-SPEC.md](../V3-IMPLEMENTATION-SPEC.md)
|
|
366
|
+
- Bootstrap Auto-Merge: `kb-labs-plugin/packages/plugin-runtime/src/v3/bootstrap.ts`
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
**Last Updated:** 2025-12-19
|
|
371
|
+
**Implementation**: Complete
|
|
372
|
+
**Packages Modified**:
|
|
373
|
+
- `@kb-labs/shared-cli-ui` — Added `defineFlags()` and `defineEnv()`
|
|
374
|
+
- `@kb-labs/sdk` — Re-exported utilities
|
|
375
|
+
- `@kb-labs/commit-contracts` — Added definitions
|
|
376
|
+
- `@kb-labs/commit-cli` — Migrated commands
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard ESLint configuration template
|
|
3
|
+
*
|
|
4
|
+
* This is the canonical template for all @kb-labs packages.
|
|
5
|
+
* DO NOT modify this file locally - it is synced from @kb-labs/devkit
|
|
6
|
+
*
|
|
7
|
+
* Customization guidelines:
|
|
8
|
+
* - DevKit preset already includes all standard ignores
|
|
9
|
+
* - Only add project-specific ignores if absolutely necessary
|
|
10
|
+
* - Document why custom ignores are needed
|
|
11
|
+
*
|
|
12
|
+
* @see https://github.com/kb-labs/devkit#eslint-configuration
|
|
13
|
+
*/
|
|
14
|
+
import nodePreset from '@kb-labs/devkit/eslint/node.js';
|
|
15
|
+
|
|
16
|
+
export default [
|
|
17
|
+
...nodePreset,
|
|
18
|
+
|
|
19
|
+
// OPTIONAL: Add project-specific ignores only if needed
|
|
20
|
+
// DevKit preset already ignores: dist/, coverage/, node_modules/, *.d.ts, scripts/, etc.
|
|
21
|
+
// {
|
|
22
|
+
// ignores: [
|
|
23
|
+
// // Add ONLY project-specific patterns here
|
|
24
|
+
// // Example: '**/*.generated.ts',
|
|
25
|
+
// ]
|
|
26
|
+
// }
|
|
27
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kb-labs/shared",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Shared utilities and contracts for KB Labs ecosystem",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Kirill Baranov",
|
|
8
|
+
"url": "https://github.com/kirill-baranov"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/kirill-baranov/kb-labs-shared.git"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/kirill-baranov/kb-labs-shared/issues"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/kirill-baranov/kb-labs-shared#readme",
|
|
19
|
+
"workspaces": [
|
|
20
|
+
"apps/*",
|
|
21
|
+
"packages/*"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"// ——— devkit": "────────────────────────────────────────",
|
|
25
|
+
"devkit:sync": "node scripts/devkit-sync.mjs",
|
|
26
|
+
"predevkit:sync": "pnpm devkit:paths",
|
|
27
|
+
"devkit:paths": "pnpm exec kb-devkit-paths",
|
|
28
|
+
"devkit:sync:ci": "node scripts/devkit-sync.mjs --ci-only",
|
|
29
|
+
"predevkit:sync:ci": "pnpm devkit:paths",
|
|
30
|
+
"devkit:check": "node scripts/devkit-sync.mjs --check",
|
|
31
|
+
"predevkit:check": "pnpm devkit:paths",
|
|
32
|
+
"devkit:force": "node scripts/devkit-sync.mjs --force",
|
|
33
|
+
"predevkit:force": "pnpm devkit:paths",
|
|
34
|
+
"devkit:help": "node scripts/devkit-sync.mjs --help",
|
|
35
|
+
"postinstall": "pnpm -s devkit:sync || true",
|
|
36
|
+
"// ——— core": "────────────────────────────────────────",
|
|
37
|
+
"build": "pnpm -r run build",
|
|
38
|
+
"build:clean": "pnpm -r run clean && pnpm -r run build",
|
|
39
|
+
"dev": "pnpm -r --parallel run dev",
|
|
40
|
+
"// ——— quality": "────────────────────────────────────────",
|
|
41
|
+
"lint": "pnpm -r --filter=\"./packages/*\" run lint",
|
|
42
|
+
"lint:fix": "pnpm -r --filter=\"./packages/*\" run lint:fix",
|
|
43
|
+
"test": "pnpm -r --if-present run test",
|
|
44
|
+
"test:coverage": "vitest run --coverage",
|
|
45
|
+
"test:watch": "pnpm -r --parallel --if-present run test:watch",
|
|
46
|
+
"type-check": "pnpm -r run type-check",
|
|
47
|
+
"format": "prettier -w .",
|
|
48
|
+
"format:check": "prettier -c .",
|
|
49
|
+
"// ——— ci/qa": "────────────────────────────────────────",
|
|
50
|
+
"check": "pnpm lint && pnpm type-check && pnpm test",
|
|
51
|
+
"ci": "pnpm clean && pnpm build && pnpm check",
|
|
52
|
+
"// ——— cleanup": "────────────────────────────────────────",
|
|
53
|
+
"clean": "pnpm -r run clean",
|
|
54
|
+
"clean:all": "rimraf node_modules packages/*/node_modules apps/*/node_modules dist"
|
|
55
|
+
},
|
|
56
|
+
"lint-staged": {
|
|
57
|
+
"*.{ts,tsx,js,jsx,json,md,yml,yaml}": [
|
|
58
|
+
"prettier -w"
|
|
59
|
+
],
|
|
60
|
+
"*.{ts,tsx,js,jsx}": [
|
|
61
|
+
"eslint --fix"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@actions/core": "^1",
|
|
66
|
+
"@actions/github": "^6",
|
|
67
|
+
"@types/node": "^24.3.3",
|
|
68
|
+
"@types/picomatch": "^4",
|
|
69
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
70
|
+
"better-sqlite3": "^12.2.0",
|
|
71
|
+
"colorette": "^2.0.20",
|
|
72
|
+
"tsup": "^8.5.0",
|
|
73
|
+
"typescript": "^5.6.3",
|
|
74
|
+
"vite": "^5.4.10",
|
|
75
|
+
"vitest": "^3.2.4",
|
|
76
|
+
"@kb-labs/devkit": "link:../../infra/kb-labs-devkit",
|
|
77
|
+
"rimraf": "^6.0.1"
|
|
78
|
+
},
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=18.18.0",
|
|
81
|
+
"pnpm": ">=9.0.0"
|
|
82
|
+
},
|
|
83
|
+
"packageManager": "pnpm@9.11.0",
|
|
84
|
+
"dependencies": {
|
|
85
|
+
"@kb-labs/devkit": "^1.1.0",
|
|
86
|
+
"zod": "^4.1.5"
|
|
87
|
+
}
|
|
88
|
+
}
|
package/package.json.bin
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kb-labs/your-package",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Your package description",
|
|
6
|
+
"bin": {
|
|
7
|
+
"your-cli": "./dist/bin.cjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsup",
|
|
14
|
+
"dev": "tsup --watch",
|
|
15
|
+
"lint": "eslint .",
|
|
16
|
+
"test": "vitest"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@kb-labs/devkit": "workspace:*",
|
|
21
|
+
"tsup": "^8.5.0",
|
|
22
|
+
"typescript": "^5.9.2",
|
|
23
|
+
"vitest": "^3.2.4"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/package.json.lib
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kb-labs/your-package",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Your package description",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsup",
|
|
19
|
+
"dev": "tsup --watch",
|
|
20
|
+
"lint": "eslint .",
|
|
21
|
+
"test": "vitest"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@kb-labs/devkit": "workspace:*",
|
|
26
|
+
"tsup": "^8.5.0",
|
|
27
|
+
"typescript": "^5.9.2",
|
|
28
|
+
"vitest": "^3.2.4"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## [1.1.0] - 2026-03-24
|
|
2
|
+
|
|
3
|
+
**5 packages** bumped to v1.1.0
|
|
4
|
+
|
|
5
|
+
| Package | Previous | Bump |
|
|
6
|
+
|---------|----------|------|
|
|
7
|
+
| `@kb-labs/perm-presets` | 1.0.0 | minor |
|
|
8
|
+
| `@kb-labs/shared-command-kit` | 1.0.0 | minor |
|
|
9
|
+
| `@kb-labs/shared-tool-kit` | 1.0.0 | minor |
|
|
10
|
+
| `@kb-labs/shared-cli-ui` | 1.0.0 | minor |
|
|
11
|
+
| `@kb-labs/shared-testing` | 1.0.0 | minor |
|
|
12
|
+
|
|
13
|
+
### ✨ New Features
|
|
14
|
+
|
|
15
|
+
- **config**: Introduces new configuration files for package management, allowing users to easily manage dependencies and ensure consistent environments across projects.
|
|
16
|
+
- **github**: Implements GitHub workflows for CI/CD, streamlining the development process and enabling quicker, more reliable software updates for users.
|
|
17
|
+
|
|
18
|
+
### 🐛 Bug Fixes
|
|
19
|
+
|
|
20
|
+
- **tests**: Improves code clarity by using an object type instead of a placeholder, which helps prevent misunderstandings in the codebase and enhances maintainability. Additionally, it resolves a linting issue that could lead to confusion when no value is returned from certain functions.
|