@oxy-hq/sdk 2.12.0 → 2.16.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 (47) hide show
  1. package/README.md +67 -0
  2. package/dist/{function-context-D8eyZuw_.d.cts → function-context-BNpL5bFb.d.cts} +223 -20
  3. package/dist/function-context-BNpL5bFb.d.cts.map +1 -0
  4. package/dist/{function-context-D8eyZuw_.d.mts → function-context-BNpL5bFb.d.mts} +223 -20
  5. package/dist/function-context-BNpL5bFb.d.mts.map +1 -0
  6. package/dist/index.cjs +80 -16
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +164 -3
  9. package/dist/index.d.cts.map +1 -1
  10. package/dist/index.d.mts +164 -3
  11. package/dist/index.d.mts.map +1 -1
  12. package/dist/index.mjs +78 -16
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/ops.d.cts +1 -1
  15. package/dist/ops.d.mts +1 -1
  16. package/dist/{react-DW7Z96sD.d.mts → react-CljeXJuw.d.cts} +142 -8
  17. package/dist/react-CljeXJuw.d.cts.map +1 -0
  18. package/dist/{react-DW7Z96sD.d.cts → react-CljeXJuw.d.mts} +142 -8
  19. package/dist/react-CljeXJuw.d.mts.map +1 -0
  20. package/dist/{react-DcT-mUPj.cjs → react-Dvkv2deI.cjs} +110 -59
  21. package/dist/react-Dvkv2deI.cjs.map +1 -0
  22. package/dist/{react-BXGyzgz0.mjs → react-OW1t_J0M.mjs} +103 -26
  23. package/dist/react-OW1t_J0M.mjs.map +1 -0
  24. package/dist/rolldown-runtime-KC0qvQup.cjs +34 -0
  25. package/dist/shell.cjs +38 -3
  26. package/dist/shell.cjs.map +1 -1
  27. package/dist/shell.d.cts +26 -3
  28. package/dist/shell.d.cts.map +1 -1
  29. package/dist/shell.d.mts +26 -3
  30. package/dist/shell.d.mts.map +1 -1
  31. package/dist/shell.mjs +34 -2
  32. package/dist/shell.mjs.map +1 -1
  33. package/dist/testing.cjs +4431 -0
  34. package/dist/testing.cjs.map +1 -0
  35. package/dist/testing.d.cts +656 -0
  36. package/dist/testing.d.cts.map +1 -0
  37. package/dist/testing.d.mts +656 -0
  38. package/dist/testing.d.mts.map +1 -0
  39. package/dist/testing.mjs +4395 -0
  40. package/dist/testing.mjs.map +1 -0
  41. package/package.json +22 -9
  42. package/dist/function-context-D8eyZuw_.d.cts.map +0 -1
  43. package/dist/function-context-D8eyZuw_.d.mts.map +0 -1
  44. package/dist/react-BXGyzgz0.mjs.map +0 -1
  45. package/dist/react-DW7Z96sD.d.cts.map +0 -1
  46. package/dist/react-DW7Z96sD.d.mts.map +0 -1
  47. package/dist/react-DcT-mUPj.cjs.map +0 -1
@@ -23,8 +23,40 @@ interface OxyAppFunctionManifest {
23
23
  pipeline: string;
24
24
  resource: string;
25
25
  };
26
+ /**
27
+ * Receive an unauthenticated POST from a third party at
28
+ * `POST /api/webhooks/apps/<org>/<app>/<name>`.
29
+ *
30
+ * The PLATFORM verifies every request — HMAC-SHA256 over the raw body, in
31
+ * constant time — before the function is enqueued, so app code never sees an
32
+ * unverified request. Omit the block and that endpoint answers 404, as if it
33
+ * did not exist.
34
+ */
35
+ webhook?: {
36
+ /**
37
+ * App-secret key holding the signing key(s) — the same `apps/<app-id>/`
38
+ * namespace `ctx.env` reads. The manifest names the secret, never holds it.
39
+ *
40
+ * **Comma-separated for rotation.** Providers that keep two live signing
41
+ * keys (Uber's `BASIC_HMAC` does) sign with either during a rotation; any
42
+ * match passes, so adopting a new key does not drop the events still
43
+ * signed with the old one.
44
+ */
45
+ secretVar: string;
46
+ /** Header carrying the signature, e.g. `x-uber-signature`. */
47
+ signatureHeader: string;
48
+ /** How the digest is encoded. Default `hex`. */
49
+ encoding?: "hex" | "base64";
50
+ };
26
51
  /** Wall-clock timeout. Default 30, max 300. */
27
52
  timeoutSeconds?: number;
53
+ /**
54
+ * Mark this function as a check. `oxyc checks run` runs it; with a
55
+ * `schedule` the platform runs it continuously and a failure pages. A
56
+ * check fails when it throws, times out, or returns `{ ok: false }`.
57
+ * Checks must not have customer-visible side effects.
58
+ */
59
+ check?: boolean;
28
60
  /**
29
61
  * Opt-in result caching for route invocations. Omit (the default) to never
30
62
  * cache — the safe choice for a side-effectful function (writes, external
@@ -43,13 +75,31 @@ interface OxyAppFunctionManifest {
43
75
  * destination here ONLY for a function that legitimately writes to it; a
44
76
  * read-only function omits it. This scopes writes away from the project's
45
77
  * source warehouse.
78
+ *
79
+ * A customer warehouse (anything but `airhouse` / `airhouse_managed`) is
80
+ * read-only: listing it here is not enough, it must also appear in
81
+ * `customerWarehouseWrites` with a reason.
46
82
  */
47
83
  destinations?: string[];
84
+ /**
85
+ * Customer warehouses this function writes to anyway, each with the reason —
86
+ * the exception to "customer warehouses are read-only". Every key must also be
87
+ * in `destinations`; a write to a customer warehouse not named here is refused.
88
+ * Prefer moving the data: facts to `airhouse`, records to `oltp`.
89
+ *
90
+ * ```json
91
+ * "customerWarehouseWrites": {
92
+ * "clickhouse": "Journal entries stay beside the legacy ClickHouse facts until QuickBooks lands in Airhouse"
93
+ * }
94
+ * ```
95
+ */
96
+ customerWarehouseWrites?: Record<string, string>;
48
97
  /**
49
98
  * Capability to write app-scoped secrets via `ctx.secrets.set` (fail-closed:
50
99
  * omit → writes rejected). Only the app's own `apps/<app-id>/` namespace is
51
- * writable. Declare for a function that persists state — e.g. a scheduled
52
- * token-refresher that writes the rotated token back to Oxy Secrets.
100
+ * writable. Declare for a function that rotates a credential — e.g. a
101
+ * scheduled token-refresher that writes the rotated token back to Oxy Secrets.
102
+ * Secrets are not a state store: a cursor or counter is a record for `oltp`.
53
103
  */
54
104
  secrets?: {
55
105
  write?: boolean;
@@ -102,6 +152,17 @@ interface OxyAppFunctionManifest {
102
152
  oltp?: {
103
153
  enabled?: boolean;
104
154
  };
155
+ /**
156
+ * Capability for `ctx.airhouse` — append the app's own FACTS (what happened,
157
+ * never edited) to its schema in the workspace's Airhouse (fail-closed: omit →
158
+ * every `ctx.airhouse` call rejected). A pure GATE like `oltp`: the schema is
159
+ * derived from the app's slug (`store-ops` → `app_store_ops`), never named
160
+ * here. Writes run as the app, whoever invoked the function, so a scheduled
161
+ * run can write. Tables come from `airhouseMigrations`.
162
+ */
163
+ airhouse?: {
164
+ enabled?: boolean;
165
+ };
105
166
  /**
106
167
  * Retry policy for **background** runs (a `schedule` fire or a manual job
107
168
  * trigger). Omit → a job run is attempted once. Route (HTTP) invocations are
@@ -128,9 +189,9 @@ interface OxyAppManifest {
128
189
  /** Must be 2. v1 manifests are no longer supported. */
129
190
  schemaVersion: 2;
130
191
  /**
131
- * Optional display name. The admin "Link existing" dialog prefills
132
- * its Name field from this. Omit to let oxy fall back to the
133
- * folder basename.
192
+ * Optional display name. Informational: the name an app shows is its
193
+ * registry row's, set when the row is created (the admin **New app**
194
+ * dialog, or `oxyc publish --name` on a first publish).
134
195
  */
135
196
  name?: string;
136
197
  /**
@@ -159,7 +220,8 @@ interface OxyAppManifest {
159
220
  */
160
221
  functions?: Record<string, OxyAppFunctionManifest>;
161
222
  /**
162
- * Schema migrations that ship WITH this bundle and run on promote.
223
+ * Schema migrations for the app's OLTP store (`ctx.oltp`) that ship WITH this
224
+ * bundle and run on promote.
163
225
  *
164
226
  * `dir` is a directory inside the built bundle holding numbered `.sql` files.
165
227
  * The platform runs them in lexical order, **once each, ever**, inside a
@@ -177,6 +239,18 @@ interface OxyAppManifest {
177
239
  migrations?: {
178
240
  dir: string;
179
241
  };
242
+ /**
243
+ * Tables for the app's FACTS, in its Airhouse schema `app_<writer>`: a
244
+ * directory of numbered `.sql` files run once each, at promote, with the same
245
+ * ledger rules as `migrations` (never edit, rename or copy one that ran).
246
+ *
247
+ * Every object must be named `app_<writer>.<name>`. Airhouse is DuckLake, so a
248
+ * file declaring a PRIMARY KEY, UNIQUE, an index or a foreign key is refused at
249
+ * publish — a table carrying one fails and leaves the writer inert.
250
+ */
251
+ airhouseMigrations?: {
252
+ dir: string;
253
+ };
180
254
  /**
181
255
  * Optional Ask Oxygen binding (agent ref + composer chips). The
182
256
  * platform's registered copy is authoritative (surfaced by
@@ -187,6 +261,37 @@ interface OxyAppManifest {
187
261
  agent?: string;
188
262
  suggestedQuestions?: string[];
189
263
  };
264
+ /**
265
+ * The secrets this app expects, keyed by env-var name — the app's
266
+ * `.env.example`, declared rather than written in a README.
267
+ *
268
+ * These are the keys your functions read as `ctx.env.KEY`. Declaring one puts
269
+ * it in the app's Secrets surface (staff console → app → Secrets, and the
270
+ * workspace's own settings) as a row to fill in, so a fresh deploy says what
271
+ * is still missing instead of failing at the first invocation. Every function's
272
+ * `webhook.secretVar` is folded in automatically — no need to repeat it here.
273
+ *
274
+ * **Names only, never values.** A manifest ships inside the bundle and is
275
+ * fetchable over the app's own host; putting a secret in one publishes it.
276
+ * Values are set out-of-band on the Secrets surface, or by
277
+ * `ctx.secrets.set` from a function holding the `secrets.write` capability.
278
+ *
279
+ * App-level rather than per-function, because a secret is app-scoped by
280
+ * construction: two functions sharing `STRIPE_API_KEY` read the same value,
281
+ * so it can only be described once.
282
+ *
283
+ * ```jsonc
284
+ * "env": {
285
+ * "STRIPE_API_KEY": { "required": true, "description": "Restricted key, Dashboard → Developers" },
286
+ * "SLACK_WEBHOOK_URL": { "description": "Optional ops channel" }
287
+ * }
288
+ * ```
289
+ *
290
+ * Read by the platform at **publish time** (like {@link OxyAppStorageManifest}),
291
+ * so the block is documented here but not round-tripped through the dev-time
292
+ * manifest fetch.
293
+ */
294
+ env?: Record<string, OxyAppEnvDeclaration>;
190
295
  /**
191
296
  * Optional app-level storage policy. Distinct from the per-function
192
297
  * `storage: { read, write }` capability: those gate what one function may
@@ -220,6 +325,24 @@ interface OxyAppManifest {
220
325
  */
221
326
  analytics?: boolean;
222
327
  }
328
+ /** One declared secret — an entry in the `env` block of `oxy-app.json`. */
329
+ interface OxyAppEnvDeclaration {
330
+ /**
331
+ * Flag the key as **Missing** (rather than merely absent) while nothing is
332
+ * stored for it, and count it in the app's missing-secrets badge.
333
+ *
334
+ * Advisory, not a gate: a publish is never blocked on an unset key, because
335
+ * the first publish is exactly when nobody could have set one yet.
336
+ *
337
+ * Default: `false` — a declaration is documentation first.
338
+ */
339
+ required?: boolean;
340
+ /**
341
+ * Shown beside the key on the Secrets surface. Say what it is and where to
342
+ * get one — this is the text that saves someone a Slack message.
343
+ */
344
+ description?: string;
345
+ }
223
346
  /** Browser-runtime performance opt-outs — the `performance` block in `oxy-app.json`. */
224
347
  interface OxyAppPerformanceManifest {
225
348
  /**
@@ -387,6 +510,14 @@ type FunctionError = Error & {
387
510
  logs?: FunctionLog[];
388
511
  status?: number;
389
512
  body?: unknown;
513
+ /**
514
+ * The platform trace this invoke ran in (32 hex chars) and the server-minted
515
+ * `x-oxy-request-id`, when the request got as far as the server. Quote
516
+ * either in a bug report: an operator can open the trace in HyperDX, and
517
+ * an app admin can filter the app's Logs by the request.
518
+ */
519
+ traceId?: string;
520
+ requestId?: string;
390
521
  };
391
522
  //#endregion
392
523
  //#region src/custom-app/react.d.ts
@@ -509,7 +640,10 @@ interface UseFunctionResult<Data = unknown> {
509
640
  data: Data | null;
510
641
  /** True while an invocation is in flight. */
511
642
  isLoading: boolean;
512
- /** Last invocation error, or null. On error this carries `.logs` too. */
643
+ /**
644
+ * Last invocation error, or null. On error this carries `.logs`, and
645
+ * `.traceId` / `.requestId` — the ids that name the run to an operator.
646
+ */
513
647
  error: Error | null;
514
648
  /**
515
649
  * `console.*` / `ctx.log` output from the last invoke (success or error), so
@@ -836,4 +970,4 @@ interface OxyChatProps {
836
970
  declare function OxyChat(props: OxyChatProps): React.JSX.Element;
837
971
  //#endregion
838
972
  export { loadCustomAppManifest as $, UseSemanticQueryOpts as A, FunctionError as B, UseProcedureRunInput as C, UseQueryOpts as D, UseQueryInput as E, useProcedureRun as F, apiErrorFromResponse as G, FunctionResult as H, useQuery as I, OxyAppFunctionManifest as J, interpretCustomAppError as K, useResolvedManifest as L, useAgentRun as M, useFunction as N, UseQueryResult as O, useOxyApp as P, _resetCustomAppManifestCacheForTest as Q, useSemanticQuery as R, UseFunctionResult as S, UseProcedureRunResult as T, CustomAppErrorReport as U, FunctionLog as V, OxyApiError as W, OxyAppPerformanceManifest as X, OxyAppManifest as Y, ResolvedCustomAppManifest as Z, SemanticFilter as _, AppFetcher as a, UseAgentRunInput as b, OxyAppProvider as c, OxyChatProps as d, ProcedureProgress as f, SemanticDateRangeOp as g, SemanticArrayOp as h, AgentSqlArtifact as i, UseSemanticQueryResult as j, UseSemanticQueryInput as k, OxyAppProviderProps as l, ProcedureRunState as m, AgentRunEvent as n, OxyAnswer as o, ProcedureResult as p, LoadManifestOptions as q, AgentRunState as r, OxyAnswerProps as s, AgentArtifact as t, OxyChat as u, SemanticScalarOp as v, UseProcedureRunOpts as w, UseAgentRunResult as x, SemanticTimeDimension as y, useTrackEvent as z };
839
- //# sourceMappingURL=react-DW7Z96sD.d.mts.map
973
+ //# sourceMappingURL=react-CljeXJuw.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-CljeXJuw.d.cts","names":[],"sources":["../src/custom-app/manifest.ts","../src/custom-app/errors.ts","../src/custom-app/function-sse.ts","../src/custom-app/react.tsx"],"mappings":"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"}
@@ -23,8 +23,40 @@ interface OxyAppFunctionManifest {
23
23
  pipeline: string;
24
24
  resource: string;
25
25
  };
26
+ /**
27
+ * Receive an unauthenticated POST from a third party at
28
+ * `POST /api/webhooks/apps/<org>/<app>/<name>`.
29
+ *
30
+ * The PLATFORM verifies every request — HMAC-SHA256 over the raw body, in
31
+ * constant time — before the function is enqueued, so app code never sees an
32
+ * unverified request. Omit the block and that endpoint answers 404, as if it
33
+ * did not exist.
34
+ */
35
+ webhook?: {
36
+ /**
37
+ * App-secret key holding the signing key(s) — the same `apps/<app-id>/`
38
+ * namespace `ctx.env` reads. The manifest names the secret, never holds it.
39
+ *
40
+ * **Comma-separated for rotation.** Providers that keep two live signing
41
+ * keys (Uber's `BASIC_HMAC` does) sign with either during a rotation; any
42
+ * match passes, so adopting a new key does not drop the events still
43
+ * signed with the old one.
44
+ */
45
+ secretVar: string;
46
+ /** Header carrying the signature, e.g. `x-uber-signature`. */
47
+ signatureHeader: string;
48
+ /** How the digest is encoded. Default `hex`. */
49
+ encoding?: "hex" | "base64";
50
+ };
26
51
  /** Wall-clock timeout. Default 30, max 300. */
27
52
  timeoutSeconds?: number;
53
+ /**
54
+ * Mark this function as a check. `oxyc checks run` runs it; with a
55
+ * `schedule` the platform runs it continuously and a failure pages. A
56
+ * check fails when it throws, times out, or returns `{ ok: false }`.
57
+ * Checks must not have customer-visible side effects.
58
+ */
59
+ check?: boolean;
28
60
  /**
29
61
  * Opt-in result caching for route invocations. Omit (the default) to never
30
62
  * cache — the safe choice for a side-effectful function (writes, external
@@ -43,13 +75,31 @@ interface OxyAppFunctionManifest {
43
75
  * destination here ONLY for a function that legitimately writes to it; a
44
76
  * read-only function omits it. This scopes writes away from the project's
45
77
  * source warehouse.
78
+ *
79
+ * A customer warehouse (anything but `airhouse` / `airhouse_managed`) is
80
+ * read-only: listing it here is not enough, it must also appear in
81
+ * `customerWarehouseWrites` with a reason.
46
82
  */
47
83
  destinations?: string[];
84
+ /**
85
+ * Customer warehouses this function writes to anyway, each with the reason —
86
+ * the exception to "customer warehouses are read-only". Every key must also be
87
+ * in `destinations`; a write to a customer warehouse not named here is refused.
88
+ * Prefer moving the data: facts to `airhouse`, records to `oltp`.
89
+ *
90
+ * ```json
91
+ * "customerWarehouseWrites": {
92
+ * "clickhouse": "Journal entries stay beside the legacy ClickHouse facts until QuickBooks lands in Airhouse"
93
+ * }
94
+ * ```
95
+ */
96
+ customerWarehouseWrites?: Record<string, string>;
48
97
  /**
49
98
  * Capability to write app-scoped secrets via `ctx.secrets.set` (fail-closed:
50
99
  * omit → writes rejected). Only the app's own `apps/<app-id>/` namespace is
51
- * writable. Declare for a function that persists state — e.g. a scheduled
52
- * token-refresher that writes the rotated token back to Oxy Secrets.
100
+ * writable. Declare for a function that rotates a credential — e.g. a
101
+ * scheduled token-refresher that writes the rotated token back to Oxy Secrets.
102
+ * Secrets are not a state store: a cursor or counter is a record for `oltp`.
53
103
  */
54
104
  secrets?: {
55
105
  write?: boolean;
@@ -102,6 +152,17 @@ interface OxyAppFunctionManifest {
102
152
  oltp?: {
103
153
  enabled?: boolean;
104
154
  };
155
+ /**
156
+ * Capability for `ctx.airhouse` — append the app's own FACTS (what happened,
157
+ * never edited) to its schema in the workspace's Airhouse (fail-closed: omit →
158
+ * every `ctx.airhouse` call rejected). A pure GATE like `oltp`: the schema is
159
+ * derived from the app's slug (`store-ops` → `app_store_ops`), never named
160
+ * here. Writes run as the app, whoever invoked the function, so a scheduled
161
+ * run can write. Tables come from `airhouseMigrations`.
162
+ */
163
+ airhouse?: {
164
+ enabled?: boolean;
165
+ };
105
166
  /**
106
167
  * Retry policy for **background** runs (a `schedule` fire or a manual job
107
168
  * trigger). Omit → a job run is attempted once. Route (HTTP) invocations are
@@ -128,9 +189,9 @@ interface OxyAppManifest {
128
189
  /** Must be 2. v1 manifests are no longer supported. */
129
190
  schemaVersion: 2;
130
191
  /**
131
- * Optional display name. The admin "Link existing" dialog prefills
132
- * its Name field from this. Omit to let oxy fall back to the
133
- * folder basename.
192
+ * Optional display name. Informational: the name an app shows is its
193
+ * registry row's, set when the row is created (the admin **New app**
194
+ * dialog, or `oxyc publish --name` on a first publish).
134
195
  */
135
196
  name?: string;
136
197
  /**
@@ -159,7 +220,8 @@ interface OxyAppManifest {
159
220
  */
160
221
  functions?: Record<string, OxyAppFunctionManifest>;
161
222
  /**
162
- * Schema migrations that ship WITH this bundle and run on promote.
223
+ * Schema migrations for the app's OLTP store (`ctx.oltp`) that ship WITH this
224
+ * bundle and run on promote.
163
225
  *
164
226
  * `dir` is a directory inside the built bundle holding numbered `.sql` files.
165
227
  * The platform runs them in lexical order, **once each, ever**, inside a
@@ -177,6 +239,18 @@ interface OxyAppManifest {
177
239
  migrations?: {
178
240
  dir: string;
179
241
  };
242
+ /**
243
+ * Tables for the app's FACTS, in its Airhouse schema `app_<writer>`: a
244
+ * directory of numbered `.sql` files run once each, at promote, with the same
245
+ * ledger rules as `migrations` (never edit, rename or copy one that ran).
246
+ *
247
+ * Every object must be named `app_<writer>.<name>`. Airhouse is DuckLake, so a
248
+ * file declaring a PRIMARY KEY, UNIQUE, an index or a foreign key is refused at
249
+ * publish — a table carrying one fails and leaves the writer inert.
250
+ */
251
+ airhouseMigrations?: {
252
+ dir: string;
253
+ };
180
254
  /**
181
255
  * Optional Ask Oxygen binding (agent ref + composer chips). The
182
256
  * platform's registered copy is authoritative (surfaced by
@@ -187,6 +261,37 @@ interface OxyAppManifest {
187
261
  agent?: string;
188
262
  suggestedQuestions?: string[];
189
263
  };
264
+ /**
265
+ * The secrets this app expects, keyed by env-var name — the app's
266
+ * `.env.example`, declared rather than written in a README.
267
+ *
268
+ * These are the keys your functions read as `ctx.env.KEY`. Declaring one puts
269
+ * it in the app's Secrets surface (staff console → app → Secrets, and the
270
+ * workspace's own settings) as a row to fill in, so a fresh deploy says what
271
+ * is still missing instead of failing at the first invocation. Every function's
272
+ * `webhook.secretVar` is folded in automatically — no need to repeat it here.
273
+ *
274
+ * **Names only, never values.** A manifest ships inside the bundle and is
275
+ * fetchable over the app's own host; putting a secret in one publishes it.
276
+ * Values are set out-of-band on the Secrets surface, or by
277
+ * `ctx.secrets.set` from a function holding the `secrets.write` capability.
278
+ *
279
+ * App-level rather than per-function, because a secret is app-scoped by
280
+ * construction: two functions sharing `STRIPE_API_KEY` read the same value,
281
+ * so it can only be described once.
282
+ *
283
+ * ```jsonc
284
+ * "env": {
285
+ * "STRIPE_API_KEY": { "required": true, "description": "Restricted key, Dashboard → Developers" },
286
+ * "SLACK_WEBHOOK_URL": { "description": "Optional ops channel" }
287
+ * }
288
+ * ```
289
+ *
290
+ * Read by the platform at **publish time** (like {@link OxyAppStorageManifest}),
291
+ * so the block is documented here but not round-tripped through the dev-time
292
+ * manifest fetch.
293
+ */
294
+ env?: Record<string, OxyAppEnvDeclaration>;
190
295
  /**
191
296
  * Optional app-level storage policy. Distinct from the per-function
192
297
  * `storage: { read, write }` capability: those gate what one function may
@@ -220,6 +325,24 @@ interface OxyAppManifest {
220
325
  */
221
326
  analytics?: boolean;
222
327
  }
328
+ /** One declared secret — an entry in the `env` block of `oxy-app.json`. */
329
+ interface OxyAppEnvDeclaration {
330
+ /**
331
+ * Flag the key as **Missing** (rather than merely absent) while nothing is
332
+ * stored for it, and count it in the app's missing-secrets badge.
333
+ *
334
+ * Advisory, not a gate: a publish is never blocked on an unset key, because
335
+ * the first publish is exactly when nobody could have set one yet.
336
+ *
337
+ * Default: `false` — a declaration is documentation first.
338
+ */
339
+ required?: boolean;
340
+ /**
341
+ * Shown beside the key on the Secrets surface. Say what it is and where to
342
+ * get one — this is the text that saves someone a Slack message.
343
+ */
344
+ description?: string;
345
+ }
223
346
  /** Browser-runtime performance opt-outs — the `performance` block in `oxy-app.json`. */
224
347
  interface OxyAppPerformanceManifest {
225
348
  /**
@@ -387,6 +510,14 @@ type FunctionError = Error & {
387
510
  logs?: FunctionLog[];
388
511
  status?: number;
389
512
  body?: unknown;
513
+ /**
514
+ * The platform trace this invoke ran in (32 hex chars) and the server-minted
515
+ * `x-oxy-request-id`, when the request got as far as the server. Quote
516
+ * either in a bug report: an operator can open the trace in HyperDX, and
517
+ * an app admin can filter the app's Logs by the request.
518
+ */
519
+ traceId?: string;
520
+ requestId?: string;
390
521
  };
391
522
  //#endregion
392
523
  //#region src/custom-app/react.d.ts
@@ -509,7 +640,10 @@ interface UseFunctionResult<Data = unknown> {
509
640
  data: Data | null;
510
641
  /** True while an invocation is in flight. */
511
642
  isLoading: boolean;
512
- /** Last invocation error, or null. On error this carries `.logs` too. */
643
+ /**
644
+ * Last invocation error, or null. On error this carries `.logs`, and
645
+ * `.traceId` / `.requestId` — the ids that name the run to an operator.
646
+ */
513
647
  error: Error | null;
514
648
  /**
515
649
  * `console.*` / `ctx.log` output from the last invoke (success or error), so
@@ -836,4 +970,4 @@ interface OxyChatProps {
836
970
  declare function OxyChat(props: OxyChatProps): React.JSX.Element;
837
971
  //#endregion
838
972
  export { loadCustomAppManifest as $, UseSemanticQueryOpts as A, FunctionError as B, UseProcedureRunInput as C, UseQueryOpts as D, UseQueryInput as E, useProcedureRun as F, apiErrorFromResponse as G, FunctionResult as H, useQuery as I, OxyAppFunctionManifest as J, interpretCustomAppError as K, useResolvedManifest as L, useAgentRun as M, useFunction as N, UseQueryResult as O, useOxyApp as P, _resetCustomAppManifestCacheForTest as Q, useSemanticQuery as R, UseFunctionResult as S, UseProcedureRunResult as T, CustomAppErrorReport as U, FunctionLog as V, OxyApiError as W, OxyAppPerformanceManifest as X, OxyAppManifest as Y, ResolvedCustomAppManifest as Z, SemanticFilter as _, AppFetcher as a, UseAgentRunInput as b, OxyAppProvider as c, OxyChatProps as d, ProcedureProgress as f, SemanticDateRangeOp as g, SemanticArrayOp as h, AgentSqlArtifact as i, UseSemanticQueryResult as j, UseSemanticQueryInput as k, OxyAppProviderProps as l, ProcedureRunState as m, AgentRunEvent as n, OxyAnswer as o, ProcedureResult as p, LoadManifestOptions as q, AgentRunState as r, OxyAnswerProps as s, AgentArtifact as t, OxyChat as u, SemanticScalarOp as v, UseProcedureRunOpts as w, UseAgentRunResult as x, SemanticTimeDimension as y, useTrackEvent as z };
839
- //# sourceMappingURL=react-DW7Z96sD.d.cts.map
973
+ //# sourceMappingURL=react-CljeXJuw.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-CljeXJuw.d.mts","names":[],"sources":["../src/custom-app/manifest.ts","../src/custom-app/errors.ts","../src/custom-app/function-sse.ts","../src/custom-app/react.tsx"],"mappings":"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"}