@classytic/arc 2.30.0 → 2.32.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 (242) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +7 -0
  3. package/TRADEMARK.md +22 -0
  4. package/dist/{BaseController-B5DwufbB.mjs → BaseController-Dk34dxhI.mjs} +21 -19
  5. package/dist/{EventTransport-QmY7A258.d.mts → EventTransport-2uVV34WU.d.mts} +1 -0
  6. package/dist/{EventTransport-C6YA8xY9.mjs → EventTransport-BV10D0oG.mjs} +1 -0
  7. package/dist/{HookSystem-WkIougo6.mjs → HookSystem-vimw5D7Z.mjs} +2 -1
  8. package/dist/{QueryCache-DOMT_iq7.d.mts → QueryCache-DFA-QrU9.d.mts} +2 -1
  9. package/dist/{ResourceRegistry-y9Hnypus.mjs → ResourceRegistry-BVr7PgA0.mjs} +18 -15
  10. package/dist/{actionPermissions-CAphcmUG.mjs → actionPermissions-Dti7ebyv.mjs} +1 -0
  11. package/dist/audit/index.d.mts +3 -2
  12. package/dist/audit/index.mjs +2 -1
  13. package/dist/auth/audit.d.mts +1 -0
  14. package/dist/auth/audit.mjs +1 -0
  15. package/dist/auth/index.d.mts +5 -4
  16. package/dist/auth/index.mjs +11 -9
  17. package/dist/auth/redis-session.d.mts +2 -1
  18. package/dist/auth/redis-session.mjs +1 -0
  19. package/dist/{applyPermissionResult-Cf6zUCvb.mjs → authorizationDecision-__T3EJDA.mjs} +19 -10
  20. package/dist/{buildHandler-BYS3Vkfz.mjs → buildHandler-Dn7rzUJo.mjs} +6 -4
  21. package/dist/cache/index.d.mts +4 -3
  22. package/dist/cache/index.mjs +4 -3
  23. package/dist/{caching-_NJeDd1_.mjs → caching-DFJqHyFs.mjs} +2 -1
  24. package/dist/cleanup/index.d.mts +39 -16
  25. package/dist/cleanup/index.mjs +50 -38
  26. package/dist/cli/commands/describe.d.mts +2 -1
  27. package/dist/cli/commands/describe.mjs +4 -5
  28. package/dist/cli/commands/docs.d.mts +1 -0
  29. package/dist/cli/commands/docs.mjs +3 -2
  30. package/dist/cli/commands/doctor.d.mts +1 -0
  31. package/dist/cli/commands/doctor.mjs +1 -0
  32. package/dist/cli/commands/generate.d.mts +2 -1
  33. package/dist/cli/commands/generate.mjs +2 -1
  34. package/dist/cli/commands/init.d.mts +2 -1
  35. package/dist/cli/commands/init.mjs +2 -1
  36. package/dist/cli/commands/introspect.d.mts +1 -0
  37. package/dist/cli/commands/introspect.mjs +2 -1
  38. package/dist/cli/index.d.mts +3 -2
  39. package/dist/cli/index.mjs +3 -2
  40. package/dist/{constants-DNre0wRg.mjs → constants-J99LGTJI.mjs} +1 -0
  41. package/dist/context/index.d.mts +1 -0
  42. package/dist/context/index.mjs +3 -2
  43. package/dist/core/index.d.mts +3 -2
  44. package/dist/core/index.mjs +7 -6
  45. package/dist/{core-poalJLvp.mjs → core-BwwmNSp7.mjs} +3 -2
  46. package/dist/{createActionRouter-BxuywVRB.mjs → createActionRouter-DkJZWo0m.mjs} +14 -10
  47. package/dist/{createAggregationRouter-BiY-lGdY.mjs → createAggregationRouter-B1exOVD8.mjs} +10 -7
  48. package/dist/{createApp-CXrKFciH.mjs → createApp-Bv0m-Q6_.mjs} +625 -229
  49. package/dist/{defineAggregation-ufWjUwml.mjs → defineAggregation-gX4No1gt.mjs} +1 -0
  50. package/dist/{defineResource-CxWqDCAy.mjs → defineResource-XFPPUu2c.mjs} +84 -50
  51. package/dist/discovery/index.d.mts +1 -0
  52. package/dist/discovery/index.mjs +1 -0
  53. package/dist/docs/index.d.mts +3 -2
  54. package/dist/docs/index.mjs +3 -2
  55. package/dist/{elevation-C9s5hFP_.d.mts → elevation-BXCfVcNG.d.mts} +1 -0
  56. package/dist/{elevation-CIz1GjGm.mjs → elevation-DNXXxgjl.mjs} +4 -3
  57. package/dist/encryption/index.d.mts +2 -1
  58. package/dist/encryption/index.mjs +5 -3
  59. package/dist/{errorHandler-Bq2OeEQL.mjs → errorHandler-B2AZUJUj.mjs} +3 -2
  60. package/dist/{errorHandler-C6yv4ZTW.d.mts → errorHandler-CpYUJmPA.d.mts} +1 -0
  61. package/dist/{errors-DHcHVAgk.d.mts → errors-BGdVwP25.d.mts} +1 -0
  62. package/dist/{errors-DkO8Nk6-.mjs → errors-Bh1KK5ps.mjs} +1 -0
  63. package/dist/{eventPlugin-D2NNR4py.mjs → eventPlugin-Dk_TyXeE.mjs} +8 -6
  64. package/dist/{eventPlugin-Bg3cP2_u.d.mts → eventPlugin-GF5nnBIq.d.mts} +2 -1
  65. package/dist/events/index.d.mts +112 -44
  66. package/dist/events/index.mjs +177 -141
  67. package/dist/events/transports/redis-stream-entry.d.mts +2 -1
  68. package/dist/events/transports/redis-stream-entry.mjs +14 -9
  69. package/dist/events/transports/redis.d.mts +2 -1
  70. package/dist/events/transports/redis.mjs +1 -0
  71. package/dist/{externalPaths-BE6wFpYv.d.mts → externalPaths-CmGOxOtD.d.mts} +1 -0
  72. package/dist/factory/index.d.mts +9 -5
  73. package/dist/factory/index.mjs +131 -7
  74. package/dist/fastify-augmentation-BppG5bMT.d.mts +179 -0
  75. package/dist/{fields-CQ_7KQWw.mjs → fields-DEi65pGj.mjs} +6 -10
  76. package/dist/{fields-D3lhgzhD.d.mts → fields-I_EeRWND.d.mts} +1 -0
  77. package/dist/{generate-D0wZupBg.mjs → generate-CRSG0jTv.mjs} +2 -1
  78. package/dist/{generate-BnsL9GBm.d.mts → generate-DCGuEbqI.d.mts} +1 -0
  79. package/dist/{headers-BvlQSDMB.mjs → headers-BXjQYbeC.mjs} +2 -1
  80. package/dist/{health-CB_m4S32.mjs → health-5XnTa2uo.mjs} +1 -0
  81. package/dist/hooks/index.d.mts +2 -1
  82. package/dist/hooks/index.mjs +2 -1
  83. package/dist/idempotency/index.d.mts +3 -2
  84. package/dist/idempotency/index.mjs +8 -5
  85. package/dist/idempotency/redis.d.mts +2 -1
  86. package/dist/idempotency/redis.mjs +1 -0
  87. package/dist/{index-CG4yqMDB.d.mts → index-C-481Zf2.d.mts} +74 -18
  88. package/dist/{index-Q5gzEIWY.d.mts → index-CpzxqePp.d.mts} +107 -32
  89. package/dist/{index-Cx7bro4R.d.mts → index-DXlHwvuE.d.mts} +5 -4
  90. package/dist/index-ZWhLTp_s.d.mts +290 -0
  91. package/dist/{index-Ch16aAah.d.mts → index-zq6VrjaB.d.mts} +122 -15
  92. package/dist/index.d.mts +9 -8
  93. package/dist/index.mjs +11 -10
  94. package/dist/{init-tlRSt667.mjs → init-BbfP8aky.mjs} +25 -27
  95. package/dist/{init-BPEu8cs-.d.mts → init-Cscs4lab.d.mts} +1 -0
  96. package/dist/integrations/event-gateway.d.mts +3 -2
  97. package/dist/integrations/event-gateway.mjs +2 -1
  98. package/dist/integrations/index.d.mts +4 -3
  99. package/dist/integrations/index.mjs +1 -0
  100. package/dist/integrations/jobs/index.d.mts +2 -1
  101. package/dist/integrations/jobs/index.mjs +109 -33
  102. package/dist/integrations/mcp/index.d.mts +6 -6
  103. package/dist/integrations/mcp/index.mjs +2 -1
  104. package/dist/integrations/mcp/testing.d.mts +3 -2
  105. package/dist/integrations/mcp/testing.mjs +2 -2
  106. package/dist/integrations/streamline.d.mts +1 -0
  107. package/dist/integrations/streamline.mjs +3 -2
  108. package/dist/integrations/webhooks.d.mts +1 -0
  109. package/dist/integrations/webhooks.mjs +1 -0
  110. package/dist/integrations/websocket-pushref-redis.d.mts +2 -1
  111. package/dist/integrations/websocket-pushref-redis.mjs +1 -0
  112. package/dist/integrations/websocket-redis.d.mts +2 -1
  113. package/dist/integrations/websocket-redis.mjs +1 -0
  114. package/dist/integrations/websocket.d.mts +3 -2
  115. package/dist/integrations/websocket.mjs +38 -34
  116. package/dist/{interface-BGZCzOGL.d.mts → interface-BOk3YnTz.d.mts} +1 -0
  117. package/dist/{interface-n5hpKg1d.mjs → interface-BP4IJCBO.mjs} +1 -0
  118. package/dist/{interface-Uk8ONJv7.d.mts → interface-DEWNOMza.d.mts} +1 -0
  119. package/dist/{jsonBody-BlzAoGCe.mjs → jsonBody-DDSR2HFl.mjs} +2 -1
  120. package/dist/{keys-Cd316u_y.mjs → keys-B-HBTGXl.mjs} +1 -0
  121. package/dist/{loadResources-DpU8pfjV.mjs → loadResources-DisEAmkm.mjs} +4 -2
  122. package/dist/{loadResourcesFromEntry-kvGT6EcO.mjs → loadResourcesFromEntry-D1MJp13f.mjs} +2 -1
  123. package/dist/logger/index.d.mts +1 -0
  124. package/dist/logger/index.mjs +1 -0
  125. package/dist/{mcpPlugin-nRzm5g2s.mjs → mcpPlugin-CpfVpKHE.mjs} +38 -38
  126. package/dist/{memory-CmnzXE5Z.mjs → memory-DsuWnj4T.mjs} +5 -4
  127. package/dist/{metrics-fdxI5mn_.mjs → metrics-DdQL8syd.mjs} +2 -1
  128. package/dist/middleware/index.d.mts +2 -1
  129. package/dist/middleware/index.mjs +3 -2
  130. package/dist/migrations/index.d.mts +1 -0
  131. package/dist/migrations/index.mjs +3 -2
  132. package/dist/module-Br81am6m.mjs +78 -0
  133. package/dist/{multipartBody-D0eBvkeq.mjs → multipartBody-BnkBLN7v.mjs} +3 -2
  134. package/dist/{openapi-B8Vkbxbn.mjs → openapi-DIRzvxC0.mjs} +6 -5
  135. package/dist/outbox-admin/index.d.mts +85 -0
  136. package/dist/outbox-admin/index.mjs +115 -0
  137. package/dist/permissions/index.d.mts +5 -4
  138. package/dist/permissions/index.mjs +6 -5
  139. package/dist/{permissions-Bfu_8y1U.mjs → permissions-Dl_m0NCe.mjs} +308 -42
  140. package/dist/{pipe-BOLmGIxa.mjs → pipe-ELHCP3zj.mjs} +3 -4
  141. package/dist/pipeline/index.d.mts +2 -1
  142. package/dist/pipeline/index.mjs +2 -1
  143. package/dist/{pipeline-BJnpkY9i.mjs → pipeline-CPA-jx0M.mjs} +17 -14
  144. package/dist/plugins/index.d.mts +8 -7
  145. package/dist/plugins/index.mjs +16 -15
  146. package/dist/plugins/response-cache.d.mts +1 -0
  147. package/dist/plugins/response-cache.mjs +2 -1
  148. package/dist/plugins/tracing-entry.d.mts +2 -1
  149. package/dist/plugins/tracing-entry.mjs +2 -1
  150. package/dist/{pluralize-BhrgwZb9.mjs → pluralize-C2ZkKbsn.mjs} +1 -0
  151. package/dist/{preloadResources-DSY5HGpS.mjs → preloadResources-CDs87fTw.mjs} +1 -0
  152. package/dist/{preloadResources-DCfa2egz.d.mts → preloadResources-T1hmlTEZ.d.mts} +117 -12
  153. package/dist/presets/filesUpload.d.mts +6 -5
  154. package/dist/presets/filesUpload.mjs +10 -12
  155. package/dist/presets/index.d.mts +3 -2
  156. package/dist/presets/index.mjs +2 -1
  157. package/dist/presets/multiTenant.d.mts +2 -1
  158. package/dist/presets/multiTenant.mjs +3 -2
  159. package/dist/presets/search.d.mts +3 -2
  160. package/dist/presets/search.mjs +2 -1
  161. package/dist/{presets-CJOEXLuk.mjs → presets-Dntd_pUO.mjs} +6 -4
  162. package/dist/{projection-UBDgfMwu.mjs → projection-CjHhM5W1.mjs} +2 -1
  163. package/dist/{pushref-registry-BbcnpNTm.d.mts → pushref-registry-Dov9l4qE.d.mts} +1 -0
  164. package/dist/{queryCachePlugin-br4otiqF.d.mts → queryCachePlugin-BzqxconG.d.mts} +3 -2
  165. package/dist/{queryCachePlugin-DSGuSVLW.mjs → queryCachePlugin-Dhps-Ldt.mjs} +6 -5
  166. package/dist/{rateLimit-DrED-C4v.mjs → rateLimit-C7mmAGs3.mjs} +7 -3
  167. package/dist/{rateLimitKey-BoWRH3e7.mjs → rateLimitKey-CccEFBfk.mjs} +1 -0
  168. package/dist/{realtime-B9nmIY5V.mjs → realtime-DVvVZZFz.mjs} +20 -9
  169. package/dist/{redis-UDtLaNj6.d.mts → redis-CduhKsJi.d.mts} +2 -1
  170. package/dist/{redis-stream-uIaauNpZ.d.mts → redis-stream-qN6A-RFv.d.mts} +2 -1
  171. package/dist/{registerRoute-JkxIEBJq.mjs → registerRoute-B_QrjYZS.mjs} +10 -7
  172. package/dist/registry/index.d.mts +3 -2
  173. package/dist/registry/index.mjs +3 -2
  174. package/dist/{registry-BYXUUg21.mjs → registry-DqUmzA9W.mjs} +2 -1
  175. package/dist/{renewingLease-3cuQH7h8.mjs → renewingLease-BpP9wwj7.mjs} +1 -0
  176. package/dist/{replyHelpers-67tRawQZ.mjs → replyHelpers-DS-P0b32.mjs} +2 -1
  177. package/dist/{repositoryFilter-Dz8k3S4P.mjs → repositoryFilter-DotlxG3L.mjs} +1 -0
  178. package/dist/{requestContext-MrlJwECf.mjs → requestContext-B6vQF-sy.mjs} +1 -0
  179. package/dist/{rolldown-runtime-8H4AJuhK.mjs → rolldown-runtime-BhflRrBs.mjs} +1 -0
  180. package/dist/{schedules-CjOd2MG9.mjs → schedules-C2Q3uv2d.mjs} +3 -2
  181. package/dist/{schemaConverter-DJvodiHj.mjs → schemaConverter-Crjvczi_.mjs} +70 -17
  182. package/dist/{schemaIR-Ca7ySNPx.mjs → schemaIR-CnyKK_1j.mjs} +2 -1
  183. package/dist/schemas/index.d.mts +1 -0
  184. package/dist/schemas/index.mjs +1 -0
  185. package/dist/scim/index.d.mts +1 -0
  186. package/dist/scim/index.mjs +2 -1
  187. package/dist/scope/index.d.mts +3 -2
  188. package/dist/scope/index.mjs +5 -4
  189. package/dist/{scope-DfaPntpo.mjs → scope-afz_Ieek.mjs} +4 -3
  190. package/dist/{sessionManager-BHOM3N_0.d.mts → sessionManager-qimlKV0P.d.mts} +1 -0
  191. package/dist/{simpleEqualityMatcher-Cg05HPsn.mjs → simpleEqualityMatcher-C4KiMWUa.mjs} +1 -0
  192. package/dist/{sse-BQ1w0dfl.mjs → sse-B9P4Y-UI.mjs} +7 -5
  193. package/dist/{sseStream-BQ7Qaynp.mjs → sseStream-B3zb_d1h.mjs} +2 -1
  194. package/dist/{storage-DLUZ04kK.d.mts → storage-Cx9Sz3Ou.d.mts} +1 -0
  195. package/dist/{store-helpers-DY6xq4sM.mjs → store-helpers-DmEMHlPQ.mjs} +1 -0
  196. package/dist/{streaming-BQcW6_Kq.mjs → streaming-DPZdQmDz.mjs} +1 -0
  197. package/dist/{subscribe-helpers-DfzsivM6.mjs → subscribe-helpers-sp5xTDVA.mjs} +2 -1
  198. package/dist/sync/changelog.d.mts +1 -0
  199. package/dist/sync/changelog.mjs +1 -0
  200. package/dist/testing/cleanupStoreContract.d.mts +2 -1
  201. package/dist/testing/cleanupStoreContract.mjs +10 -5
  202. package/dist/testing/index.d.mts +166 -12
  203. package/dist/testing/index.mjs +315 -43
  204. package/dist/testing/outboxStoreContract.d.mts +12 -2
  205. package/dist/testing/outboxStoreContract.mjs +110 -20
  206. package/dist/testing/storageContract.d.mts +2 -1
  207. package/dist/testing/storageContract.mjs +11 -5
  208. package/dist/{tracing-CsGKQJGg.d.mts → tracing-Dro5eH6j.d.mts} +1 -0
  209. package/dist/{transactionContext-PNdoyLLm.mjs → transactionContext-BvLKvOIL.mjs} +1 -0
  210. package/dist/{typeGuards-C9KXUly6.mjs → typeGuards-B_5-hKjJ.mjs} +1 -0
  211. package/dist/types/index.d.mts +6 -5
  212. package/dist/types/index.mjs +1 -0
  213. package/dist/types/storage.d.mts +2 -1
  214. package/dist/types/storage.mjs +1 -0
  215. package/dist/{types-ChvvVNP8.d.mts → types-B7XeLEgK.d.mts} +34 -2
  216. package/dist/{types-Cc91nXuA.d.mts → types-ByHn9rEO.d.mts} +1 -0
  217. package/dist/{types-C_ZZRcD6.d.mts → types-C4QE8qnm.d.mts} +1 -0
  218. package/dist/{types-D_n8L6VY.d.mts → types-CT5vu6M0.d.mts} +132 -17
  219. package/dist/{types-DjC-KUCz.d.mts → types-ChuShpCP.d.mts} +1 -0
  220. package/dist/{types-Bmmn-fO0.d.mts → types-CwcUQ610.d.mts} +2 -6
  221. package/dist/{types-CSyCxl2V.mjs → types-DXYX7dIR.mjs} +4 -3
  222. package/dist/usage/index.d.mts +3 -2
  223. package/dist/usage/index.mjs +0 -0
  224. package/dist/{userHelpers-Cg_y3fBz.mjs → userHelpers-BNsOXzOd.mjs} +1 -0
  225. package/dist/utils/index.d.mts +16 -7
  226. package/dist/utils/index.mjs +10 -9
  227. package/dist/{utils-taUVD4p3.mjs → utils-BtOha_Sp.mjs} +3 -2
  228. package/dist/{validate-Bk44F2yT.mjs → validate-PMCPR9El.mjs} +2 -1
  229. package/dist/{versioning-gKWyryT3.mjs → versioning-CKv2jz_U.mjs} +4 -3
  230. package/dist/{versioning-DXgY5BUm.d.mts → versioning-D_rhHfZm.d.mts} +5 -2
  231. package/dist/{websocket-_Pd0CgR0.d.mts → websocket-BOXVggMf.d.mts} +2 -1
  232. package/package.json +557 -539
  233. package/skills/arc/SKILL.md +22 -8
  234. package/skills/arc/references/api-reference.md +4 -0
  235. package/skills/arc/references/auth.md +3 -0
  236. package/skills/arc/references/integrations.md +33 -0
  237. package/skills/arc/references/mcp.md +6 -7
  238. package/skills/arc/references/production.md +24 -25
  239. package/skills/arc-code-review/references/anti-patterns.md +3 -3
  240. package/dist/fastify-augmentation-0WhPnUH7.d.mts +0 -76
  241. package/dist/index-CCzVR-N3.d.mts +0 -107
  242. package/dist/module-_-M7C5ES.mjs +0 -29
@@ -1,3 +1,5 @@
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { n as evaluateAndApplyPermission } from "../../authorizationDecision-__T3EJDA.mjs";
1
3
  import fp from "fastify-plugin";
2
4
  //#region src/integrations/jobs/execution.ts
3
5
  async function executeTimedHandler(options) {
@@ -149,6 +151,49 @@ const jobsPluginImpl = async (fastify, options) => {
149
151
  const dlqQueues = /* @__PURE__ */ new Map();
150
152
  const workers = /* @__PURE__ */ new Map();
151
153
  const throttledJobs = /* @__PURE__ */ new Map();
154
+ const seenNames = /* @__PURE__ */ new Set();
155
+ for (const job of jobs) {
156
+ if (typeof job.name !== "string" || job.name.trim() === "") throw new Error("[arc/jobs] a job definition has an empty name — names are the queue key.");
157
+ if (seenNames.has(job.name)) throw new Error(`[arc/jobs] duplicate job name "${job.name}". A name is the queue key, so two definitions sharing one would leave an untracked worker consuming the same queue after shutdown. Rename one, or register it in a single definition.`);
158
+ seenNames.add(job.name);
159
+ const positiveInt = (v, field) => {
160
+ if (v === void 0) return;
161
+ if (typeof v !== "number" || !Number.isInteger(v) || v <= 0) throw new Error(`[arc/jobs] Job '${job.name}' has ${field}=${String(v)} — must be a positive integer.`);
162
+ };
163
+ const nonNegativeInt = (v, field) => {
164
+ if (v === void 0) return;
165
+ if (typeof v !== "number" || !Number.isInteger(v) || v < 0) throw new Error(`[arc/jobs] Job '${job.name}' has ${field}=${String(v)} — must be a non-negative integer.`);
166
+ };
167
+ positiveInt(job.maxConcurrent, "maxConcurrent");
168
+ positiveInt(job.concurrency, "concurrency");
169
+ positiveInt(job.timeout, "timeout");
170
+ nonNegativeInt(job.retries, "retries");
171
+ nonNegativeInt(job.cancelGraceMs, "cancelGraceMs");
172
+ if (job.rateLimit) {
173
+ positiveInt(job.rateLimit.max, "rateLimit.max");
174
+ positiveInt(job.rateLimit.duration, "rateLimit.duration");
175
+ }
176
+ if (job.backoff) nonNegativeInt(job.backoff.delay, "backoff.delay");
177
+ if (job.repeat) {
178
+ positiveInt(job.repeat.every, "repeat.every");
179
+ positiveInt(job.repeat.limit, "repeat.limit");
180
+ if (job.repeat.pattern !== void 0 && job.repeat.pattern.trim() === "") throw new Error(`[arc/jobs] Job '${job.name}' has an empty repeat.pattern.`);
181
+ }
182
+ }
183
+ if (defaults) {
184
+ const d = defaults;
185
+ const defaultPositiveInt = (v, field) => {
186
+ if (v === void 0) return;
187
+ if (typeof v !== "number" || !Number.isInteger(v) || v <= 0) throw new Error(`[arc/jobs] defaults.${field}=${String(v)} — must be a positive integer.`);
188
+ };
189
+ const defaultNonNegativeInt = (v, field) => {
190
+ if (v === void 0) return;
191
+ if (typeof v !== "number" || !Number.isInteger(v) || v < 0) throw new Error(`[arc/jobs] defaults.${field}=${String(v)} — must be a non-negative integer.`);
192
+ };
193
+ defaultNonNegativeInt(d.retries, "retries");
194
+ defaultPositiveInt(d.timeout, "timeout");
195
+ if (d.backoff) defaultNonNegativeInt(d.backoff.delay, "backoff.delay");
196
+ }
152
197
  for (const job of jobs) {
153
198
  if (!job.repeat) continue;
154
199
  const { pattern, every, tz } = job.repeat;
@@ -280,7 +325,7 @@ const jobsPluginImpl = async (fastify, options) => {
280
325
  });
281
326
  workers.set(queueName, worker);
282
327
  }
283
- const JOB_PAYLOAD_WARN_BYTES = 100 * 1024;
328
+ const JOB_PAYLOAD_WARN_BYTES = 102400;
284
329
  const jobDefsByName = /* @__PURE__ */ new Map();
285
330
  for (const job of jobs) if (!jobDefsByName.has(job.name)) jobDefsByName.set(job.name, job);
286
331
  const dispatcher = {
@@ -296,19 +341,22 @@ const jobsPluginImpl = async (fastify, options) => {
296
341
  }, `[arc/jobs] Large job payload — prefer passing IDs and reloading in the handler`);
297
342
  } catch {}
298
343
  const jobDef = jobDefsByName.get(name);
299
- return { jobId: (await queue.add(name, data, {
300
- delay: opts.delay,
301
- priority: opts.priority,
302
- jobId: opts.jobId,
303
- removeOnComplete: opts.removeOnComplete ?? defaults.removeOnComplete ?? 100,
304
- removeOnFail: opts.removeOnFail ?? defaults.removeOnFail ?? 500,
305
- attempts: jobDef?.retries ?? defaults.retries ?? 3,
306
- backoff: jobDef?.backoff ?? defaults.backoff ?? {
307
- type: "exponential",
308
- delay: 1e3
309
- },
310
- repeat: jobDef?.repeat ?? opts.repeat
311
- })).id };
344
+ return {
345
+ queue: name,
346
+ jobId: (await queue.add(name, data, {
347
+ delay: opts.delay,
348
+ priority: opts.priority,
349
+ jobId: opts.jobId,
350
+ removeOnComplete: opts.removeOnComplete ?? defaults.removeOnComplete ?? 100,
351
+ removeOnFail: opts.removeOnFail ?? defaults.removeOnFail ?? 500,
352
+ attempts: jobDef?.retries ?? defaults.retries ?? 3,
353
+ backoff: jobDef?.backoff ?? defaults.backoff ?? {
354
+ type: "exponential",
355
+ delay: 1e3
356
+ },
357
+ repeat: jobDef?.repeat ?? opts.repeat
358
+ })).id
359
+ };
312
360
  },
313
361
  getQueue(name) {
314
362
  return queues.get(name) ?? null;
@@ -327,10 +375,12 @@ const jobsPluginImpl = async (fastify, options) => {
327
375
  }
328
376
  return stats;
329
377
  },
330
- async getStatus(jobId) {
331
- for (const [name, queue] of queues) {
378
+ async getStatus(queueName, jobId) {
379
+ const queue = queues.get(queueName);
380
+ if (queue) {
381
+ const name = queueName;
332
382
  const job = await queue.getJob(jobId);
333
- if (!job) continue;
383
+ if (!job) return null;
334
384
  const state = typeof job.getState === "function" ? await job.getState() : "unknown";
335
385
  const throttled = throttledJobs.get(name)?.has(jobId) || void 0;
336
386
  return {
@@ -358,24 +408,50 @@ const jobsPluginImpl = async (fastify, options) => {
358
408
  }
359
409
  };
360
410
  if (!fastify.hasDecorator("jobs")) fastify.decorate("jobs", dispatcher);
361
- fastify.get(`${prefix}/stats`, async () => {
362
- return {
363
- success: true,
364
- data: await dispatcher.getStats()
411
+ const management = options.managementRoutes;
412
+ if (management) {
413
+ const gate = management.operatorPermission;
414
+ if (!gate._platformOnly && !management.allowUnverifiedOperatorPermission) throw new Error("[arc/jobs] managementRoutes.operatorPermission must be platform-only. These routes are global (jobs carry no tenant identity), so an org-role gate would let a member of one organization read another's jobs. Use requirePlatformRole('platform-ops') — or requireRoles([...], { includeOrgRoles: false }) with allowUnverifiedOperatorPermission: true if you have verified the check yourself.");
415
+ const guard = async (req, reply) => {
416
+ if (!await evaluateAndApplyPermission(gate, {
417
+ user: req.user ?? null,
418
+ request: req,
419
+ resource: "jobs",
420
+ action: "read"
421
+ }, req, reply)) return false;
422
+ const policy = req._policyFilters;
423
+ if (policy && Object.keys(policy).length > 0) {
424
+ fastify.log.error("[arc/jobs] managementRoutes.operatorPermission returned a row-level policy, which this surface cannot apply — jobs carry no tenant identity. Gate it on an operator role (e.g. requireRoles(['platform-ops'])) and serve tenant-facing job status from a resource that owns its own row policy.");
425
+ await reply.status(403).send({
426
+ code: "arc.jobs.policy_unsupported",
427
+ message: "Job management routes are an operator surface and cannot apply a row-level policy.",
428
+ status: 403
429
+ });
430
+ return false;
431
+ }
432
+ return true;
365
433
  };
366
- });
367
- fastify.get(`${prefix}/:id/status`, async (req, reply) => {
368
- const { id } = req.params;
369
- const status = await dispatcher.getStatus(id);
370
- if (!status) return reply.status(404).send({
371
- success: false,
372
- error: "Job not found"
434
+ fastify.get(`${prefix}/stats`, async (req, reply) => {
435
+ if (!await guard(req, reply)) return reply;
436
+ return { stats: await dispatcher.getStats() };
373
437
  });
374
- return {
375
- success: true,
376
- data: status
377
- };
378
- });
438
+ fastify.get(`${prefix}/:queue/:id/status`, async (req, reply) => {
439
+ if (!await guard(req, reply)) return reply;
440
+ const { queue, id } = req.params;
441
+ const status = await dispatcher.getStatus(queue, id);
442
+ if (!status) return reply.status(404).send({
443
+ code: "arc.not_found",
444
+ message: "Job not found",
445
+ status: 404
446
+ });
447
+ const { returnValue, failedReason, ...safe } = status;
448
+ return {
449
+ ...safe,
450
+ ...management.exposeResult ? { returnValue } : {},
451
+ ...management.exposeFailureReason ? { failedReason } : {}
452
+ };
453
+ });
454
+ }
379
455
  fastify.addHook("onClose", async () => {
380
456
  await dispatcher.close();
381
457
  });
@@ -1,8 +1,9 @@
1
- import { Rt as IControllerResponse, V as ResourceDefinition, Vt as ServerAccessor, zt as IRequestContext } from "../../index-Q5gzEIWY.mjs";
2
- import { i as RequestScope } from "../../types-DjC-KUCz.mjs";
3
- import { r as PermissionCheck } from "../../types-ChvvVNP8.mjs";
4
- import { n as FieldPermissionMap } from "../../fields-D3lhgzhD.mjs";
5
- import { _ as ToolDefinition, a as CrudDescriptionOverride, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, i as CrudDescriptionMeta, l as McpExecutionWiring, m as SessionEntry, n as CallToolResult, o as CrudOperation, p as PromptResult, r as CreateMcpServerConfig, s as McpAuthResolver, t as BetterAuthHandler, u as McpPluginOptions } from "../../types-Bmmn-fO0.mjs";
1
+
2
+ import { Ht as ServerAccessor, Rt as IControllerResponse, V as ResourceDefinition, zt as IRequestContext } from "../../index-CpzxqePp.mjs";
3
+ import { i as RequestScope } from "../../types-ChuShpCP.mjs";
4
+ import { r as PermissionCheck } from "../../types-B7XeLEgK.mjs";
5
+ import { n as FieldPermissionMap } from "../../fields-I_EeRWND.mjs";
6
+ import { _ as ToolDefinition, a as CrudDescriptionOverride, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, i as CrudDescriptionMeta, l as McpExecutionWiring, m as SessionEntry, n as CallToolResult, o as CrudOperation, p as PromptResult, r as CreateMcpServerConfig, s as McpAuthResolver, t as BetterAuthHandler, u as McpPluginOptions } from "../../types-CwcUQ610.mjs";
6
7
  import { ErrorContract } from "@classytic/repo-core/errors";
7
8
  import { FastifyPluginAsync } from "fastify";
8
9
  import { z } from "zod";
@@ -529,7 +530,6 @@ declare module "fastify" {
529
530
  }
530
531
  interface ResourceFilterInputs {
531
532
  readonly expose?: readonly string[];
532
- readonly include?: readonly string[];
533
533
  readonly exclude?: readonly string[];
534
534
  }
535
535
  /**
@@ -1,4 +1,5 @@
1
- import { a as defaultCrudDescription, c as mcpHandlerAdapter, d as toCallToolResult, f as toCallToolSuccess, h as resolveToolCollisions, i as fieldRulesToZod, l as permissionDeniedResult, m as createMcpServer, n as mcpPlugin, o as resolveCrudDescription, p as buildRequestContext, r as resourceToTools, s as invokeController, t as filterResourcesForMcp, u as toCallToolError } from "../../mcpPlugin-nRzm5g2s.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { a as defaultCrudDescription, c as mcpHandlerAdapter, d as toCallToolResult, f as toCallToolSuccess, h as resolveToolCollisions, i as fieldRulesToZod, l as permissionDeniedResult, m as createMcpServer, n as mcpPlugin, o as resolveCrudDescription, p as buildRequestContext, r as resourceToTools, s as invokeController, t as filterResourcesForMcp, u as toCallToolError } from "../../mcpPlugin-CpfVpKHE.mjs";
2
3
  //#region src/integrations/mcp/defineTool.ts
3
4
  /**
4
5
  * Define a type-safe MCP tool.
@@ -1,8 +1,9 @@
1
- import { c as McpAuthResult, u as McpPluginOptions } from "../../types-Bmmn-fO0.mjs";
1
+
2
+ import { c as McpAuthResult, u as McpPluginOptions } from "../../types-CwcUQ610.mjs";
2
3
  //#region src/integrations/mcp/testing.d.ts
3
4
  interface TestMcpClientOptions {
4
5
  /** MCP plugin options (resources, overrides, etc.) — same as mcpPlugin config */
5
- pluginOptions?: Pick<McpPluginOptions, "resources" | "overrides" | "expose" | "include" | "exclude" | "toolNamePrefix" | "extraTools" | "extraPrompts" | "instructions">;
6
+ pluginOptions?: Pick<McpPluginOptions, "resources" | "overrides" | "expose" | "exclude" | "toolNamePrefix" | "extraTools" | "extraPrompts" | "instructions">;
6
7
  /** Auth identity for the test session */
7
8
  auth?: McpAuthResult | null;
8
9
  /** Server name (default: 'test-mcp') */
@@ -1,4 +1,5 @@
1
- import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-nRzm5g2s.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-CpfVpKHE.mjs";
2
3
  //#region src/integrations/mcp/testing.ts
3
4
  /**
4
5
  * @classytic/arc/mcp/testing — MCP Test Utilities
@@ -54,7 +55,6 @@ async function createTestMcpClient(options = {}) {
54
55
  const overrides = pluginOpts.overrides ?? {};
55
56
  const tools = filterResourcesForMcp(pluginOpts.resources ?? [], {
56
57
  expose: pluginOpts.expose,
57
- include: pluginOpts.include,
58
58
  exclude: pluginOpts.exclude
59
59
  }).flatMap((r) => {
60
60
  const resOverrides = overrides[r.name] ?? {};
@@ -1,3 +1,4 @@
1
+
1
2
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
2
3
  //#region src/integrations/streamline.d.ts
3
4
  /**
@@ -1,5 +1,6 @@
1
- import { f as createError, i as NotFoundError, r as ForbiddenError } from "../errors-DkO8Nk6-.mjs";
2
- import { a as promoteStreamTokenToHeader, n as forwardedStreamHeaders } from "../streaming-BQcW6_Kq.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { f as createError, i as NotFoundError, r as ForbiddenError } from "../errors-Bh1KK5ps.mjs";
3
+ import { a as promoteStreamTokenToHeader, n as forwardedStreamHeaders } from "../streaming-DPZdQmDz.mjs";
3
4
  import fp from "fastify-plugin";
4
5
  //#region src/integrations/streamline.ts
5
6
  /**
@@ -1,3 +1,4 @@
1
+
1
2
  import { FastifyPluginAsync } from "fastify";
2
3
  //#region src/integrations/webhooks.d.ts
3
4
  interface WebhookSubscription {
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
1
2
  import { createHmac, timingSafeEqual } from "node:crypto";
2
3
  import fp from "fastify-plugin";
3
4
  //#region src/integrations/webhooks.ts
@@ -1,4 +1,5 @@
1
- import { c as SerializedEntry, i as Principal, n as FencedWriteOutcome, s as PushRefStore, t as EnvelopeSnapshot } from "../pushref-registry-BbcnpNTm.mjs";
1
+
2
+ import { c as SerializedEntry, i as Principal, n as FencedWriteOutcome, s as PushRefStore, t as EnvelopeSnapshot } from "../pushref-registry-Dov9l4qE.mjs";
2
3
  //#region src/integrations/websocket-pushref-redis.d.ts
3
4
  /**
4
5
  * Minimal `ioredis` shape — typed structurally so this file doesn't
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
1
2
  //#region src/integrations/websocket-pushref-redis.ts
2
3
  /**
3
4
  * Lua script for atomic claim. Runs server-side, single-roundtrip.
@@ -1,4 +1,5 @@
1
- import { f as WebSocketAdapter } from "../websocket-_Pd0CgR0.mjs";
1
+
2
+ import { f as WebSocketAdapter } from "../websocket-BOXVggMf.mjs";
2
3
  //#region src/integrations/websocket-redis.d.ts
3
4
  interface RedisLike {
4
5
  publish(channel: string, message: string): Promise<number>;
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
1
2
  //#region src/integrations/websocket-redis.ts
2
3
  /**
3
4
  * Redis Pub/Sub adapter for cross-instance WebSocket broadcast.
@@ -1,3 +1,4 @@
1
- import { a as GeoRoomOptions, c as WebSocketClient, d as LocalWebSocketAdapter, f as WebSocketAdapter, i as GeoRoom, l as WebSocketMessage, n as GeoPoint, o as RoomManager, r as GeoPublishOpts, s as AuthResult, t as websocketPlugin, u as WebSocketPluginOptions } from "../websocket-_Pd0CgR0.mjs";
2
- import { a as PushRefRegistry, c as SerializedEntry, i as Principal, o as PushRefRegistryOptions, r as MemoryPushRefStore, s as PushRefStore } from "../pushref-registry-BbcnpNTm.mjs";
1
+
2
+ import { a as GeoRoomOptions, c as WebSocketClient, d as LocalWebSocketAdapter, f as WebSocketAdapter, i as GeoRoom, l as WebSocketMessage, n as GeoPoint, o as RoomManager, r as GeoPublishOpts, s as AuthResult, t as websocketPlugin, u as WebSocketPluginOptions } from "../websocket-BOXVggMf.mjs";
3
+ import { a as PushRefRegistry, c as SerializedEntry, i as Principal, o as PushRefRegistryOptions, r as MemoryPushRefStore, s as PushRefStore } from "../pushref-registry-Dov9l4qE.mjs";
3
4
  export { type AuthResult, type GeoPoint, type GeoPublishOpts, GeoRoom, type GeoRoomOptions, LocalWebSocketAdapter, MemoryPushRefStore, type Principal, PushRefRegistry, type PushRefRegistryOptions, type PushRefStore, RoomManager, type SerializedEntry, type WebSocketAdapter, type WebSocketClient, type WebSocketMessage, type WebSocketPluginOptions, websocketPlugin };
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
1
2
  import { randomUUID } from "node:crypto";
2
3
  import sjson from "secure-json-parse";
3
4
  import fp from "fastify-plugin";
@@ -333,19 +334,21 @@ var MemoryPushRefStore = class {
333
334
  }
334
335
  async claim(args) {
335
336
  const existing = this.entries.get(args.pushRef);
336
- if (existing) if (!existing.active && existing.expiresAt <= args.now) this.entries.delete(args.pushRef);
337
- else {
338
- if (existing.principal !== args.principal) return { outcome: "rejected" };
339
- const supersededActive = existing.active === true;
340
- existing.active = true;
341
- existing.expiresAt = args.now + args.ttlMs;
342
- existing.generation = (existing.generation ?? 0) + 1;
343
- this.entries.set(args.pushRef, existing);
344
- return {
345
- outcome: "resumed",
346
- entry: existing,
347
- supersededActive
348
- };
337
+ if (existing) {
338
+ if (!existing.active && existing.expiresAt <= args.now) this.entries.delete(args.pushRef);
339
+ else {
340
+ if (existing.principal !== args.principal) return { outcome: "rejected" };
341
+ const supersededActive = existing.active === true;
342
+ existing.active = true;
343
+ existing.expiresAt = args.now + args.ttlMs;
344
+ existing.generation = (existing.generation ?? 0) + 1;
345
+ this.entries.set(args.pushRef, existing);
346
+ return {
347
+ outcome: "resumed",
348
+ entry: existing,
349
+ supersededActive
350
+ };
351
+ }
349
352
  }
350
353
  if (this.entries.size >= args.maxEntries && !this.evictOldestInactive()) return { outcome: "rejected" };
351
354
  const fresh = args.mintFresh();
@@ -1052,9 +1055,7 @@ async function handleConnection(ctx, socket, request) {
1052
1055
  }));
1053
1056
  break;
1054
1057
  }
1055
- default:
1056
- await options.onMessage?.(client, msg);
1057
- break;
1058
+ default: await options.onMessage?.(client, msg);
1058
1059
  }
1059
1060
  });
1060
1061
  socket.on("close", async () => {
@@ -1136,10 +1137,12 @@ function registerStatsRoute(fastify, rooms, path, expose) {
1136
1137
  fastify.get(`${path}/stats`, async () => rooms.getStats());
1137
1138
  return;
1138
1139
  }
1139
- if (expose === "authenticated") if (fastify.hasDecorator("authenticate")) {
1140
- const authenticate = fastify.authenticate;
1141
- fastify.get(`${path}/stats`, { preHandler: authenticate }, async () => rooms.getStats());
1142
- } else fastify.log.warn("arc-websocket: exposeStats is \"authenticated\" but fastify.authenticate is not registered — stats endpoint skipped");
1140
+ if (expose === "authenticated") {
1141
+ if (fastify.hasDecorator("authenticate")) {
1142
+ const authenticate = fastify.authenticate;
1143
+ fastify.get(`${path}/stats`, { preHandler: authenticate }, async () => rooms.getStats());
1144
+ } else fastify.log.warn("arc-websocket: exposeStats is \"authenticated\" but fastify.authenticate is not registered — stats endpoint skipped");
1145
+ }
1143
1146
  }
1144
1147
  //#endregion
1145
1148
  //#region src/integrations/websocket/outbound-truncate.ts
@@ -1163,7 +1166,7 @@ function registerStatsRoute(fastify, rooms, path, expose) {
1163
1166
  * instance, eliminating module state.
1164
1167
  */
1165
1168
  /** 5 MiB default — same as n8n's `relayViaPubSub` ceiling. */
1166
- const DEFAULT_MAX_OUTBOUND_BYTES = 5 * 1024 * 1024;
1169
+ const DEFAULT_MAX_OUTBOUND_BYTES = 5242880;
1167
1170
  /**
1168
1171
  * Returns either the original payload (when within `max`) or a
1169
1172
  * placeholder JSON string (when oversize). The placeholder carries the
@@ -1206,7 +1209,7 @@ function createTruncator(max = DEFAULT_MAX_OUTBOUND_BYTES) {
1206
1209
  * other instances fan out to their local sockets.
1207
1210
  */
1208
1211
  /** Drop fan-out to a client whose outbound buffer exceeds this threshold. */
1209
- const WS_BACKPRESSURE_LIMIT = 256 * 1024;
1212
+ const WS_BACKPRESSURE_LIMIT = 262144;
1210
1213
  var RoomManager = class {
1211
1214
  rooms = /* @__PURE__ */ new Map();
1212
1215
  clients = /* @__PURE__ */ new Map();
@@ -1425,18 +1428,19 @@ var RoomManager = class {
1425
1428
  if (client.socket.readyState !== 1) return false;
1426
1429
  const queue = client.queue;
1427
1430
  if (queue) {
1428
- if (cls === "critical") if (client.envelope) try {
1429
- const parsed = JSON.parse(message);
1430
- queue.send(client.envelope.wrap(parsed));
1431
- if (this.registry) safeAsync(this.registry.persist(client.pushRef, client.generation), this.logger, "registry.persist", {
1432
- pushRef: client.pushRef,
1433
- generation: client.generation
1434
- });
1435
- } catch {
1436
- queue.send(message);
1437
- }
1438
- else queue.send(message);
1439
- else queue.sendRealtime(message, coalesceKey);
1431
+ if (cls === "critical") {
1432
+ if (client.envelope) try {
1433
+ const parsed = JSON.parse(message);
1434
+ queue.send(client.envelope.wrap(parsed));
1435
+ if (this.registry) safeAsync(this.registry.persist(client.pushRef, client.generation), this.logger, "registry.persist", {
1436
+ pushRef: client.pushRef,
1437
+ generation: client.generation
1438
+ });
1439
+ } catch {
1440
+ queue.send(message);
1441
+ }
1442
+ else queue.send(message);
1443
+ } else queue.sendRealtime(message, coalesceKey);
1440
1444
  return true;
1441
1445
  }
1442
1446
  if ((client.socket.bufferedAmount ?? 0) > WS_BACKPRESSURE_LIMIT) return false;
@@ -1,3 +1,4 @@
1
+
1
2
  import { CacheAdapter } from "@classytic/repo-core/cache";
2
3
  //#region src/cache/interface.d.ts
3
4
  interface CacheLogger {
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
1
2
  //#region src/idempotency/stores/interface.ts
2
3
  /**
3
4
  * Helper to create a result object
@@ -1,3 +1,4 @@
1
+
1
2
  //#region src/idempotency/stores/interface.d.ts
2
3
  /**
3
4
  * Idempotency Store Interface
@@ -1,4 +1,5 @@
1
- import { t as ArcError } from "./errors-DkO8Nk6-.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as ArcError } from "./errors-Bh1KK5ps.mjs";
2
3
  import sjson from "secure-json-parse";
3
4
  //#region src/utils/jsonBody.ts
4
5
  /**
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
1
2
  //#region src/cache/keys.ts
2
3
  /**
3
4
  * Cache Key Utilities
@@ -1,4 +1,5 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-BhflRrBs.mjs";
2
3
  import { arcLog } from "./logger/index.mjs";
3
4
  import { readdir } from "node:fs/promises";
4
5
  import { dirname, join, resolve } from "node:path";
@@ -60,7 +61,8 @@ var loadResources_exports = /* @__PURE__ */ __exportAll({ loadResources: () => l
60
61
  */
61
62
  async function loadResources(dir, options = {}) {
62
63
  const { suffix = ".resource", recursive = true, exclude, include, filter } = options;
63
- const absDir = resolve(dir.startsWith("file://") ? dirname(fileURLToPath(dir)) : dir);
64
+ const resolvedDir = dir.startsWith("file://") ? dirname(fileURLToPath(dir)) : dir;
65
+ const absDir = resolve(resolvedDir);
64
66
  const discovered = await collectFiles(absDir, new RegExp(`${escapeRegex(suffix)}\\.(ts|js|mts|mjs)$`), recursive);
65
67
  discovered.sort();
66
68
  const files = filter ? discovered.filter((f) => filter(f)) : discovered;
@@ -1,4 +1,5 @@
1
- import { t as ResourceRegistry } from "./ResourceRegistry-y9Hnypus.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as ResourceRegistry } from "./ResourceRegistry-BVr7PgA0.mjs";
2
3
  import { resolve } from "node:path";
3
4
  import { pathToFileURL } from "node:url";
4
5
  //#region src/cli/utils/loadResourcesFromEntry.ts
@@ -1,3 +1,4 @@
1
+
1
2
  //#region src/logger/index.d.ts
2
3
  /**
3
4
  * Arc Logger — Centralized debug & warning system
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
1
2
  //#region src/logger/index.ts
2
3
  let globalOptions = {};
3
4
  /**