@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,278 @@
1
+ import type { PermissionSpec, PermissionPreset, PresetBuilder, RuntimePermissionSpec, PlatformPermissions } from './types';
2
+
3
+ /**
4
+ * Merge two string arrays, removing duplicates
5
+ */
6
+ function mergeArrays(a?: string[], b?: string[]): string[] | undefined {
7
+ if (!a && !b) {return undefined;}
8
+ const set = new Set([...(a ?? []), ...(b ?? [])]);
9
+ return set.size > 0 ? [...set] : undefined;
10
+ }
11
+
12
+ /**
13
+ * Merge platform permissions
14
+ */
15
+ function mergePlatformPermissions(
16
+ base?: PermissionSpec['platform'],
17
+ next?: PermissionSpec['platform']
18
+ ): PermissionSpec['platform'] | undefined {
19
+ if (!base && !next) {return undefined;}
20
+ if (!base) {return next;}
21
+ if (!next) {return base;}
22
+
23
+ const result: PermissionSpec['platform'] = {};
24
+
25
+ // Merge each platform service (second value wins for booleans, arrays are merged)
26
+ const keys = new Set([...Object.keys(base), ...Object.keys(next)]) as Set<keyof typeof base>;
27
+
28
+ for (const key of keys) {
29
+ const baseVal = base[key];
30
+ const nextVal = next[key];
31
+
32
+ if (nextVal === undefined) {
33
+ result[key] = baseVal as any;
34
+ } else if (Array.isArray(nextVal)) {
35
+ // Merge arrays (for cache namespaces, storage paths)
36
+ result[key] = mergeArrays(
37
+ Array.isArray(baseVal) ? baseVal : undefined,
38
+ nextVal
39
+ ) as any;
40
+ } else if (typeof nextVal === 'object' && nextVal !== null) {
41
+ // Merge objects (for llm.models, vectorStore.collections, etc.)
42
+ result[key] = { ...(typeof baseVal === 'object' ? baseVal : {}), ...nextVal } as any;
43
+ } else {
44
+ // Boolean or primitive - second value wins
45
+ result[key] = nextVal as any;
46
+ }
47
+ }
48
+
49
+ return Object.keys(result).length > 0 ? result : undefined;
50
+ }
51
+
52
+ /**
53
+ * Merge two permission specs together
54
+ * Arrays are merged (union), scalars use the second value
55
+ */
56
+ function mergeSpecs(base: PermissionSpec, next: PermissionSpec): PermissionSpec {
57
+ const result: PermissionSpec = {};
58
+
59
+ // Merge fs
60
+ if (base.fs || next.fs) {
61
+ result.fs = {
62
+ // readWrite wins over read
63
+ mode: next.fs?.mode ?? base.fs?.mode,
64
+ allow: mergeArrays(base.fs?.allow, next.fs?.allow),
65
+ };
66
+ // Clean up undefined fields
67
+ if (result.fs.mode === undefined) {delete result.fs.mode;}
68
+ if (result.fs.allow === undefined) {delete result.fs.allow;}
69
+ if (Object.keys(result.fs).length === 0) {delete result.fs;}
70
+ }
71
+
72
+ // Merge env
73
+ if (base.env || next.env) {
74
+ result.env = {
75
+ read: mergeArrays(base.env?.read, next.env?.read),
76
+ };
77
+ if (result.env.read === undefined) {delete result.env.read;}
78
+ if (Object.keys(result.env).length === 0) {delete result.env;}
79
+ }
80
+
81
+ // Merge network
82
+ if (base.network || next.network) {
83
+ result.network = {
84
+ fetch: mergeArrays(base.network?.fetch, next.network?.fetch),
85
+ };
86
+ if (result.network.fetch === undefined) {delete result.network.fetch;}
87
+ if (Object.keys(result.network).length === 0) {delete result.network;}
88
+ }
89
+
90
+ // Merge shell
91
+ if (base.shell || next.shell) {
92
+ result.shell = {
93
+ allow: mergeArrays(base.shell?.allow, next.shell?.allow),
94
+ };
95
+ if (result.shell.allow === undefined) {delete result.shell.allow;}
96
+ if (Object.keys(result.shell).length === 0) {delete result.shell;}
97
+ }
98
+
99
+ // Merge platform
100
+ result.platform = mergePlatformPermissions(base.platform, next.platform);
101
+
102
+ // Merge quotas (second value wins)
103
+ if (base.quotas || next.quotas) {
104
+ result.quotas = {
105
+ timeoutMs: next.quotas?.timeoutMs ?? base.quotas?.timeoutMs,
106
+ memoryMb: next.quotas?.memoryMb ?? base.quotas?.memoryMb,
107
+ cpuMs: next.quotas?.cpuMs ?? base.quotas?.cpuMs,
108
+ };
109
+ if (result.quotas.timeoutMs === undefined) {delete result.quotas.timeoutMs;}
110
+ if (result.quotas.memoryMb === undefined) {delete result.quotas.memoryMb;}
111
+ if (result.quotas.cpuMs === undefined) {delete result.quotas.cpuMs;}
112
+ if (Object.keys(result.quotas).length === 0) {delete result.quotas;}
113
+ }
114
+
115
+ return result;
116
+ }
117
+
118
+ /**
119
+ * Convert declarative PermissionSpec to explicit RuntimePermissionSpec
120
+ *
121
+ * Transforms:
122
+ * { mode: 'readWrite', allow: ['*.json'] }
123
+ * Into:
124
+ * { read: ['*.json'], write: ['*.json'] }
125
+ */
126
+ function toRuntimeFormat(spec: PermissionSpec): RuntimePermissionSpec {
127
+ const result: RuntimePermissionSpec = {};
128
+
129
+ // Convert fs: mode + allow → read[] + write[]
130
+ if (spec.fs) {
131
+ const { mode, allow } = spec.fs;
132
+ result.fs = {};
133
+
134
+ if (allow && allow.length > 0) {
135
+ // read is always granted for allowed paths
136
+ result.fs.read = [...allow];
137
+
138
+ // write only if mode is 'readWrite'
139
+ if (mode === 'readWrite') {
140
+ result.fs.write = [...allow];
141
+ }
142
+ }
143
+
144
+ if (Object.keys(result.fs).length === 0) {delete result.fs;}
145
+ }
146
+
147
+ // env, network, shell, platform, quotas pass through unchanged
148
+ if (spec.env) {
149
+ result.env = { ...spec.env };
150
+ }
151
+
152
+ if (spec.network) {
153
+ result.network = { ...spec.network };
154
+ }
155
+
156
+ if (spec.shell) {
157
+ result.shell = { ...spec.shell };
158
+ }
159
+
160
+ if (spec.platform) {
161
+ result.platform = { ...spec.platform };
162
+ }
163
+
164
+ if (spec.quotas) {
165
+ result.quotas = { ...spec.quotas };
166
+ }
167
+
168
+ return result;
169
+ }
170
+
171
+ /**
172
+ * Create a builder for combining permission presets
173
+ *
174
+ * @example
175
+ * ```typescript
176
+ * const permissions = combine()
177
+ * .with(presets.gitWorkflow)
178
+ * .with(presets.npmPublish)
179
+ * .withEnv(['MY_CUSTOM_VAR'])
180
+ * .build();
181
+ * ```
182
+ */
183
+ export function combine(): PresetBuilder {
184
+ let accumulated: PermissionSpec = {};
185
+
186
+ const builder: PresetBuilder = {
187
+ with(preset: PermissionPreset | PermissionSpec): PresetBuilder {
188
+ const spec = 'permissions' in preset ? preset.permissions : preset;
189
+ accumulated = mergeSpecs(accumulated, spec);
190
+ return builder;
191
+ },
192
+
193
+ withEnv(vars: string[]): PresetBuilder {
194
+ accumulated = mergeSpecs(accumulated, { env: { read: vars } });
195
+ return builder;
196
+ },
197
+
198
+ withFs(fs: PermissionSpec['fs']): PresetBuilder {
199
+ if (fs) {
200
+ accumulated = mergeSpecs(accumulated, { fs });
201
+ }
202
+ return builder;
203
+ },
204
+
205
+ withNetwork(network: PermissionSpec['network']): PresetBuilder {
206
+ if (network) {
207
+ accumulated = mergeSpecs(accumulated, { network });
208
+ }
209
+ return builder;
210
+ },
211
+
212
+ withShell(shell: PermissionSpec['shell']): PresetBuilder {
213
+ if (shell) {
214
+ accumulated = mergeSpecs(accumulated, { shell });
215
+ }
216
+ return builder;
217
+ },
218
+
219
+ withPlatform(platform: PermissionSpec['platform']): PresetBuilder {
220
+ if (platform) {
221
+ accumulated = mergeSpecs(accumulated, { platform });
222
+ }
223
+ return builder;
224
+ },
225
+
226
+ withQuotas(quotas: PermissionSpec['quotas']): PresetBuilder {
227
+ if (quotas) {
228
+ accumulated = mergeSpecs(accumulated, { quotas });
229
+ }
230
+ return builder;
231
+ },
232
+
233
+ withStorage(storage: PlatformPermissions['storage']): PresetBuilder {
234
+ if (storage !== undefined) {
235
+ accumulated = mergeSpecs(accumulated, {
236
+ platform: { storage },
237
+ });
238
+ }
239
+ return builder;
240
+ },
241
+
242
+ withDatabase(database: PlatformPermissions['database']): PresetBuilder {
243
+ if (database !== undefined) {
244
+ accumulated = mergeSpecs(accumulated, {
245
+ platform: { database },
246
+ });
247
+ }
248
+ return builder;
249
+ },
250
+
251
+ build(): RuntimePermissionSpec {
252
+ return toRuntimeFormat(accumulated);
253
+ },
254
+ };
255
+
256
+ return builder;
257
+ }
258
+
259
+ /**
260
+ * Quickly combine multiple presets into a single permission spec
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * const permissions = combinePresets(presets.gitWorkflow, presets.npmPublish);
265
+ * ```
266
+ */
267
+ export function combinePresets(...presets: (PermissionPreset | PermissionSpec)[]): RuntimePermissionSpec {
268
+ let builder = combine();
269
+ for (const preset of presets) {
270
+ builder = builder.with(preset);
271
+ }
272
+ return builder.build();
273
+ }
274
+
275
+ /**
276
+ * Export toRuntimeFormat for advanced use cases
277
+ */
278
+ export { toRuntimeFormat };
@@ -0,0 +1,18 @@
1
+ // Types
2
+ export type { PermissionSpec, PermissionPreset, PresetBuilder, RuntimePermissionSpec } from './types';
3
+
4
+ // Presets
5
+ export { minimal } from './presets/minimal';
6
+ export { gitWorkflow } from './presets/git-workflow';
7
+ export { npmPublish } from './presets/npm-publish';
8
+ export { fullEnv } from './presets/full-env';
9
+ export { kbPlatform } from './presets/kb-platform';
10
+ export { llmAccess } from './presets/llm-access';
11
+ export { vectorStore } from './presets/vector-store';
12
+ export { ciEnvironment } from './presets/ci-environment';
13
+
14
+ // Re-export all presets as a namespace
15
+ export * as presets from './presets/index.js';
16
+
17
+ // Builder
18
+ export { combine, combinePresets, toRuntimeFormat } from './combine';
@@ -0,0 +1,34 @@
1
+ import type { PermissionPreset } from '../types';
2
+
3
+ /**
4
+ * CI Environment preset - for plugins running in CI/CD
5
+ * Includes GitHub Actions, GitLab CI, and common CI variables
6
+ */
7
+ export const ciEnvironment: PermissionPreset = {
8
+ id: 'ci-environment',
9
+ description: 'CI/CD environment - GitHub Actions, GitLab CI tokens and vars',
10
+ permissions: {
11
+ env: {
12
+ read: [
13
+ // Common CI
14
+ 'CI',
15
+ 'CI_*',
16
+ 'CONTINUOUS_INTEGRATION',
17
+ // GitHub Actions
18
+ 'GITHUB_TOKEN',
19
+ 'GITHUB_*',
20
+ 'GH_TOKEN',
21
+ // GitLab CI
22
+ 'GITLAB_*',
23
+ 'CI_JOB_TOKEN',
24
+ // Jenkins
25
+ 'JENKINS_*',
26
+ 'BUILD_*',
27
+ // Generic
28
+ 'BRANCH_NAME',
29
+ 'TAG_NAME',
30
+ 'COMMIT_SHA',
31
+ ],
32
+ },
33
+ },
34
+ };
@@ -0,0 +1,16 @@
1
+ import type { PermissionPreset } from '../types';
2
+
3
+ /**
4
+ * Full environment preset - access to all environment variables
5
+ * Use for trusted plugins that need full system access
6
+ * WARNING: This bypasses env filtering entirely
7
+ */
8
+ export const fullEnv: PermissionPreset = {
9
+ id: 'full-env',
10
+ description: 'Full environment access - all env vars available (trusted plugins only)',
11
+ permissions: {
12
+ env: {
13
+ read: ['*'], // Wildcard - all env vars
14
+ },
15
+ },
16
+ };
@@ -0,0 +1,40 @@
1
+ import type { PermissionPreset } from '../types';
2
+
3
+ /**
4
+ * Git workflow preset - for plugins that use git (simple-git, etc.)
5
+ * Includes HOME for ~/.gitconfig, USER for author info
6
+ */
7
+ export const gitWorkflow: PermissionPreset = {
8
+ id: 'git-workflow',
9
+ description: 'Git operations - includes HOME, USER, and git config access',
10
+ permissions: {
11
+ env: {
12
+ read: [
13
+ // System (required for git to find config)
14
+ 'HOME',
15
+ 'USER',
16
+ 'PATH',
17
+ 'SHELL',
18
+ 'TERM',
19
+ 'LANG',
20
+ 'LC_ALL',
21
+ 'TZ',
22
+ 'TMPDIR',
23
+ // Git-specific
24
+ 'GIT_*', // All git env vars (GIT_AUTHOR_NAME, GIT_DIR, etc.)
25
+ 'SSH_AUTH_SOCK', // For SSH key auth
26
+ 'SSH_AGENT_PID',
27
+ // Node
28
+ 'NODE_ENV',
29
+ ],
30
+ },
31
+ fs: {
32
+ mode: 'readWrite',
33
+ allow: [
34
+ '**/.git/**', // Git directory
35
+ '**/.gitignore',
36
+ '**/.gitattributes',
37
+ ],
38
+ },
39
+ },
40
+ };
@@ -0,0 +1,8 @@
1
+ export { minimal } from './minimal';
2
+ export { gitWorkflow } from './git-workflow';
3
+ export { npmPublish } from './npm-publish';
4
+ export { fullEnv } from './full-env';
5
+ export { kbPlatform } from './kb-platform';
6
+ export { llmAccess } from './llm-access';
7
+ export { vectorStore } from './vector-store';
8
+ export { ciEnvironment } from './ci-environment';
@@ -0,0 +1,30 @@
1
+ import type { PermissionPreset } from '../types';
2
+
3
+ /**
4
+ * KB Platform preset - for KB Labs internal plugins
5
+ * Includes KB_* env vars and .kb/ directory access
6
+ */
7
+ export const kbPlatform: PermissionPreset = {
8
+ id: 'kb-platform',
9
+ description: 'KB Labs platform access - KB_* env vars and .kb/ directory',
10
+ permissions: {
11
+ env: {
12
+ read: [
13
+ // System basics
14
+ 'HOME',
15
+ 'USER',
16
+ 'PATH',
17
+ 'TMPDIR',
18
+ 'NODE_ENV',
19
+ // KB Labs specific
20
+ 'KB_*', // All KB env vars
21
+ ],
22
+ },
23
+ fs: {
24
+ mode: 'readWrite',
25
+ allow: [
26
+ '.kb/**', // KB Labs config directory
27
+ ],
28
+ },
29
+ },
30
+ };
@@ -0,0 +1,29 @@
1
+ import type { PermissionPreset } from '../types';
2
+
3
+ /**
4
+ * LLM Access preset - for plugins that use LLM APIs
5
+ * Includes OpenAI and Anthropic API keys and network access
6
+ */
7
+ export const llmAccess: PermissionPreset = {
8
+ id: 'llm-access',
9
+ description: 'LLM API access - OpenAI, Anthropic keys and network',
10
+ permissions: {
11
+ env: {
12
+ read: [
13
+ 'OPENAI_API_KEY',
14
+ 'OPENAI_ORG_ID',
15
+ 'OPENAI_BASE_URL',
16
+ 'ANTHROPIC_API_KEY',
17
+ 'AZURE_OPENAI_*', // Azure OpenAI
18
+ 'LLM_*', // Generic LLM config
19
+ ],
20
+ },
21
+ network: {
22
+ fetch: [
23
+ 'api.openai.com',
24
+ 'api.anthropic.com',
25
+ '*.openai.azure.com', // Azure OpenAI
26
+ ],
27
+ },
28
+ },
29
+ };
@@ -0,0 +1,21 @@
1
+ import type { PermissionPreset } from '../types';
2
+
3
+ /**
4
+ * Minimal preset - only basic Node.js environment
5
+ * Use when plugin doesn't need any external access
6
+ */
7
+ export const minimal: PermissionPreset = {
8
+ id: 'minimal',
9
+ description: 'Minimal permissions - basic Node.js environment only',
10
+ permissions: {
11
+ env: {
12
+ read: [
13
+ 'NODE_ENV',
14
+ 'PATH',
15
+ 'LANG',
16
+ 'LC_ALL',
17
+ 'TZ',
18
+ ],
19
+ },
20
+ },
21
+ };
@@ -0,0 +1,48 @@
1
+ import type { PermissionPreset } from '../types';
2
+
3
+ /**
4
+ * NPM publish preset - for plugins that publish to npm
5
+ * Includes HOME for ~/.npmrc, npm auth tokens
6
+ */
7
+ export const npmPublish: PermissionPreset = {
8
+ id: 'npm-publish',
9
+ description: 'NPM operations - includes HOME, npm tokens, and registry access',
10
+ permissions: {
11
+ env: {
12
+ read: [
13
+ // System (required for npm to find config)
14
+ 'HOME',
15
+ 'USER',
16
+ 'PATH',
17
+ 'TMPDIR',
18
+ 'LANG',
19
+ 'LC_ALL',
20
+ 'TZ',
21
+ // NPM-specific
22
+ 'NPM_TOKEN',
23
+ 'NPM_AUTH_TOKEN',
24
+ 'NODE_AUTH_TOKEN',
25
+ 'npm_*', // All npm env vars
26
+ // Node
27
+ 'NODE_ENV',
28
+ 'NODE_OPTIONS',
29
+ ],
30
+ },
31
+ fs: {
32
+ mode: 'readWrite',
33
+ allow: [
34
+ '**/package.json',
35
+ '**/package-lock.json',
36
+ '**/pnpm-lock.yaml',
37
+ '**/.npmrc',
38
+ '**/.npmignore',
39
+ ],
40
+ },
41
+ network: {
42
+ fetch: [
43
+ 'registry.npmjs.org',
44
+ 'npm.pkg.github.com',
45
+ ],
46
+ },
47
+ },
48
+ };
@@ -0,0 +1,40 @@
1
+ import type { PermissionPreset } from '../types';
2
+
3
+ /**
4
+ * Vector Store preset - for plugins that use vector databases
5
+ * Includes Qdrant, Pinecone, Weaviate access
6
+ */
7
+ export const vectorStore: PermissionPreset = {
8
+ id: 'vector-store',
9
+ description: 'Vector database access - Qdrant, Pinecone, Weaviate',
10
+ permissions: {
11
+ env: {
12
+ read: [
13
+ // Qdrant
14
+ 'QDRANT_URL',
15
+ 'QDRANT_API_KEY',
16
+ 'QDRANT_*',
17
+ // Pinecone
18
+ 'PINECONE_API_KEY',
19
+ 'PINECONE_ENVIRONMENT',
20
+ 'PINECONE_*',
21
+ // Weaviate
22
+ 'WEAVIATE_URL',
23
+ 'WEAVIATE_API_KEY',
24
+ 'WEAVIATE_*',
25
+ // Generic
26
+ 'VECTOR_STORE_*',
27
+ 'EMBEDDING_*',
28
+ ],
29
+ },
30
+ network: {
31
+ fetch: [
32
+ 'localhost',
33
+ '127.0.0.1',
34
+ '*.qdrant.io',
35
+ '*.pinecone.io',
36
+ '*.weaviate.io',
37
+ ],
38
+ },
39
+ },
40
+ };