okengine 0.3.6 → 0.5.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 (205) hide show
  1. package/AGENTS.md +2 -0
  2. package/package.json +14 -12
  3. package/site/content/docs/ai/index.mdx +24 -0
  4. package/site/content/docs/ai/llms-txt.mdx +3 -0
  5. package/site/content/docs/ai/meta.json +1 -1
  6. package/site/content/docs/ai/skills.mdx +5 -3
  7. package/site/content/docs/console/gates.mdx +46 -8
  8. package/site/content/docs/console/index.mdx +54 -0
  9. package/site/content/docs/console/meta.json +1 -0
  10. package/site/content/docs/elements/ai.mdx +2 -0
  11. package/site/content/docs/elements/channel.mdx +2 -0
  12. package/site/content/docs/elements/clock.mdx +1 -4
  13. package/site/content/docs/elements/flow.mdx +4 -10
  14. package/site/content/docs/elements/gate.mdx +189 -48
  15. package/site/content/docs/elements/index.mdx +45 -0
  16. package/site/content/docs/elements/meta.json +1 -1
  17. package/site/content/docs/elements/signal.mdx +1 -5
  18. package/site/content/docs/elements/store.mdx +27 -6
  19. package/site/content/docs/elements/vault.mdx +10 -11
  20. package/site/content/docs/get-started/basic-usage.mdx +79 -43
  21. package/site/content/docs/get-started/index.mdx +33 -0
  22. package/site/content/docs/get-started/installation.mdx +95 -43
  23. package/site/content/docs/get-started/introduction.mdx +128 -75
  24. package/site/content/docs/get-started/meta.json +1 -1
  25. package/site/content/docs/get-started/why.mdx +141 -0
  26. package/site/content/docs/index.mdx +9 -31
  27. package/site/content/docs/plugins/anonymous.mdx +95 -0
  28. package/site/content/docs/plugins/compression.mdx +2 -2
  29. package/site/content/docs/plugins/cors.mdx +2 -2
  30. package/site/content/docs/plugins/csrf.mdx +2 -2
  31. package/site/content/docs/plugins/email-otp.mdx +111 -0
  32. package/site/content/docs/plugins/{security-headers.mdx → headers.mdx} +2 -2
  33. package/site/content/docs/plugins/index.mdx +69 -0
  34. package/site/content/docs/plugins/ip-allowlist.mdx +1 -2
  35. package/site/content/docs/plugins/magic-link.mdx +112 -0
  36. package/site/content/docs/plugins/maintenance-mode.mdx +8 -8
  37. package/site/content/docs/plugins/meta.json +10 -1
  38. package/site/content/docs/plugins/passkey.mdx +128 -0
  39. package/site/content/docs/plugins/phone-number.mdx +111 -0
  40. package/site/content/docs/plugins/two-factor.mdx +116 -0
  41. package/site/content/docs/plugins/username.mdx +117 -0
  42. package/site/content/docs/reference/client.mdx +331 -0
  43. package/site/content/docs/reference/configuration.mdx +1 -1
  44. package/site/content/docs/reference/environment-variables.mdx +5 -3
  45. package/site/content/docs/reference/fx.mdx +36 -8
  46. package/site/content/docs/reference/index.mdx +45 -0
  47. package/site/content/docs/reference/meta.json +11 -1
  48. package/site/content/docs/reference/plugins.mdx +25 -14
  49. package/src/auth/auth.test.ts +20 -2
  50. package/src/auth/bindings.ts +439 -0
  51. package/src/auth/breach-check.ts +112 -0
  52. package/src/auth/config.ts +288 -0
  53. package/src/auth/cookies.ts +123 -0
  54. package/src/auth/gate-auth.test.ts +379 -0
  55. package/src/auth/identity.ts +190 -0
  56. package/src/auth/index.ts +117 -1
  57. package/src/auth/method-context.ts +33 -0
  58. package/src/auth/operator.ts +27 -1
  59. package/src/auth/password-policy.test.ts +126 -0
  60. package/src/auth/password-policy.ts +77 -0
  61. package/src/auth/plugin.ts +62 -4
  62. package/src/auth/rate.ts +45 -0
  63. package/src/auth/schema.ts +260 -0
  64. package/src/auth/secondary-storage.ts +37 -0
  65. package/src/auth/sessions.ts +58 -1
  66. package/src/auth/tables.ts +4 -0
  67. package/src/auth/verification.ts +78 -0
  68. package/src/cli/competitor-mention-removal.test.ts +117 -0
  69. package/src/cli/dev.test.ts +3 -3
  70. package/src/cli/dev.ts +20 -0
  71. package/src/cli/meilisearch-local.test.ts +69 -0
  72. package/src/cli/meilisearch-local.ts +188 -0
  73. package/src/cli/schema.ts +95 -23
  74. package/src/client/auth.ts +120 -0
  75. package/src/client-react/index.ts +93 -0
  76. package/src/compiler/aot.test.ts +2 -1
  77. package/src/compiler/extract.ts +19 -0
  78. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +5 -1
  79. package/src/compiler/response.ts +16 -2
  80. package/src/console/server/app.ts +10 -6
  81. package/src/console/server/auth-rate.test.ts +3 -3
  82. package/src/console/server/bind.ts +12 -1
  83. package/src/console/server/channels.test.ts +1 -1
  84. package/src/console/server/console-gates.ts +14 -0
  85. package/src/console/server/console.test.ts +6 -6
  86. package/src/console/server/flows-invoke.test.ts +2 -2
  87. package/src/console/server/flows.ts +2 -0
  88. package/src/console/server/gates.ts +8 -1
  89. package/src/console/server/operator-db.test.ts +4 -4
  90. package/src/console/server/operator-db.ts +22 -4
  91. package/src/console/server/security.gate.test.ts +3 -3
  92. package/src/console/server/store.test.ts +1 -1
  93. package/src/console/server/store.ts +11 -1
  94. package/src/console/ui/dist/assets/index-CjxwRGVv.js +10 -0
  95. package/src/console/ui/dist/assets/panel-access-BGv45snf.js +64 -0
  96. package/src/console/ui/dist/assets/{panel-ai-D_m6WQI8.js → panel-ai-B2S7LEii.js} +1 -1
  97. package/src/console/ui/dist/assets/{panel-architecture-CKnXFyUx.js → panel-architecture-D7UJh91v.js} +1 -1
  98. package/src/console/ui/dist/assets/{panel-channels-DCDd4WAC.js → panel-channels-9T3ybqRu.js} +1 -1
  99. package/src/console/ui/dist/assets/panel-clock-Cb1UXGRQ.js +1 -0
  100. package/src/console/ui/dist/assets/{panel-diff-cdonmH8c.js → panel-diff-DmYbKWmN.js} +1 -1
  101. package/src/console/ui/dist/assets/panel-flows-PiHwT55z.js +48 -0
  102. package/src/console/ui/dist/assets/{panel-gates-B5eTE8XH.js → panel-gates-BQGYXvjT.js} +1 -1
  103. package/src/console/ui/dist/assets/panel-overview-BBnRO18l.js +1 -0
  104. package/src/console/ui/dist/assets/{panel-plugins-Cj7DK1er.js → panel-plugins-D0PsmVw2.js} +1 -1
  105. package/src/console/ui/dist/assets/panel-runs-CWuRDe0r.js +1 -0
  106. package/src/console/ui/dist/assets/{panel-signals-whmDXIg3.js → panel-signals-Bbg4ewpP.js} +1 -1
  107. package/src/console/ui/dist/assets/{panel-store-CEMHLvaw.js → panel-store-CPCbsDRa.js} +1 -1
  108. package/src/console/ui/dist/assets/panel-traces-DVAzuA_S.js +1 -0
  109. package/src/console/ui/dist/assets/{panel-vault-C9wjbki8.js → panel-vault-D1_MvOmo.js} +1 -1
  110. package/src/console/ui/dist/assets/{rolldown-runtime-CNC7AqOf.js → rolldown-runtime-B0Z9INg1.js} +1 -1
  111. package/src/console/ui/dist/index.html +2 -2
  112. package/src/console/ui/gates/fixture.ts +4 -0
  113. package/src/console/ui/gates/types.ts +2 -0
  114. package/src/console/ui/shell/client.ts +1 -0
  115. package/src/docker/compose.ts +5 -0
  116. package/src/docker/docker.test.ts +41 -0
  117. package/src/docker/recipes/index.ts +10 -2
  118. package/src/docker/recipes/meilisearch.ts +31 -0
  119. package/src/drivers/conformance.test.ts +16 -1
  120. package/src/drivers/conformance.ts +40 -3
  121. package/src/drivers/index.ts +14 -2
  122. package/src/drivers/libsql.ts +4 -4
  123. package/src/drivers/meilisearch.integration.test.ts +77 -0
  124. package/src/drivers/meilisearch.test.ts +181 -0
  125. package/src/drivers/meilisearch.ts +208 -0
  126. package/src/drivers/memory.ts +4 -4
  127. package/src/drivers/pgvector.ts +6 -6
  128. package/src/drivers/types.ts +93 -12
  129. package/src/drivers/vault-driver-removal.test.ts +6 -0
  130. package/src/drivers/vault-types.ts +4 -4
  131. package/src/elements/ai/runtime.ts +6 -0
  132. package/src/elements/ai.test.ts +22 -0
  133. package/src/elements/gate/boot.ts +136 -0
  134. package/src/elements/gate/config.ts +69 -0
  135. package/src/elements/gate/declare.ts +51 -1
  136. package/src/elements/gate/runtime.ts +3 -1
  137. package/src/elements/gate.test.ts +77 -0
  138. package/src/elements/gate.ts +20 -1
  139. package/src/elements/index.ts +8 -0
  140. package/src/elements/store/index-boot.test.ts +49 -7
  141. package/src/elements/store/runtime.ts +50 -15
  142. package/src/elements/store.ts +2 -0
  143. package/src/elements/vault.test.ts +27 -4
  144. package/src/elements/vault.ts +1 -1
  145. package/src/index.ts +15 -0
  146. package/src/kernel/app.ts +253 -32
  147. package/src/kernel/boot-bind/store.test.ts +9 -0
  148. package/src/kernel/boot-bind/store.ts +30 -2
  149. package/src/kernel/boot.test.ts +40 -3
  150. package/src/kernel/boot.ts +8 -0
  151. package/src/kernel/call.test.ts +46 -2
  152. package/src/kernel/concurrency.test.ts +58 -0
  153. package/src/kernel/concurrency.ts +48 -0
  154. package/src/kernel/edge.test.ts +3 -3
  155. package/src/kernel/flow.test.ts +2 -2
  156. package/src/kernel/fx.test.ts +12 -2
  157. package/src/kernel/fx.ts +97 -5
  158. package/src/kernel/hooks.test.ts +4 -4
  159. package/src/kernel/index.ts +22 -1
  160. package/src/kernel/pipeline.test.ts +12 -8
  161. package/src/kernel/pipeline.ts +23 -4
  162. package/src/kernel/plugin/decorate.test.ts +3 -3
  163. package/src/kernel/plugin/scoping.test.ts +3 -3
  164. package/src/kernel/plugin-elements.test.ts +51 -0
  165. package/src/kernel/plugin-needs.test.ts +83 -0
  166. package/src/kernel/plugin-needs.ts +129 -0
  167. package/src/kernel/plugin.ts +101 -0
  168. package/src/kernel/redacted.ts +74 -0
  169. package/src/kernel/registry-isolation.test.ts +5 -5
  170. package/src/kernel/registry.ts +102 -3
  171. package/src/kernel/router.ts +3 -3
  172. package/src/manifest/types.ts +2 -0
  173. package/src/plugins/anonymous.ts +58 -0
  174. package/src/plugins/auth/shared.ts +121 -0
  175. package/src/plugins/auth-methods.test.ts +176 -0
  176. package/src/plugins/compression.test.ts +5 -5
  177. package/src/plugins/config-source.test.ts +1 -1
  178. package/src/plugins/cors.test.ts +16 -10
  179. package/src/plugins/csrf.test.ts +1 -1
  180. package/src/plugins/email-otp.ts +161 -0
  181. package/src/plugins/index.ts +31 -0
  182. package/src/plugins/ip-allowlist.test.ts +19 -9
  183. package/src/plugins/magic-link.ts +163 -0
  184. package/src/plugins/maintenance-mode.test.ts +9 -5
  185. package/src/plugins/passkey.ts +216 -0
  186. package/src/plugins/phone-number.ts +149 -0
  187. package/src/plugins/security-headers.test.ts +14 -14
  188. package/src/plugins/two-factor.ts +249 -0
  189. package/src/plugins/username.ts +148 -0
  190. package/src/runs/runs.test.ts +6 -2
  191. package/src/runtime/primitives.ts +37 -4
  192. package/src/runtime/serve.test.ts +3 -2
  193. package/src/runtime/types.ts +25 -2
  194. package/src/test/create-test-app.test.ts +1 -1
  195. package/src/test/create-test-app.ts +4 -1
  196. package/src/test/provisions.integration.test.ts +2 -2
  197. package/site/content/docs/get-started/comparison.mdx +0 -65
  198. package/src/console/ui/dist/assets/index-CrKMmO__.js +0 -10
  199. package/src/console/ui/dist/assets/panel-access-C0J2D-a2.js +0 -64
  200. package/src/console/ui/dist/assets/panel-clock-DjGGFPzr.js +0 -1
  201. package/src/console/ui/dist/assets/panel-flows-DlCU5zjA.js +0 -45
  202. package/src/console/ui/dist/assets/panel-overview-BsFvDdts.js +0 -1
  203. package/src/console/ui/dist/assets/panel-runs-C0gmnoYL.js +0 -1
  204. package/src/console/ui/dist/assets/panel-traces-BDiAuVSK.js +0 -1
  205. package/src/drivers/vault-infisical.ts +0 -57
@@ -751,6 +751,7 @@ const GatesListOut = z.object({
751
751
  plane: z.enum(["user", "operator"]),
752
752
  gates: z.array(z.string()),
753
753
  unguarded: z.boolean(),
754
+ explicitPublic: z.boolean(),
754
755
  }),
755
756
  ),
756
757
  gates: z.array(
@@ -2817,6 +2818,7 @@ function createGatesList(state: ConsoleState) {
2817
2818
  plane: f.plane,
2818
2819
  gates: [...f.gates],
2819
2820
  unguarded: f.unguarded,
2821
+ explicitPublic: f.explicitPublic,
2820
2822
  })),
2821
2823
  gates: projection.gates.map((g) => ({
2822
2824
  name: g.name,
@@ -66,8 +66,13 @@ export interface ConsoleFlowGatesRow {
66
66
  readonly flowId: string;
67
67
  readonly plane: "user" | "operator";
68
68
  readonly gates: readonly string[];
69
- /** User-plane with empty chain — public. */
69
+ /**
70
+ * User-plane with empty chain — missing auth posture (boot error when
71
+ * `unguardedHttp: "deny"`). Distinct from {@link explicitPublic}.
72
+ */
70
73
  readonly unguarded: boolean;
74
+ /** Chain includes the reserved `public` sentinel (`gate.public`). */
75
+ readonly explicitPublic: boolean;
71
76
  }
72
77
 
73
78
  /**
@@ -449,11 +454,13 @@ function projectFlows(manifest: Manifest | null): ConsoleFlowGatesRow[] {
449
454
  for (const [flowId, flow] of Object.entries(manifest.flows)) {
450
455
  const plane = flow.plane === "operator" ? "operator" : "user";
451
456
  const gates = [...(flow.gates ?? [])];
457
+ const explicitPublic = gates.includes("public");
452
458
  rows.push({
453
459
  flowId,
454
460
  plane,
455
461
  gates,
456
462
  unguarded: plane === "user" && gates.length === 0,
463
+ explicitPublic,
457
464
  });
458
465
  }
459
466
  return rows.sort((a, b) => a.flowId.localeCompare(b.flowId));
@@ -36,7 +36,7 @@ describe("console operator persistence", () => {
36
36
  const op = await createOperator(first.operators, {
37
37
  email: "ops@example.com",
38
38
  name: "Ops",
39
- password: "password123",
39
+ password: "password1234",
40
40
  });
41
41
  first.persistOperator(op.id);
42
42
  first.close();
@@ -77,7 +77,7 @@ describe("console operator persistence", () => {
77
77
  const op = await createOperator(first.operators, {
78
78
  email: "ops@example.com",
79
79
  name: "Ops",
80
- password: "password123",
80
+ password: "password1234",
81
81
  });
82
82
  first.persistOperator(op.id);
83
83
  const issued = await issueSession(
@@ -120,7 +120,7 @@ describe("console operator persistence", () => {
120
120
  claimCode: first.state.claim.code,
121
121
  email: "ops@example.com",
122
122
  name: "Ops",
123
- password: "password123",
123
+ password: "password1234",
124
124
  }),
125
125
  }),
126
126
  );
@@ -169,7 +169,7 @@ describe("console operator persistence", () => {
169
169
  const op = await createOperator(persistence.operators, {
170
170
  email: "ops@example.com",
171
171
  name: "Ops",
172
- password: "password123",
172
+ password: "password1234",
173
173
  });
174
174
  persistence.persistOperator(op.id);
175
175
 
@@ -157,7 +157,8 @@ export function migrateOperatorSchema(db: Database): void {
157
157
  family_id TEXT NOT NULL,
158
158
  revoked_at INTEGER,
159
159
  created_at INTEGER NOT NULL,
160
- expires_at INTEGER NOT NULL
160
+ expires_at INTEGER NOT NULL,
161
+ last_active_at INTEGER
161
162
  );
162
163
  CREATE TABLE IF NOT EXISTS ${AUTH_TABLES.refreshTokens} (
163
164
  id TEXT PRIMARY KEY NOT NULL,
@@ -169,6 +170,20 @@ export function migrateOperatorSchema(db: Database): void {
169
170
  revoked_at INTEGER
170
171
  );
171
172
  `);
173
+ ensureSessionLastActiveColumn(db);
174
+ }
175
+
176
+ /**
177
+ * Add `last_active_at` when opening an older console.sqlite that predates idle TTL.
178
+ *
179
+ * @param db - Open database
180
+ */
181
+ function ensureSessionLastActiveColumn(db: Database): void {
182
+ const cols = db.query(`PRAGMA table_info(${AUTH_TABLES.sessions})`).all() as Array<{
183
+ name: string;
184
+ }>;
185
+ if (cols.some((c) => c.name === "last_active_at")) return;
186
+ db.exec(`ALTER TABLE ${AUTH_TABLES.sessions} ADD COLUMN last_active_at INTEGER`);
172
187
  }
173
188
 
174
189
  /**
@@ -181,7 +196,7 @@ export function loadSessionStore(db: Database): SessionStore {
181
196
 
182
197
  const sessionRows = db
183
198
  .query(
184
- `SELECT id, plane, principal_id, family_id, revoked_at, created_at, expires_at
199
+ `SELECT id, plane, principal_id, family_id, revoked_at, created_at, expires_at, last_active_at
185
200
  FROM ${AUTH_TABLES.sessions}`,
186
201
  )
187
202
  .all() as Array<{
@@ -192,6 +207,7 @@ export function loadSessionStore(db: Database): SessionStore {
192
207
  revoked_at: number | null;
193
208
  created_at: number;
194
209
  expires_at: number;
210
+ last_active_at: number | null;
195
211
  }>;
196
212
 
197
213
  for (const row of sessionRows) {
@@ -203,6 +219,7 @@ export function loadSessionStore(db: Database): SessionStore {
203
219
  revokedAt: row.revoked_at,
204
220
  createdAt: row.created_at,
205
221
  expiresAt: row.expires_at,
222
+ lastActiveAt: row.last_active_at ?? row.created_at,
206
223
  };
207
224
  store.sessions.set(session.id, session);
208
225
  }
@@ -250,8 +267,8 @@ export function persistSessions(db: Database, store: SessionStore): void {
250
267
 
251
268
  const insertSession = db.query(
252
269
  `INSERT INTO ${AUTH_TABLES.sessions}
253
- (id, plane, principal_id, family_id, revoked_at, created_at, expires_at)
254
- VALUES ($id, $plane, $principal, $family, $revoked, $created, $expires)`,
270
+ (id, plane, principal_id, family_id, revoked_at, created_at, expires_at, last_active_at)
271
+ VALUES ($id, $plane, $principal, $family, $revoked, $created, $expires, $lastActive)`,
255
272
  );
256
273
  for (const session of store.sessions.values()) {
257
274
  insertSession.run({
@@ -262,6 +279,7 @@ export function persistSessions(db: Database, store: SessionStore): void {
262
279
  $revoked: session.revokedAt,
263
280
  $created: session.createdAt,
264
281
  $expires: session.expiresAt,
282
+ $lastActive: session.lastActiveAt,
265
283
  });
266
284
  }
267
285
 
@@ -69,7 +69,7 @@ describe("console security gates (whole surface)", () => {
69
69
  claimCode: handle.state.claim.code,
70
70
  email: "ops@example.com",
71
71
  name: "Ops",
72
- password: "password123",
72
+ password: "password1234",
73
73
  }),
74
74
  }),
75
75
  );
@@ -234,7 +234,7 @@ describe("console security gates (whole surface)", () => {
234
234
  headers: { "content-type": "application/json" },
235
235
  body: JSON.stringify({
236
236
  email: "ops@example.com",
237
- password: "password123",
237
+ password: "password1234",
238
238
  }),
239
239
  }),
240
240
  );
@@ -252,7 +252,7 @@ describe("console security gates (whole surface)", () => {
252
252
  headers: { "content-type": "application/json" },
253
253
  body: JSON.stringify({
254
254
  email: "other@example.com",
255
- password: "password123",
255
+ password: "password1234",
256
256
  }),
257
257
  }),
258
258
  );
@@ -137,7 +137,7 @@ describe("index driver resolution", () => {
137
137
  expect(decl).toBeDefined();
138
138
  const handle = (await runtime.open(decl!, {
139
139
  effects: { reads: ["index:docs"], writes: ["index:docs"] },
140
- })) as import("../../elements/store.ts").IndexStoreFxHandle;
140
+ })) as import("../../elements/store.ts").VectorIndexStoreFxHandle;
141
141
  expect(handle.driverId).toBe("memory");
142
142
  await handle.upsert("d1", [1, 0, 0], { t: 1 });
143
143
  const hits = await handle.search([1, 0, 0], 1);
@@ -329,6 +329,7 @@ export interface StoreQueryInput {
329
329
  readonly prefix?: string;
330
330
  readonly limit?: number;
331
331
  readonly vector?: readonly number[];
332
+ readonly q?: string;
332
333
  readonly topK?: number;
333
334
  readonly revealPii?: boolean;
334
335
  }
@@ -350,6 +351,7 @@ export interface StoreQueryResult {
350
351
  readonly score: number;
351
352
  readonly meta?: Record<string, unknown>;
352
353
  }>;
354
+ readonly facetDistribution?: Record<string, Record<string, number>>;
353
355
  readonly masked: boolean;
354
356
  readonly routedRole?: "primary" | "replica";
355
357
  }
@@ -438,12 +440,20 @@ export async function queryStore(
438
440
 
439
441
  // index
440
442
  const idx = handle as IndexStoreFxHandle;
443
+ void manifest;
444
+ if (idx.driverId === "meilisearch") {
445
+ const q = input.q ?? "";
446
+ if (q.trim().length === 0) {
447
+ return { facet, hits: [], masked: false };
448
+ }
449
+ const result = await idx.search(q, { topK: input.topK ?? 5 });
450
+ return { facet, hits: result.hits, facetDistribution: result.facetDistribution, masked: false };
451
+ }
441
452
  const vector = input.vector ?? [];
442
453
  if (vector.length === 0) {
443
454
  return { facet, hits: [], masked: false };
444
455
  }
445
456
  const hits = await idx.search(vector, input.topK ?? 5);
446
- void manifest;
447
457
  return { facet, hits, masked: false };
448
458
  }
449
459