@plumbus/core 0.6.3 → 0.6.5

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 (196) hide show
  1. package/CHANGELOG.md +385 -0
  2. package/README.md +23 -13
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/ai/ai/security.d.ts +36 -0
  5. package/dist/ai/ai-service.d.ts.map +1 -1
  6. package/dist/ai/ai-service.js +36 -8
  7. package/dist/ai/ai-service.js.map +1 -1
  8. package/dist/ai/index.d.ts +1 -1
  9. package/dist/ai/index.d.ts.map +1 -1
  10. package/dist/ai/index.js +1 -1
  11. package/dist/ai/index.js.map +1 -1
  12. package/dist/ai/security.d.ts +9 -0
  13. package/dist/ai/security.d.ts.map +1 -1
  14. package/dist/ai/security.js +18 -1
  15. package/dist/ai/security.js.map +1 -1
  16. package/dist/ai/types/config.d.ts +11 -0
  17. package/dist/ai/types/entity.d.ts +15 -0
  18. package/dist/ai/types/fields.d.ts +51 -0
  19. package/dist/api/index.d.ts +2 -2
  20. package/dist/api/index.d.ts.map +1 -1
  21. package/dist/api/index.js +1 -1
  22. package/dist/api/index.js.map +1 -1
  23. package/dist/api/route-generator.d.ts +17 -0
  24. package/dist/api/route-generator.d.ts.map +1 -1
  25. package/dist/api/route-generator.js +55 -2
  26. package/dist/api/route-generator.js.map +1 -1
  27. package/dist/cli/commands/api.d.ts +9 -0
  28. package/dist/cli/commands/api.d.ts.map +1 -1
  29. package/dist/cli/commands/api.js +10 -1
  30. package/dist/cli/commands/api.js.map +1 -1
  31. package/dist/cli/commands/init.js +1 -1
  32. package/dist/cli/mcp-serve-context.d.ts.map +1 -1
  33. package/dist/cli/mcp-serve-context.js +40 -35
  34. package/dist/cli/mcp-serve-context.js.map +1 -1
  35. package/dist/cli/templates/resources.d.ts.map +1 -1
  36. package/dist/cli/templates/resources.js +5 -6
  37. package/dist/cli/templates/resources.js.map +1 -1
  38. package/dist/config/loader.d.ts.map +1 -1
  39. package/dist/config/loader.js +37 -0
  40. package/dist/config/loader.js.map +1 -1
  41. package/dist/data/field-encryption.d.ts +17 -0
  42. package/dist/data/field-encryption.d.ts.map +1 -0
  43. package/dist/data/field-encryption.js +80 -0
  44. package/dist/data/field-encryption.js.map +1 -0
  45. package/dist/data/index.d.ts +2 -0
  46. package/dist/data/index.d.ts.map +1 -1
  47. package/dist/data/index.js +2 -0
  48. package/dist/data/index.js.map +1 -1
  49. package/dist/data/mask-fields.d.ts +17 -0
  50. package/dist/data/mask-fields.d.ts.map +1 -0
  51. package/dist/data/mask-fields.js +56 -0
  52. package/dist/data/mask-fields.js.map +1 -0
  53. package/dist/data/registry.d.ts +4 -0
  54. package/dist/data/registry.d.ts.map +1 -1
  55. package/dist/data/registry.js +6 -0
  56. package/dist/data/registry.js.map +1 -1
  57. package/dist/data/repository.d.ts +3 -0
  58. package/dist/data/repository.d.ts.map +1 -1
  59. package/dist/data/repository.js +123 -41
  60. package/dist/data/repository.js.map +1 -1
  61. package/dist/define/defineCapability.d.ts +2 -0
  62. package/dist/define/defineCapability.d.ts.map +1 -1
  63. package/dist/define/defineCapability.js.map +1 -1
  64. package/dist/define/defineTranslation.d.ts +39 -3
  65. package/dist/define/defineTranslation.d.ts.map +1 -1
  66. package/dist/define/defineTranslation.js +3 -0
  67. package/dist/define/defineTranslation.js.map +1 -1
  68. package/dist/errors/data-errors.d.ts +23 -0
  69. package/dist/errors/data-errors.d.ts.map +1 -0
  70. package/dist/errors/data-errors.js +45 -0
  71. package/dist/errors/data-errors.js.map +1 -0
  72. package/dist/errors/index.d.ts +3 -11
  73. package/dist/errors/index.d.ts.map +1 -1
  74. package/dist/errors/index.js +3 -16
  75. package/dist/errors/index.js.map +1 -1
  76. package/dist/errors/plumbus-error.d.ts +13 -0
  77. package/dist/errors/plumbus-error.d.ts.map +1 -0
  78. package/dist/errors/plumbus-error.js +15 -0
  79. package/dist/errors/plumbus-error.js.map +1 -0
  80. package/dist/execution/capability-executor.d.ts.map +1 -1
  81. package/dist/execution/capability-executor.js +142 -61
  82. package/dist/execution/capability-executor.js.map +1 -1
  83. package/dist/execution/capability-invocation.d.ts +3 -1
  84. package/dist/execution/capability-invocation.d.ts.map +1 -1
  85. package/dist/execution/capability-invocation.js +41 -2
  86. package/dist/execution/capability-invocation.js.map +1 -1
  87. package/dist/execution/context-deps.d.ts +23 -0
  88. package/dist/execution/context-deps.d.ts.map +1 -0
  89. package/dist/execution/context-deps.js +45 -0
  90. package/dist/execution/context-deps.js.map +1 -0
  91. package/dist/execution/context-factory.d.ts.map +1 -1
  92. package/dist/execution/context-factory.js +9 -1
  93. package/dist/execution/context-factory.js.map +1 -1
  94. package/dist/execution/deferred-flow-service.d.ts +9 -0
  95. package/dist/execution/deferred-flow-service.d.ts.map +1 -0
  96. package/dist/execution/deferred-flow-service.js +54 -0
  97. package/dist/execution/deferred-flow-service.js.map +1 -0
  98. package/dist/execution/index.d.ts +4 -0
  99. package/dist/execution/index.d.ts.map +1 -1
  100. package/dist/execution/index.js +2 -0
  101. package/dist/execution/index.js.map +1 -1
  102. package/dist/execution/transactional-outbox.d.ts +33 -0
  103. package/dist/execution/transactional-outbox.d.ts.map +1 -0
  104. package/dist/execution/transactional-outbox.js +84 -0
  105. package/dist/execution/transactional-outbox.js.map +1 -0
  106. package/dist/flows/engine.d.ts +1 -0
  107. package/dist/flows/engine.d.ts.map +1 -1
  108. package/dist/flows/engine.js +1 -1
  109. package/dist/flows/engine.js.map +1 -1
  110. package/dist/flows/flow-service.d.ts.map +1 -1
  111. package/dist/flows/flow-service.js +2 -2
  112. package/dist/flows/flow-service.js.map +1 -1
  113. package/dist/governance/index.d.ts +1 -1
  114. package/dist/governance/index.d.ts.map +1 -1
  115. package/dist/governance/index.js +1 -1
  116. package/dist/governance/index.js.map +1 -1
  117. package/dist/index.d.ts +10 -10
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +8 -8
  120. package/dist/index.js.map +1 -1
  121. package/dist/jobs/deferred-job-dispatch-service.d.ts +7 -0
  122. package/dist/jobs/deferred-job-dispatch-service.d.ts.map +1 -0
  123. package/dist/jobs/deferred-job-dispatch-service.js +16 -0
  124. package/dist/jobs/deferred-job-dispatch-service.js.map +1 -0
  125. package/dist/jobs/dispatch.d.ts.map +1 -1
  126. package/dist/jobs/dispatch.js +8 -2
  127. package/dist/jobs/dispatch.js.map +1 -1
  128. package/dist/jobs/index.d.ts +3 -0
  129. package/dist/jobs/index.d.ts.map +1 -1
  130. package/dist/jobs/index.js +2 -0
  131. package/dist/jobs/index.js.map +1 -1
  132. package/dist/jobs/job-dispatch-service.d.ts +24 -0
  133. package/dist/jobs/job-dispatch-service.d.ts.map +1 -0
  134. package/dist/jobs/job-dispatch-service.js +26 -0
  135. package/dist/jobs/job-dispatch-service.js.map +1 -0
  136. package/dist/observability/index.d.ts +1 -1
  137. package/dist/observability/index.d.ts.map +1 -1
  138. package/dist/observability/index.js +1 -1
  139. package/dist/observability/index.js.map +1 -1
  140. package/dist/observability/metrics.d.ts +4 -0
  141. package/dist/observability/metrics.d.ts.map +1 -1
  142. package/dist/observability/metrics.js +19 -1
  143. package/dist/observability/metrics.js.map +1 -1
  144. package/dist/runtime/bootstrap.d.ts +2 -0
  145. package/dist/runtime/bootstrap.d.ts.map +1 -1
  146. package/dist/runtime/bootstrap.js +3 -1
  147. package/dist/runtime/bootstrap.js.map +1 -1
  148. package/dist/runtime/register-consumers.d.ts.map +1 -1
  149. package/dist/runtime/register-consumers.js +12 -16
  150. package/dist/runtime/register-consumers.js.map +1 -1
  151. package/dist/runtime/start-worker-pool.d.ts.map +1 -1
  152. package/dist/runtime/start-worker-pool.js +5 -1
  153. package/dist/runtime/start-worker-pool.js.map +1 -1
  154. package/dist/runtime/startup-warnings.d.ts +8 -0
  155. package/dist/runtime/startup-warnings.d.ts.map +1 -0
  156. package/dist/runtime/startup-warnings.js +26 -0
  157. package/dist/runtime/startup-warnings.js.map +1 -0
  158. package/dist/server/bootstrap.d.ts +1 -1
  159. package/dist/server/bootstrap.d.ts.map +1 -1
  160. package/dist/server/bootstrap.js +49 -23
  161. package/dist/server/bootstrap.js.map +1 -1
  162. package/dist/testing/e2e.d.ts.map +1 -1
  163. package/dist/testing/e2e.js +4 -1
  164. package/dist/testing/e2e.js.map +1 -1
  165. package/dist/translations/index.d.ts +2 -0
  166. package/dist/translations/index.d.ts.map +1 -1
  167. package/dist/translations/index.js +10 -0
  168. package/dist/translations/index.js.map +1 -1
  169. package/dist/types/capability.d.ts +5 -0
  170. package/dist/types/capability.d.ts.map +1 -1
  171. package/dist/types/config.d.ts +11 -0
  172. package/dist/types/config.d.ts.map +1 -1
  173. package/dist/types/context.d.ts +37 -1
  174. package/dist/types/context.d.ts.map +1 -1
  175. package/dist/worker/bootstrap.d.ts.map +1 -1
  176. package/dist/worker/bootstrap.js +25 -37
  177. package/dist/worker/bootstrap.js.map +1 -1
  178. package/dist/worker/index.d.ts +1 -1
  179. package/dist/worker/index.d.ts.map +1 -1
  180. package/dist/worker/index.js +1 -1
  181. package/dist/worker/index.js.map +1 -1
  182. package/instructions/README.md +38 -0
  183. package/instructions/ai.md +68 -20
  184. package/instructions/api.md +2 -0
  185. package/instructions/capabilities.md +19 -1
  186. package/instructions/cli.md +68 -2
  187. package/instructions/events.md +2 -0
  188. package/instructions/framework.md +5 -1
  189. package/instructions/governance.md +2 -0
  190. package/instructions/patterns.md +1 -1
  191. package/instructions/peer-dependencies.md +17 -5
  192. package/instructions/prompts.md +84 -0
  193. package/instructions/security.md +27 -15
  194. package/instructions/testing.md +45 -32
  195. package/instructions/translations.md +21 -2
  196. package/package.json +6 -5
@@ -15,15 +15,19 @@ import { runCapability, simulateFlow, mockAI, createTestContext } from "@plumbus
15
15
  Execute a capability in an isolated test environment:
16
16
 
17
17
  ```ts
18
- const result = await runCapability(getUser, {
19
- input: { userId: "usr_123" },
20
- auth: { userId: "admin_1", roles: ["admin"], scopes: [], provider: "test" },
21
- data: {
22
- User: [{ id: "usr_123", name: "Alice", email: "alice@test.com" }],
18
+ const result = await runCapability(
19
+ getUser,
20
+ { userId: "usr_123" },
21
+ {
22
+ auth: { userId: "admin_1", roles: ["admin"], scopes: [], provider: "test" },
23
+ data: {
24
+ User: [{ id: "usr_123", name: "Alice", email: "alice@test.com" }],
25
+ },
23
26
  },
24
- });
27
+ );
25
28
 
26
- expect(result.name).toBe("Alice");
29
+ expect(result.success).toBe(true);
30
+ expect(result.data?.name).toBe("Alice");
27
31
  ```
28
32
 
29
33
  ### Paginated list capabilities
@@ -37,8 +41,10 @@ When testing `kind: 'query'` list endpoints that paginate via `findMany` + `coun
37
41
  ```ts
38
42
  const page1 = await runCapability(listStaff, { page: 1, limit: 2 }, { ctx });
39
43
  const page2 = await runCapability(listStaff, { page: 2, limit: 2 }, { ctx });
40
- expect(page1.items).not.toEqual(page2.items);
41
- expect(page1.total).toBeGreaterThan(page1.limit);
44
+ expect(page1.success && page1.data).toBeTruthy();
45
+ expect(page2.success && page2.data).toBeTruthy();
46
+ expect(page1.data.items).not.toEqual(page2.data.items);
47
+ expect(page1.data.total).toBeGreaterThan(page1.data.limit);
42
48
  ```
43
49
 
44
50
  ### `simulateFlow`
@@ -46,16 +52,21 @@ expect(page1.total).toBeGreaterThan(page1.limit);
46
52
  Simulate flow execution and inspect step history:
47
53
 
48
54
  ```ts
49
- const execution = await simulateFlow("refundApproval", {
50
- input: { refundId: "rf_1", amount: 50 },
51
- events: {
52
- "refund.approved": { refundId: "rf_1", approvedBy: "mgr_1" },
55
+ import { refundApproval } from "../refundApproval/flow.js";
56
+
57
+ const execution = await simulateFlow(
58
+ refundApproval,
59
+ { refundId: "rf_1", amount: 50 },
60
+ {
61
+ capabilityResults: {
62
+ "billing.validateRefund": { valid: true },
63
+ },
53
64
  },
54
- });
65
+ );
55
66
 
56
67
  expect(execution.status).toBe("completed");
57
- expect(execution.steps).toHaveLength(4);
58
- expect(execution.steps[0].name).toBe("validateRefund");
68
+ expect(execution.history.length).toBeGreaterThan(0);
69
+ expect(execution.history[0]?.stepName).toBe("validateRefund");
59
70
  ```
60
71
 
61
72
  ### `mockAI`
@@ -65,7 +76,7 @@ Mock AI provider responses:
65
76
  ```ts
66
77
  const ctx = createTestContext({
67
78
  ai: mockAI({
68
- summarizeTicket: { summary: "Customer wants refund", priority: "high", sentiment: "negative" },
79
+ generate: { summary: "Customer wants refund", priority: "high", sentiment: "negative" },
69
80
  }),
70
81
  });
71
82
 
@@ -73,6 +84,8 @@ const result = await ctx.ai.generate({ prompt: "summarizeTicket", input: { ticke
73
84
  expect(result.priority).toBe("high");
74
85
  ```
75
86
 
87
+ `mockAI` keys responses by **operation** (`generate`, `extract`, `classify`, `retrieve`), not by prompt name. All prompts share the configured response for each operation.
88
+
76
89
  ### `createTestContext`
77
90
 
78
91
  Build a test `ctx` with controllable mocks:
@@ -101,21 +114,21 @@ const execution = await simulateFlow(myFlow, input, {
101
114
  ## Security Test Patterns
102
115
 
103
116
  ```ts
104
- // Assert unauthorized access is rejected
105
- await expect(
106
- runCapability("deleteUser", {
107
- input: { userId: "usr_1" },
108
- auth: { roles: ["viewer"], scopes: [], provider: "test" },
109
- })
110
- ).rejects.toMatchObject({ code: "forbidden" });
111
-
112
- // Assert cross-tenant access is blocked
113
- await expect(
114
- runCapability("getUser", {
115
- input: { userId: "usr_1" },
116
- auth: { tenantId: "other_tenant", roles: ["admin"], scopes: [], provider: "test" },
117
- })
118
- ).rejects.toMatchObject({ code: "forbidden" });
117
+ import { assertCapabilityDenied } from "@plumbus/core/testing";
118
+
119
+ // Assert unauthorized access is rejected (returns { success: false }, does not throw)
120
+ const denied = await runCapability(
121
+ deleteUser,
122
+ { userId: "usr_1" },
123
+ { auth: { roles: ["viewer"], scopes: [], provider: "test" } },
124
+ );
125
+ expect(denied.success).toBe(false);
126
+ expect(denied.error?.code).toBe("forbidden");
127
+
128
+ // Or use the helper
129
+ await assertCapabilityDenied(deleteUser, { userId: "usr_1" }, {
130
+ auth: { roles: ["viewer"], scopes: [], provider: "test" },
131
+ });
119
132
  ```
120
133
 
121
134
  ## Governance Test Patterns
@@ -30,7 +30,9 @@ export const commonTranslation = defineTranslation({
30
30
 
31
31
  - Place translation files in `app/translations/<name>.translation.ts` (classic layout), **or** use the locale-folder layout below
32
32
  - Each assembler exports one `defineTranslation()` result
33
- - All locales **must** have the same key set — mismatched keys throw at import time
33
+ - All locales **must** have the same key set — mismatched keys fail at typecheck for literal catalogs and throw at import time otherwise
34
+ - Prefer literal / `as const` catalogs so `tsc` catches drift. A locale typed as `Record<string, string>` skips compile-time key checks and still relies on import-time validation
35
+ - When a non-default locale has an extra key, typecheck may error on the **default** locale (“missing key X”) while runtime errors on the **other** locale (“extra key X”) — both catch the same drift
34
36
  - Messages use ICU MessageFormat: `{name}` for interpolation, `{count, plural, ...}` for plurals, `{gender, select, ...}` for select
35
37
  - The `name` field is the namespace: keys resolve as `<namespace>.<key>` (e.g., `common.nav.overview`)
36
38
 
@@ -105,4 +107,21 @@ function Nav() {
105
107
 
106
108
  ## Translation Sync
107
109
 
108
- `defineTranslation()` validates key consistency at import time. If locale "he" is missing keys that "en" has, the app throws immediately. This ensures tests and CI catch translation drift.
110
+ `defineTranslation()` enforces key consistency at typecheck for literal / `as const` catalogs, and again at import time. If locale "he" is missing keys that "en" has, `tsc` fails for typed catalogs and the app throws immediately otherwise. This ensures tests and CI catch translation drift.
111
+
112
+ ### Dynamic locales
113
+
114
+ ```ts
115
+ const he: Record<string, string> = loadFromCms("he"); // no compile-time key parity
116
+
117
+ defineTranslation({
118
+ name: "common",
119
+ defaultLocale: "en",
120
+ locales: ["en", "he"],
121
+ messages: {
122
+ en: { greeting: "Hello", farewell: "Bye" },
123
+ he,
124
+ },
125
+ });
126
+ // Runtime still throws if `he` is missing/extra keys relative to `en`.
127
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumbus/core",
3
- "version": "0.6.3",
3
+ "version": "0.6.5",
4
4
  "description": "Plumbus framework core — types, SDK, runtime, CLI, test utilities",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -32,7 +32,8 @@
32
32
  },
33
33
  "files": [
34
34
  "dist",
35
- "instructions"
35
+ "instructions",
36
+ "CHANGELOG.md"
36
37
  ],
37
38
  "keywords": [
38
39
  "plumbus",
@@ -95,8 +96,8 @@
95
96
  "esbuild": "^0.25.12",
96
97
  "typescript": "^5.7.0",
97
98
  "@plumbus/api": "0.1.2",
98
- "@plumbus/mcp": "0.5.1",
99
- "@plumbus/voice": "0.3.0"
99
+ "@plumbus/voice": "0.3.0",
100
+ "@plumbus/mcp": "0.5.1"
100
101
  },
101
102
  "scripts": {
102
103
  "build": "tsc -b",
@@ -109,6 +110,6 @@
109
110
  "lint": "biome lint ./src",
110
111
  "format": "biome format --write ./src",
111
112
  "format:check": "biome format ./src",
112
- "typecheck": "tsc --noEmit"
113
+ "typecheck": "tsc --noEmit && node ./scripts/check-define-translation-types.mjs"
113
114
  }
114
115
  }