@classytic/arc 2.18.5 → 2.20.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 (92) hide show
  1. package/README.md +1 -1
  2. package/bin/arc.js +37 -0
  3. package/dist/{BaseController-Dy6EQHjM.mjs → BaseController-D-MHZ27_.mjs} +4 -4
  4. package/dist/{ResourceRegistry-5fKZwhK_.mjs → ResourceRegistry-7RnrEWNP.mjs} +1 -1
  5. package/dist/{actionPermissions-h7DYDNMg.mjs → actionPermissions-C9RMiIpc.mjs} +2 -1
  6. package/dist/audit/index.mjs +1 -1
  7. package/dist/auth/index.d.mts +1 -1
  8. package/dist/auth/index.mjs +17 -6
  9. package/dist/{buildHandler-B0qvAguf.mjs → buildHandler-D_2ULWxZ.mjs} +3 -3
  10. package/dist/cache/index.mjs +2 -2
  11. package/dist/cli/commands/describe.d.mts +1 -1
  12. package/dist/cli/commands/describe.mjs +2 -2
  13. package/dist/cli/commands/docs.mjs +2 -2
  14. package/dist/cli/commands/generate.mjs +1 -1
  15. package/dist/cli/commands/init.mjs +1 -1
  16. package/dist/cli/commands/introspect.mjs +4 -13
  17. package/dist/cli/index.mjs +2 -2
  18. package/dist/{constants-gaEeMlz-.mjs → constants-DNre0wRg.mjs} +1 -1
  19. package/dist/core/index.d.mts +2 -2
  20. package/dist/core/index.mjs +4 -4
  21. package/dist/{core-ZnQBa5rh.mjs → core-CWhyGkiM.mjs} +136 -59
  22. package/dist/{createActionRouter-CagItpxI.mjs → createActionRouter-HlQso0jO.mjs} +8 -7
  23. package/dist/{createAggregationRouter-DVKroXhC.mjs → createAggregationRouter-5LzPzgw1.mjs} +5 -4
  24. package/dist/{createApp--703hQE1.mjs → createApp-D6uwzCKu.mjs} +210 -17
  25. package/dist/docs/index.d.mts +1 -1
  26. package/dist/docs/index.mjs +1 -1
  27. package/dist/encryption/index.d.mts +222 -0
  28. package/dist/encryption/index.mjs +270 -0
  29. package/dist/events/index.mjs +9 -6
  30. package/dist/factory/index.d.mts +3 -2
  31. package/dist/factory/index.mjs +2 -2
  32. package/dist/{fastify-augmentation-Cxb0ROIw.d.mts → fastify-augmentation-CCQJEDgh.d.mts} +12 -1
  33. package/dist/{generate-Brans3fW.mjs → generate-usRSdQmP.mjs} +4 -3
  34. package/dist/hooks/index.d.mts +1 -1
  35. package/dist/idempotency/index.mjs +1 -1
  36. package/dist/{index-CRKiiP5o.d.mts → index-CdFkIMEd.d.mts} +5 -0
  37. package/dist/{index-Dh0_RSTd.d.mts → index-DUa8WHz3.d.mts} +7 -7
  38. package/dist/{index-CHNQIhcb.d.mts → index-_--GyzcO.d.mts} +111 -2
  39. package/dist/index.d.mts +3 -3
  40. package/dist/index.mjs +6 -6
  41. package/dist/{init-Bqpt1Hxf.mjs → init-YH_nslQR.mjs} +87 -5
  42. package/dist/integrations/index.d.mts +1 -1
  43. package/dist/integrations/mcp/index.d.mts +2 -2
  44. package/dist/integrations/mcp/index.mjs +1 -1
  45. package/dist/integrations/mcp/testing.d.mts +1 -1
  46. package/dist/integrations/mcp/testing.mjs +1 -1
  47. package/dist/integrations/streamline.d.mts +17 -5
  48. package/dist/integrations/streamline.mjs +9 -5
  49. package/dist/{loadResourcesFromEntry-BTlFEx05.mjs → loadResourcesFromEntry-OMCvIEE7.mjs} +1 -1
  50. package/dist/{mcpPlugin-D1wuRD2c.mjs → mcpPlugin-CuW6L_uD.mjs} +148 -49
  51. package/dist/middleware/index.d.mts +1 -1
  52. package/dist/middleware/index.mjs +1 -1
  53. package/dist/module-JYH9V0I8.d.mts +384 -0
  54. package/dist/{openapi-xVJibapr.mjs → openapi-Dq6RbEGK.mjs} +3 -3
  55. package/dist/permissions/index.d.mts +1 -1
  56. package/dist/permissions/index.mjs +1 -1
  57. package/dist/{permissions-BPB1xqGf.mjs → permissions-CgbOLJZG.mjs} +10 -2
  58. package/dist/pipeline/index.d.mts +1 -1
  59. package/dist/plugins/index.d.mts +10 -5
  60. package/dist/plugins/index.mjs +3 -3
  61. package/dist/plugins/tracing-entry.mjs +1 -1
  62. package/dist/{pluralize-DccFV9R7.mjs → pluralize-BhrgwZb9.mjs} +3 -3
  63. package/dist/presets/filesUpload.d.mts +1 -1
  64. package/dist/presets/filesUpload.mjs +1 -1
  65. package/dist/presets/index.d.mts +16 -2
  66. package/dist/presets/index.mjs +1 -1
  67. package/dist/presets/multiTenant.d.mts +1 -1
  68. package/dist/presets/multiTenant.mjs +1 -1
  69. package/dist/presets/search.d.mts +1 -1
  70. package/dist/presets/search.mjs +3 -2
  71. package/dist/{presets-BtyFwTO4.mjs → presets-DWsYQdbV.mjs} +1 -1
  72. package/dist/{queryCachePlugin-emHb0CuX.mjs → queryCachePlugin-DzqLN904.mjs} +2 -2
  73. package/dist/{registerRoute-CPmdkZGu.mjs → registerRoute-DGSREwPw.mjs} +20 -2
  74. package/dist/registry/index.d.mts +1 -1
  75. package/dist/registry/index.mjs +2 -2
  76. package/dist/{registry-Bm9LjWKs.mjs → registry-vcOCtPij.mjs} +1 -1
  77. package/dist/{schemaIR-D1MJwqmp.mjs → schemaIR-ajetw3Fv.mjs} +1 -42
  78. package/dist/scim/index.mjs +2 -2
  79. package/dist/sync/changelog.d.mts +2 -0
  80. package/dist/sync/changelog.mjs +2 -0
  81. package/dist/testing/index.d.mts +2 -2
  82. package/dist/testing/index.mjs +2 -2
  83. package/dist/types/index.d.mts +2 -2
  84. package/dist/{types-CmkknLzI.d.mts → types-BHMKlMBU.d.mts} +53 -195
  85. package/dist/{types-D60PFwfG.d.mts → types-C9b2HR5W.d.mts} +1 -1
  86. package/dist/utils/index.d.mts +1 -1
  87. package/dist/utils/index.mjs +1 -1
  88. package/dist/{utils-C6QQ9-hd.mjs → utils-ChjYQpjn.mjs} +1400 -1400
  89. package/dist/{validate-CRcaWzp2.mjs → validate-C2mGgSXg.mjs} +3 -3
  90. package/package.json +22 -8
  91. package/skills/arc/SKILL.md +10 -0
  92. package/skills/arc/references/mcp.md +2 -0
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
- import { $t as BaseController, A as RequestIdOptions, An as ArcDeleteResult, At as AggregationRateLimit, B as defineResource, C as RequestContext, Ct as AggMeasureShorthand, D as HealthCheck, Dt as AggregationIndexHint, E as GracefulShutdownOptions, Et as AggregationDateRangeRequirement, F as FastifyWithDecorators, Fn as ControllerConfigurableOptions, In as ControllerConstructionOptions, J as CrudRouteKey, Jt as ArcRequest, Kt as AnyRecord, L as RequestWithExtras, Ln as ListResult, Mn as ArcListResult, N as FastifyRequestExtras, Nn as ArcUpdateResult, O as HealthOptions, Ot as AggregationMaterializedContext, P as FastifyWithAuth, Pn as BaseControllerOptions, Q as MiddlewareConfig, Qt as UserOrganization, S as QueryParserInterface, St as AggMeasureInput, T as CrudRouterOptions, Tt as AggregationConfig, V as ResourceDefinition, Vt as AuthPluginOptions, X as EventDefinition, Y as CrudSchemas, Yt as JWTPayload, Z as FieldRule, a as InferAdapterDoc, an as SlugMixin, bt as IRequestContext, c as TypedController, cn as BaseCrudController, d as PaginationResult, en as SoftDeleteExt, f as IntrospectionData, g as ArcInternalMetadata, gt as ControllerLike, h as ResourceMetadata, i as ValidationResult, in as SlugExt, it as RateLimitConfig, jn as ArcGetResult, jt as AggregationsMap, k as IntrospectionPluginOptions, kn as ArcCreateResult, kt as AggregationMaterializedResult, l as TypedRepository, m as RegistryStats, mt as RouteSchemaOptions, n as ConfigError, nn as TreeExt, o as InferDocType, on as BulkExt, p as RegistryEntry, q as CrudController, qt as ApiResponse, r as ValidateOptions, rn as TreeMixin, rt as PresetResult, s as InferResourceDoc, sn as BulkMixin, st as ResourceConfig, t as RouteHandlerMethod, tn as SoftDeleteMixin, tt as PresetFunction, u as TypedResourceConfig, vt as IController, w as ServiceContext, wt as AggregationCacheConfig, xt as RouteHandler, y as OwnershipCheck, yt as IControllerResponse } from "./index-CHNQIhcb.mjs";
1
+ import { $t as UserOrganization, A as RequestIdOptions, An as ArcCreateResult, At as AggregationMaterializedResult, B as defineResource, C as RequestContext, Ct as AggMeasureInput, D as HealthCheck, Dt as AggregationDateRangeRequirement, E as GracefulShutdownOptions, Et as AggregationConfig, F as FastifyWithDecorators, Fn as BaseControllerOptions, Ht as AuthPluginOptions, In as ControllerConfigurableOptions, J as CrudRouteKey, Jt as ApiResponse, L as RequestWithExtras, Ln as ControllerConstructionOptions, Mn as ArcGetResult, Mt as AggregationsMap, N as FastifyRequestExtras, Nn as ArcListResult, O as HealthOptions, Ot as AggregationIndexHint, P as FastifyWithAuth, Pn as ArcUpdateResult, Q as MiddlewareConfig, Rn as ListResult, S as QueryParserInterface, St as RouteHandler, T as CrudRouterOptions, Tt as AggregationCacheConfig, V as ResourceDefinition, X as EventDefinition, Xt as JWTPayload, Y as CrudSchemas, Yt as ArcRequest, Z as FieldRule, _t as ControllerLike, a as InferAdapterDoc, an as SlugExt, bt as IControllerResponse, c as TypedController, cn as BulkMixin, d as PaginationResult, en as BaseController, f as IntrospectionData, g as ArcInternalMetadata, h as ResourceMetadata, ht as RouteSchemaOptions, i as ValidationResult, in as TreeMixin, it as RateLimitConfig, jn as ArcDeleteResult, jt as AggregationRateLimit, k as IntrospectionPluginOptions, kt as AggregationMaterializedContext, l as TypedRepository, ln as BaseCrudController, m as RegistryStats, n as ConfigError, nn as SoftDeleteMixin, o as InferDocType, on as SlugMixin, p as RegistryEntry, q as CrudController, qt as AnyRecord, r as ValidateOptions, rn as TreeExt, rt as PresetResult, s as InferResourceDoc, sn as BulkExt, st as ResourceConfig, t as RouteHandlerMethod, tn as SoftDeleteExt, tt as PresetFunction, u as TypedResourceConfig, w as ServiceContext, wt as AggMeasureShorthand, xt as IRequestContext, y as OwnershipCheck, yt as IController } from "./index-_--GyzcO.mjs";
2
2
  import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, t as FieldPermission, u as PermissionResult } from "./fields-C7ahdGYf.mjs";
3
- import { A as MAX_FILTER_DEPTH, C as DEFAULT_SORT, D as HOOK_PHASES, E as HOOK_OPERATIONS, F as RESERVED_QUERY_PARAMS, I as SYSTEM_FIELDS, M as MAX_SEARCH_LENGTH, N as MUTATION_OPERATIONS, O as HookOperation, P as MutationOperation, S as DEFAULT_MAX_LIMIT, T as DEFAULT_UPDATE_METHOD, _ as defineAggregation, b as DEFAULT_ID_FIELD, f as defineResourceVariants, j as MAX_REGEX_LENGTH, k as HookPhase, m as defineAction, s as getControllerScope, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "./index-Dh0_RSTd.mjs";
4
- import { A as requireRoles, C as allOf, E as denyAll, M as when, O as requireAuth, S as createOrgPermissions, T as anyOf, a as presets_d_exports, c as readOnly, d as requireOrgRole, f as requireScopeContext, i as ownerWithAdminBypass, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "./index-CRKiiP5o.mjs";
3
+ import { A as MAX_FILTER_DEPTH, C as DEFAULT_SORT, D as HOOK_PHASES, E as HOOK_OPERATIONS, F as RESERVED_QUERY_PARAMS, I as SYSTEM_FIELDS, M as MAX_SEARCH_LENGTH, N as MUTATION_OPERATIONS, O as HookOperation, P as MutationOperation, S as DEFAULT_MAX_LIMIT, T as DEFAULT_UPDATE_METHOD, _ as defineAggregation, b as DEFAULT_ID_FIELD, f as defineResourceVariants, j as MAX_REGEX_LENGTH, k as HookPhase, m as defineAction, s as getControllerScope, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "./index-DUa8WHz3.mjs";
4
+ import { A as requireRoles, C as allOf, E as denyAll, M as when, O as requireAuth, S as createOrgPermissions, T as anyOf, a as presets_d_exports, c as readOnly, d as requireOrgRole, f as requireScopeContext, i as ownerWithAdminBypass, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "./index-CdFkIMEd.mjs";
5
5
  import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-DOHkjQlD.mjs";
6
6
 
7
7
  //#region src/index.d.ts
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-gaEeMlz-.mjs";
1
+ import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-DNre0wRg.mjs";
2
2
  import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-DkO8Nk6-.mjs";
3
- import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-Dy6EQHjM.mjs";
4
- import { a as defineResource, i as defineResourceVariants, o as ResourceDefinition, s as defineAction, u as defineAggregation } from "./core-ZnQBa5rh.mjs";
5
- import { C as requireAuth, D as when, F as applyFieldWritePermissions, I as fields, P as applyFieldReadPermissions, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "./permissions-BPB1xqGf.mjs";
6
- import { l as getControllerScope } from "./actionPermissions-h7DYDNMg.mjs";
3
+ import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-D-MHZ27_.mjs";
4
+ import { C as requireAuth, D as when, F as applyFieldWritePermissions, I as fields, P as applyFieldReadPermissions, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "./permissions-CgbOLJZG.mjs";
5
+ import { a as defineResource, i as defineResourceVariants, o as ResourceDefinition, s as defineAction, u as defineAggregation } from "./core-CWhyGkiM.mjs";
6
+ import { l as getControllerScope } from "./actionPermissions-C9RMiIpc.mjs";
7
7
  //#region src/index.ts
8
- const version = "2.18.5";
8
+ const version = "2.20.0";
9
9
  //#endregion
10
10
  export { ArcError, BaseController, BaseCrudController, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, ForbiddenError, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, NotFoundError, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
@@ -1,6 +1,8 @@
1
1
  import * as fs from "node:fs/promises";
2
2
  import * as path from "node:path";
3
- import { accessSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { accessSync, existsSync, readFileSync } from "node:fs";
4
6
  import * as readline from "node:readline";
5
7
  import { execSync, spawn } from "node:child_process";
6
8
  //#region src/cli/commands/init/templates/adapter.ts
@@ -929,11 +931,32 @@ ${config.adapter === "mongokit" ? ` await mongoose.connection.collection('use
929
931
  }
930
932
  //#endregion
931
933
  //#region src/cli/commands/init/dependency-plan.ts
934
+ /**
935
+ * Single source of truth for scaffolded project dependencies.
936
+ *
937
+ * Two layers keep the scaffold from ever contradicting the arc release
938
+ * that ships it:
939
+ *
940
+ * 1. The static table below — tracks published npm latest, bumped on
941
+ * release. Serves as the offline fallback.
942
+ * 2. A runtime overlay from arc's OWN package.json (version + declared
943
+ * peer floors). The 2.20.0 review found the static pins had drifted
944
+ * (`arc ^2.18.5` + `primitives ^0.6.0` while arc 2.20 peers demand
945
+ * >=0.9.0 → ERESOLVE on the first `arc init` a new user runs).
946
+ * Deriving from the installed package.json makes that class of
947
+ * breakage structurally impossible: the scaffold always pins the
948
+ * arc version actually running and ranges that satisfy its peers.
949
+ *
950
+ * Used by both `packageJsonTemplate` (declares the deps in the generated
951
+ * `package.json` so `npm install` works without a pre-pass) and
952
+ * `installDependencies` (runs the package manager's `install` against
953
+ * the declared ranges). One source — no drift.
954
+ */
932
955
  const SCAFFOLD_DEP_VERSIONS = {
933
956
  core: {
934
- "@classytic/arc": "^2.18.5",
935
- "@classytic/primitives": "^0.6.0",
936
- "@classytic/repo-core": "^0.6.0",
957
+ "@classytic/arc": "^2.20.0",
958
+ "@classytic/primitives": "^0.9.1",
959
+ "@classytic/repo-core": "^0.7.0",
937
960
  "@fastify/cors": "^11.2.0",
938
961
  "@fastify/helmet": "^13.0.2",
939
962
  "@fastify/rate-limit": "^10.3.0",
@@ -970,6 +993,64 @@ const SCAFFOLD_DEP_VERSIONS = {
970
993
  typesJwt: { "@types/bcryptjs": "^3.0.0" }
971
994
  };
972
995
  /**
996
+ * Locate arc's own package.json by walking up from the executing file.
997
+ * A path walk (vs `require.resolve('@classytic/arc/package.json')`) works
998
+ * regardless of bundle chunk layout and of package.json not being in the
999
+ * exports map. Returns undefined when not found — callers fall back to
1000
+ * the static table.
1001
+ */
1002
+ function readOwnPackageJson() {
1003
+ try {
1004
+ let dir = dirname(fileURLToPath(import.meta.url));
1005
+ for (let depth = 0; depth < 6; depth++) {
1006
+ const candidate = join(dir, "package.json");
1007
+ if (existsSync(candidate)) {
1008
+ const parsed = JSON.parse(readFileSync(candidate, "utf8"));
1009
+ if (parsed.name === "@classytic/arc") return parsed;
1010
+ }
1011
+ const parent = dirname(dir);
1012
+ if (parent === dir) break;
1013
+ dir = parent;
1014
+ }
1015
+ } catch {}
1016
+ }
1017
+ /** First x.y.z triple in a range string, or undefined. */
1018
+ function parseFloor(range) {
1019
+ const m = /(\d+)\.(\d+)\.(\d+)/.exec(range);
1020
+ if (!m) return void 0;
1021
+ return [
1022
+ Number(m[1]),
1023
+ Number(m[2]),
1024
+ Number(m[3])
1025
+ ];
1026
+ }
1027
+ function floorLessThan(a, b) {
1028
+ if (a[0] !== b[0]) return a[0] < b[0];
1029
+ if (a[1] !== b[1]) return a[1] < b[1];
1030
+ return a[2] < b[2];
1031
+ }
1032
+ /**
1033
+ * Overlay live truth from arc's own package.json onto the static pins:
1034
+ * - `@classytic/arc` pins the exact running version (`^<version>`).
1035
+ * - Any scaffolded dep that is also an arc peer gets raised to `^<peer
1036
+ * floor>` when the static pin's floor is BELOW the declared peer floor
1037
+ * (never lowered — static pins may legitimately be ahead of the floor).
1038
+ */
1039
+ function overlayLiveArcVersions(dependencies) {
1040
+ const own = readOwnPackageJson();
1041
+ if (!own) return;
1042
+ if (own.version && dependencies["@classytic/arc"]) dependencies["@classytic/arc"] = `^${own.version}`;
1043
+ const peers = own.peerDependencies ?? {};
1044
+ for (const [name, staticRange] of Object.entries(dependencies)) {
1045
+ const peerRange = peers[name];
1046
+ if (!peerRange) continue;
1047
+ const peerFloor = parseFloor(peerRange);
1048
+ const staticFloor = parseFloor(staticRange);
1049
+ if (!peerFloor || !staticFloor) continue;
1050
+ if (floorLessThan(staticFloor, peerFloor)) dependencies[name] = `^${peerFloor.join(".")}`;
1051
+ }
1052
+ }
1053
+ /**
973
1054
  * Resolve the dependency manifest for a scaffold configuration.
974
1055
  *
975
1056
  * Returns sorted records (alphabetical by package name) so the generated
@@ -987,6 +1068,7 @@ function resolveScaffoldDependencies(config) {
987
1068
  }
988
1069
  if (config.adapter === "mongokit") Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.adapterMongokit);
989
1070
  if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.devTypescript);
1071
+ overlayLiveArcVersions(dependencies);
990
1072
  return {
991
1073
  dependencies: sortByKey(dependencies),
992
1074
  devDependencies: sortByKey(devDependencies)
@@ -3022,7 +3104,7 @@ async function gatherConfig(options) {
3022
3104
  output: process.stdout
3023
3105
  });
3024
3106
  const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
3025
- const nonInteractive = !!options.name;
3107
+ const nonInteractive = !!options.name || !process.stdin.isTTY;
3026
3108
  try {
3027
3109
  const name = options.name || await question("Project name: ") || "my-arc-app";
3028
3110
  let adapter = options.adapter || "mongokit";
@@ -1,7 +1,7 @@
1
1
  import { c as WebSocketClient, l as WebSocketMessage, u as WebSocketPluginOptions } from "../websocket-MlYlrYq0.mjs";
2
2
  import { EventGatewayOptions } from "./event-gateway.mjs";
3
3
  import { JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, QueueStats } from "./jobs.mjs";
4
- import { c as McpAuthResult, d as PromptDefinition, g as ToolDefinition, h as ToolContext, l as McpPluginOptions, m as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpResourceConfig } from "../types-D60PFwfG.mjs";
4
+ import { c as McpAuthResult, d as PromptDefinition, g as ToolDefinition, h as ToolContext, l as McpPluginOptions, m as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpResourceConfig } from "../types-C9b2HR5W.mjs";
5
5
  import { StreamlinePluginOptions, WorkflowLike, WorkflowRunLike } from "./streamline.mjs";
6
6
  import { WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription } from "./webhooks.mjs";
7
7
  export type { BetterAuthHandler, CallToolResult, CreateMcpServerConfig, CrudOperation, EventGatewayOptions, JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, McpAuthResult, McpPluginOptions, McpResourceConfig, PromptDefinition, QueueStats, StreamlinePluginOptions, ToolAnnotations, ToolContext, ToolDefinition, WebSocketClient, WebSocketMessage, WebSocketPluginOptions, WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription, WorkflowLike, WorkflowRunLike };
@@ -1,7 +1,7 @@
1
- import { V as ResourceDefinition, bt as IRequestContext, yt as IControllerResponse } from "../../index-CHNQIhcb.mjs";
1
+ import { V as ResourceDefinition, bt as IControllerResponse, xt as IRequestContext } from "../../index-_--GyzcO.mjs";
2
2
  import { i as RequestScope } from "../../types-LNebCoJx.mjs";
3
3
  import { c as PermissionCheck } from "../../fields-C7ahdGYf.mjs";
4
- import { a as CrudDescriptionOverride, c as McpAuthResult, d as PromptDefinition, f as PromptResult, g as ToolDefinition, h as ToolContext, i as CrudDescriptionMeta, l as McpPluginOptions, m as ToolAnnotations, n as CallToolResult, o as CrudOperation, p as SessionEntry, r as CreateMcpServerConfig, s as McpAuthResolver, t as BetterAuthHandler, u as McpResourceConfig } from "../../types-D60PFwfG.mjs";
4
+ import { a as CrudDescriptionOverride, c as McpAuthResult, d as PromptDefinition, f as PromptResult, g as ToolDefinition, h as ToolContext, i as CrudDescriptionMeta, l as McpPluginOptions, m as ToolAnnotations, n as CallToolResult, o as CrudOperation, p as SessionEntry, r as CreateMcpServerConfig, s as McpAuthResolver, t as BetterAuthHandler, u as McpResourceConfig } from "../../types-C9b2HR5W.mjs";
5
5
  import { ErrorContract } from "@classytic/repo-core/errors";
6
6
  import { FastifyPluginAsync } from "fastify";
7
7
  import { z } from "zod";
@@ -1,4 +1,4 @@
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-D1wuRD2c.mjs";
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-CuW6L_uD.mjs";
2
2
  //#region src/integrations/mcp/defineTool.ts
3
3
  /**
4
4
  * Define a type-safe MCP tool.
@@ -1,4 +1,4 @@
1
- import { c as McpAuthResult, l as McpPluginOptions } from "../../types-D60PFwfG.mjs";
1
+ import { c as McpAuthResult, l as McpPluginOptions } from "../../types-C9b2HR5W.mjs";
2
2
 
3
3
  //#region src/integrations/mcp/testing.d.ts
4
4
  interface TestMcpClientOptions {
@@ -1,4 +1,4 @@
1
- import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-D1wuRD2c.mjs";
1
+ import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-CuW6L_uD.mjs";
2
2
  //#region src/integrations/mcp/testing.ts
3
3
  /**
4
4
  * @classytic/arc/mcp/testing — MCP Test Utilities
@@ -28,8 +28,12 @@ interface WorkflowLike {
28
28
  start(input: unknown, options?: WorkflowStartOptions): Promise<WorkflowRunLike>;
29
29
  execute(runId: string): Promise<WorkflowRunLike>;
30
30
  resume(runId: string, payload?: unknown): Promise<WorkflowRunLike>;
31
- cancel(runId: string): Promise<WorkflowRunLike>;
32
- pause?(runId: string): Promise<WorkflowRunLike>;
31
+ cancel(runId: string, options?: {
32
+ reason?: string;
33
+ }): Promise<WorkflowRunLike>;
34
+ pause?(runId: string, options?: {
35
+ reason?: string;
36
+ }): Promise<WorkflowRunLike>;
33
37
  rewindTo?(runId: string, stepId: string): Promise<WorkflowRunLike>;
34
38
  get(runId: string): Promise<WorkflowRunLike | null>;
35
39
  waitFor?(runId: string, options?: {
@@ -39,7 +43,9 @@ interface WorkflowLike {
39
43
  };
40
44
  start(input: unknown, options?: WorkflowStartOptions): Promise<WorkflowRunLike>;
41
45
  resume(runId: string, payload?: unknown): Promise<WorkflowRunLike>;
42
- cancel(runId: string): Promise<WorkflowRunLike>;
46
+ cancel(runId: string, options?: {
47
+ reason?: string;
48
+ }): Promise<WorkflowRunLike>;
43
49
  get(runId: string): Promise<WorkflowRunLike | null>;
44
50
  shutdown?(): void;
45
51
  /** Streamline container for event bridging + repository access (streamline >=2.1) */
@@ -114,6 +120,12 @@ interface WorkflowRunLike {
114
120
  * toward dead-letter.
115
121
  */
116
122
  recoveryAttempts?: number;
123
+ /**
124
+ * Streamline >= 2.7 — operator-supplied cancellation reason, set when
125
+ * `cancel(runId, { reason })` was called. Absent on runs cancelled without
126
+ * a reason or under older streamline. Surfaced so dashboards can show WHY.
127
+ */
128
+ cancellationReason?: string;
117
129
  }
118
130
  /**
119
131
  * Streamline >= 2.3.3 dead-letter discriminator. The run.status stays
@@ -148,7 +160,7 @@ interface StreamlinePluginOptions {
148
160
  * - Step events: started, completed, failed, waiting, skipped,
149
161
  * retry-scheduled, compensated
150
162
  * - Workflow lifecycle: started, completed, failed, waiting, resumed,
151
- * cancelled, recovered, retry, compensating
163
+ * cancelled, recovered, retry, compensating, paused (>= 2.7)
152
164
  * - Engine telemetry: engine:error, scheduler:error,
153
165
  * scheduler:circuit-open
154
166
  *
@@ -231,7 +243,7 @@ interface StreamlinePluginOptions {
231
243
  * adds can be bridged by updating this list; arc never breaks just
232
244
  * because streamline extended its bus.
233
245
  */
234
- declare const STREAMLINE_BUS_EVENTS: readonly ["step:started", "step:completed", "step:failed", "step:waiting", "step:skipped", "step:retry-scheduled", "step:compensated", "workflow:started", "workflow:completed", "workflow:failed", "workflow:waiting", "workflow:resumed", "workflow:cancelled", "workflow:recovered", "workflow:retry", "workflow:compensating", "engine:error", "scheduler:error", "scheduler:circuit-open"];
246
+ declare const STREAMLINE_BUS_EVENTS: readonly ["step:started", "step:completed", "step:failed", "step:waiting", "step:skipped", "step:retry-scheduled", "step:compensated", "workflow:started", "workflow:completed", "workflow:failed", "workflow:waiting", "workflow:resumed", "workflow:cancelled", "workflow:recovered", "workflow:retry", "workflow:compensating", "workflow:paused", "engine:error", "scheduler:error", "scheduler:circuit-open"];
235
247
  /**
236
248
  * Non-durable streaming frames from streamline >= 2.6's `ctx.stream(frame)`
237
249
  * (LLM tokens, percent-complete, live previews).
@@ -45,6 +45,7 @@ const STREAMLINE_BUS_EVENTS = [
45
45
  "workflow:recovered",
46
46
  "workflow:retry",
47
47
  "workflow:compensating",
48
+ "workflow:paused",
48
49
  "engine:error",
49
50
  "scheduler:error",
50
51
  "scheduler:circuit-open"
@@ -80,7 +81,7 @@ const STREAMLINE_TERMINAL_EVENTS = [
80
81
  * emit no further bus events, so the SSE handler sends its snapshot and
81
82
  * closes immediately rather than holding a connection open on a dead run.
82
83
  */
83
- const TERMINAL_RUN_STATUSES = new Set([
84
+ const TERMINAL_RUN_STATUSES = /* @__PURE__ */ new Set([
84
85
  "done",
85
86
  "failed",
86
87
  "cancelled"
@@ -130,7 +131,7 @@ const streamlinePluginImpl = async (fastify, options) => {
130
131
  code: "arc.streamline.invalid_body",
131
132
  workflowId: id
132
133
  });
133
- const envelopeKeys = new Set([
134
+ const envelopeKeys = /* @__PURE__ */ new Set([
134
135
  "input",
135
136
  "meta",
136
137
  "idempotencyKey",
@@ -223,11 +224,13 @@ const streamlinePluginImpl = async (fastify, options) => {
223
224
  if (!await checkPerm("cancel", request)) throw new ForbiddenError();
224
225
  const { runId } = request.params;
225
226
  await assertRunVisible(request, runId);
226
- const run = await wf.cancel(runId);
227
+ const { reason: cancelReason } = request.body ?? {};
228
+ const run = await wf.cancel(runId, cancelReason !== void 0 ? { reason: cancelReason } : void 0);
227
229
  if (bridgeEvents && fastify.events?.publish) try {
228
230
  await fastify.events.publish(`workflow.${id}.cancelled`, {
229
231
  runId: run._id,
230
- workflowId: id
232
+ workflowId: id,
233
+ ...cancelReason !== void 0 ? { reason: cancelReason } : {}
231
234
  });
232
235
  } catch (err) {
233
236
  fastify.log.warn({
@@ -271,7 +274,8 @@ const streamlinePluginImpl = async (fastify, options) => {
271
274
  if (wf.engine.pause) fastify.post(`${routePrefix}/runs/:runId/pause`, { preHandler: authPreHandler }, async (request, _reply) => {
272
275
  const { runId } = request.params;
273
276
  await assertRunVisible(request, runId);
274
- return await wf.engine.pause?.(runId);
277
+ const { reason: pauseReason } = request.body ?? {};
278
+ return await wf.engine.pause?.(runId, pauseReason !== void 0 ? { reason: pauseReason } : void 0);
275
279
  });
276
280
  if (wf.engine.rewindTo) fastify.post(`${routePrefix}/runs/:runId/rewind`, { preHandler: authPreHandler }, async (request, _reply) => {
277
281
  const { runId } = request.params;
@@ -1,4 +1,4 @@
1
- import { t as ResourceRegistry } from "./ResourceRegistry-5fKZwhK_.mjs";
1
+ import { t as ResourceRegistry } from "./ResourceRegistry-7RnrEWNP.mjs";
2
2
  import { resolve } from "node:path";
3
3
  import { pathToFileURL } from "node:url";
4
4
  //#region src/cli/utils/loadResourcesFromEntry.ts