create-oke 0.2.8 → 0.3.4

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 (142) hide show
  1. package/README.md +11 -32
  2. package/package.json +2 -4
  3. package/src/cli.test.ts +29 -117
  4. package/src/cli.ts +16 -139
  5. package/src/docs-origin.ts +2 -3
  6. package/src/index.ts +1 -2
  7. package/src/scaffold.ts +13 -31
  8. package/src/templates.ts +12 -90
  9. package/src/transform.ts +1 -1
  10. package/template/.env.example +56 -0
  11. package/{templates/standard → template}/README.md +25 -12
  12. package/template/bun.lock +845 -0
  13. package/template/drizzle.config.ts +25 -0
  14. package/{templates/full → template}/oke.config.ts +11 -7
  15. package/{templates/minimal → template}/src/core.ts +1 -1
  16. package/template/src/schema.decl.ts +12 -0
  17. package/examples/linkly/.env.example +0 -15
  18. package/examples/linkly/drizzle.config.ts +0 -11
  19. package/examples/linkly/oke.config.ts +0 -12
  20. package/examples/linkly/package.json +0 -18
  21. package/examples/linkly/src/app.ts +0 -21
  22. package/examples/linkly/src/core.ts +0 -4
  23. package/examples/linkly/src/flows/analytics/index.ts +0 -39
  24. package/examples/linkly/src/flows/links/index.ts +0 -82
  25. package/examples/linkly/src/flows/links/shapes.ts +0 -22
  26. package/examples/linkly/src/flows/links/signals.ts +0 -14
  27. package/examples/linkly/src/gates.ts +0 -10
  28. package/examples/linkly/src/schema.decl.ts +0 -39
  29. package/examples/linkly/src/schema.generated.ts +0 -30
  30. package/examples/linkly/src/schema.ts +0 -2
  31. package/examples/linkly/tests/linkly.test.ts +0 -19
  32. package/examples/notes/.env.example +0 -12
  33. package/examples/notes/drizzle.config.ts +0 -11
  34. package/examples/notes/oke.config.ts +0 -14
  35. package/examples/notes/package.json +0 -19
  36. package/examples/notes/src/app.ts +0 -13
  37. package/examples/notes/src/core.ts +0 -4
  38. package/examples/notes/src/flows/notes/index.ts +0 -58
  39. package/examples/notes/src/schema.ts +0 -9
  40. package/examples/notes/tests/notes.test.ts +0 -10
  41. package/examples/provisions/.env.example +0 -19
  42. package/examples/provisions/drizzle.config.ts +0 -11
  43. package/examples/provisions/oke.config.ts +0 -19
  44. package/examples/provisions/package.json +0 -18
  45. package/examples/provisions/src/app.ts +0 -60
  46. package/examples/provisions/src/channels.ts +0 -15
  47. package/examples/provisions/src/core.ts +0 -4
  48. package/examples/provisions/src/flows/notifications/index.ts +0 -25
  49. package/examples/provisions/src/flows/orders/index.ts +0 -97
  50. package/examples/provisions/src/flows/orders/shapes.ts +0 -21
  51. package/examples/provisions/src/flows/orders/signals.ts +0 -19
  52. package/examples/provisions/src/flows/payments/index.ts +0 -43
  53. package/examples/provisions/src/flows/payments/shapes.ts +0 -3
  54. package/examples/provisions/src/flows/payments/stripe.ts +0 -18
  55. package/examples/provisions/src/gates.ts +0 -4
  56. package/examples/provisions/src/locales/ar.ts +0 -1
  57. package/examples/provisions/src/locales/en.ts +0 -1
  58. package/examples/provisions/src/plugins/audit-schema.ts +0 -2
  59. package/examples/provisions/src/plugins/audit.ts +0 -14
  60. package/examples/provisions/src/schema.ts +0 -16
  61. package/examples/provisions/src/vault.ts +0 -16
  62. package/examples/provisions/tests/orders.test.ts +0 -19
  63. package/examples/skyport/.env.example +0 -34
  64. package/examples/skyport/drizzle.config.ts +0 -11
  65. package/examples/skyport/evals/triage.jsonl +0 -1
  66. package/examples/skyport/oke.config.ts +0 -47
  67. package/examples/skyport/oke.images.lock +0 -4
  68. package/examples/skyport/package.json +0 -19
  69. package/examples/skyport/src/ai.ts +0 -25
  70. package/examples/skyport/src/app.ts +0 -46
  71. package/examples/skyport/src/channels.ts +0 -12
  72. package/examples/skyport/src/core.ts +0 -4
  73. package/examples/skyport/src/flows/bookings/index.ts +0 -73
  74. package/examples/skyport/src/flows/bookings/shapes.ts +0 -6
  75. package/examples/skyport/src/flows/bookings/signals.ts +0 -13
  76. package/examples/skyport/src/flows/notifications/index.ts +0 -16
  77. package/examples/skyport/src/flows/payments/index.ts +0 -14
  78. package/examples/skyport/src/flows/payments/shapes.ts +0 -5
  79. package/examples/skyport/src/flows/support/index.ts +0 -50
  80. package/examples/skyport/src/flows/users/elements.ts +0 -2
  81. package/examples/skyport/src/flows/users/index.ts +0 -12
  82. package/examples/skyport/src/flows/users/shapes.ts +0 -6
  83. package/examples/skyport/src/gates.ts +0 -10
  84. package/examples/skyport/src/journeys.ts +0 -9
  85. package/examples/skyport/src/locales/ar.ts +0 -4
  86. package/examples/skyport/src/locales/en.ts +0 -4
  87. package/examples/skyport/src/plugins/audit-schema.ts +0 -7
  88. package/examples/skyport/src/plugins/audit.ts +0 -14
  89. package/examples/skyport/src/plugins/panel.tsx +0 -4
  90. package/examples/skyport/src/schema.ts +0 -25
  91. package/examples/skyport/src/vault.ts +0 -24
  92. package/examples/skyport/tests/support.test.ts +0 -16
  93. package/src/sync-templates.ts +0 -77
  94. package/templates/full/.env.example +0 -24
  95. package/templates/full/README.md +0 -65
  96. package/templates/full/drizzle.config.ts +0 -14
  97. package/templates/full/package.json +0 -18
  98. package/templates/full/src/ai.ts +0 -11
  99. package/templates/full/src/app.ts +0 -34
  100. package/templates/full/src/channels.ts +0 -9
  101. package/templates/full/src/core.ts +0 -4
  102. package/templates/full/src/flows/main/index.ts +0 -45
  103. package/templates/full/src/flows/main/shapes.ts +0 -3
  104. package/templates/full/src/flows/main/signals.ts +0 -8
  105. package/templates/full/src/gates.ts +0 -4
  106. package/templates/full/src/locales/ar.ts +0 -3
  107. package/templates/full/src/locales/en.ts +0 -3
  108. package/templates/full/src/schema.ts +0 -8
  109. package/templates/full/src/vault.ts +0 -9
  110. package/templates/full/tests/full.test.ts +0 -11
  111. package/templates/hello/.env.example +0 -9
  112. package/templates/hello/README.md +0 -40
  113. package/templates/hello/oke.config.ts +0 -3
  114. package/templates/hello/package.json +0 -14
  115. package/templates/hello/src/app.ts +0 -10
  116. package/templates/hello/src/flows/hello/index.ts +0 -27
  117. package/templates/hello/tests/hello.test.ts +0 -10
  118. package/templates/minimal/.env.example +0 -13
  119. package/templates/minimal/README.md +0 -49
  120. package/templates/minimal/drizzle.config.ts +0 -14
  121. package/templates/minimal/oke.config.ts +0 -14
  122. package/templates/minimal/package.json +0 -18
  123. package/templates/minimal/src/app.ts +0 -13
  124. package/templates/minimal/src/flows/main/index.ts +0 -49
  125. package/templates/minimal/src/schema.ts +0 -8
  126. package/templates/minimal/tests/minimal.test.ts +0 -13
  127. package/templates/standard/.env.example +0 -21
  128. package/templates/standard/drizzle.config.ts +0 -14
  129. package/templates/standard/oke.config.ts +0 -51
  130. package/templates/standard/src/core.ts +0 -4
  131. package/templates/standard/src/schema.ts +0 -9
  132. /package/{templates/standard → template}/package.json +0 -0
  133. /package/{templates/standard → template}/src/app.ts +0 -0
  134. /package/{templates/standard → template}/src/channels.ts +0 -0
  135. /package/{templates/standard → template}/src/flows/main/index.ts +0 -0
  136. /package/{templates/standard → template}/src/flows/main/shapes.ts +0 -0
  137. /package/{templates/standard → template}/src/flows/main/signals.ts +0 -0
  138. /package/{templates/standard → template}/src/gates.ts +0 -0
  139. /package/{templates/standard → template}/src/locales/ar.ts +0 -0
  140. /package/{templates/standard → template}/src/locales/en.ts +0 -0
  141. /package/{templates/standard → template}/src/vault.ts +0 -0
  142. /package/{templates/standard → template}/tests/standard.test.ts +0 -0
package/src/index.ts CHANGED
@@ -5,8 +5,7 @@
5
5
  * ```bash
6
6
  * bunx create-oke@latest my-app
7
7
  * bunx create-oke@latest my-app --yes
8
- * bunx create-oke@latest my-app --template hello
9
- * bunx create-oke@latest my-app --from-example notes
8
+ * bunx create-oke@latest my-app --template standard
10
9
  * ```
11
10
  *
12
11
  * @module
package/src/scaffold.ts CHANGED
@@ -13,13 +13,7 @@ import {
13
13
  writeFileSync,
14
14
  } from "node:fs";
15
15
  import { join, relative, resolve } from "node:path";
16
- import {
17
- resolveExampleDir,
18
- resolveLocalOkengineRoot,
19
- resolveTemplateDir,
20
- type ExampleId,
21
- type TemplateId,
22
- } from "./templates.ts";
16
+ import { resolveLocalOkengineRoot, resolveTemplateDir, type TemplateId } from "./templates.ts";
23
17
  import { agentsMdContent } from "./agents-md.ts";
24
18
  import {
25
19
  DEFAULT_SQL_DRIVER,
@@ -27,16 +21,13 @@ import {
27
21
  shouldSkipTemplatePath,
28
22
  transformConfigForSqlDriver,
29
23
  transformPackageJson,
30
- transformSchemaForSqlDriver,
31
24
  resolveOkengineDependency,
32
25
  type ScaffoldPackageJson,
33
26
  type SqlDriverId,
34
27
  } from "./transform.ts";
35
28
 
36
- /** Where the scaffold copies from. */
37
- export type ScaffoldSource =
38
- | { readonly kind: "template"; readonly id: TemplateId }
39
- | { readonly kind: "example"; readonly id: ExampleId };
29
+ /** The bundled starter copied by the scaffold. */
30
+ export type ScaffoldSource = { readonly kind: "template"; readonly id: TemplateId };
40
31
 
41
32
  /** Options for {@link scaffold}. */
42
33
  export type ScaffoldOptions = {
@@ -44,14 +35,13 @@ export type ScaffoldOptions = {
44
35
  readonly targetDir: string;
45
36
  /** npm package / folder name. */
46
37
  readonly name: string;
47
- /** Template or teaching-example source. */
38
+ /** Starter template source. */
48
39
  readonly source: ScaffoldSource;
49
40
  /** Write root `AGENTS.md` (default true). */
50
41
  readonly writeAgentsMd?: boolean;
51
42
  /**
52
- * Store SQL driver — rewrites `src/schema.ts` dialect and pins
53
- * `oke.config.ts` `store.sql` local/docker/prod when `postgres`.
54
- * Default `sqlite`.
43
+ * Store SQL driver — pins `oke.config.ts` `store.sql` local/docker/prod
44
+ * when `postgres`. Default `sqlite` keeps the dual-mode config.
55
45
  */
56
46
  readonly sqlDriver?: SqlDriverId;
57
47
  };
@@ -71,17 +61,14 @@ export type ScaffoldResult = {
71
61
  };
72
62
 
73
63
  /**
74
- * Scaffold a new okengine project from a clean template or teaching example.
64
+ * Scaffold a new okengine project from the standard template.
75
65
  *
76
66
  * @param options - Name, source, destination
77
67
  */
78
68
  export function scaffold(options: ScaffoldOptions): ScaffoldResult {
79
69
  const name = sanitizeProjectName(options.name);
80
70
  const targetDir = resolve(options.targetDir);
81
- const sourceDir =
82
- options.source.kind === "template"
83
- ? resolveTemplateDir(options.source.id)
84
- : resolveExampleDir(options.source.id);
71
+ const sourceDir = resolveTemplateDir(options.source.id);
85
72
  const label = options.source.id;
86
73
  const sqlDriver = options.sqlDriver ?? DEFAULT_SQL_DRIVER;
87
74
 
@@ -140,22 +127,17 @@ export function scaffold(options: ScaffoldOptions): ScaffoldResult {
140
127
  }
141
128
 
142
129
  /**
143
- * Rewrite schema dialect + (for postgres) `store.sql` pins.
130
+ * For postgres, pin `store.sql` local/docker/prod in `oke.config.ts`.
144
131
  *
145
- * `sqlite` keeps the template dual-mode config (`local: sqlite` ·
146
- * `docker`/`prod: postgres`) only the Drizzle dialect is ensured.
147
- * `postgres` writes `pgTable` and pins local/docker/prod to postgres.
132
+ * The default template ships abstract `src/schema.decl.ts` — dialect is
133
+ * emitted from the active `store.sql` driver, so there is no hand-written
134
+ * `sqliteTable`/`pgTable` source to rewrite. `sqlite` keeps the template
135
+ * dual-mode config (`local: sqlite` · `docker`/`prod: postgres`) untouched.
148
136
  *
149
137
  * @param targetDir - Scaffolded project root
150
138
  * @param sqlDriver - Chosen store.sql driver
151
139
  */
152
140
  function applySqlDriverTransforms(targetDir: string, sqlDriver: SqlDriverId): void {
153
- const schemaPath = join(targetDir, "src/schema.ts");
154
- if (existsSync(schemaPath)) {
155
- const next = transformSchemaForSqlDriver(readFileSync(schemaPath, "utf8"), sqlDriver);
156
- writeFileSync(schemaPath, next, "utf8");
157
- }
158
-
159
141
  if (sqlDriver !== "postgres") return;
160
142
 
161
143
  const configPath = join(targetDir, "oke.config.ts");
package/src/templates.ts CHANGED
@@ -1,17 +1,15 @@
1
1
  /**
2
- * Template / example ids and resolution.
2
+ * Standard template resolution.
3
3
  *
4
- * Clean starters live in repo-root `templates/<id>`.
5
- * Teaching apps live in repo-root `examples/<id>` (`--from-example`).
6
- * Published installs use the prepack copies under this package.
4
+ * The only starter lives in this package at `template/`.
7
5
  */
8
6
 
9
7
  import { existsSync, readFileSync } from "node:fs";
10
8
  import { dirname, join, resolve } from "node:path";
11
9
  import { fileURLToPath } from "node:url";
12
10
 
13
- /** Clean starter template ids — match repo-root `templates/*`. */
14
- export const TEMPLATES = ["hello", "minimal", "standard", "full"] as const;
11
+ /** The single supported starter template. */
12
+ export const TEMPLATES = ["standard"] as const;
15
13
 
16
14
  /** A known clean starter template. */
17
15
  export type TemplateId = (typeof TEMPLATES)[number];
@@ -19,32 +17,9 @@ export type TemplateId = (typeof TEMPLATES)[number];
19
17
  /** Default when `--template` is omitted (recommended project layout). */
20
18
  export const DEFAULT_TEMPLATE: TemplateId = "standard";
21
19
 
22
- /** One-line purpose for each clean template (interactive select + help). */
20
+ /** One-line purpose for the starter (interactive select + help). */
23
21
  export const TEMPLATE_PURPOSES: Readonly<Record<TemplateId, string>> = {
24
- hello: 'Fastest possible "it works" — one flow, no Store',
25
- minimal: "Smallest shape you'd actually ship — Store + 1–2 flows",
26
22
  standard: "Full recommended file layout, empty scaffolding",
27
- full: "Every element present and wired, no business logic",
28
- };
29
-
30
- /** Teaching example ids — match `examples/*` and four-applications.md. */
31
- export const EXAMPLES = ["notes", "linkly", "provisions", "skyport"] as const;
32
-
33
- /** A known teaching example. */
34
- export type ExampleId = (typeof EXAMPLES)[number];
35
-
36
- /**
37
- * "New ideas" one-liners from four-applications.md — reused for
38
- * `--from-example` help and the interactive example select.
39
- */
40
- export const EXAMPLE_NEW_IDEAS: Readonly<Record<ExampleId, string>> = {
41
- notes: "`oke`, `on`, `flow`, `http`, `store.sql`, `fx`, typed errors, the typed client.",
42
- linkly:
43
- "`signal` and its three delivery physics · `clock` · `gate` · triggers beyond HTTP · transactional emit · cross-unit decoupling.",
44
- provisions:
45
- "`durable` flows and the journal · `vault` · `channel` with fallback chains and i18n · live queries · plugins · a CDC trigger · the three cache tiers.",
46
- skyport:
47
- "the `ai` element (models, prompts, RAG, agents) · multi-tenancy · SLOs and journeys · distributed topology · the three scaling axes.",
48
23
  };
49
24
 
50
25
  /**
@@ -56,15 +31,6 @@ export function isTemplateId(value: string): value is TemplateId {
56
31
  return (TEMPLATES as readonly string[]).includes(value);
57
32
  }
58
33
 
59
- /**
60
- * Whether `value` is a known {@link ExampleId}.
61
- *
62
- * @param value - Candidate string
63
- */
64
- export function isExampleId(value: string): value is ExampleId {
65
- return (EXAMPLES as readonly string[]).includes(value);
66
- }
67
-
68
34
  /**
69
35
  * Directory that contains this package (`packages/create-oke`).
70
36
  */
@@ -73,67 +39,23 @@ export function packageRoot(): string {
73
39
  }
74
40
 
75
41
  /**
76
- * Resolve the directory to copy for a clean `--template`.
42
+ * Resolve the directory to copy for the starter.
77
43
  *
78
44
  * Order:
79
- * 1. `CREATE_OKE_TEMPLATES` env (absolute path to a `templates/` tree)
80
- * 2. Monorepo `templates/<template>` (two levels up from this package)
81
- * 3. Bundled `templates/<template>` (npm prepack copy)
45
+ * 1. `CREATE_OKE_TEMPLATE` env (absolute path to a template)
46
+ * 2. Bundled `template/`
82
47
  *
83
48
  * @param template - Template id
84
49
  * @returns Absolute path to the template source tree
85
50
  */
86
51
  export function resolveTemplateDir(template: TemplateId): string {
87
- const envRoot = process.env["CREATE_OKE_TEMPLATES"];
88
- if (envRoot) {
89
- const fromEnv = resolve(envRoot, template);
90
- if (existsSync(fromEnv)) return fromEnv;
91
- }
92
-
52
+ const envRoot = process.env["CREATE_OKE_TEMPLATE"];
53
+ if (envRoot && existsSync(envRoot)) return resolve(envRoot);
93
54
  const pkg = packageRoot();
94
- const monorepo = resolve(pkg, "../../templates", template);
95
- if (existsSync(monorepo)) return monorepo;
96
-
97
- const bundled = resolve(pkg, "templates", template);
98
- if (existsSync(bundled)) return bundled;
99
-
100
- throw new Error(
101
- `create-oke: template "${template}" not found.\n` +
102
- ` looked at: ${monorepo}\n` +
103
- ` ${bundled}`,
104
- );
105
- }
106
-
107
- /**
108
- * Resolve the directory to copy for `--from-example`.
109
- *
110
- * Order:
111
- * 1. `CREATE_OKE_EXAMPLES` env (absolute path to an `examples/` tree)
112
- * 2. Monorepo `examples/<example>` (two levels up from this package)
113
- * 3. Bundled `examples/<example>` (npm prepack copy)
114
- *
115
- * @param example - Example id
116
- * @returns Absolute path to the example source tree
117
- */
118
- export function resolveExampleDir(example: ExampleId): string {
119
- const envRoot = process.env["CREATE_OKE_EXAMPLES"];
120
- if (envRoot) {
121
- const fromEnv = resolve(envRoot, example);
122
- if (existsSync(fromEnv)) return fromEnv;
123
- }
124
-
125
- const pkg = packageRoot();
126
- const monorepo = resolve(pkg, "../../examples", example);
127
- if (existsSync(monorepo)) return monorepo;
128
-
129
- const bundled = resolve(pkg, "examples", example);
55
+ const bundled = resolve(pkg, "template");
130
56
  if (existsSync(bundled)) return bundled;
131
57
 
132
- throw new Error(
133
- `create-oke: example "${example}" not found.\n` +
134
- ` looked at: ${monorepo}\n` +
135
- ` ${bundled}`,
136
- );
58
+ throw new Error(`create-oke: template "${template}" not found at ${bundled}`);
137
59
  }
138
60
 
139
61
  /**
package/src/transform.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Rewrites applied when copying a `templates/<id>` or `examples/<id>` tree
2
+ * Rewrites applied when copying the bundled starter
3
3
  * into a new project.
4
4
  *
5
5
  * Exactly:
@@ -0,0 +1,56 @@
1
+ # Environment template — copy to `.env.local` for local overrides.
2
+ # create-oke copies this file to `.env.local` when you scaffold a new project.
3
+ #
4
+ # Resolution order (first hit wins):
5
+ # process.env → .env.local → docker/.env.docker → vault driver → dev fallback
6
+ #
7
+ # --- Vault (app secrets) ---
8
+ # Declare secrets in src/vault.ts with `vault.secret(...)`, then uncomment lines here.
9
+ #
10
+ # --- Infrastructure ---
11
+ # Same keys as `docker/.env.docker` after `oke dev --docker`.
12
+ # Uncomment to override compose credentials for a host-managed service.
13
+ # Host ports under docker mode are unique per project — do not assume defaults.
14
+
15
+ # ── channel.email — Mailpit (SMTP + UI) ─────────────────────
16
+ # OKE_CHANNEL_EMAIL_URL=smtp://127.0.0.1:1025
17
+ # SMTP_URL=smtp://127.0.0.1:1025
18
+ # SMTP_HOST=127.0.0.1
19
+ # SMTP_PORT=1025
20
+ # MAILPIT_UI_URL=http://127.0.0.1:8025
21
+ # Optional controls:
22
+ # SMTP_USER=
23
+ # SMTP_PASSWORD=
24
+ # MP_MAX_MESSAGES=500
25
+ # MP_SMTP_AUTH_ACCEPT_ANY=1
26
+ # MP_SMTP_AUTH_ALLOW_INSECURE=1
27
+
28
+ # ── store.files — object storage (S3) ───────────────────────
29
+ # OKE_STORE_FILES_URL=http://access-key:secret-key@127.0.0.1:9000/oke
30
+ # S3_ACCESS_KEY_ID=access-key
31
+ # S3_SECRET_ACCESS_KEY=secret-key
32
+ # S3_BUCKET=oke
33
+ # S3_URL=http://access-key:secret-key@127.0.0.1:9000/oke
34
+ # S3_ENDPOINT=http://127.0.0.1:9000
35
+ # S3_CONSOLE_URL=http://127.0.0.1:9001
36
+ # S3_REGION=us-east-1
37
+ # Optional controls:
38
+ # S3_SESSION_TOKEN=
39
+
40
+ # ── store.kv — Redis ────────────────────────────────────────
41
+ # OKE_STORE_KV_PASSWORD=password
42
+ # OKE_STORE_KV_URL=redis://:password@127.0.0.1:6379
43
+ # REDIS_URL=redis://:password@127.0.0.1:6379
44
+ # Optional controls:
45
+ # OKE_STORE_KV_MAXMEMORY=256mb
46
+ # OKE_STORE_KV_MAXMEMORY_POLICY=allkeys-lru
47
+
48
+ # ── store.sql — Postgres ────────────────────────────────────
49
+ # OKE_STORE_SQL_USER=oke
50
+ # OKE_STORE_SQL_PASSWORD=password
51
+ # OKE_STORE_SQL_DB=oke
52
+ # OKE_STORE_SQL_URL=postgres://oke:password@127.0.0.1:5432/oke
53
+ # DATABASE_URL=postgres://oke:password@127.0.0.1:5432/oke
54
+ # Optional controls:
55
+ # PGDATA=/var/lib/postgresql/data/pgdata
56
+ # POSTGRES_INITDB_ARGS=--data-checksums
@@ -8,10 +8,10 @@ business logic. Default `create-oke` template.
8
8
  ```bash
9
9
  bun install
10
10
  oke dev # app :6530 · Console :6533 · MCP :6535
11
- # or: oke mode docker && oke dev # postgres · redis · Mailpit · RustFS · sops
11
+ # or: oke mode docker && oke dev # postgres · redis · Mailpit · RustFS · OpenBao
12
12
  ```
13
13
 
14
- Local `oke dev` auto-runs `oke db push` when `schema.ts` changes (opt out:
14
+ Local `oke dev` auto-runs `oke db push` when `schema.decl.ts` changes (opt out:
15
15
  `--no-db-push`). Docker/prod never auto-apply DDL — use `oke db migrate`.
16
16
 
17
17
  | Port | Try |
@@ -29,7 +29,7 @@ standard/
29
29
  ├── oke.config.ts # local: sqlite · docker/prod: postgres
30
30
  ├── src/
31
31
  │ ├── app.ts # adopt({ main }); wires stores + side modules
32
- │ ├── core.ts / schema.ts # Store (replace the placeholder table)
32
+ │ ├── core.ts / schema.decl.ts # Store (replace the placeholder table)
33
33
  │ ├── gates.ts # Gate stubs
34
34
  │ ├── vault.ts # Vault stubs
35
35
  │ ├── channels.ts # Channel stubs
@@ -45,20 +45,33 @@ standard/
45
45
  - **Unit:** `main`
46
46
  - **Flows to replace:** `root`, `health` — delete or rename once your domain exists
47
47
 
48
- Fill `schema.ts` (or `schema.decl.ts` + `oke db`), then add real flows under
49
- `src/flows/<unit>/`. Prefer this layout for new products; use `hello` / `minimal`
50
- only when you want less surface.
48
+ Fill `schema.decl.ts` (abstract tables `oke db` emits `schema.generated.ts`
49
+ for the active dialect), then add real flows under
50
+ `src/flows/<unit>/`.
51
51
 
52
52
  ## Docker mode (`oke dev --docker`)
53
53
 
54
54
  Closest to production protocols: Postgres, Redis, SMTP (Mailpit), S3 (RustFS),
55
- vault `sops`/age. Compose credentials land in `docker/.env.docker`.
55
+ and a real OpenBao vault (durable Raft storage, real init/unseal — not a
56
+ `-dev` server). Compose credentials land in `docker/.env.docker`.
56
57
 
57
- | Surface | URL |
58
- | -------------- | ------------------------------------------------ |
59
- | Mailpit UI | [http://127.0.0.1:8025](http://127.0.0.1:8025) |
60
- | RustFS console | [http://127.0.0.1:9001](http://127.0.0.1:9001) |
58
+ On first `oke dev --docker` / `oke docker --prod` bring-up, `oke` initializes
59
+ OpenBao, unseals it, and mints a least-privilege token for the app. The root
60
+ token and the single unseal key stay on the host under `.oke/openbao/`
61
+ (`0600`, gitignored) never in `docker/.env.docker`, never in YAML.
62
+
63
+ > **Single point of failure by design:** back up `.oke/openbao/unseal.key` to
64
+ > a separate safe location. Losing it means losing every secret permanently,
65
+ > with no recovery.
66
+
67
+ Host ports are unique per project so multiple apps can run at once. Use
68
+ `oke stack` or the `oke dev` Docker summary for the Mailpit UI and RustFS
69
+ console URLs — do not assume `:8025` / `:9001`.
70
+
71
+ `docker/.env.docker` uses protocol-native keys (`DATABASE_URL`, `REDIS_URL`,
72
+ `S3_*`, `SMTP_*`, `MAILPIT_UI_URL`) and includes commented optional controls.
73
+ Supported controls you uncomment are preserved when the generated stack refreshes.
61
74
 
62
75
  ## Agent contract
63
76
 
64
- See [`AGENTS.md`](./AGENTS.md). Handbook: [okengine.vercel.app/docs](https://okengine.vercel.app/docs)
77
+ See [`AGENTS.md`](./AGENTS.md). Handbook: [oke.omqkhafi.dev/docs](https://oke.omqkhafi.dev/docs)