@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,335 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/helpers/platform
3
+ * Platform service access helpers with graceful error handling.
4
+ *
5
+ * These helpers provide convenient access to platform services with automatic
6
+ * configuration checks and helpful error messages.
7
+ */
8
+
9
+ import type { PluginContextV3 as PluginContext } from '@kb-labs/plugin-runtime';
10
+ import type {
11
+ ILLM,
12
+ IEmbeddings,
13
+ IVectorStore,
14
+ ICache,
15
+ IStorage,
16
+ ILogger,
17
+ IAnalytics,
18
+ IEventBus,
19
+ LLMOptions,
20
+ LLMResponse,
21
+ VectorSearchResult,
22
+ } from '@kb-labs/core-platform';
23
+
24
+ /**
25
+ * Error thrown when required platform service is not configured.
26
+ */
27
+ export class ServiceNotConfiguredError extends Error {
28
+ constructor(
29
+ public readonly service: string,
30
+ public readonly requiredAdapter?: string
31
+ ) {
32
+ super(
33
+ requiredAdapter
34
+ ? `Service '${service}' is not configured. Add "${requiredAdapter}" to kb.config.json adapters.`
35
+ : `Service '${service}' is not configured. Configure it in kb.config.json.`
36
+ );
37
+ this.name = 'ServiceNotConfiguredError';
38
+ }
39
+ }
40
+
41
+ // ═══════════════════════════════════════════════════════════════════════════
42
+ // ADAPTERS (Replaceable Services)
43
+ // ═══════════════════════════════════════════════════════════════════════════
44
+
45
+ /**
46
+ * Get LLM service with configuration check.
47
+ * Throws if LLM is not configured (using NoOp/Mock).
48
+ *
49
+ * @param ctx - Plugin context
50
+ * @returns LLM service
51
+ * @throws {ServiceNotConfiguredError} If LLM not configured
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const llm = useLLM(ctx);
56
+ * const response = await llm.complete('Hello, world!');
57
+ * ```
58
+ */
59
+ export function useLLM(ctx: PluginContext): ILLM {
60
+ if (!ctx.platform.llm) {
61
+ throw new ServiceNotConfiguredError('llm', '@kb-labs/shared-openai');
62
+ }
63
+ return ctx.platform.llm;
64
+ }
65
+
66
+ /**
67
+ * Get embeddings service with configuration check.
68
+ * Throws if embeddings are not configured.
69
+ *
70
+ * @param ctx - Plugin context
71
+ * @returns Embeddings service
72
+ * @throws {ServiceNotConfiguredError} If embeddings not configured
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const embeddings = useEmbeddings(ctx);
77
+ * const vector = await embeddings.embed('text to embed');
78
+ * ```
79
+ */
80
+ export function useEmbeddings(ctx: PluginContext): IEmbeddings {
81
+ if (!ctx.platform.embeddings) {
82
+ throw new ServiceNotConfiguredError('embeddings', '@kb-labs/shared-openai');
83
+ }
84
+ return ctx.platform.embeddings;
85
+ }
86
+
87
+ /**
88
+ * Get vector store with configuration check.
89
+ * Throws if vector store is not configured (using in-memory fallback).
90
+ *
91
+ * @param ctx - Plugin context
92
+ * @returns Vector store service
93
+ * @throws {ServiceNotConfiguredError} If vectorStore not configured
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const vectorStore = useVectorStore(ctx);
98
+ * const results = await vectorStore.search(queryVector, 10);
99
+ * ```
100
+ */
101
+ export function useVectorStore(ctx: PluginContext): IVectorStore {
102
+ if (!ctx.platform.vectorStore) {
103
+ throw new ServiceNotConfiguredError('vectorStore', '@kb-labs/mind-qdrant');
104
+ }
105
+ return ctx.platform.vectorStore;
106
+ }
107
+
108
+ /**
109
+ * Get cache service.
110
+ * Safe to use even without configuration (falls back to in-memory).
111
+ *
112
+ * @param ctx - Plugin context
113
+ * @returns Cache service (always available)
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const cache = useCache(ctx);
118
+ * await cache.set('key', value, 3600000); // TTL 1 hour
119
+ * const cached = await cache.get('key');
120
+ * ```
121
+ */
122
+ export function useCache(ctx: PluginContext): ICache {
123
+ return ctx.platform.cache!;
124
+ }
125
+
126
+ /**
127
+ * Get storage service.
128
+ * Safe to use even without configuration (falls back to in-memory).
129
+ *
130
+ * @param ctx - Plugin context
131
+ * @returns Storage service (always available)
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const storage = useStorage(ctx);
136
+ * await storage.write('path/to/file.txt', Buffer.from('content'));
137
+ * const content = await storage.read('path/to/file.txt');
138
+ * ```
139
+ */
140
+ export function useStorage(ctx: PluginContext): IStorage {
141
+ return ctx.platform.storage!;
142
+ }
143
+
144
+ /**
145
+ * Get logger service.
146
+ * Always available (falls back to console logger).
147
+ *
148
+ * @param ctx - Plugin context
149
+ * @returns Logger service (always available)
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * const logger = useLogger(ctx);
154
+ * logger.info('Processing started', { itemCount: 10 });
155
+ * logger.error('Failed to process', error);
156
+ * ```
157
+ */
158
+ export function useLogger(ctx: PluginContext): ILogger {
159
+ return ctx.platform.logger!;
160
+ }
161
+
162
+ /**
163
+ * Get analytics service.
164
+ * Safe to use even without configuration (falls back to NoOp).
165
+ *
166
+ * @param ctx - Plugin context
167
+ * @returns Analytics service (always available)
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * const analytics = useAnalytics(ctx);
172
+ * await analytics.track('feature.used', { feature: 'search' });
173
+ * ```
174
+ */
175
+ export function useAnalytics(ctx: PluginContext): IAnalytics {
176
+ return ctx.platform.analytics!;
177
+ }
178
+
179
+ /**
180
+ * Get event bus service.
181
+ * Safe to use even without configuration (falls back to in-memory).
182
+ *
183
+ * @param ctx - Plugin context
184
+ * @returns Event bus service (always available)
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * const events = useEventBus(ctx);
189
+ * await events.publish('user.created', { userId: '123' });
190
+ * const unsubscribe = events.subscribe('user.created', async (event) => {
191
+ * console.log('User created:', event);
192
+ * });
193
+ * ```
194
+ */
195
+ export function useEventBus(ctx: PluginContext): IEventBus {
196
+ return ctx.platform.eventBus;
197
+ }
198
+
199
+ // ═══════════════════════════════════════════════════════════════════════════
200
+ // SHORTCUT FUNCTIONS (High-level operations)
201
+ // ═══════════════════════════════════════════════════════════════════════════
202
+
203
+ /**
204
+ * Generate embedding for text.
205
+ * Shortcut for embeddings.embed().
206
+ *
207
+ * @param ctx - Plugin context
208
+ * @param text - Text to embed
209
+ * @returns Embedding vector
210
+ * @throws {ServiceNotConfiguredError} If embeddings not configured
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * const vector = await embedText(ctx, 'Hello, world!');
215
+ * console.log(vector.length); // e.g., 1536 for OpenAI ada-002
216
+ * ```
217
+ */
218
+ export async function embedText(ctx: PluginContext, text: string): Promise<number[]> {
219
+ const embeddings = useEmbeddings(ctx);
220
+ return embeddings.embed(text);
221
+ }
222
+
223
+ /**
224
+ * Generate embeddings for multiple texts.
225
+ * Shortcut for embeddings.embedBatch().
226
+ *
227
+ * @param ctx - Plugin context
228
+ * @param texts - Array of texts to embed
229
+ * @returns Array of embedding vectors
230
+ * @throws {ServiceNotConfiguredError} If embeddings not configured
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * const vectors = await embedBatch(ctx, ['text 1', 'text 2', 'text 3']);
235
+ * ```
236
+ */
237
+ export async function embedBatch(ctx: PluginContext, texts: string[]): Promise<number[][]> {
238
+ const embeddings = useEmbeddings(ctx);
239
+ return embeddings.embedBatch(texts);
240
+ }
241
+
242
+ /**
243
+ * Perform vector search.
244
+ * Shortcut for vectorStore.search().
245
+ *
246
+ * @param ctx - Plugin context
247
+ * @param query - Query vector
248
+ * @param limit - Maximum results (default: 10)
249
+ * @returns Search results
250
+ * @throws {ServiceNotConfiguredError} If vectorStore not configured
251
+ *
252
+ * @example
253
+ * ```typescript
254
+ * const queryVector = await embedText(ctx, 'search query');
255
+ * const results = await searchVectors(ctx, queryVector, 5);
256
+ *
257
+ * for (const result of results) {
258
+ * console.log(`Score: ${result.score}, ID: ${result.id}`);
259
+ * }
260
+ * ```
261
+ */
262
+ export async function searchVectors(
263
+ ctx: PluginContext,
264
+ query: number[],
265
+ limit = 10
266
+ ): Promise<VectorSearchResult[]> {
267
+ const vectorStore = useVectorStore(ctx);
268
+ return vectorStore.search(query, limit);
269
+ }
270
+
271
+ /**
272
+ * Call LLM with text prompt.
273
+ * Shortcut for llm.complete().
274
+ *
275
+ * @param ctx - Plugin context
276
+ * @param prompt - Prompt text
277
+ * @param options - LLM options
278
+ * @returns LLM response
279
+ * @throws {ServiceNotConfiguredError} If LLM not configured
280
+ *
281
+ * @example
282
+ * ```typescript
283
+ * const response = await completeLLM(ctx, 'Explain quantum computing', {
284
+ * temperature: 0.7,
285
+ * maxTokens: 500,
286
+ * });
287
+ * console.log(response.content);
288
+ * ```
289
+ */
290
+ export async function completeLLM(
291
+ ctx: PluginContext,
292
+ prompt: string,
293
+ options?: LLMOptions
294
+ ): Promise<LLMResponse> {
295
+ const llm = useLLM(ctx);
296
+ return llm.complete(prompt, options);
297
+ }
298
+
299
+ /**
300
+ * Stream LLM response.
301
+ * Shortcut for llm.stream().
302
+ *
303
+ * @param ctx - Plugin context
304
+ * @param prompt - Prompt text
305
+ * @param options - LLM options
306
+ * @returns Async iterable of response chunks
307
+ * @throws {ServiceNotConfiguredError} If LLM not configured
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * for await (const chunk of streamLLM(ctx, 'Write a story')) {
312
+ * ctx.ui.message(chunk);
313
+ * }
314
+ * ```
315
+ */
316
+ export function streamLLM(
317
+ ctx: PluginContext,
318
+ prompt: string,
319
+ options?: LLMOptions
320
+ ): AsyncIterable<string> {
321
+ const llm = useLLM(ctx);
322
+ return llm.stream(prompt, options);
323
+ }
324
+
325
+ /**
326
+ * Check if a service is configured.
327
+ * Non-throwing alternative to use* functions.
328
+ *
329
+ * @param ctx - Plugin context
330
+ * @param service - Service name to check ('llm' | 'embeddings' | 'vectorStore' | 'cache' | 'storage' | 'analytics' | 'eventBus')
331
+ * @returns true if service is configured, false otherwise
332
+ */
333
+ export function isServiceConfigured(ctx: PluginContext, service: keyof typeof ctx.platform): boolean {
334
+ return !!ctx.platform[service];
335
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/helpers/use-analytics
3
+ * Global analytics access helper
4
+ *
5
+ * Provides clean access to analytics/telemetry without context drilling.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { useAnalytics } from '@kb-labs/shared-command-kit';
10
+ *
11
+ * async handler(ctx, argv, flags) {
12
+ * const analytics = useAnalytics();
13
+ *
14
+ * if (analytics) {
15
+ * await analytics.track('release_started', { version: '1.0.0' });
16
+ * analytics.metric('release_duration_ms', 1234);
17
+ * }
18
+ * }
19
+ * ```
20
+ */
21
+
22
+ import { usePlatform } from './use-platform';
23
+ import type { IAnalytics } from '@kb-labs/core-platform';
24
+
25
+ /**
26
+ * Access global analytics adapter
27
+ *
28
+ * Returns the platform analytics adapter for tracking events and metrics.
29
+ * Returns undefined if analytics is not configured (graceful degradation).
30
+ *
31
+ * **Methods:**
32
+ * - `analytics.track(event, properties?)` - Track events
33
+ * - `analytics.metric(name, value, tags?)` - Record metrics
34
+ *
35
+ * **Always check availability:**
36
+ * ```typescript
37
+ * const analytics = useAnalytics();
38
+ * if (analytics) {
39
+ * await analytics.track('event');
40
+ * }
41
+ * ```
42
+ *
43
+ * @returns Analytics adapter or undefined if not configured
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const analytics = useAnalytics();
48
+ *
49
+ * if (analytics) {
50
+ * await analytics.track('command_executed', {
51
+ * command: 'release:run',
52
+ * duration_ms: 1234,
53
+ * success: true,
54
+ * });
55
+ *
56
+ * analytics.metric('release_packages_count', 5, {
57
+ * project: 'kb-labs',
58
+ * });
59
+ * }
60
+ * ```
61
+ */
62
+ export function useAnalytics(): IAnalytics | undefined {
63
+ const platform = usePlatform();
64
+ return platform.analytics;
65
+ }
66
+
67
+ /**
68
+ * Track event with analytics (safe, global singleton)
69
+ *
70
+ * Convenience wrapper that uses global platform analytics.
71
+ * Does nothing if analytics is not configured.
72
+ *
73
+ * NOTE: For context-based analytics, use trackEvent() from '../analytics/with-analytics'.
74
+ * This helper uses global singleton, not request-scoped context.
75
+ *
76
+ * @param event - Event name
77
+ * @param properties - Event properties
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * import { trackAnalyticsEvent } from '@kb-labs/shared-command-kit/helpers';
82
+ *
83
+ * // No need to check if analytics exists
84
+ * await trackAnalyticsEvent('release_completed', { version: '1.0.0', packages: 5 });
85
+ * ```
86
+ */
87
+ export async function trackAnalyticsEvent(
88
+ event: string,
89
+ properties?: Record<string, unknown>
90
+ ): Promise<void> {
91
+ const analytics = useAnalytics();
92
+ if (analytics) {
93
+ await analytics.track(event, properties);
94
+ }
95
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/helpers/use-cache
3
+ * Global Cache access helper
4
+ *
5
+ * Provides clean access to platform cache (Redis, InMemory, or custom adapter).
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { useCache } from '@kb-labs/shared-command-kit';
10
+ *
11
+ * async handler(ctx, argv, flags) {
12
+ * const cache = useCache();
13
+ *
14
+ * if (cache) {
15
+ * await cache.set('key', { data: 'value' }, 60000); // TTL: 60s
16
+ * const value = await cache.get('key');
17
+ * console.log(value);
18
+ * }
19
+ * }
20
+ * ```
21
+ */
22
+
23
+ import { usePlatform } from './use-platform.js';
24
+ import type { ICache } from '@kb-labs/core-platform';
25
+
26
+ /**
27
+ * Access global cache adapter
28
+ *
29
+ * Returns the platform cache adapter (Redis, InMemory, or custom).
30
+ * Returns undefined if cache is not configured (graceful degradation).
31
+ *
32
+ * **Methods:**
33
+ * - `cache.set(key, value, ttlMs?)` - Store value with optional TTL
34
+ * - `cache.get<T>(key)` - Retrieve value by key
35
+ * - `cache.delete(key)` - Remove value
36
+ * - `cache.clear()` - Clear all cached values
37
+ *
38
+ * **Always check availability:**
39
+ * ```typescript
40
+ * const cache = useCache();
41
+ * if (cache) {
42
+ * await cache.set('query-123', result, 60000);
43
+ * } else {
44
+ * // No caching, compute every time
45
+ * }
46
+ * ```
47
+ *
48
+ * @returns Cache adapter or undefined if not configured
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const cache = useCache();
53
+ *
54
+ * if (cache) {
55
+ * // Check cache first
56
+ * const cached = await cache.get<QueryResult>('query-123');
57
+ * if (cached) {
58
+ * return cached;
59
+ * }
60
+ *
61
+ * // Compute result
62
+ * const result = await expensiveQuery();
63
+ *
64
+ * // Cache for 5 minutes
65
+ * await cache.set('query-123', result, 5 * 60 * 1000);
66
+ *
67
+ * return result;
68
+ * }
69
+ * ```
70
+ */
71
+ export function useCache(): ICache | undefined {
72
+ const platform = usePlatform();
73
+ return platform.cache;
74
+ }
75
+
76
+ /**
77
+ * Check if cache is available
78
+ *
79
+ * Useful for conditional logic (cached vs non-cached execution).
80
+ *
81
+ * @returns true if cache is configured and ready
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * if (isCacheAvailable()) {
86
+ * // Use cached results
87
+ * const result = await getCachedOrCompute(key);
88
+ * } else {
89
+ * // Compute every time
90
+ * const result = await compute();
91
+ * }
92
+ * ```
93
+ */
94
+ export function isCacheAvailable(): boolean {
95
+ const cache = useCache();
96
+ return !!cache;
97
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/helpers/use-config
3
+ * Global config access helper
4
+ *
5
+ * Provides clean access to product-specific configuration without context drilling.
6
+ * Similar to React hooks pattern, but for KB Labs config.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { useConfig } from '@kb-labs/shared-command-kit';
11
+ *
12
+ * // In any command handler
13
+ * async handler(ctx, argv, flags) {
14
+ * const config = await useConfig('mind');
15
+ *
16
+ * if (config) {
17
+ * const scopes = config.scopes;
18
+ * // Use config...
19
+ * }
20
+ * }
21
+ * ```
22
+ */
23
+
24
+ /**
25
+ * Access product-specific configuration from kb.config.json
26
+ *
27
+ * Returns ONLY the config for the specified product and profile.
28
+ * Uses platform.config adapter (works across parent/child processes via IPC).
29
+ * Supports both Profiles v2 and legacy config structures.
30
+ *
31
+ * **Security:** This function returns ONLY the product-specific config,
32
+ * not the entire kb.config.json. This prevents cross-product config access.
33
+ *
34
+ * **Auto-detection:** If productId is not provided, it's automatically inferred
35
+ * from the plugin's manifest.configSection field (passed via execution context).
36
+ *
37
+ * **Profiles v2 structure:**
38
+ * ```json
39
+ * {
40
+ * "profiles": [
41
+ * {
42
+ * "id": "default",
43
+ * "products": {
44
+ * "mind": { "scopes": [...] },
45
+ * "workflow": { "maxConcurrency": 10 }
46
+ * }
47
+ * }
48
+ * ]
49
+ * }
50
+ * ```
51
+ *
52
+ * **Legacy structure:**
53
+ * ```json
54
+ * {
55
+ * "knowledge": { "scopes": [...] }, // for "mind" product
56
+ * "workflow": { "maxConcurrency": 10 }
57
+ * }
58
+ * ```
59
+ *
60
+ * @param productId - Product identifier (e.g., 'mind', 'workflow', 'plugins'). Optional - auto-detected from context.
61
+ * @param profileId - Profile identifier (defaults to 'default' or KB_PROFILE env var)
62
+ * @returns Promise resolving to product-specific config or undefined
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * // Auto-detect from context (recommended)
67
+ * const config = await useConfig();
68
+ *
69
+ * // Explicit product ID
70
+ * const mindConfig = await useConfig('mind');
71
+ * if (mindConfig?.scopes) {
72
+ * // Use scopes
73
+ * }
74
+ *
75
+ * // With explicit profile
76
+ * const workflowConfig = await useConfig('workflow', 'production');
77
+ * ```
78
+ */
79
+ export async function useConfig<T = any>(productId?: string, profileId?: string): Promise<T | undefined> {
80
+ // Auto-detect productId from manifest.configSection if not provided
81
+ let effectiveProductId = productId;
82
+ if (!effectiveProductId) {
83
+ effectiveProductId = (globalThis as any).__KB_CONFIG_SECTION__;
84
+ }
85
+
86
+ if (!effectiveProductId) {
87
+ return undefined;
88
+ }
89
+
90
+ const { usePlatform } = await import('./use-platform.js');
91
+ const platform = usePlatform();
92
+
93
+ if (!platform) {
94
+ return undefined;
95
+ }
96
+
97
+ // Returns ONLY the product-specific config, not the entire kb.config.json
98
+ return await platform.config.getConfig(effectiveProductId, profileId) as T | undefined;
99
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @module @kb-labs/shared-command-kit/helpers/use-embeddings
3
+ * Global Embeddings access helper
4
+ */
5
+
6
+ import { usePlatform } from './use-platform';
7
+ import type { IEmbeddings } from '@kb-labs/core-platform';
8
+
9
+ /**
10
+ * Access global Embeddings adapter
11
+ *
12
+ * Returns the platform embeddings adapter (OpenAI, etc.).
13
+ * Returns undefined if embeddings is not configured (graceful degradation).
14
+ *
15
+ * @returns Embeddings adapter or undefined if not configured
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const embeddings = useEmbeddings();
20
+ *
21
+ * if (embeddings) {
22
+ * const vector = await embeddings.embed('Hello, world!');
23
+ * console.log(vector.length); // e.g., 1536 for OpenAI
24
+ * }
25
+ * ```
26
+ */
27
+ export function useEmbeddings(): IEmbeddings | undefined {
28
+ const platform = usePlatform();
29
+ return platform.embeddings;
30
+ }
31
+
32
+ /**
33
+ * Check if Embeddings is available
34
+ *
35
+ * @returns true if embeddings is configured and ready
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * if (isEmbeddingsAvailable()) {
40
+ * const vector = await embeddings.embed(text);
41
+ * } else {
42
+ * // Use deterministic fallback
43
+ * }
44
+ * ```
45
+ */
46
+ export function isEmbeddingsAvailable(): boolean {
47
+ const embeddings = useEmbeddings();
48
+ return !!embeddings;
49
+ }