mythik 0.2.0 → 0.2.1
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 +68 -44
- package/dist/actions/dispatcher.d.ts +2 -0
- package/dist/actions/dispatcher.d.ts.map +1 -1
- package/dist/actions/dispatcher.js +11 -2
- package/dist/actions/dispatcher.js.map +1 -1
- package/dist/contract/extractor.js +3 -0
- package/dist/contract/extractor.js.map +1 -1
- package/dist/data/data-sources.d.ts +4 -0
- package/dist/data/data-sources.d.ts.map +1 -1
- package/dist/data/data-sources.js +3 -1
- package/dist/data/data-sources.js.map +1 -1
- package/dist/editor-session/engine.d.ts +1 -0
- package/dist/editor-session/engine.d.ts.map +1 -1
- package/dist/editor-session/engine.js +5 -4
- package/dist/editor-session/engine.js.map +1 -1
- package/dist/fetch/framework-fetch.d.ts +1 -0
- package/dist/fetch/framework-fetch.d.ts.map +1 -1
- package/dist/fetch/framework-fetch.js +34 -4
- package/dist/fetch/framework-fetch.js.map +1 -1
- package/dist/fetch/interceptors/auth.d.ts +2 -0
- package/dist/fetch/interceptors/auth.d.ts.map +1 -1
- package/dist/fetch/interceptors/auth.js +31 -2
- package/dist/fetch/interceptors/auth.js.map +1 -1
- package/dist/fetch/types.d.ts +4 -0
- package/dist/fetch/types.d.ts.map +1 -1
- package/dist/renderer/engine.d.ts.map +1 -1
- package/dist/renderer/engine.js +29 -4
- package/dist/renderer/engine.js.map +1 -1
- package/dist/renderer/prop-schemas.d.ts +5 -0
- package/dist/renderer/prop-schemas.d.ts.map +1 -1
- package/dist/renderer/prop-schemas.js +11 -2
- package/dist/renderer/prop-schemas.js.map +1 -1
- package/dist/runtime/mount-spec-runtime.d.ts +2 -0
- package/dist/runtime/mount-spec-runtime.d.ts.map +1 -1
- package/dist/runtime/mount-spec-runtime.js +4 -1
- package/dist/runtime/mount-spec-runtime.js.map +1 -1
- package/dist/security/spec-validator.d.ts.map +1 -1
- package/dist/security/spec-validator.js +61 -0
- package/dist/security/spec-validator.js.map +1 -1
- package/dist/spec-stores/file.js +1 -1
- package/dist/spec-stores/file.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/consumer/ai-context-patterns.md +42 -7
- package/docs/consumer/ai-context-primitives.md +25 -2
- package/docs/consumer/ai-context-runtime-semantics.md +36 -26
- package/docs/consumer/ai-context.md +57 -38
- package/docs/consumer/reference-doc.md +97 -59
- package/docs/wiki/compiled/concept-component-variants.md +39 -10
- package/docs/wiki/compiled/concept-templates-vs-variants.md +77 -13
- package/docs/wiki/compiled/pattern-reusable-components.md +42 -12
- package/package.json +1 -1
|
@@ -88,7 +88,7 @@ Every screen is a flat tree: `root` ID + `elements` map + optional `initialActio
|
|
|
88
88
|
| `style` | object | CSS styles (can contain expressions) |
|
|
89
89
|
| `visible` | expression | Show/hide condition |
|
|
90
90
|
| `permission` | object | `{ visible, editable, readonly }` per role |
|
|
91
|
-
| `repeat` | object | Iterate over array: `{ statePath, key }` or `{ source, key }` |
|
|
91
|
+
| `repeat` | object | Iterate over array: `{ statePath, key }` or `{ source, key }`; optional `layout` controls item row direction/gap/wrap |
|
|
92
92
|
| `on` | object | Event handlers: `{ press, change, submit }` |
|
|
93
93
|
| `hover` | object | Style overrides on pointer enter |
|
|
94
94
|
| `active` | object | Style overrides on press |
|
|
@@ -108,17 +108,17 @@ mythik init-store --dialect postgres --dry-run # Print SQL store DDL f
|
|
|
108
108
|
mythik init-store --dialect sqlserver --server localhost --database Mythik --user "$DB_USER" --password "$DB_PASSWORD" --encrypt false --trust-server-certificate
|
|
109
109
|
mythik manifest <screen> # See structural tree
|
|
110
110
|
mythik elements <screen> <id1,id2> # Get element details
|
|
111
|
-
mythik patch <screen> --from-file patch.json --author <agent> # Apply versioned RFC 6902 patches
|
|
112
|
-
mythik pull <screen> # Export full spec for backup/review
|
|
113
|
-
mythik push <screen> --from-file spec.json --author <agent> # Create a new spec
|
|
114
|
-
mythik push <screen> --from-file spec.json --replace --author <agent> # Intentional full replacement
|
|
115
|
-
mythik validate <screen> # Validate spec
|
|
116
|
-
mythik reveal start # Start local runtime context bridge
|
|
117
|
-
mythik reveal apps --json # List connected running apps
|
|
118
|
-
mythik reveal context --app <name> # Read live app contract/state/diagnostics
|
|
119
|
-
mythik reveal element <id> --app <name> # Inspect one live element
|
|
120
|
-
mythik agent init codex|claude|all # Install project-local AI operating protocol
|
|
121
|
-
mythik agent context --app <app-id> --include-screens --out .mythik/agent/context.md
|
|
111
|
+
mythik patch <screen> --from-file patch.json --author <agent> # Apply versioned RFC 6902 patches
|
|
112
|
+
mythik pull <screen> # Export full spec for backup/review
|
|
113
|
+
mythik push <screen> --from-file spec.json --author <agent> # Create a new spec
|
|
114
|
+
mythik push <screen> --from-file spec.json --replace --author <agent> # Intentional full replacement
|
|
115
|
+
mythik validate <screen> # Validate spec
|
|
116
|
+
mythik reveal start # Start local runtime context bridge
|
|
117
|
+
mythik reveal apps --json # List connected running apps
|
|
118
|
+
mythik reveal context --app <name> # Read live app contract/state/diagnostics
|
|
119
|
+
mythik reveal element <id> --app <name> # Inspect one live element
|
|
120
|
+
mythik agent init codex|claude|all # Install project-local AI operating protocol
|
|
121
|
+
mythik agent context --app <app-id> --include-screens --out .mythik/agent/context.md
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
### Required edit loop for existing specs
|
|
@@ -128,15 +128,17 @@ When an AI agent modifies an existing Mythik spec, use this loop by default:
|
|
|
128
128
|
1. `mythik manifest <screen>` - inspect the current structure and identify candidate element IDs.
|
|
129
129
|
2. `mythik elements <screen> <id1,id2,...>` - inspect only the exact elements and nearby containers that will change.
|
|
130
130
|
3. Write a small RFC 6902 patch file.
|
|
131
|
-
4. `mythik patch <screen> --from-file patch.json --author <agent>` - apply the surgical change through the validated, versioned CLI path.
|
|
132
|
-
5. Run `mythik validate <screen>`.
|
|
133
|
-
6. Re-run `mythik manifest <screen>` or `mythik elements <screen> <ids>` to verify the changed surface.
|
|
134
|
-
|
|
135
|
-
Do not edit database rows directly, do not call `SpecStore.save()` from app code, and do not replace a whole screen with `push` when a targeted `patch` can express the change. `pull` is for backup, migration, review, or full-spec creation workflows; it is not the normal first step for a small edit.
|
|
131
|
+
4. `mythik patch <screen> --from-file patch.json --author <agent>` - apply the surgical change through the validated, versioned CLI path.
|
|
132
|
+
5. Run `mythik validate <screen>`.
|
|
133
|
+
6. Re-run `mythik manifest <screen>` or `mythik elements <screen> <ids>` to verify the changed surface.
|
|
134
|
+
|
|
135
|
+
Do not edit database rows directly, do not call `SpecStore.save()` from app code, and do not replace a whole screen with `push` when a targeted `patch` can express the change. `pull` is for backup, migration, review, or full-spec creation workflows; it is not the normal first step for a small edit.
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
Mythik Sentinel is built into the CLI to help fresh agents stay on that loop. It prints advisory guidance on first project use and when it detects repeated full-replacement intent with little/no patch usage. Sentinel is best-effort: it does not change command exit codes, it does not store specs or credentials, and it preserves JSON/TOON machine-readable outputs. Disable only for exceptional automation with `MYTHIK_SENTINEL=off`.
|
|
138
138
|
|
|
139
|
-
**Patch
|
|
139
|
+
**Patch rules:** `"op": "add"` with numeric index **inserts before** (not replace). Use `/-` to append. Use `"op": "replace"` to overwrite. Prefer `mythik patch <id> --from-file patch.json --author <agent>` for any patch containing `$state`, `$template`, `$auth`, or other shell-sensitive strings.
|
|
140
|
+
|
|
141
|
+
**Patch input precedence:** explicit sources win. `--from-file <path>` reads that file even if the host process has non-TTY stdin (common in PowerShell/agent runners). Stdin still works via `--from-file -` or by piping without `--from-file`: `cat patch.json | mythik patch <id> --author <agent>`.
|
|
140
142
|
|
|
141
143
|
All commands accept `--json`, `--table <name>`, `--store`, `--url`, `--key`. Never pass API keys inline — use `.mythikrc` + env vars.
|
|
142
144
|
|
|
@@ -197,7 +199,7 @@ should ask Reveal before proposing a patch.
|
|
|
197
199
|
|
|
198
200
|
### CLI store configuration
|
|
199
201
|
|
|
200
|
-
The CLI can read and write specs from `memory`, `file`, `supabase`, `sqlserver`, `postgres`, `mysql`, and `sqlite` stores. SQL stores share the same commands and the same required edit loop: `manifest -> elements -> patch --from-file --author -> validate -> verify`.
|
|
202
|
+
The CLI can read and write specs from `memory`, `file`, `supabase`, `sqlserver`, `postgres`, `mysql`, and `sqlite` stores. SQL stores share the same commands and the same required edit loop: `manifest -> elements -> patch --from-file --author -> validate -> verify`.
|
|
201
203
|
|
|
202
204
|
```bash
|
|
203
205
|
# SQLite: local development, tests, demos, lightweight deployments
|
|
@@ -229,13 +231,13 @@ Environment equivalents: `MYTHIK_STORE`, `MYTHIK_DATABASE_URL`, `MYTHIK_SQLITE_F
|
|
|
229
231
|
|
|
230
232
|
Per reference-doc rule 248: three approved forms.
|
|
231
233
|
|
|
232
|
-
- **Shell**: `mythik push <id> --from-file spec.json --author <agent>` and `mythik patch <id> --from-file patch.json --author <agent>` (cross-shell ergonomic for any spec/patch containing `$state`, `$template`, `$auth`, or `$row`)
|
|
233
|
-
- **Bulk**: `mythik push --from-dir <folder> --author <agent>` — sequential per-file push of every `*.json`. Continue-on-error: failures don't stop subsequent specs. No rollback. Partial state recovers by fixing failures and re-running.
|
|
234
|
-
- **Programmatic**: `import { runPush, runPatch, parsePatchInput, type PushResult } from 'mythik-cli/api'` — same code path as the binary, no shell. Pass `json: true` in options to receive structured command output via `JSON.parse(result.output)`. `runPatch` success output includes `versioned: boolean` and `version?: number` when a versioned store + `author` creates history.
|
|
235
|
-
|
|
236
|
-
`SpecStore.save()` is `@internal` — calling it from application code skips validation and produces runtime errors only at render time. The three forms above are the only validated paths.
|
|
237
|
-
|
|
238
|
-
Existing persisted specs are protected by the Agent Protocol: full replacements require `--replace`, and persisted writes require `--author <name>` for versioned stores or explicit `--allow-unversioned` for intentionally unversioned stores.
|
|
234
|
+
- **Shell**: `mythik push <id> --from-file spec.json --author <agent>` and `mythik patch <id> --from-file patch.json --author <agent>` (cross-shell ergonomic for any spec/patch containing `$state`, `$template`, `$auth`, or `$row`)
|
|
235
|
+
- **Bulk**: `mythik push --from-dir <folder> --author <agent>` — sequential per-file push of every `*.json`. Continue-on-error: failures don't stop subsequent specs. No rollback. Partial state recovers by fixing failures and re-running.
|
|
236
|
+
- **Programmatic**: `import { runPush, runPatch, parsePatchInput, type PushResult } from 'mythik-cli/api'` — same code path as the binary, no shell. Pass `json: true` in options to receive structured command output via `JSON.parse(result.output)`. `runPatch` success output includes `versioned: boolean` and `version?: number` when a versioned store + `author` creates history.
|
|
237
|
+
|
|
238
|
+
`SpecStore.save()` is `@internal` — calling it from application code skips validation and produces runtime errors only at render time. The three forms above are the only validated paths.
|
|
239
|
+
|
|
240
|
+
Existing persisted specs are protected by the Agent Protocol: full replacements require `--replace`, and persisted writes require `--author <name>` for versioned stores or explicit `--allow-unversioned` for intentionally unversioned stores.
|
|
239
241
|
|
|
240
242
|
### Pre-push linting
|
|
241
243
|
|
|
@@ -515,7 +517,7 @@ Any action binding may include `params.skipIf`. Mythik resolves `skipIf` at disp
|
|
|
515
517
|
- Sets `/ui/loading` while in flight
|
|
516
518
|
- On error: sets `/ui/lastError` with status and message
|
|
517
519
|
- Optional `errorTarget` writes the same structured error to a screen-owned path and clears that path on success. Use it for critical screen-load fetches instead of relying only on global `/ui/lastError`
|
|
518
|
-
- Auth headers auto-injected for `authDomains`
|
|
520
|
+
- Auth headers auto-injected for `apiBaseUrl` exact-origin framework URLs and explicit `authDomains` hosts
|
|
519
521
|
|
|
520
522
|
### Transactions (Optimistic Updates)
|
|
521
523
|
|
|
@@ -621,6 +623,18 @@ Chain: `$array: "filter"` → `$array: "search"` → `$array: "slice"` for filte
|
|
|
621
623
|
|
|
622
624
|
Inside repeated elements: `$item`, `$index`, `$bindItem` access current item.
|
|
623
625
|
|
|
626
|
+
Repeated rows can opt into horizontal/wrapping layout without changing the child primitive:
|
|
627
|
+
|
|
628
|
+
```json
|
|
629
|
+
"repeat": {
|
|
630
|
+
"source": { "$state": "/filters" },
|
|
631
|
+
"key": "id",
|
|
632
|
+
"layout": { "direction": "horizontal", "gap": 8, "wrap": true }
|
|
633
|
+
}
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
For grouped repeats, group headers and footers remain vertical; `repeat.layout` applies only to each group's item row.
|
|
637
|
+
|
|
624
638
|
### Grouped Repeat
|
|
625
639
|
|
|
626
640
|
**Client-side** (engine groups flat array): `groupBy: "category"`
|
|
@@ -920,7 +934,7 @@ Interceptors:
|
|
|
920
934
|
"interceptors": { "logging": true, "timeout": { "ms": 15000 }, "retryOnError": { "maxRetries": 2, "statuses": [502, 503] } }
|
|
921
935
|
```
|
|
922
936
|
|
|
923
|
-
Security: tokens NEVER in state (engine closure only). `$auth` blocks token/password fields. Auth headers only for `authDomains`. Credentials cleared after login. Rate limit: 5/min. Cross-tab sync automatic.
|
|
937
|
+
Security: tokens NEVER in state (engine closure only). `$auth` blocks token/password fields. Auth headers are injected only for the host `apiBaseUrl` exact origin or explicit `authDomains`. Credentials cleared after login. Rate limit: 5/min. Cross-tab sync automatic.
|
|
924
938
|
|
|
925
939
|
Custom JWT provider response mapping: `tokenPath`, `refreshTokenPath`, and `userPath` are dot paths against the full login/refresh response. `rolePath` and `rolesPath` use a compat dual contract: plain keys like `"role"` / `"roles"` resolve inside the extracted `userPath` object; dotted paths like `"user.role"` or `"data.user.role"` resolve against the full response. If no role or roles are found, Mythik uses `defaultRole` (`"user"` by default) and warns in development.
|
|
926
940
|
|
|
@@ -1232,7 +1246,7 @@ Reference: `"hover": { "$token": "motion.presets.hoverLift" }`
|
|
|
1232
1246
|
|
|
1233
1247
|
## Component Variants
|
|
1234
1248
|
|
|
1235
|
-
Token-driven styling. Define in `tokens.components.{type}.{variant}`:
|
|
1249
|
+
Token-driven styling. **Use this before copying the same style block into multiple elements.** Define in `tokens.components.{type}.{variant}` and reference it from `props.variant`:
|
|
1236
1250
|
|
|
1237
1251
|
```json
|
|
1238
1252
|
"tokens": {
|
|
@@ -1249,7 +1263,9 @@ Token-driven styling. Define in `tokens.components.{type}.{variant}`:
|
|
|
1249
1263
|
```
|
|
1250
1264
|
Usage: `{ "type": "button", "props": { "label": "Save", "variant": "primary" } }`
|
|
1251
1265
|
`$path` references (`$colors.primary`) resolve against active tokens — dark mode works automatically.
|
|
1252
|
-
Element-level style/hover overrides variant (variant is base, element is override). Supports: `style`, `hover`, `active`, `focus`, `transition`.
|
|
1266
|
+
Element-level style/hover overrides variant (variant is base, element is override). Supports: `style`, `hover`, `active`, `focus`, `transition`.
|
|
1267
|
+
|
|
1268
|
+
Important boundary: variants are for primitive visual slots. They do **not** carry arbitrary primitive props such as `table.headerStyle`, `table.rowStyle`, `columns`, or action bindings. For prop-bearing reusable patterns, define an AppSpec `templates` entry and use `$prop` to pass through data/columns/actions. Example: use `tokens.components.box.tableCard` for card styling, but use an `ops-table` template when several tables need the same `headerStyle` + `rowStyle` chrome. For composed filter chips (`touchable` + `text`), put static shared styling in variants and keep state/item-specific active colors on the element.
|
|
1253
1269
|
|
|
1254
1270
|
## Skeleton & Export
|
|
1255
1271
|
|
|
@@ -1466,8 +1482,8 @@ When the framework changes the schema in a future version, this section will gai
|
|
|
1466
1482
|
28. loginScreen always accessible — prevents redirect loops
|
|
1467
1483
|
29. Login renders fullscreen (no layout) — appears automatically when not authenticated
|
|
1468
1484
|
30. Login paths: `/screens/login/...` not `/form/...` — clears on logout with statePolicy reset
|
|
1469
|
-
31. Auth headers auto-injected for `authDomains` — no manual headers in fetch
|
|
1470
|
-
32. Use `variant` prop for
|
|
1485
|
+
31. Auth headers auto-injected for `apiBaseUrl` exact-origin framework URLs and explicit `authDomains` hosts — no manual headers in fetch
|
|
1486
|
+
32. Use `variant` prop for reusable primitive styling — don't copy style objects; put `variant` inside `props`
|
|
1471
1487
|
33. `$path` references in variants resolve with dark mode automatically
|
|
1472
1488
|
34. Use `mythik push` for spec creation — no seed scripts
|
|
1473
1489
|
35. AppSpec patches use `/layout/elements/` not `/elements/`
|
|
@@ -1502,11 +1518,11 @@ When the framework changes the schema in a future version, this section will gai
|
|
|
1502
1518
|
64. Custom element black-box boundary — consumer's instance-level `animations`, `hover`, `active`, `focus`, `motion`, `style`, `visible`, and `key` apply to the OUTER primitive only. Inner primitives are the author's domain and are not reachable from the consumer. Identity cascade (rule 63 / cascade level 1) still reaches inner primitives; consumer cannot override them directly
|
|
1503
1519
|
65. `$prop` is nearest-enclosing-custom-element-scoped — inside a custom element's render tree, `$prop` resolves against THAT element's merged props. Nesting a custom element inside another pushes a new prop context; the outer's props are shadowed, not merged. Pass values explicitly via prop declarations when nested access is needed
|
|
1504
1520
|
66. `$children` marker in custom element render trees — authors write `"$children"` as a string item in their render tree `children` array to mark where consumer children are inserted during expansion. Multiple markers each splice the full consumer children. Same slotting semantics as spec templates
|
|
1505
|
-
67. `variant` is a PROP — place it inside `props`, never as a top-level element field. Applies to built-in primitives and Layer 3 custom elements alike: `{ "type": "stat-card", "props": { "variant": "primary", ... } }`. Top-level `variant` is silently ignored (the renderer reads `props.variant` only). Consumer may drive it dynamically via an expression
|
|
1521
|
+
67. `variant` is a PROP — place it inside `props`, never as a top-level element field. Applies to built-in primitives and Layer 3 custom elements alike: `{ "type": "stat-card", "props": { "variant": "primary", ... } }`. Top-level `variant` is silently ignored (the renderer reads `props.variant` only). Consumer may drive it dynamically via an expression. Variants are style/interaction slots only; use templates/custom elements when the reusable pattern must carry props like table `headerStyle`/`rowStyle` or composed children.
|
|
1506
1522
|
68. Custom elements may expose action-chain props — author declares a prop (e.g. `onSelect`, type `"array"`) and the render tree's `on:<event>` references it as `{ "$prop": "onSelect" }`. Consumers supply the full action array as the prop value; inner `$state` / `$template` / `$item` inside those actions resolve at press time with the current state (not at render time). Enables tabs, menu items, and similar patterns where the consumer owns the action chain
|
|
1507
1523
|
69. Never use `$row` literal — there is no `$row` expression handler. Read row data via `$state: '/ui/selectedRow/<key>'` (framework writes clicked row before column action dispatch).
|
|
1508
1524
|
70. Never combine `crud: {}` with `endpoint.path` ending in `/:id`. CRUD operations auto-append `/:id` to PUT/DELETE routes. Declaring `path: '/api/x/:id'` produces `/api/x/:id/:id`.
|
|
1509
|
-
71.
|
|
1525
|
+
71. Prefer `MythikApp apiBaseUrl` for the app's own backend. Relative runtime URLs (`/api/...`) resolve against that base and inherit auth only for the exact base origin when `authDomains` is omitted or empty. Providing `authDomains` disables the automatic `apiBaseUrl` origin allowlist; list every trusted absolute host explicitly. Never include `:port` in `auth.authDomains[]` entries because that matcher uses hostnames.
|
|
1510
1526
|
72. `spatial-map` is the generic SVG/data-first primitive for floor plans, seating maps, parking maps, warehouse layouts, hospital beds, and similar spatial workflows. JSON `onItemPress` actions write item context to `/ui/selectedSpatialItem` before lazy dispatch. Compose domain menus/drawers/modals externally; do not encode restaurant-specific behavior into the primitive. Use `{ "$state": "/path" }` expressions for dynamic `items`, `zones`, `mode`, and `statusStyles`; do not invent `*Path` prop aliases.
|
|
1511
1527
|
73. For `spatial-map` editing, use `editPolicy` for movement rules and `onItemChange` for persistence. Do not use `interactionPolicy` for drag/keyboard movement. In JSON specs, persist moved items with `$array: "replace"` reading from `/ui/spatialItemChange` or the configured `itemChangePath`; use plain `setState` for non-undoable screens and wrap the same value in `editorCommit` for undoable editors.
|
|
1512
1528
|
74. For JSON-created client-side item ids, use `$uniqueId` with an explicit `source`, `field`, `prefix`, and optional `padding`. It is deterministic and scoped to the source array; use it for local/editor objects, not as a substitute for database primary keys when a backend owns identity.
|
|
@@ -1521,12 +1537,12 @@ When the framework changes the schema in a future version, this section will gai
|
|
|
1521
1537
|
82. Use `editorSessions.<id>.persistence` plus `editorSave` for generic editor document persistence. The AI should not hand-compose `transaction` + `editorMarkSaved` for normal editor saves. `editorSave` captures the tracked paths snapshot, persists it through the host fetcher with URL-guard checks, and marks only the sent snapshot as saved after success. Failed saves keep `dirty: true` and expose save metadata under `/ui/editorSessions/<id>`.
|
|
1522
1538
|
83. Use `navigation.editorSessionGuard` for generic unsaved-changes protection in app specs instead of hand-rolled JSON dirty checks. Configure `sessions`, render your own JSON modal from `/ui/navigationGuard/pending`, call `navigationGuardCancel`, `navigationGuardSaveAndProceed`, `navigationGuardProceed`, or `navigationGuardDiscardAndProceed`, and keep `pendingPath` under a consumer-owned `/ui/<segment>` path that does not collide with reserved framework paths. `navigationGuardSaveAndProceed` is the normal save-first UX for persisted editor sessions; `navigationGuardProceed` is a low-level non-destructive retry that only resumes after the pending editor sessions are already clean; use `navigationGuardDiscardAndProceed` when the user explicitly chooses to abandon unsaved tracked-path changes.
|
|
1523
1539
|
84. In React apps without auth framework fetch, pass `fetcher` to `MythikApp` when editor sessions use `editorSave` or `navigationGuardSaveAndProceed`. Auth-enabled apps continue to use the framework fetch produced by auth interceptors. Do not route save-and-continue through `/ui/lastError` or a hand-composed fetch action; the editor session engine owns save metadata under `/ui/editorSessions/<id>`.
|
|
1524
|
-
85. For existing spec edits, the required AI loop is `mythik manifest` -> `mythik elements` -> `mythik patch --from-file --author` -> `mythik validate` -> verify. Manifest tells you the structure; elements gives the exact JSON you are changing; patch is the validated write path. Do not skip directly to full-spec `pull`/rewrite/push for a local change, do not mutate DB rows manually, and do not call `SpecStore.save()` from app code. Use `push` for new specs or intentional full replacement only; existing specs require explicit `--replace`.
|
|
1540
|
+
85. For existing spec edits, the required AI loop is `mythik manifest` -> `mythik elements` -> `mythik patch --from-file --author` -> `mythik validate` -> verify. Manifest tells you the structure; elements gives the exact JSON you are changing; patch is the validated write path. Do not skip directly to full-spec `pull`/rewrite/push for a local change, do not mutate DB rows manually, and do not call `SpecStore.save()` from app code. Use `push` for new specs or intentional full replacement only; existing specs require explicit `--replace`.
|
|
1525
1541
|
86. Mythik's AI documentation ships with the `mythik` npm package. Before generating or modifying specs, locate it with `mythik docs path` and start from `docs/llms.txt`, `docs/consumer/ai-context.md`, and `docs/wiki/compiled/README.md`. Use `mythik docs copy ./mythik-docs` when a project-local copy is easier to hand to an AI agent.
|
|
1526
1542
|
87. DNA numeric seeds (`roundness`, `density`, `depth`, `formality`) are canonical `0–1` values. Generate `0.7`, not `70`. The runtime tolerates legacy `0–100` values by normalizing any numeric seed greater than `1` with `/100` during DNA derivation, including initial AppSpec load and runtime `updateTokens`.
|
|
1527
1543
|
88. API query endpoints can combine `pagination: "offset"` with `scopeFilter`. For generated counts, Mythik applies the scope filter to the source query before `COUNT(*)`, so paginated totals remain tenant-scoped. Prefer generated counts. If a custom `endpoint.count` is truly needed with `scopeFilter`, include `{{scopeWhere[:alias]}}` or `{{scopeAnd[:alias]}}`; Mythik expands the macro to the correct scope predicate and removes it for bypass roles. Other custom count SQL is left verbatim. Use `:alias` for JOIN/subquery counts, and do not reference internal scope params directly.
|
|
1528
1544
|
89. Transaction `confirm` failures from `fetch` preserve backend error details for `onError`. Read `/tx/error/message` for the best available message; when the backend returns `{ error: { code, message } }`, Mythik keeps that message, `code`, HTTP `status`, and raw `data` after rollback. Do not parse `/ui/lastError` from transaction specs.
|
|
1529
|
-
90. For SQL-backed stores and servers, use the generic `mythik/server` SQL boundary. Initialize tables with `mythik init-store --dialect <sqlserver|postgres|mysql|sqlite>` or inspect DDL with `--dry-run`; configure the CLI with `--store`, `--url`/`--filename`/SQL Server flags, or `MYTHIK_*` environment variables; and keep spec edits on the required `manifest -> elements -> patch --from-file --author -> validate -> verify` loop. Write custom API SQL in the selected dialect with Mythik named params (`@name`); Mythik does not translate custom SQL between dialects.
|
|
1545
|
+
90. For SQL-backed stores and servers, use the generic `mythik/server` SQL boundary. Initialize tables with `mythik init-store --dialect <sqlserver|postgres|mysql|sqlite>` or inspect DDL with `--dry-run`; configure the CLI with `--store`, `--url`/`--filename`/SQL Server flags, or `MYTHIK_*` environment variables; and keep spec edits on the required `manifest -> elements -> patch --from-file --author -> validate -> verify` loop. Write custom API SQL in the selected dialect with Mythik named params (`@name`); Mythik does not translate custom SQL between dialects.
|
|
1530
1546
|
91. Event arrays may mix normal actions and transaction bindings. Mythik executes them sequentially and awaits each transaction before continuing. Use this when a flow needs a small action before or after an optimistic transaction; do not wrap a transaction inside another transaction phase.
|
|
1531
1547
|
92. `$ref` and `$template` placeholders can read nested values from `$let` object bindings with dot notation, for example `{ "$ref": "user.name" }` or `${user.name}`. If a dotted `$ref` segment is missing, runtime throws an unknown `$ref` error rather than silently returning undefined.
|
|
1532
1548
|
93. Use `params.skipIf` for a dispatch-time action guard when an action should be skipped but the surrounding action chain should continue. `skipIf` is resolved before other params and is removed before the action handler runs. Do not use `skipIf` as a substitute for form validation or transaction rollback.
|
|
@@ -1536,4 +1552,7 @@ When the framework changes the schema in a future version, this section will gai
|
|
|
1536
1552
|
97. Missing SQL adapter errors are actionable. The thrown `SqlDriverError` includes `packageName`, `installCommand`, and a message with the exact `npm install ...` command for the selected dialect.
|
|
1537
1553
|
98. For native Expo apps, install renderer peer packages with `npx expo install react-native-svg react-native-reanimated react-native-worklets ...` before installing `mythik mythik-react-native`, so Expo selects native module versions that match the app SDK. Keep `react-native-reanimated/plugin` last in the app Babel config. Keep `root` as a stable string element id; use `$platform` only inside localized props, style, children, or values. `$platform` matches exact platform keys first, then falls back from `ios`/`android` to `native`; it has no `default` key. Before using a primitive in native specs, check `REACT_NATIVE_PRIMITIVE_SUPPORT` or `getReactNativePrimitiveSupport` from `mythik-react-native`; native-milestone primitives should fail visibly instead of being treated as supported.
|
|
1538
1554
|
99. Use Mythik Reveal before guessing about running-app behavior. Start `mythik reveal start`, wire the host `reveal` config in development, then inspect with `mythik reveal apps`, `context`, `current`, `screen`, or `element`. Reveal returns live renderer/environment/spec/state/diagnostics/events with redaction, so agents can diagnose runtime behavior from structured context instead of screenshots, stale pulled specs, or source-code assumptions. Never enable Reveal in production, never commit the token, and include/redact state paths deliberately.
|
|
1539
|
-
100. **Use Mythik Agent Context
|
|
1555
|
+
100. **Use Mythik Agent Context, Agent Protocol, and Sentinel for fresh AI agents**. Run `mythik agent init codex`, `mythik agent init claude`, or `mythik agent init all` to install project-local agent instructions. `codex` creates/updates `AGENTS.md`, `claude` creates/updates `CLAUDE.md`, and `all` updates both; existing file content outside the Mythik-managed `<!-- mythik-agent-protocol:start -->` / `<!-- mythik-agent-protocol:end -->` block is preserved. Generate live project context with `mythik agent context --app <id> --include-screens --out .mythik/agent/context.md`. Existing stored specs stay on `manifest -> elements -> patch --from-file --author -> validate -> verify`. The active store is the source of truth; local spec files are drafts/snapshots/migrations/fixtures unless a file store is intentionally configured. Use TOON for large reads when supported, and use `mythik lint` for new local drafts, replacement files, bulk imports/migrations, and relevant consumer code changes. Mythik Sentinel runs from the CLI as advisory coaching: first project use reminds the agent to initialize instructions, repeated full replacement intent warns the agent back to patch-first edits, identical `push --replace` writes are skipped as `skipped: true`, and no spec contents or credentials are persisted in the Sentinel cache. Disable only with `MYTHIK_SENTINEL=off` for exceptional automation.
|
|
1556
|
+
101. `repeat.layout` controls repeated item rows (`direction`, `gap`, `wrap`). In grouped repeats, headers/footers remain vertical and the layout applies only to the group item row.
|
|
1557
|
+
102. `select` normalizes option identity for display: DB integer IDs and string option values match, `0` is a valid selected value, and null/undefined show the placeholder. Values emitted by existing `onChange` remain string-compatible.
|
|
1558
|
+
103. `text.on.press` is supported for inline interactive text. Web receives button semantics plus keyboard activation; React Native receives `accessibilityRole="button"`. Use `button` or `touchable` for primary/larger actions.
|