apps 0.0.1-beta.89 → 0.0.1-beta.90
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/README.md +27 -10
- package/framework-reference.json +1 -1
- package/js/{chunk-H6NFR354.js → chunk-36UFTECB.js} +6 -8
- package/js/{chunk-I46RIOKQ.js → chunk-5MDA7MKL.js} +14 -13
- package/js/{chunk-NQW2E44U.js → chunk-6XQLA5NC.js} +579 -81
- package/js/{chunk-6FUJH3T4.js → chunk-7PHHWYV4.js} +6 -5
- package/js/{chunk-7Z3NUCTP.js → chunk-DADXWWRZ.js} +24 -6
- package/js/{chunk-BZFFXNWA.js → chunk-I5C7FD5Z.js} +1 -1
- package/js/{chunk-EKZLPXHK.js → chunk-KUCCHNVY.js} +3 -3
- package/js/{chunk-ZK7JDZJS.js → chunk-PYQLOLOC.js} +2 -2
- package/js/{chunk-ELSILABS.js → chunk-WMD4NHXZ.js} +113 -73
- package/js/{chunk-JJH3MBAM.js → chunk-YNJ5CZMJ.js} +3 -2
- package/js/{chunk-5ZVAYXLT.js → chunk-YRGL4QEF.js} +1 -1
- package/js/{chunk-GLXEYET6.js → chunk-YWFUWTUJ.js} +12 -7
- package/js/client.js +1 -1
- package/js/contracts.js +37 -25
- package/js/effect.js +8 -9
- package/js/graphql.js +10 -11
- package/js/host.js +11 -13
- package/js/index.js +29 -31
- package/js/mcp/effect.js +9 -10
- package/js/mcp.js +11 -12
- package/js/openapi.js +9 -11
- package/js/skills.js +6 -6
- package/js/ui/contracts.js +1 -1
- package/js/ui/serving.js +5 -6
- package/package.json +1 -1
- package/runtime.json +1 -1
- package/types/apps/src/contracts/app.d.ts +51 -8
- package/types/apps/src/contracts/cache.d.ts +1 -1
- package/types/apps/src/contracts/context.d.ts +37 -8
- package/types/apps/src/contracts/events.d.ts +2 -1
- package/types/apps/src/contracts/host.d.ts +800 -4
- package/types/apps/src/contracts/operations.d.ts +6 -3
- package/types/apps/src/contracts/protocol-version.d.ts +1 -1
- package/types/apps/src/contracts/protocols/11.d.ts +1149 -0
- package/types/apps/src/contracts/protocols/12.d.ts +3310 -0
- package/types/apps/src/contracts/protocols/current.d.ts +4445 -1633
- package/types/apps/src/contracts/schedules.d.ts +7 -1
- package/types/apps/src/contracts/ui.d.ts +11 -15
- package/types/apps/src/contracts/webhooks.d.ts +24 -7
- package/types/apps/src/contracts/workflows.d.ts +13 -17
- package/types/apps/src/implementation/app.d.ts +41 -14
- package/types/apps/src/implementation/cache.d.ts +1 -1
- package/types/apps/src/implementation/events.d.ts +6 -1
- package/types/apps/src/implementation/failure-detail.d.ts +3 -2
- package/types/apps/src/implementation/operations.d.ts +40 -5
- package/types/apps/src/implementation/router-catalog.d.ts +4 -0
- package/types/apps/src/implementation/schedules.d.ts +39 -8
- package/types/apps/src/implementation/ui-serving.d.ts +2 -2
- package/types/apps/src/implementation/webhooks.d.ts +15 -6
- package/types/apps/src/implementation/workflow-context.d.ts +6 -2
- package/types/apps/src/implementation/workflows.d.ts +10 -3
- package/types/apps/src/index.d.ts +15 -9
- package/js/chunk-F2G534HD.js +0 -285
|
@@ -33,9 +33,15 @@ export declare const ScheduleTiming: Schema.Union<readonly [Schema.Struct<{
|
|
|
33
33
|
}>;
|
|
34
34
|
}>]>;
|
|
35
35
|
export type ScheduleTiming = typeof ScheduleTiming.Type;
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* A named trigger attached to the mutation it invokes, including schema-validated arguments.
|
|
38
|
+
* `scope: "app"` marks an app schedule: one schedule, run without a caller with the app's accounts.
|
|
39
|
+
* Without it, each member who enables the schedule has a copy that runs as them; bundles of
|
|
40
|
+
* protocol 12 and earlier declare only those.
|
|
41
|
+
*/
|
|
37
42
|
export declare const OperationSchedule: Schema.Struct<{
|
|
38
43
|
readonly name: Schema.NonEmptyString;
|
|
44
|
+
readonly scope: Schema.optionalKey<Schema.Literal<"app">>;
|
|
39
45
|
readonly timing: Schema.Union<readonly [Schema.Struct<{
|
|
40
46
|
readonly kind: Schema.Literal<"interval">;
|
|
41
47
|
readonly milliseconds: Schema.Int;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/** Browser-to-host operations bind identity and authentication outside authored app code. */
|
|
2
2
|
import { Schema, type Effect, type Stream } from "effect";
|
|
3
3
|
import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "effect/http-api";
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Non-secret page context injected by the serving host. `accounts` names the account IDs the page
|
|
6
|
+
* runs with, by requirement, when the app has requirements.
|
|
7
|
+
*/
|
|
5
8
|
export declare const UiContext: Schema.Struct<{
|
|
6
9
|
readonly deployment: Schema.NonEmptyString;
|
|
7
|
-
readonly
|
|
8
|
-
readonly expectedProfileRevision: Schema.optional<Schema.Int>;
|
|
10
|
+
readonly accounts: Schema.optional<Schema.$Record<Schema.NonEmptyString, Schema.$Array<Schema.NonEmptyString>>>;
|
|
9
11
|
}>;
|
|
10
|
-
/** A problem with one of the page
|
|
12
|
+
/** A problem with one of the page's accounts, from stored state. Labels are the owner's own names. */
|
|
11
13
|
export type UiAccountProblem = {
|
|
12
14
|
readonly provider: string;
|
|
13
15
|
readonly reason: "missing" | "removed" | "incompatible";
|
|
@@ -20,10 +22,8 @@ export type UiAccountProblem = {
|
|
|
20
22
|
export interface UiAccountNotice {
|
|
21
23
|
readonly app: string;
|
|
22
24
|
readonly problems: readonly UiAccountProblem[];
|
|
23
|
-
/** The
|
|
25
|
+
/** The app's accounts in the dashboard. */
|
|
24
26
|
readonly fix: string;
|
|
25
|
-
/** The dashboard chooser, returning to this page. */
|
|
26
|
-
readonly choose: string;
|
|
27
27
|
}
|
|
28
28
|
/** Retained browser bytes. Hosts authorize access before reading or rendering them. */
|
|
29
29
|
export interface AppUiFile {
|
|
@@ -51,8 +51,7 @@ export declare const UiOperation: Schema.Struct<{
|
|
|
51
51
|
readonly name: Schema.NonEmptyString;
|
|
52
52
|
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
53
53
|
readonly deployment: Schema.NonEmptyString;
|
|
54
|
-
readonly
|
|
55
|
-
readonly expectedProfileRevision: Schema.optional<Schema.Int>;
|
|
54
|
+
readonly accounts: Schema.optional<Schema.$Record<Schema.NonEmptyString, Schema.$Array<Schema.NonEmptyString>>>;
|
|
56
55
|
}>;
|
|
57
56
|
declare const UiUnauthorized_base: Schema.Class<UiUnauthorized, Schema.TaggedStruct<"UiUnauthorized", {}>, import("effect/Cause").YieldableError>;
|
|
58
57
|
/** The app session is absent or its parent login was revoked. */
|
|
@@ -88,20 +87,17 @@ export declare const AppUiApi: HttpApi.HttpApi<"app-ui", HttpApiGroup.HttpApiGro
|
|
|
88
87
|
readonly name: Schema.NonEmptyString;
|
|
89
88
|
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
90
89
|
readonly deployment: Schema.NonEmptyString;
|
|
91
|
-
readonly
|
|
92
|
-
readonly expectedProfileRevision: Schema.optional<Schema.Int>;
|
|
90
|
+
readonly accounts: Schema.optional<Schema.$Record<Schema.NonEmptyString, Schema.$Array<Schema.NonEmptyString>>>;
|
|
93
91
|
}>>, never, Schema.toCodecJson<Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.toCodecJson<typeof UiUnauthorized | typeof UiForbidden | typeof UiDeploymentChanged | typeof UiFailed>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"mutate", "POST", "/_executor/api/mutate", never, never, Schema.toCodecJson<Schema.Struct<{
|
|
94
92
|
readonly name: Schema.NonEmptyString;
|
|
95
93
|
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
96
94
|
readonly deployment: Schema.NonEmptyString;
|
|
97
|
-
readonly
|
|
98
|
-
readonly expectedProfileRevision: Schema.optional<Schema.Int>;
|
|
95
|
+
readonly accounts: Schema.optional<Schema.$Record<Schema.NonEmptyString, Schema.$Array<Schema.NonEmptyString>>>;
|
|
99
96
|
}>>, never, Schema.toCodecJson<Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.toCodecJson<typeof UiUnauthorized | typeof UiForbidden | typeof UiDeploymentChanged | typeof UiFailed>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"subscribe", "POST", "/_executor/api/subscribe", never, never, Schema.toCodecJson<Schema.Struct<{
|
|
100
97
|
readonly name: Schema.NonEmptyString;
|
|
101
98
|
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
102
99
|
readonly deployment: Schema.NonEmptyString;
|
|
103
|
-
readonly
|
|
104
|
-
readonly expectedProfileRevision: Schema.optional<Schema.Int>;
|
|
100
|
+
readonly accounts: Schema.optional<Schema.$Record<Schema.NonEmptyString, Schema.$Array<Schema.NonEmptyString>>>;
|
|
105
101
|
}>>, never, HttpApiSchema.StreamSse<HttpApiSchema.SseEventFromData<Schema.Union<readonly [Schema.Struct<{
|
|
106
102
|
readonly type: Schema.Literal<"snapshot">;
|
|
107
103
|
readonly value: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
/** Account-bound webhook lifecycle. Register and unregister must be idempotent for subscriptionId. */
|
|
2
2
|
import type { Effect, Schema } from "effect";
|
|
3
3
|
import type { ManualWebhookSetup } from "./webhook-protocol.js";
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import type { AccountScope, BoundContext, ScopedSlots } from "./app.js";
|
|
5
|
+
/** What every webhook context provides; a context with `user` serves user-account webhooks. */
|
|
6
|
+
type HookContext = Pick<BoundContext<ScopedSlots, AccountScope>, "app" | "fetch" | "signal">;
|
|
7
|
+
/**
|
|
8
|
+
* The accounts of the webhook's scope. A context with `user` names a user requirement; one of the
|
|
9
|
+
* `"app"` scope, which has no `user`, an app requirement.
|
|
10
|
+
*/
|
|
11
|
+
type ScopeAccounts<Context extends HookContext> = Context extends {
|
|
12
|
+
readonly user: {
|
|
13
|
+
readonly accounts: infer Accounts;
|
|
14
|
+
};
|
|
15
|
+
} ? Accounts : Context["app"]["accounts"];
|
|
16
|
+
type SourceAccount<Context extends HookContext> = Context extends {
|
|
17
|
+
readonly user: unknown;
|
|
18
|
+
} ? {
|
|
19
|
+
readonly user: keyof ScopeAccounts<Context> & string;
|
|
20
|
+
} : {
|
|
21
|
+
readonly app: keyof ScopeAccounts<Context> & string;
|
|
22
|
+
};
|
|
23
|
+
type SelectedAccount<Context extends HookContext> = {
|
|
24
|
+
[Slot in keyof ScopeAccounts<Context>]: ScopeAccounts<Context>[Slot] extends readonly (infer Account)[] ? Account : ScopeAccounts<Context>[Slot];
|
|
25
|
+
}[keyof ScopeAccounts<Context>];
|
|
9
26
|
/**
|
|
10
27
|
* Registration, delivery and cleanup share the selected accounts.
|
|
11
28
|
* The host stores account IDs and parsed state, never credentials.
|
|
12
29
|
* Register runs when enabling a subscription, not on every app evaluation.
|
|
13
30
|
*/
|
|
14
|
-
interface WebhookLifecycle<Context extends
|
|
31
|
+
interface WebhookLifecycle<Context extends HookContext, Config extends Schema.Decoder<unknown>, State extends Schema.Decoder<unknown>, Error = unknown> {
|
|
15
32
|
readonly account: SourceAccount<Context>;
|
|
16
33
|
readonly config: Config;
|
|
17
34
|
readonly state: State;
|
|
@@ -43,7 +60,7 @@ interface WebhookLifecycle<Context extends Pick<BoundContext<AccountSlots>, "acc
|
|
|
43
60
|
}) => Effect.Effect<void, Error>;
|
|
44
61
|
}
|
|
45
62
|
/** Manual subscriptions collect the state schema in a private browser form instead of invoking provider APIs. */
|
|
46
|
-
export type Webhook<Context extends
|
|
63
|
+
export type Webhook<Context extends HookContext, Config extends Schema.Decoder<unknown>, State extends Schema.Decoder<unknown>, Error = unknown> = (WebhookLifecycle<Context, Config, State, Error> & {
|
|
47
64
|
readonly setup?: never;
|
|
48
65
|
}) | (Omit<WebhookLifecycle<Context, Config, State, Error>, "register" | "unregister"> & {
|
|
49
66
|
readonly setup: typeof ManualWebhookSetup.Type;
|
|
@@ -3,6 +3,7 @@ import { Schema, type Effect } from "effect";
|
|
|
3
3
|
import { RecordedMessage } from "../../../utils/src/recorded-message.js";
|
|
4
4
|
import { JsonValue } from "./schema.js";
|
|
5
5
|
import type { AppContext, AppRequirements, QueryContext, MutationContext } from "./context.js";
|
|
6
|
+
import type { AccountScope } from "./app.js";
|
|
6
7
|
import type { Operation } from "../implementation/operations.js";
|
|
7
8
|
import type { HostContext } from "./host.js";
|
|
8
9
|
/** Run identity is opaque and shared by author and SDK interfaces. */
|
|
@@ -73,7 +74,6 @@ export type HostedWorkflow = typeof HostedWorkflow.Type;
|
|
|
73
74
|
/** Results are available only on completed runs; failures carry a reason code and app error detail. */
|
|
74
75
|
export declare const WorkflowRun: Schema.Union<readonly [Schema.Struct<{
|
|
75
76
|
readonly status: Schema.Literals<readonly ["queued", "running", "waiting", "paused", "waitingForPause"]>;
|
|
76
|
-
readonly profile: Schema.optionalKey<Schema.NonEmptyString>;
|
|
77
77
|
readonly id: Schema.brand<Schema.NonEmptyString, "wfr">;
|
|
78
78
|
readonly app: Schema.NonEmptyString;
|
|
79
79
|
readonly deployment: Schema.NonEmptyString;
|
|
@@ -82,7 +82,6 @@ export declare const WorkflowRun: Schema.Union<readonly [Schema.Struct<{
|
|
|
82
82
|
}>, Schema.Struct<{
|
|
83
83
|
readonly status: Schema.Literal<"complete">;
|
|
84
84
|
readonly output: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
85
|
-
readonly profile: Schema.optionalKey<Schema.NonEmptyString>;
|
|
86
85
|
readonly id: Schema.brand<Schema.NonEmptyString, "wfr">;
|
|
87
86
|
readonly app: Schema.NonEmptyString;
|
|
88
87
|
readonly deployment: Schema.NonEmptyString;
|
|
@@ -97,7 +96,6 @@ export declare const WorkflowRun: Schema.Union<readonly [Schema.Struct<{
|
|
|
97
96
|
errorName: Schema.optionalKey<Schema.String>;
|
|
98
97
|
message: Schema.optionalKey<Schema.String>;
|
|
99
98
|
}>>;
|
|
100
|
-
readonly profile: Schema.optionalKey<Schema.NonEmptyString>;
|
|
101
99
|
readonly id: Schema.brand<Schema.NonEmptyString, "wfr">;
|
|
102
100
|
readonly app: Schema.NonEmptyString;
|
|
103
101
|
readonly deployment: Schema.NonEmptyString;
|
|
@@ -105,7 +103,6 @@ export declare const WorkflowRun: Schema.Union<readonly [Schema.Struct<{
|
|
|
105
103
|
readonly createdAt: Schema.String;
|
|
106
104
|
}>, Schema.Struct<{
|
|
107
105
|
readonly status: Schema.Literal<"terminated">;
|
|
108
|
-
readonly profile: Schema.optionalKey<Schema.NonEmptyString>;
|
|
109
106
|
readonly id: Schema.brand<Schema.NonEmptyString, "wfr">;
|
|
110
107
|
readonly app: Schema.NonEmptyString;
|
|
111
108
|
readonly deployment: Schema.NonEmptyString;
|
|
@@ -117,7 +114,6 @@ export type WorkflowRun = typeof WorkflowRun.Type;
|
|
|
117
114
|
export declare const WorkflowRunPage: Schema.Struct<{
|
|
118
115
|
readonly items: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
|
|
119
116
|
readonly status: Schema.Literals<readonly ["queued", "running", "waiting", "paused", "waitingForPause"]>;
|
|
120
|
-
readonly profile: Schema.optionalKey<Schema.NonEmptyString>;
|
|
121
117
|
readonly id: Schema.brand<Schema.NonEmptyString, "wfr">;
|
|
122
118
|
readonly app: Schema.NonEmptyString;
|
|
123
119
|
readonly deployment: Schema.NonEmptyString;
|
|
@@ -126,7 +122,6 @@ export declare const WorkflowRunPage: Schema.Struct<{
|
|
|
126
122
|
}>, Schema.Struct<{
|
|
127
123
|
readonly status: Schema.Literal<"complete">;
|
|
128
124
|
readonly output: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
129
|
-
readonly profile: Schema.optionalKey<Schema.NonEmptyString>;
|
|
130
125
|
readonly id: Schema.brand<Schema.NonEmptyString, "wfr">;
|
|
131
126
|
readonly app: Schema.NonEmptyString;
|
|
132
127
|
readonly deployment: Schema.NonEmptyString;
|
|
@@ -141,7 +136,6 @@ export declare const WorkflowRunPage: Schema.Struct<{
|
|
|
141
136
|
errorName: Schema.optionalKey<Schema.String>;
|
|
142
137
|
message: Schema.optionalKey<Schema.String>;
|
|
143
138
|
}>>;
|
|
144
|
-
readonly profile: Schema.optionalKey<Schema.NonEmptyString>;
|
|
145
139
|
readonly id: Schema.brand<Schema.NonEmptyString, "wfr">;
|
|
146
140
|
readonly app: Schema.NonEmptyString;
|
|
147
141
|
readonly deployment: Schema.NonEmptyString;
|
|
@@ -149,7 +143,6 @@ export declare const WorkflowRunPage: Schema.Struct<{
|
|
|
149
143
|
readonly createdAt: Schema.String;
|
|
150
144
|
}>, Schema.Struct<{
|
|
151
145
|
readonly status: Schema.Literal<"terminated">;
|
|
152
|
-
readonly profile: Schema.optionalKey<Schema.NonEmptyString>;
|
|
153
146
|
readonly id: Schema.brand<Schema.NonEmptyString, "wfr">;
|
|
154
147
|
readonly app: Schema.NonEmptyString;
|
|
155
148
|
readonly deployment: Schema.NonEmptyString;
|
|
@@ -181,25 +174,28 @@ export interface WorkflowControls extends WorkflowReads {
|
|
|
181
174
|
readonly run: string;
|
|
182
175
|
}) => Promise<WorkflowRun>;
|
|
183
176
|
}
|
|
184
|
-
/**
|
|
185
|
-
|
|
177
|
+
/**
|
|
178
|
+
* External steps get fresh credentials and cancellation, without storage or live elicitation. A run
|
|
179
|
+
* started by app-scope work, such as an app schedule, has the `"app"` scope: no `user`.
|
|
180
|
+
*/
|
|
181
|
+
export type WorkflowStepContext<Requirements extends AppRequirements = AppRequirements, Scope extends AccountScope = "user"> = Omit<AppContext<Requirements, Scope>, "elicit" | "workflows"> & {
|
|
186
182
|
readonly runId: WorkflowRunId;
|
|
187
183
|
readonly stepId: string;
|
|
188
184
|
readonly idempotencyKey: string;
|
|
189
185
|
};
|
|
190
186
|
/** Explicit durable boundaries; database access passes through registered app operations. */
|
|
191
|
-
export interface WorkflowStep<Requirements extends AppRequirements = AppRequirements> {
|
|
192
|
-
do<Output>(name: string, run: (context: WorkflowStepContext<Requirements>) => Promise<Output>): Promise<Output>;
|
|
193
|
-
do<Output>(name: string, options: WorkflowStepOptions, run: (context: WorkflowStepContext<Requirements>) => Promise<Output>): Promise<Output>;
|
|
194
|
-
runQuery<Input, Output>(name: string, operation: Operation<Input, Output, "query", QueryContext<Requirements>>, input: NoInfer<Input>, options?: WorkflowStepOptions): Promise<Output>;
|
|
195
|
-
runMutation<Input, Output>(name: string, operation: Operation<Input, Output, "mutation", MutationContext<Requirements>>, input: NoInfer<Input>, options?: WorkflowStepOptions): Promise<Output>;
|
|
187
|
+
export interface WorkflowStep<Requirements extends AppRequirements = AppRequirements, Scope extends AccountScope = "user"> {
|
|
188
|
+
do<Output>(name: string, run: (context: WorkflowStepContext<Requirements, Scope>) => Promise<Output>): Promise<Output>;
|
|
189
|
+
do<Output>(name: string, options: WorkflowStepOptions, run: (context: WorkflowStepContext<Requirements, Scope>) => Promise<Output>): Promise<Output>;
|
|
190
|
+
runQuery<Input, Output>(name: string, operation: Operation<Input, Output, "query", QueryContext<Requirements, Scope>>, input: NoInfer<Input>, options?: WorkflowStepOptions): Promise<Output>;
|
|
191
|
+
runMutation<Input, Output>(name: string, operation: Operation<Input, Output, "mutation", MutationContext<Requirements, Scope>>, input: NoInfer<Input>, options?: WorkflowStepOptions): Promise<Output>;
|
|
196
192
|
readonly sleep: (name: string, duration: WorkflowDuration) => Promise<void>;
|
|
197
193
|
readonly sleepUntil: (name: string, timestamp: number | Date) => Promise<void>;
|
|
198
194
|
}
|
|
199
195
|
/** The orchestration body gets no account, database or interactive capabilities. */
|
|
200
|
-
export interface WorkflowContext<Requirements extends AppRequirements = AppRequirements> {
|
|
196
|
+
export interface WorkflowContext<Requirements extends AppRequirements = AppRequirements, Scope extends AccountScope = "user"> {
|
|
201
197
|
readonly runId: WorkflowRunId;
|
|
202
|
-
readonly step: WorkflowStep<Requirements>;
|
|
198
|
+
readonly step: WorkflowStep<Requirements, Scope>;
|
|
203
199
|
}
|
|
204
200
|
/** Framework-owned native declaration; only the callback crosses the author Promise boundary. */
|
|
205
201
|
export interface AppWorkflow<Input = unknown, Output = unknown> {
|
|
@@ -1,41 +1,68 @@
|
|
|
1
1
|
import type { ScheduleDeclaration } from "./schedules.js";
|
|
2
|
-
import type { App as NativeApp, AppDefinition as NativeDefinition } from "../contracts/app.js";
|
|
3
|
-
import type { AppRequirements,
|
|
2
|
+
import type { App as NativeApp, AccountScope, AppDefinition as NativeDefinition, EvaluationContext } from "../contracts/app.js";
|
|
3
|
+
import type { AppRequirements, QueryContext, MutationContext, RequirementSlots, WebhookContext } from "../contracts/context.js";
|
|
4
4
|
import { type PromiseMethods } from "./authoring.js";
|
|
5
5
|
import { type WorkflowDeclaration } from "./workflows.js";
|
|
6
6
|
import type { WorkflowContext } from "../contracts/workflows.js";
|
|
7
7
|
import { type RouterDeclaration } from "./router.js";
|
|
8
8
|
import { type Schema } from "./schema.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
/** One native webhook definition with the given handler context. */
|
|
10
|
+
type NativeWebhook<Context> = NonNullable<NativeDefinition<Context>["webhooks"]>[string];
|
|
11
|
+
/** A webhook as authors write it: Promise handlers, author schemas and its source requirement. */
|
|
12
|
+
type AuthorWebhook<Context, Account> = {
|
|
13
|
+
readonly [Key in keyof NativeWebhook<Context>]: Key extends "config" | "state" ? Schema<unknown, boolean> : Key extends "account" ? Account : PromiseMethods<NativeWebhook<Context>>[Key];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* A user-account webhook gets the caller-shaped context; an app-account webhook runs without a
|
|
17
|
+
* caller, so its context has no `user`.
|
|
18
|
+
*/
|
|
19
|
+
type AuthorWebhooks<Requirements extends AppRequirements> = Readonly<Record<string, AuthorWebhook<WebhookContext<Requirements>, {
|
|
20
|
+
readonly user: keyof RequirementSlots<Requirements>["user"] & string;
|
|
21
|
+
}> | AuthorWebhook<WebhookContext<Requirements, "app">, {
|
|
22
|
+
readonly app: keyof RequirementSlots<Requirements>["app"] & string;
|
|
23
|
+
}>>>;
|
|
24
|
+
/**
|
|
25
|
+
* User schedules run as each member who enables them; app schedules run without a caller, so their
|
|
26
|
+
* mutation takes a context of the `"app"` scope.
|
|
27
|
+
*/
|
|
28
|
+
type AuthorSchedules<Requirements extends AppRequirements> = Readonly<Record<string, ScheduleDeclaration<MutationContext<Requirements>, "user"> | ScheduleDeclaration<MutationContext<Requirements, "app">, "app">>>;
|
|
29
|
+
/**
|
|
30
|
+
* A run started by a caller binds its accounts; one started without a caller, such as by an app
|
|
31
|
+
* schedule, has no `user`, so its workflow declares a context of the `"app"` scope.
|
|
32
|
+
*/
|
|
33
|
+
type AuthorWorkflows<Requirements extends AppRequirements> = Readonly<Record<string, WorkflowDeclaration<WorkflowContext<Requirements>> | WorkflowDeclaration<WorkflowContext<Requirements, "app">>>>;
|
|
14
34
|
/** Author definition projected from native capabilities. Excluding callable objects keeps
|
|
15
35
|
* factories from being inferred as definitions and preserves contextual handler inference. */
|
|
16
36
|
export type AppDefinition<Requirements extends AppRequirements> = {
|
|
17
|
-
readonly [Key in keyof NativeDefinition<WebhookContext<Requirements>>]: Key extends "workflows" ?
|
|
37
|
+
readonly [Key in keyof NativeDefinition<WebhookContext<Requirements>>]: Key extends "workflows" ? AuthorWorkflows<Requirements> : Key extends "schedules" ? AuthorSchedules<Requirements> : Key extends "tools" ? RouterDeclaration<QueryContext<Requirements>, MutationContext<Requirements>> : Key extends "webhooks" ? AuthorWebhooks<Requirements> : NativeDefinition<WebhookContext<Requirements>>[Key];
|
|
18
38
|
} & {
|
|
19
39
|
readonly name?: never;
|
|
20
40
|
readonly queries?: never;
|
|
21
41
|
readonly mutations?: never;
|
|
22
42
|
readonly call?: never;
|
|
23
43
|
};
|
|
44
|
+
/** A webhook context as the host builds it: an app-account hook's has no `user`. */
|
|
45
|
+
type HostWebhookContext = WebhookContext<AppRequirements, AccountScope> & Partial<Pick<WebhookContext, "user">>;
|
|
24
46
|
/** Adapt operation and webhook catalogs without evaluating their handlers. */
|
|
25
47
|
export type EffectDefinition<Def> = {
|
|
26
|
-
readonly [Key in keyof Def]: Key extends "tools" ? NonNullable<NativeDefinition<unknown>["tools"]> : Key extends "workflows" ? Readonly<Record<string, import("../contracts/workflows.js").AppWorkflow>> : Key extends "schedules" ? NonNullable<NativeDefinition<unknown>["schedules"]> : Key extends "webhooks" ? NonNullable<NativeDefinition<
|
|
48
|
+
readonly [Key in keyof Def]: Key extends "tools" ? NonNullable<NativeDefinition<unknown>["tools"]> : Key extends "workflows" ? Readonly<Record<string, import("../contracts/workflows.js").AppWorkflow>> : Key extends "schedules" ? NonNullable<NativeDefinition<unknown>["schedules"]> : Key extends "webhooks" ? NonNullable<NativeDefinition<HostWebhookContext>["webhooks"]> : Key extends "skills" ? NonNullable<NativeDefinition<unknown>["skills"]> : Key extends "dynamicSkills" ? NonNullable<NativeDefinition<unknown>["dynamicSkills"]> : Def[Key];
|
|
27
49
|
};
|
|
28
50
|
declare const InternalApp: unique symbol;
|
|
29
51
|
/** Recognize a declaration from this framework instance before host adaptation. */
|
|
30
52
|
export declare const isApp: (value: unknown) => value is App<AppRequirements, AppDefinition<AppRequirements>>;
|
|
31
53
|
/** Public app handle; the native app is retained for host use without an async round trip. */
|
|
32
54
|
export interface App<Requirements extends AppRequirements, Def extends AppDefinition<Requirements>> {
|
|
33
|
-
readonly [InternalApp]: NativeApp<Requirements
|
|
34
|
-
readonly accounts: Requirements
|
|
35
|
-
readonly evaluate: (context:
|
|
55
|
+
readonly [InternalApp]: NativeApp<RequirementSlots<Requirements>, EffectDefinition<Def>>;
|
|
56
|
+
readonly accounts: RequirementSlots<Requirements>;
|
|
57
|
+
readonly evaluate: (context: AppFactoryContext<Requirements>) => Promise<Def>;
|
|
36
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* What a dynamic definition's factory receives. App-scope work, such as an app schedule, evaluates
|
|
61
|
+
* the app without a caller, so `user` is absent then.
|
|
62
|
+
*/
|
|
63
|
+
export type AppFactoryContext<Requirements extends AppRequirements> = EvaluationContext<RequirementSlots<Requirements>>;
|
|
37
64
|
/** Retrieve the same declaration for an Effect host. No evaluation or I/O occurs. */
|
|
38
|
-
export declare const toEffectApp: <Requirements extends AppRequirements, Def extends AppDefinition<Requirements>>(app: App<Requirements, Def>) => NativeApp<Requirements
|
|
65
|
+
export declare const toEffectApp: <Requirements extends AppRequirements, Def extends AppDefinition<Requirements>>(app: App<Requirements, Def>) => NativeApp<RequirementSlots<Requirements>, EffectDefinition<Def>>;
|
|
39
66
|
/** Assemble app behavior. Package names belong in package.json; hosts name installed copies. */
|
|
40
|
-
export declare const defineApp: <const Requirements extends AppRequirements, Def extends AppDefinition<Requirements>>(requirements: Requirements, definition: (Def & AppDefinition<Requirements>) | ((context:
|
|
67
|
+
export declare const defineApp: <const Requirements extends AppRequirements, Def extends AppDefinition<Requirements>>(requirements: Requirements, definition: (Def & AppDefinition<Requirements>) | ((context: AppFactoryContext<Requirements>) => Promise<Def & AppDefinition<Requirements>>)) => App<Requirements, Def>;
|
|
41
68
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Bind the portable Effect cache to an app invocation's author API. */
|
|
2
2
|
import { type Context } from "effect";
|
|
3
3
|
import type { AppCache, CacheGetOptions, HostCache } from "../contracts/cache.js";
|
|
4
|
-
import type
|
|
4
|
+
import { type ResolvedAccounts } from "../contracts/host.js";
|
|
5
5
|
import type { JsonValue } from "../contracts/schema.js";
|
|
6
6
|
/**
|
|
7
7
|
* Framework-only: `get` that also reads other keys of the same scope in its round trip to the
|
|
@@ -50,8 +50,13 @@ export interface EventEmitter<Events extends Readonly<Record<string, AnyEventDec
|
|
|
50
50
|
/** One invocation's buffer. The handler reads `emitted` only after the invocation succeeds. */
|
|
51
51
|
export declare const makeEmitter: (input: {
|
|
52
52
|
readonly events: Readonly<Record<string, AppEvent>>;
|
|
53
|
-
/** Every account ID bound to this invocation. */
|
|
53
|
+
/** Every account ID bound to this invocation, which an emit may name. */
|
|
54
54
|
readonly accounts: readonly string[];
|
|
55
|
+
/**
|
|
56
|
+
* The caller's account IDs. An emit that names no account is attributed to the only one, if
|
|
57
|
+
* there is exactly one. App accounts never count: they are bound to every call.
|
|
58
|
+
*/
|
|
59
|
+
readonly attributable: readonly string[];
|
|
55
60
|
/** The webhook's source account, which an emit names by default. */
|
|
56
61
|
readonly sourceAccount?: string;
|
|
57
62
|
readonly emitted: EmittedEvent[];
|
|
@@ -11,8 +11,9 @@ export interface FailureDetail {
|
|
|
11
11
|
readonly fields?: FailureFields;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* Every credential field value of
|
|
15
|
-
*
|
|
14
|
+
* Every credential field value of an invocation's accounts by scope, longest first. The accounts
|
|
15
|
+
* may not have been checked yet, so each scope is read only when it is a slot-to-account record;
|
|
16
|
+
* each account keeps its credential values in `fields`.
|
|
16
17
|
*/
|
|
17
18
|
export declare const accountFieldSecrets: (accounts: unknown) => string[];
|
|
18
19
|
/** Every credential field value of an invocation's selected accounts. */
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
/** Pure operation declarations. Only the author callback crosses the Promise boundary. */
|
|
2
2
|
import { Schema as EffectSchema } from "effect";
|
|
3
3
|
import type { AppOperation } from "../contracts/operations.js";
|
|
4
|
-
import type { AppContext,
|
|
4
|
+
import type { AppContext, AppRequirements, AnyScopeMutationContext, MutationContext, QueryContext } from "../contracts/context.js";
|
|
5
|
+
import type { AccountScope } from "../contracts/app.js";
|
|
5
6
|
import type { Approval } from "../approval.js";
|
|
6
7
|
import type { ToolAnnotations } from "../contracts/tools.js";
|
|
7
8
|
import type { JsonObject } from "../contracts/schema.js";
|
|
8
9
|
import { type Schema } from "./schema.js";
|
|
9
10
|
declare const NativeOperation: unique symbol;
|
|
11
|
+
declare const ApprovalDeclared: unique symbol;
|
|
12
|
+
/**
|
|
13
|
+
* Marks an operation declared with an approval. App-scope work, such as an app schedule, has no
|
|
14
|
+
* person to approve a call, so it accepts only operations without this mark.
|
|
15
|
+
*/
|
|
16
|
+
export interface Approved {
|
|
17
|
+
readonly [ApprovalDeclared]: true;
|
|
18
|
+
}
|
|
19
|
+
/** An operation declared without an approval. */
|
|
20
|
+
export interface WithoutApproval {
|
|
21
|
+
readonly [ApprovalDeclared]?: never;
|
|
22
|
+
}
|
|
23
|
+
/** The context any handler may declare: either scope, so `user` may be absent. */
|
|
24
|
+
export type AnyContext = AppContext<AppRequirements, AccountScope>;
|
|
10
25
|
declare const QueryHandlerContext: unique symbol;
|
|
11
26
|
declare const MutationHandlerContext: unique symbol;
|
|
12
27
|
/**
|
|
@@ -90,14 +105,34 @@ export declare const operationOptions: <Input, Output>(options: OperationOptions
|
|
|
90
105
|
*/
|
|
91
106
|
export declare const approvedOperation: <Input, Native extends AppOperation<Input, unknown>>(operation: Native, approval: Approval<Input>) => Native;
|
|
92
107
|
/** Attach the same approval function to a generated or shared operation. */
|
|
93
|
-
export declare const withApproval: <Input, Output, Kind extends "query" | "mutation", Context>(operation: Operation<Input, Output, Kind, Context>, approval: Approval<Input>) => Operation<Input, Output, Kind, Context
|
|
108
|
+
export declare const withApproval: <Input, Output, Kind extends "query" | "mutation", Context>(operation: Operation<Input, Output, Kind, Context>, approval: Approval<Input>) => Operation<Input, Output, Kind, Context> & Approved;
|
|
94
109
|
/**
|
|
95
110
|
* The advisory hints an operation carries, such as an MCP server's `destructiveHint`. App code
|
|
96
111
|
* reads them to choose an approval; the framework never infers one from them.
|
|
97
112
|
*/
|
|
98
113
|
export declare const toolAnnotations: (operation: OperationDeclaration<"query" | "mutation", never>) => ToolAnnotations | undefined;
|
|
99
114
|
/** Read operation. External reads are allowed; only database writes are mechanically prohibited. */
|
|
100
|
-
export declare const query: <Input, Output, Context extends
|
|
101
|
-
/**
|
|
102
|
-
|
|
115
|
+
export declare const query: <Input, Output, Context extends AnyContext = QueryContext>(options: OperationOptions<Input, Output>, run: (context: Context, input: Input) => Promise<Output>) => Operation<Input, Output, "query", Context>;
|
|
116
|
+
/** The parameters a mutation's handler declares: its context and input, its context, or none. */
|
|
117
|
+
type HandlerParameters<Context, Input> = [context: Context, input: Input] | [context: Context] | [];
|
|
118
|
+
/** The context a handler declares; one without parameters may run in either scope. */
|
|
119
|
+
type DeclaredContext<Signature, Context> = Signature extends [] ? AnyScopeMutationContext : Signature extends readonly [infer Declared, ...unknown[]] ? Declared : Context;
|
|
120
|
+
/**
|
|
121
|
+
* Explicit write operation. Database writes roll back on failure; external effects cannot be undone.
|
|
122
|
+
* A handler that declares a context gets the caller's, with `user`, unless its type says otherwise.
|
|
123
|
+
* One that declares no parameters, in a call without explicit type arguments, uses no context, so
|
|
124
|
+
* it may run as the app, as an app schedule runs it. Explicit type arguments name the context with
|
|
125
|
+
* the third, which defaults to the caller's. One declared with an approval is marked `Approved`, so
|
|
126
|
+
* app-scope schedules refuse it.
|
|
127
|
+
*/
|
|
128
|
+
export declare function mutation<Input, Output, Context extends AnyContext = MutationContext>(options: OperationOptions<Input, Output> & {
|
|
129
|
+
readonly approval: Approval<Input>;
|
|
130
|
+
}, run: (context: Context, input: Input) => Promise<Output>): Operation<Input, Output, "mutation", Context> & Approved;
|
|
131
|
+
export declare function mutation<Input, Output, Context extends AnyContext = MutationContext, Signature extends HandlerParameters<Context, Input> = [context: Context, input: Input]>(options: OperationOptions<Input, Output> & {
|
|
132
|
+
readonly approval?: undefined;
|
|
133
|
+
}, run: (...parameters: Signature) => Promise<Output>): Operation<Input, Output, "mutation", DeclaredContext<Signature, Context>>;
|
|
134
|
+
/** A handler whose context's type the caller's does not fit, such as one of the `"app"` scope. */
|
|
135
|
+
export declare function mutation<Input, Output, Context extends AnyContext>(options: OperationOptions<Input, Output> & {
|
|
136
|
+
readonly approval?: undefined;
|
|
137
|
+
}, run: (context: Context, input: Input) => Promise<Output>): Operation<Input, Output, "mutation", Context>;
|
|
103
138
|
export {};
|
|
@@ -51,6 +51,7 @@ export declare const operationSummary: (name: string, router: string, operation:
|
|
|
51
51
|
};
|
|
52
52
|
};
|
|
53
53
|
readonly input: Schema.Json;
|
|
54
|
+
readonly scope?: "app";
|
|
54
55
|
}[];
|
|
55
56
|
readonly readOnly?: boolean;
|
|
56
57
|
readonly tags?: readonly string[];
|
|
@@ -90,6 +91,7 @@ export declare const operationDescription: (name: string, router: string, operat
|
|
|
90
91
|
};
|
|
91
92
|
};
|
|
92
93
|
readonly input: Schema.Json;
|
|
94
|
+
readonly scope?: "app";
|
|
93
95
|
}[];
|
|
94
96
|
readonly readOnly?: boolean;
|
|
95
97
|
readonly tags?: readonly string[];
|
|
@@ -153,6 +155,7 @@ export declare const readCatalog: (root: AppRouter | DynamicRouter | undefined,
|
|
|
153
155
|
};
|
|
154
156
|
};
|
|
155
157
|
readonly input: Schema.Json;
|
|
158
|
+
readonly scope?: "app";
|
|
156
159
|
}[];
|
|
157
160
|
readonly readOnly?: boolean;
|
|
158
161
|
readonly tags?: readonly string[];
|
|
@@ -181,6 +184,7 @@ export declare const readCatalog: (root: AppRouter | DynamicRouter | undefined,
|
|
|
181
184
|
};
|
|
182
185
|
};
|
|
183
186
|
readonly input: Schema.Json;
|
|
187
|
+
readonly scope?: "app";
|
|
184
188
|
}[];
|
|
185
189
|
readonly readOnly?: boolean;
|
|
186
190
|
readonly tags?: readonly string[];
|
|
@@ -1,16 +1,47 @@
|
|
|
1
1
|
import { Interval, ScheduleTiming } from "../contracts/schedules.js";
|
|
2
2
|
import { JsonValue } from "../contracts/schema.js";
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import type { AccountScope } from "../contracts/app.js";
|
|
4
|
+
import { type Operation, type OperationDeclaration, type WithoutApproval } from "./operations.js";
|
|
5
|
+
/**
|
|
6
|
+
* The app adapter resolves this operation handle to its declared mutation name. A `"user"`
|
|
7
|
+
* schedule has one copy per member who enables it, run as them with their linked accounts. An
|
|
8
|
+
* `"app"` schedule is one schedule, enabled by an app manager, run without a caller with the app's
|
|
9
|
+
* accounts only.
|
|
10
|
+
*/
|
|
11
|
+
export interface ScheduleDeclaration<Context = never, Scope extends AccountScope = AccountScope> {
|
|
12
|
+
readonly scope: Scope;
|
|
6
13
|
readonly operation: OperationDeclaration<"mutation", Context>;
|
|
7
14
|
readonly timing: ScheduleTiming;
|
|
8
15
|
readonly input: JsonValue;
|
|
9
16
|
}
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Refuses, with a message the type error shows, a mutation whose handler context has the caller's
|
|
19
|
+
* `user`, such as one that declares a context without a type.
|
|
20
|
+
*/
|
|
21
|
+
type RunsAsApp<Context> = [Context] extends [{
|
|
22
|
+
readonly user: unknown;
|
|
23
|
+
}] ? {
|
|
24
|
+
readonly 'An app schedule runs without a caller: type the handler\'s context as MutationContext<typeof requirements, "app">, pass it as the third type argument, or declare no parameters and pass no type arguments': never;
|
|
25
|
+
} : unknown;
|
|
26
|
+
/** Run an existing mutation at a fixed interval, once per member who enables it, as them. */
|
|
27
|
+
export declare const userInterval: <Input, Output, Context>(duration: Interval, operation: Operation<Input, Output, "mutation", Context>, input: NoInfer<Input>) => ScheduleDeclaration<Context, "user">;
|
|
28
|
+
/**
|
|
29
|
+
* Calendar alternative for wall-clock schedules, once per member who enables it, as them. UTC is the
|
|
30
|
+
* explicit default when timezone is omitted.
|
|
31
|
+
*/
|
|
32
|
+
export declare const userCron: <Input, Output, Context>(calendar: {
|
|
14
33
|
readonly expression: string;
|
|
15
34
|
readonly timezone?: string;
|
|
16
|
-
}, operation: Operation<Input, Output, "mutation", Context>, input: NoInfer<Input>) => ScheduleDeclaration<Context>;
|
|
35
|
+
}, operation: Operation<Input, Output, "mutation", Context>, input: NoInfer<Input>) => ScheduleDeclaration<Context, "user">;
|
|
36
|
+
/**
|
|
37
|
+
* Run an existing mutation at a fixed interval as the app: one schedule an app manager enables, run
|
|
38
|
+
* without a caller with the app's accounts. The mutation takes a context of the `"app"` scope and
|
|
39
|
+
* declares no approval.
|
|
40
|
+
*/
|
|
41
|
+
export declare const appInterval: <Input, Output, Context>(duration: Interval, operation: Operation<Input, Output, "mutation", Context> & WithoutApproval & RunsAsApp<Context>, input: NoInfer<Input>) => ScheduleDeclaration<Context, "app">;
|
|
42
|
+
/** Calendar alternative to `appInterval`. UTC is the explicit default when timezone is omitted. */
|
|
43
|
+
export declare const appCron: <Input, Output, Context>(calendar: {
|
|
44
|
+
readonly expression: string;
|
|
45
|
+
readonly timezone?: string;
|
|
46
|
+
}, operation: Operation<Input, Output, "mutation", Context> & WithoutApproval & RunsAsApp<Context>, input: NoInfer<Input>) => ScheduleDeclaration<Context, "app">;
|
|
47
|
+
export {};
|
|
@@ -7,8 +7,8 @@ import { UiFailed, UiForbidden, type AppUiAsset, type AppUiRange, type AppUiStor
|
|
|
7
7
|
*/
|
|
8
8
|
export declare const appDocument: <E, R>(options: {
|
|
9
9
|
readonly deployment: string;
|
|
10
|
-
|
|
11
|
-
readonly
|
|
10
|
+
/** The account IDs the page runs with, by requirement. */
|
|
11
|
+
readonly accountIds?: Readonly<Record<string, readonly string[]>> | undefined;
|
|
12
12
|
readonly origin: string;
|
|
13
13
|
readonly accounts?: UiAccountNotice | undefined;
|
|
14
14
|
readonly asset: (path: string) => Effect.Effect<AppUiAsset | undefined, E, R>;
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
/** Native webhook dispatch. The author verifies signatures before parsing or performing side effects. */
|
|
2
2
|
import { Effect, Schema } from "effect";
|
|
3
|
-
import type { AppDefinition } from "../contracts/app.js";
|
|
4
|
-
import { HostDeclarationInvalid, HostInputInvalid, HostOperationFailed, HostOperationNotFound,
|
|
3
|
+
import type { AppDefinition, ScopedSlots } from "../contracts/app.js";
|
|
4
|
+
import { HostDeclarationInvalid, HostInputInvalid, HostOperationFailed, HostOperationNotFound, HostAccountsInvalid, HostOutputInvalid } from "../contracts/host.js";
|
|
5
5
|
import { type WebhookCommand } from "../contracts/webhook-protocol.js";
|
|
6
|
-
|
|
6
|
+
type ScopeAccounts = {
|
|
7
|
+
readonly accounts: Readonly<Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Run one hook with freshly bound context. No credentials or raw failures enter the response
|
|
11
|
+
* envelope. An app-account hook runs without a caller: its context has no `user`, whatever the
|
|
12
|
+
* invocation bound.
|
|
13
|
+
*/
|
|
7
14
|
export declare const dispatchWebhook: <Context extends {
|
|
8
15
|
readonly signal?: AbortSignal;
|
|
9
|
-
readonly
|
|
10
|
-
|
|
16
|
+
readonly app: ScopeAccounts;
|
|
17
|
+
readonly user?: ScopeAccounts;
|
|
18
|
+
}>(definition: AppDefinition<Context>, command: WebhookCommand, context: Context, slots: ScopedSlots) => Effect.Effect<Schema.Json | {
|
|
11
19
|
readonly name: string;
|
|
12
20
|
readonly account: string;
|
|
13
21
|
readonly configSchema: {
|
|
@@ -26,4 +34,5 @@ export declare const dispatchWebhook: <Context extends {
|
|
|
26
34
|
readonly [x: string]: string;
|
|
27
35
|
};
|
|
28
36
|
readonly body: string;
|
|
29
|
-
}, HostDeclarationInvalid | HostOperationNotFound | HostOperationFailed | HostInputInvalid | HostOutputInvalid, never>;
|
|
37
|
+
}, HostDeclarationInvalid | HostAccountsInvalid | HostOperationNotFound | HostOperationFailed | HostInputInvalid | HostOutputInvalid, never>;
|
|
38
|
+
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/** Author-facing step methods delegate persistence to the host's durable engine. */
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
-
import type { AppDefinition } from "../contracts/app.js";
|
|
4
|
-
import
|
|
3
|
+
import type { AccountScope, AppDefinition } from "../contracts/app.js";
|
|
4
|
+
import type { AppRequirements } from "../contracts/context.js";
|
|
5
|
+
import { WorkflowFailure, type WorkflowContext, type WorkflowExecution, type WorkflowStepContext as AuthorStepContext } from "../contracts/workflows.js";
|
|
6
|
+
/** A step's context as the host builds it: a run without a caller has no `user`. */
|
|
7
|
+
type WorkflowStepContext = AuthorStepContext<AppRequirements, AccountScope> & Partial<Pick<AuthorStepContext, "user">>;
|
|
5
8
|
/**
|
|
6
9
|
* Preserve typed failures and cancellation. Other errors keep their name and bounded message,
|
|
7
10
|
* with the given account secrets replaced.
|
|
@@ -14,3 +17,4 @@ fresh: (stepId: string, signal: AbortSignal) => Effect.Effect<{
|
|
|
14
17
|
readonly context: WorkflowStepContext;
|
|
15
18
|
readonly secrets: readonly string[];
|
|
16
19
|
}, WorkflowFailure>, signal: AbortSignal) => Effect.Effect<WorkflowContext>;
|
|
20
|
+
export {};
|