skedyul 1.7.0 → 1.7.2

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.
package/dist/cli/index.js CHANGED
@@ -3870,6 +3870,72 @@ async function handleProvision(body, hooks) {
3870
3870
  }
3871
3871
  }
3872
3872
 
3873
+ // src/server/handlers/setup-revalidate-handler.ts
3874
+ async function handleSetupRevalidate(body, hooks) {
3875
+ const revalidateHook = hooks?.setup?.revalidate;
3876
+ if (!revalidateHook) {
3877
+ return {
3878
+ status: 404,
3879
+ body: { error: "Setup revalidate handler not configured" }
3880
+ };
3881
+ }
3882
+ if (!body.context?.appInstallationId || !body.context?.workplace || !body.context?.app || !body.reason || !Array.isArray(body.steps)) {
3883
+ return {
3884
+ status: 400,
3885
+ body: {
3886
+ error: {
3887
+ code: -32602,
3888
+ message: "Missing context (appInstallationId, workplace, app, reason, and steps required)"
3889
+ }
3890
+ }
3891
+ };
3892
+ }
3893
+ const ctx = {
3894
+ env: body.env ?? {},
3895
+ workplace: body.context.workplace,
3896
+ appInstallationId: body.context.appInstallationId,
3897
+ app: body.context.app,
3898
+ reason: body.reason,
3899
+ steps: body.steps,
3900
+ crm: body.crm,
3901
+ envChange: body.envChange,
3902
+ invocation: body.invocation,
3903
+ log: createContextLogger()
3904
+ };
3905
+ const requestConfig = {
3906
+ baseUrl: body.env?.SKEDYUL_API_URL ?? process.env.SKEDYUL_API_URL ?? "",
3907
+ apiToken: body.env?.SKEDYUL_API_TOKEN ?? process.env.SKEDYUL_API_TOKEN ?? ""
3908
+ };
3909
+ try {
3910
+ const handler = typeof revalidateHook === "function" ? revalidateHook : revalidateHook.handler;
3911
+ const result = await runWithLogContext(
3912
+ { invocation: body.invocation },
3913
+ async () => {
3914
+ return await runWithConfig(requestConfig, async () => {
3915
+ return await handler(ctx);
3916
+ });
3917
+ }
3918
+ );
3919
+ return {
3920
+ status: 200,
3921
+ body: {
3922
+ completed: result?.completed ?? [],
3923
+ invalidated: result?.invalidated ?? []
3924
+ }
3925
+ };
3926
+ } catch (err) {
3927
+ return {
3928
+ status: 500,
3929
+ body: {
3930
+ error: {
3931
+ code: -32603,
3932
+ message: err instanceof Error ? err.message : String(err ?? "")
3933
+ }
3934
+ }
3935
+ };
3936
+ }
3937
+ }
3938
+
3873
3939
  // src/server/handler-helpers.ts
3874
3940
  function parseHandlerEnvelope(parsedBody) {
3875
3941
  if (typeof parsedBody !== "object" || parsedBody === null || Array.isArray(parsedBody) || !("env" in parsedBody) || !("request" in parsedBody)) {
@@ -4261,6 +4327,14 @@ async function handleProvisionRoute(req, ctx) {
4261
4327
  const result = await handleProvision(parseResult.data, ctx.config.hooks);
4262
4328
  return { status: result.status, body: result.body };
4263
4329
  }
4330
+ async function handleSetupRevalidateRoute(req, ctx) {
4331
+ const parseResult = parseJsonBody(req);
4332
+ if (!parseResult.success) {
4333
+ return parseResult.error;
4334
+ }
4335
+ const result = await handleSetupRevalidate(parseResult.data, ctx.config.hooks);
4336
+ return { status: result.status, body: result.body };
4337
+ }
4264
4338
  async function handleOAuthCallbackRoute(req, ctx) {
4265
4339
  const parseResult = parseJsonBody(req);
4266
4340
  if (!parseResult.success) {
@@ -4622,6 +4696,9 @@ async function routeRequest(req, ctx) {
4622
4696
  if (req.path === "/provision" && req.method === "POST") {
4623
4697
  return handleProvisionRoute(req, ctx);
4624
4698
  }
4699
+ if (req.path === "/setup/revalidate" && req.method === "POST") {
4700
+ return handleSetupRevalidateRoute(req, ctx);
4701
+ }
4625
4702
  if (req.path === "/oauth_callback" && req.method === "POST") {
4626
4703
  return handleOAuthCallbackRoute(req, ctx);
4627
4704
  }
@@ -6,7 +6,7 @@
6
6
  import type { ToolRegistry, WebhookRegistry, ToolMetadata, WebhookMetadata } from '../types';
7
7
  import type { ServerHooks } from '../types/handlers';
8
8
  import type { CoreApiConfig } from '../core/types';
9
- import type { EnvSchema, ComputeLayer, ModelDefinition, EntityDefinition, RelationshipDefinition, ChannelDefinition, WorkflowDefinition, PageDefinition, NavigationConfig, AgentDefinition, SignalDefinition } from './types';
9
+ import type { EnvSchema, ComputeLayer, ModelDefinition, EntityDefinition, RelationshipDefinition, ChannelDefinition, WorkflowDefinition, PageDefinition, NavigationConfig, AgentDefinition, SignalDefinition, SetupStepDefinition } from './types';
10
10
  import type { AppEventDefinition } from './types/app-event';
11
11
  import type { QueueRegistry, SerializableQueueConfig } from './queue-config';
12
12
  import type { SequencerRegistry, SerializableSequencerConfig } from './sequencer-config';
@@ -50,6 +50,11 @@ export interface ProvisionConfig {
50
50
  pages?: PageDefinition[];
51
51
  /** App signal definitions (event bus subscriptions created on install) */
52
52
  signals?: SignalDefinition[];
53
+ /**
54
+ * Install setup checklist steps (opt-in).
55
+ * Seeded as AppInstallSetupStep rows; exposed via setup.* Core API.
56
+ */
57
+ setup?: SetupStepDefinition[];
53
58
  }
54
59
  /**
55
60
  * Build configuration - controls how the integration is bundled.
@@ -23,6 +23,7 @@ import type { WorkflowDefinition } from './types/workflow';
23
23
  import type { AgentDefinition } from './types/agent';
24
24
  import type { EnvSchema } from './types/env';
25
25
  import type { NavigationConfig } from './types/navigation';
26
+ import type { SetupStepDefinition } from './types/setup';
26
27
  /**
27
28
  * Define a model with full type safety.
28
29
  *
@@ -150,3 +151,18 @@ export declare function defineEnv(env: EnvSchema): EnvSchema;
150
151
  * })
151
152
  */
152
153
  export declare function defineNavigation(navigation: NavigationConfig): NavigationConfig;
154
+ /**
155
+ * Define an install setup step with full type safety.
156
+ *
157
+ * @example
158
+ * export default defineSetupStep({
159
+ * handle: 'crm_members_bookings_events',
160
+ * label: 'Setup Members, Bookings and Events',
161
+ * kind: 'crm',
162
+ * requires: ['access_granted'],
163
+ * entities: ['member', 'booking', 'event'],
164
+ * listenToCrm: true,
165
+ * capabilities: ['crm.member', 'crm.booking', 'crm.event'],
166
+ * })
167
+ */
168
+ export declare function defineSetupStep(step: SetupStepDefinition): SetupStepDefinition;
@@ -11,7 +11,7 @@
11
11
  export * from './types';
12
12
  export type { InstallConfig, ProvisionConfig, BuildConfig, CorsOptions, SkedyulConfig, SerializableSkedyulConfig, QueueScope, QueueConfig, SerializableQueueConfig, QueueRegistry, SequencerScope, SerializableSequencerConfig, SequencerRegistry, } from './app-config';
13
13
  export { defineConfig } from './app-config';
14
- export { defineModel, defineEntity, defineChannel, definePage, defineWorkflow, defineAgent, defineEnv, defineNavigation, } from './define';
14
+ export { defineModel, defineEntity, defineChannel, definePage, defineWorkflow, defineAgent, defineEnv, defineNavigation, defineSetupStep, } from './define';
15
15
  export { SCHEMA_FILE_EXTENSIONS, loadSchema, saveSchema, serializeSchemaToJson, serializeSchemaToTypeScript, transformToBackendSchema, transformFromBackendSchema, type LoadSchemaOptions, type LoadSchemaResult, type SerializeSchemaOptions, type BackendModelDefinition, type BackendFieldDefinition, type BackendRelationshipDefinition, type BackendDesiredSchema, } from './schema-loader';
16
16
  export { loadAndResolveConfig, serializeResolvedConfig, type ResolvedConfig } from './resolver';
17
17
  export { getAllEnvKeys, getRequiredInstallEnvKeys } from './utils';
@@ -18,7 +18,15 @@ export interface EntityFieldDefinition {
18
18
  description?: string;
19
19
  /** Data type hint for the install mapper UI */
20
20
  type?: 'string' | 'long_string' | 'number' | 'boolean' | 'date' | 'datetime' | 'object';
21
- /** Whether this field is a candidate for upsert match */
21
+ /**
22
+ * Whether this field uniquely identifies a record and can be used as an
23
+ * upsert match key (e.g. external id, email, phone).
24
+ */
25
+ isUnique?: boolean;
26
+ /**
27
+ * @deprecated Prefer `isUnique`. Kept for backward compatibility —
28
+ * treated the same as `isUnique` by the CRM map editor.
29
+ */
22
30
  matchCandidate?: boolean;
23
31
  /** Whether this field should be mapped for a complete configuration */
24
32
  required?: boolean;
@@ -352,15 +352,7 @@ export interface ListBlock {
352
352
  /** Message when no items */
353
353
  emptyMessage?: string;
354
354
  }
355
- /**
356
- * Model mapper block definition - for mapping SHARED models to workspace models.
357
- */
358
- export interface ModelMapperBlock {
359
- type: 'model_mapper';
360
- /** The SHARED model handle from provision config */
361
- model: string;
362
- }
363
355
  /**
364
356
  * Union of all block types.
365
357
  */
366
- export type BlockDefinition = CardBlock | ListBlock | ModelMapperBlock;
358
+ export type BlockDefinition = CardBlock | ListBlock;
@@ -13,6 +13,7 @@ export * from './workflow';
13
13
  export * from './agent';
14
14
  export * from './webhook';
15
15
  export * from './signal';
16
+ export * from './setup';
16
17
  export * from './app-event';
17
18
  export * from './navigation';
18
19
  export * from './context';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * App install setup step definition for provision config.
3
+ *
4
+ * Declared steps are seeded onto each AppInstallation as AppInstallSetupStep
5
+ * rows. Apps and the platform UI read/update status via the setup.* Core API.
6
+ */
7
+ export type SetupStepKind = 'app' | 'crm' | 'realtime' | 'env';
8
+ export interface SetupStepDefinition {
9
+ /** Stable step handle (unique within the app) */
10
+ handle: string;
11
+ /** UI label */
12
+ label: string;
13
+ /** Optional longer description */
14
+ description?: string;
15
+ /** Step kind — drives default CTAs and listeners */
16
+ kind: SetupStepKind;
17
+ /** Prerequisite step handles that must be READY */
18
+ requires?: string[];
19
+ /** CRM entity handles this step covers (kind: crm) */
20
+ entities?: string[];
21
+ /** Bundled workflow handles this step wires (kind: realtime) */
22
+ workflowHandles?: string[];
23
+ /** Env keys this step depends on (kind: env) */
24
+ envKeys?: string[];
25
+ /**
26
+ * When true, platform emits install.setup.crm_changed after CRM migrations
27
+ * and invokes hooks.setup.revalidate so the app can complete/invalidate.
28
+ */
29
+ listenToCrm?: boolean;
30
+ /**
31
+ * When true, platform emits install.setup.env_changed when matching env
32
+ * keys are removed/cleared and invokes hooks.setup.revalidate.
33
+ */
34
+ listenToEnv?: boolean;
35
+ /** Capability keys unlocked when this step is READY */
36
+ capabilities?: string[];
37
+ }
@@ -1241,4 +1241,43 @@ export declare const report: {
1241
1241
  */
1242
1242
  get(handle: string): Promise<ReportDefinition | null>;
1243
1243
  };
1244
+ export type SetupStepStatus = 'PENDING' | 'READY' | 'SKIPPED' | 'INVALIDATED' | 'BLOCKED';
1245
+ export type SetupStepKindApi = 'APP' | 'CRM' | 'REALTIME' | 'ENV';
1246
+ export type SetupStepView = {
1247
+ id: string;
1248
+ handle: string;
1249
+ kind: SetupStepKindApi;
1250
+ status: SetupStepStatus;
1251
+ sortOrder: number;
1252
+ label: string;
1253
+ description: string | null;
1254
+ requires: string[];
1255
+ config: {
1256
+ entities?: string[];
1257
+ workflowHandles?: string[];
1258
+ envKeys?: string[];
1259
+ listenToCrm?: boolean;
1260
+ listenToEnv?: boolean;
1261
+ capabilities?: string[];
1262
+ };
1263
+ completedAt: string | null;
1264
+ skippedAt: string | null;
1265
+ invalidatedAt: string | null;
1266
+ metadata: Record<string, unknown> | null;
1267
+ };
1268
+ export type SetupListResult = {
1269
+ steps: SetupStepView[];
1270
+ capabilities: Record<string, boolean>;
1271
+ };
1272
+ /**
1273
+ * Install setup checklist API (requires sk_wkp_ token).
1274
+ */
1275
+ export declare const setup: {
1276
+ list(): Promise<SetupListResult>;
1277
+ get(handle: string): Promise<SetupStepView | null>;
1278
+ complete(handle: string, metadata?: Record<string, unknown>): Promise<SetupStepView>;
1279
+ skip(handle: string, metadata?: Record<string, unknown>): Promise<SetupStepView>;
1280
+ invalidate(handle: string, reason?: string, metadata?: Record<string, unknown>): Promise<SetupStepView>;
1281
+ capabilities(): Promise<Record<string, boolean>>;
1282
+ };
1244
1283
  export {};
@@ -1200,6 +1200,72 @@ async function handleProvision(body, hooks) {
1200
1200
  }
1201
1201
  }
1202
1202
 
1203
+ // src/server/handlers/setup-revalidate-handler.ts
1204
+ async function handleSetupRevalidate(body, hooks) {
1205
+ const revalidateHook = hooks?.setup?.revalidate;
1206
+ if (!revalidateHook) {
1207
+ return {
1208
+ status: 404,
1209
+ body: { error: "Setup revalidate handler not configured" }
1210
+ };
1211
+ }
1212
+ if (!body.context?.appInstallationId || !body.context?.workplace || !body.context?.app || !body.reason || !Array.isArray(body.steps)) {
1213
+ return {
1214
+ status: 400,
1215
+ body: {
1216
+ error: {
1217
+ code: -32602,
1218
+ message: "Missing context (appInstallationId, workplace, app, reason, and steps required)"
1219
+ }
1220
+ }
1221
+ };
1222
+ }
1223
+ const ctx = {
1224
+ env: body.env ?? {},
1225
+ workplace: body.context.workplace,
1226
+ appInstallationId: body.context.appInstallationId,
1227
+ app: body.context.app,
1228
+ reason: body.reason,
1229
+ steps: body.steps,
1230
+ crm: body.crm,
1231
+ envChange: body.envChange,
1232
+ invocation: body.invocation,
1233
+ log: createContextLogger()
1234
+ };
1235
+ const requestConfig = {
1236
+ baseUrl: body.env?.SKEDYUL_API_URL ?? process.env.SKEDYUL_API_URL ?? "",
1237
+ apiToken: body.env?.SKEDYUL_API_TOKEN ?? process.env.SKEDYUL_API_TOKEN ?? ""
1238
+ };
1239
+ try {
1240
+ const handler = typeof revalidateHook === "function" ? revalidateHook : revalidateHook.handler;
1241
+ const result = await runWithLogContext(
1242
+ { invocation: body.invocation },
1243
+ async () => {
1244
+ return await runWithConfig(requestConfig, async () => {
1245
+ return await handler(ctx);
1246
+ });
1247
+ }
1248
+ );
1249
+ return {
1250
+ status: 200,
1251
+ body: {
1252
+ completed: result?.completed ?? [],
1253
+ invalidated: result?.invalidated ?? []
1254
+ }
1255
+ };
1256
+ } catch (err) {
1257
+ return {
1258
+ status: 500,
1259
+ body: {
1260
+ error: {
1261
+ code: -32603,
1262
+ message: err instanceof Error ? err.message : String(err ?? "")
1263
+ }
1264
+ }
1265
+ };
1266
+ }
1267
+ }
1268
+
1203
1269
  // src/server/handler-helpers.ts
1204
1270
  function parseHandlerEnvelope(parsedBody) {
1205
1271
  if (typeof parsedBody !== "object" || parsedBody === null || Array.isArray(parsedBody) || !("env" in parsedBody) || !("request" in parsedBody)) {
@@ -1591,6 +1657,14 @@ async function handleProvisionRoute(req, ctx) {
1591
1657
  const result = await handleProvision(parseResult.data, ctx.config.hooks);
1592
1658
  return { status: result.status, body: result.body };
1593
1659
  }
1660
+ async function handleSetupRevalidateRoute(req, ctx) {
1661
+ const parseResult = parseJsonBody(req);
1662
+ if (!parseResult.success) {
1663
+ return parseResult.error;
1664
+ }
1665
+ const result = await handleSetupRevalidate(parseResult.data, ctx.config.hooks);
1666
+ return { status: result.status, body: result.body };
1667
+ }
1594
1668
  async function handleOAuthCallbackRoute(req, ctx) {
1595
1669
  const parseResult = parseJsonBody(req);
1596
1670
  if (!parseResult.success) {
@@ -1952,6 +2026,9 @@ async function routeRequest(req, ctx) {
1952
2026
  if (req.path === "/provision" && req.method === "POST") {
1953
2027
  return handleProvisionRoute(req, ctx);
1954
2028
  }
2029
+ if (req.path === "/setup/revalidate" && req.method === "POST") {
2030
+ return handleSetupRevalidateRoute(req, ctx);
2031
+ }
1955
2032
  if (req.path === "/oauth_callback" && req.method === "POST") {
1956
2033
  return handleOAuthCallbackRoute(req, ctx);
1957
2034
  }
@@ -1303,6 +1303,8 @@ var EntityFieldDefinitionSchema = z8.object({
1303
1303
  "datetime",
1304
1304
  "object"
1305
1305
  ]).optional(),
1306
+ isUnique: z8.boolean().optional(),
1307
+ /** @deprecated Prefer isUnique */
1306
1308
  matchCandidate: z8.boolean().optional(),
1307
1309
  required: z8.boolean().optional(),
1308
1310
  options: z8.array(
@@ -1743,16 +1745,10 @@ var ListBlockDefinitionSchema = z8.object({
1743
1745
  icon: z8.string().optional(),
1744
1746
  emptyMessage: z8.string().optional()
1745
1747
  });
1746
- var ModelMapperBlockDefinitionSchema = z8.object({
1747
- type: z8.literal("model_mapper"),
1748
- /** The SHARED model handle from install config (e.g., "client", "patient") */
1749
- model: z8.string()
1750
- });
1751
1748
  var PageBlockDefinitionSchema = z8.union([
1752
1749
  CardBlockDefinitionSchema,
1753
1750
  LegacyFormBlockDefinitionSchema,
1754
- ListBlockDefinitionSchema,
1755
- ModelMapperBlockDefinitionSchema
1751
+ ListBlockDefinitionSchema
1756
1752
  ]);
1757
1753
  var PageContextModeSchema = z8.enum(["first", "many", "count", "all"]).transform((val) => val === "all" ? "many" : val);
1758
1754
  var PageContextFiltersSchema = z8.record(
@@ -1891,6 +1887,20 @@ var InstallConfigSchema = z8.object({
1891
1887
  /** Relationship definitions between SHARED models */
1892
1888
  relationships: z8.array(RelationshipDefinitionSchema).optional()
1893
1889
  });
1890
+ var SetupStepKindSchema = z8.enum(["app", "crm", "realtime", "env"]);
1891
+ var SetupStepDefinitionSchema = z8.object({
1892
+ handle: z8.string(),
1893
+ label: z8.string(),
1894
+ description: z8.string().optional(),
1895
+ kind: SetupStepKindSchema,
1896
+ requires: z8.array(z8.string()).optional(),
1897
+ entities: z8.array(z8.string()).optional(),
1898
+ workflowHandles: z8.array(z8.string()).optional(),
1899
+ envKeys: z8.array(z8.string()).optional(),
1900
+ listenToCrm: z8.boolean().optional(),
1901
+ listenToEnv: z8.boolean().optional(),
1902
+ capabilities: z8.array(z8.string()).optional()
1903
+ });
1894
1904
  var ProvisionConfigSchema = z8.object({
1895
1905
  env: EnvSchemaSchema.optional(),
1896
1906
  /** INTERNAL model definitions (app-owned, not visible to users) */
@@ -1903,7 +1913,9 @@ var ProvisionConfigSchema = z8.object({
1903
1913
  workflows: z8.array(WorkflowDefinitionSchema).optional(),
1904
1914
  /** Base navigation configuration for all pages (can be overridden per page) */
1905
1915
  navigation: NavigationConfigSchema.optional(),
1906
- pages: z8.array(PageDefinitionSchema).optional()
1916
+ pages: z8.array(PageDefinitionSchema).optional(),
1917
+ /** Install setup checklist steps (opt-in) */
1918
+ setup: z8.array(SetupStepDefinitionSchema).optional()
1907
1919
  });
1908
1920
  var SkedyulConfigSchema = z8.object({
1909
1921
  name: z8.string(),
@@ -3552,6 +3564,47 @@ var report = {
3552
3564
  return data;
3553
3565
  }
3554
3566
  };
3567
+ var setup = {
3568
+ async list() {
3569
+ const { data } = await callCore("setup.list", {});
3570
+ return data;
3571
+ },
3572
+ async get(handle) {
3573
+ const { data } = await callCore("setup.get", {
3574
+ handle
3575
+ });
3576
+ return data;
3577
+ },
3578
+ async complete(handle, metadata) {
3579
+ const { data } = await callCore("setup.complete", {
3580
+ handle,
3581
+ ...metadata ? { metadata } : {}
3582
+ });
3583
+ return data;
3584
+ },
3585
+ async skip(handle, metadata) {
3586
+ const { data } = await callCore("setup.skip", {
3587
+ handle,
3588
+ ...metadata ? { metadata } : {}
3589
+ });
3590
+ return data;
3591
+ },
3592
+ async invalidate(handle, reason, metadata) {
3593
+ const { data } = await callCore("setup.invalidate", {
3594
+ handle,
3595
+ ...reason ? { reason } : {},
3596
+ ...metadata ? { metadata } : {}
3597
+ });
3598
+ return data;
3599
+ },
3600
+ async capabilities() {
3601
+ const { data } = await callCore(
3602
+ "setup.capabilities",
3603
+ {}
3604
+ );
3605
+ return data.capabilities;
3606
+ }
3607
+ };
3555
3608
 
3556
3609
  // src/ratelimit/context.ts
3557
3610
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
@@ -4586,6 +4639,72 @@ async function handleProvision(body, hooks) {
4586
4639
  }
4587
4640
  }
4588
4641
 
4642
+ // src/server/handlers/setup-revalidate-handler.ts
4643
+ async function handleSetupRevalidate(body, hooks) {
4644
+ const revalidateHook = hooks?.setup?.revalidate;
4645
+ if (!revalidateHook) {
4646
+ return {
4647
+ status: 404,
4648
+ body: { error: "Setup revalidate handler not configured" }
4649
+ };
4650
+ }
4651
+ if (!body.context?.appInstallationId || !body.context?.workplace || !body.context?.app || !body.reason || !Array.isArray(body.steps)) {
4652
+ return {
4653
+ status: 400,
4654
+ body: {
4655
+ error: {
4656
+ code: -32602,
4657
+ message: "Missing context (appInstallationId, workplace, app, reason, and steps required)"
4658
+ }
4659
+ }
4660
+ };
4661
+ }
4662
+ const ctx = {
4663
+ env: body.env ?? {},
4664
+ workplace: body.context.workplace,
4665
+ appInstallationId: body.context.appInstallationId,
4666
+ app: body.context.app,
4667
+ reason: body.reason,
4668
+ steps: body.steps,
4669
+ crm: body.crm,
4670
+ envChange: body.envChange,
4671
+ invocation: body.invocation,
4672
+ log: createContextLogger()
4673
+ };
4674
+ const requestConfig = {
4675
+ baseUrl: body.env?.SKEDYUL_API_URL ?? process.env.SKEDYUL_API_URL ?? "",
4676
+ apiToken: body.env?.SKEDYUL_API_TOKEN ?? process.env.SKEDYUL_API_TOKEN ?? ""
4677
+ };
4678
+ try {
4679
+ const handler = typeof revalidateHook === "function" ? revalidateHook : revalidateHook.handler;
4680
+ const result = await runWithLogContext(
4681
+ { invocation: body.invocation },
4682
+ async () => {
4683
+ return await runWithConfig(requestConfig, async () => {
4684
+ return await handler(ctx);
4685
+ });
4686
+ }
4687
+ );
4688
+ return {
4689
+ status: 200,
4690
+ body: {
4691
+ completed: result?.completed ?? [],
4692
+ invalidated: result?.invalidated ?? []
4693
+ }
4694
+ };
4695
+ } catch (err) {
4696
+ return {
4697
+ status: 500,
4698
+ body: {
4699
+ error: {
4700
+ code: -32603,
4701
+ message: err instanceof Error ? err.message : String(err ?? "")
4702
+ }
4703
+ }
4704
+ };
4705
+ }
4706
+ }
4707
+
4589
4708
  // src/server/handler-helpers.ts
4590
4709
  function parseHandlerEnvelope(parsedBody) {
4591
4710
  if (typeof parsedBody !== "object" || parsedBody === null || Array.isArray(parsedBody) || !("env" in parsedBody) || !("request" in parsedBody)) {
@@ -4972,6 +5091,14 @@ async function handleProvisionRoute(req, ctx) {
4972
5091
  const result = await handleProvision(parseResult.data, ctx.config.hooks);
4973
5092
  return { status: result.status, body: result.body };
4974
5093
  }
5094
+ async function handleSetupRevalidateRoute(req, ctx) {
5095
+ const parseResult = parseJsonBody(req);
5096
+ if (!parseResult.success) {
5097
+ return parseResult.error;
5098
+ }
5099
+ const result = await handleSetupRevalidate(parseResult.data, ctx.config.hooks);
5100
+ return { status: result.status, body: result.body };
5101
+ }
4975
5102
  async function handleOAuthCallbackRoute(req, ctx) {
4976
5103
  const parseResult = parseJsonBody(req);
4977
5104
  if (!parseResult.success) {
@@ -5333,6 +5460,9 @@ async function routeRequest(req, ctx) {
5333
5460
  if (req.path === "/provision" && req.method === "POST") {
5334
5461
  return handleProvisionRoute(req, ctx);
5335
5462
  }
5463
+ if (req.path === "/setup/revalidate" && req.method === "POST") {
5464
+ return handleSetupRevalidateRoute(req, ctx);
5465
+ }
5336
5466
  if (req.path === "/oauth_callback" && req.method === "POST") {
5337
5467
  return handleOAuthCallbackRoute(req, ctx);
5338
5468
  }
@@ -5808,6 +5938,9 @@ function defineEnv(env) {
5808
5938
  function defineNavigation(navigation) {
5809
5939
  return navigation;
5810
5940
  }
5941
+ function defineSetupStep(step) {
5942
+ return step;
5943
+ }
5811
5944
 
5812
5945
  // src/config/schema-loader.ts
5813
5946
  import * as fs4 from "fs";
@@ -8345,7 +8478,6 @@ export {
8345
8478
  ModelDefinitionSchema,
8346
8479
  ModelDependencySchema,
8347
8480
  ModelFieldDefinitionSchema,
8348
- ModelMapperBlockDefinitionSchema,
8349
8481
  MoneyMinorRangeSchema,
8350
8482
  NavigationBreadcrumbSchema,
8351
8483
  NavigationConfigSchema,
@@ -8396,6 +8528,8 @@ export {
8396
8528
  SequencerContextError,
8397
8529
  SequencerLockError,
8398
8530
  SequencerNotFoundError,
8531
+ SetupStepDefinitionSchema,
8532
+ SetupStepKindSchema,
8399
8533
  SkedyulConfigSchema,
8400
8534
  SkillExampleSchema,
8401
8535
  SkillMetadataSchema,
@@ -8491,6 +8625,7 @@ export {
8491
8625
  defineNavigation,
8492
8626
  definePage,
8493
8627
  defineSchema,
8628
+ defineSetupStep,
8494
8629
  defineSkill,
8495
8630
  defineWorkflow,
8496
8631
  defineWorkflowYAML,
@@ -8552,6 +8687,7 @@ export {
8552
8687
  allow as sequencerAllow,
8553
8688
  release as sequencerRelease,
8554
8689
  server,
8690
+ setup,
8555
8691
  toGsm7,
8556
8692
  token,
8557
8693
  validateCRMSchema,
package/dist/index.d.ts CHANGED
@@ -8,15 +8,15 @@ export { DEFAULT_DOCKERFILE } from './dockerfile';
8
8
  export { InstallError, MissingRequiredFieldError, AuthenticationError, InvalidConfigurationError, ConnectionError, AppAuthInvalidError, } from './errors';
9
9
  export type { InstallErrorCode } from './errors';
10
10
  export { z };
11
- export { workplace, communicationChannel, instance, token, file, webhook, cron, event, resource, ai, call, report, configure, getConfig, runWithConfig, createInstanceClient, } from './core/client';
12
- export type { InstanceClient, InstanceContext, InstanceData, InstanceEnv, InstanceWriteOptions, InstanceGetOptions, InstanceCreateManyItem, InstanceUpdateManyItem, InstanceMeta, InstancePagination, InstanceListResult, InstanceListArgs, FileInfo, FileUrlResponse, FileUploadParams, FileUploadResult, WebhookCreateResult, WebhookListItem, WebhookDeleteByNameOptions, WebhookListOptions, CallStartParams, CallStartResult, CallAppendTranscriptParams, CallEndParams, CallSummarizeResult, CronSubscribeParams, CronSubscribeResult, CronSubscriptionItem, CronListOptions, EventCreateResult, EventCreateOptions, ResourceLinkParams, ResourceLinkResult, AITextContent, AIFileContent, AIImageContent, AIMessageContent, AIMessage, GenerateObjectOptions, GenerateObjectResult, ReportGenerateParams, ReportGenerateResult, ReportDefineParams, ReportDefineResult, ReportListParams, ReportListItem, ReportListResult, ReportDefinition, } from './core/client';
11
+ export { workplace, communicationChannel, instance, token, file, webhook, cron, event, resource, ai, call, report, setup, configure, getConfig, runWithConfig, createInstanceClient, } from './core/client';
12
+ export type { InstanceClient, InstanceContext, InstanceData, InstanceEnv, InstanceWriteOptions, InstanceGetOptions, InstanceCreateManyItem, InstanceUpdateManyItem, InstanceMeta, InstancePagination, InstanceListResult, InstanceListArgs, FileInfo, FileUrlResponse, FileUploadParams, FileUploadResult, WebhookCreateResult, WebhookListItem, WebhookDeleteByNameOptions, WebhookListOptions, CallStartParams, CallStartResult, CallAppendTranscriptParams, CallEndParams, CallSummarizeResult, CronSubscribeParams, CronSubscribeResult, CronSubscriptionItem, CronListOptions, EventCreateResult, EventCreateOptions, ResourceLinkParams, ResourceLinkResult, AITextContent, AIFileContent, AIImageContent, AIMessageContent, AIMessage, GenerateObjectOptions, GenerateObjectResult, ReportGenerateParams, ReportGenerateResult, ReportDefineParams, ReportDefineResult, ReportListParams, ReportListItem, ReportListResult, ReportDefinition, SetupStepStatus, SetupStepKindApi, SetupStepView, SetupListResult, } from './core/client';
13
13
  export { createContextLogger } from './server/logger';
14
14
  export type { ContextLogger } from './server/logger';
15
15
  declare const _default: {
16
16
  z: typeof z;
17
17
  };
18
18
  export default _default;
19
- export { defineConfig, defineModel, defineEntity, defineChannel, definePage, defineWorkflow, defineAgent, defineEnv, defineNavigation, getAllEnvKeys, getRequiredInstallEnvKeys, } from './config';
19
+ export { defineConfig, defineModel, defineEntity, defineChannel, definePage, defineWorkflow, defineAgent, defineEnv, defineNavigation, defineSetupStep, getAllEnvKeys, getRequiredInstallEnvKeys, } from './config';
20
20
  export { queuedFetch, requeue, resolveQueue, createQueueHandle, queuedFetchResponse, registerQueueConfig, runWithRateLimitExecutionContext, getRateLimitExecutionContext, defaultShouldRetry, QueueContextError, QueueNotFoundError, QueuedFetchExhaustedError, RequeueOutsideContextError, RateLimitBackendError, RateLimitExceededError, } from './ratelimit';
21
21
  export type { QueueInput, QueueSelector, Lease, QueueLimits, ResolvedQueue, RateLimitExecutionContext, RateLimitBackend, QueueScope, QueueConfig, SerializableQueueConfig, QueueRegistry, } from './ratelimit';
22
22
  export { sequencer, allow as sequencerAllow, acquire as sequencerAcquire, release as sequencerRelease, resolveSequencer, createSequencerHandle, registerSequencerConfig, clearRegisteredSequencerConfig, getSequencerConfig, getSequencerDefinitions, resetSequencerBackendForTests, memorySequencerBackend, platformSequencerBackend, SequencerContextError, SequencerNotFoundError, SequencerBackendError, SequencerLockError, } from './sequencer';
@@ -35,7 +35,7 @@ export type { CRMContext, SenderContext, ThreadContextItem, ThreadInfo, SandboxC
35
35
  export { MemoryEntryTypeSchema, MemoryEntrySchema, WorkingMemoryConfigSchema, SemanticMemoryConfigSchema, ExternalMemoryConfigSchema, MemoryConfigSchema, MemoryScopeSchema, MemoryQueryOptionsSchema, ConversationSummarySchema, AgentObservationSchema, ExternalDataCacheSchema, MemoryService, InMemoryStore, createInMemoryService, } from './memory';
36
36
  export type { MemoryEntryType, MemoryEntry, WorkingMemoryConfig as MemoryWorkingConfig, SemanticMemoryConfig as MemorySemanticConfig, ExternalMemoryConfig as MemoryExternalConfig, MemoryConfig, MemoryScope, MemoryQueryOptions, ConversationSummary, AgentObservation, ExternalDataCache, MemoryStore, } from './memory';
37
37
  export type { CRMFieldType, CRMFieldRequirement, CRMFieldOption, CRMFieldDefinition, CRMFieldSchema, CRMModelSchema, CRMCardinality, CRMOnDelete, CRMRelationshipLink, CRMRelationshipSchema, CRMSchema, CRMSchemaValidationResult, } from './schemas';
38
- export type { SkedyulConfig, SerializableSkedyulConfig, InstallConfig, ProvisionConfig, BaseDefinition, Scope, FieldOwner, Visibility, ComputeLayer, StructuredFilter, FilterOperator, FilterCondition, FieldOption, EnvVariable, EnvSchema, FieldType, Cardinality, OnDelete, InlineFieldDefinition, FieldVisibility, FieldDefinition, ModelDefinition, RelationshipLink, RelationshipDefinition, CapabilityType, ChannelCapability, ChannelBatchCapability, ChannelFieldPermissions, ChannelField, ChannelDefinition, WorkflowActionInput, WorkflowAction, WorkflowDefinition, AgentDefinition, NavigationItem, NavigationSection, NavigationSidebar, BreadcrumbItem, NavigationBreadcrumb, NavigationConfig, ContextMode, ContextItemModel, ContextItemTool, ContextItem, ContextDefinition, FormStyleProps, ButtonVariant, ButtonSize, ButtonProps, RelationshipExtension, FormHeader, FormActionDefinition, ActionDefinition, ModalFormDefinition, InputComponent, TextareaComponent, SelectComponent, ComboboxComponent, CheckboxComponent, DatePickerComponent, TimePickerComponent, StatusIndicator, FieldSettingComponent, ImageSettingComponent, FileSettingComponent, ListItemTemplate, ListComponent, EmptyFormComponent, AlertComponent, FormComponent, FormLayoutColumn, FormLayoutRow, FormLayoutConfig, FormProps, CardHeader, CardBlock, ListBlock, ModelMapperBlock, BlockDefinition, PageType, PageDefinition, HttpMethod, WebhookRequest, WebhookHandlerContext, WebhookHandlerResponse, WebhookHandlerFn, WebhookHandlerDefinition, Webhooks, WebhookHandlerMetadata, ModelDependency, ChannelDependency, WorkflowDependency, ResourceDependency, } from './config';
38
+ export type { SkedyulConfig, SerializableSkedyulConfig, InstallConfig, ProvisionConfig, BaseDefinition, Scope, FieldOwner, Visibility, ComputeLayer, StructuredFilter, FilterOperator, FilterCondition, FieldOption, EnvVariable, EnvSchema, FieldType, Cardinality, OnDelete, InlineFieldDefinition, FieldVisibility, FieldDefinition, ModelDefinition, RelationshipLink, RelationshipDefinition, CapabilityType, ChannelCapability, ChannelBatchCapability, ChannelFieldPermissions, ChannelField, ChannelDefinition, WorkflowActionInput, WorkflowAction, WorkflowDefinition, AgentDefinition, NavigationItem, NavigationSection, NavigationSidebar, BreadcrumbItem, NavigationBreadcrumb, NavigationConfig, ContextMode, ContextItemModel, ContextItemTool, ContextItem, ContextDefinition, FormStyleProps, ButtonVariant, ButtonSize, ButtonProps, RelationshipExtension, FormHeader, FormActionDefinition, ActionDefinition, ModalFormDefinition, InputComponent, TextareaComponent, SelectComponent, ComboboxComponent, CheckboxComponent, DatePickerComponent, TimePickerComponent, StatusIndicator, FieldSettingComponent, ImageSettingComponent, FileSettingComponent, ListItemTemplate, ListComponent, EmptyFormComponent, AlertComponent, FormComponent, FormLayoutColumn, FormLayoutRow, FormLayoutConfig, FormProps, CardHeader, CardBlock, ListBlock, BlockDefinition, SetupStepDefinition, SetupStepKind, PageType, PageDefinition, HttpMethod, WebhookRequest, WebhookHandlerContext, WebhookHandlerResponse, WebhookHandlerFn, WebhookHandlerDefinition, Webhooks, WebhookHandlerMetadata, ModelDependency, ChannelDependency, WorkflowDependency, ResourceDependency, } from './config';
39
39
  export { compileAgent, compileWorkflow } from './compiler';
40
40
  export type { ValidationError, ValidationWarning, ResolvedPersona, ResolvedTool, EventConfig as CompilerEventConfig, IRMemoryConfig, PolicyConfig, IRRuntimeConfig, AgentIR, WorkflowStepIR, WorkflowIR, CompilationResult, } from './compiler';
41
41
  export { TimeStampSchema, DayOfWeekSchema, TimeWindowSlotSchema, WaitUnitSchema, WaitInputRelativeSchema, WaitInputAbsoluteSchema, WaitInputSchema, } from './scheduling/types';