@almadar/std 16.202.0 → 16.204.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 (64) hide show
  1. package/behaviors/lolo/ui/core/atoms/std-modal-editor.lolo +230 -0
  2. package/behaviors/lolo/ui/core/molecules/ui-code-block.lolo +302 -0
  3. package/behaviors/lolo/ui/core/molecules/ui-pagination.lolo +1 -1
  4. package/behaviors/lolo/ui/core/molecules/ui-table-view.lolo +1 -1
  5. package/behaviors/lolo/ui/game/atoms/std-choice-gate.lolo +1 -1
  6. package/behaviors/lolo/ui/game/atoms/std-fx-narrative.lolo +1 -1
  7. package/behaviors/lolo/ui/game/atoms/std-fx-particles.lolo +1 -1
  8. package/behaviors/lolo/ui/game/atoms/std-game-design-sheet.lolo +69 -0
  9. package/behaviors/lolo/ui/game/atoms/std-gate-lock.lolo +1 -1
  10. package/behaviors/lolo/ui/game/atoms/std-lives.lolo +1 -1
  11. package/behaviors/lolo/ui/game/atoms/std-loop-lock.lolo +1 -1
  12. package/behaviors/lolo/ui/game/atoms/std-objective-flow.lolo +1 -1
  13. package/behaviors/lolo/ui/game/atoms/std-pad-lock.lolo +1 -1
  14. package/behaviors/lolo/ui/game/atoms/std-patrol-hazard.lolo +1 -1
  15. package/behaviors/lolo/ui/game/atoms/std-pickup.lolo +1 -1
  16. package/behaviors/lolo/ui/game/atoms/std-platformer-body.lolo +1 -1
  17. package/behaviors/lolo/ui/game/atoms/std-tutorial-overlay.lolo +1 -1
  18. package/behaviors/lolo/ui/game/atoms/std-velocity-gate.lolo +1 -1
  19. package/behaviors/lolo/ui/learning/atoms/ui-algo-graph-canvas.lolo +1 -1
  20. package/behaviors/lolo/ui/learning/atoms/ui-algorithm-canvas.lolo +1 -1
  21. package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +1 -1
  22. package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +1 -1
  23. package/behaviors/lolo/ui/learning/atoms/ui-learning-canvas.lolo +1 -1
  24. package/behaviors/lolo/ui/learning/atoms/ui-math-canvas.lolo +3 -3
  25. package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +1 -1
  26. package/behaviors/registry/ui/core/atoms/std-modal-editor.orb +1450 -0
  27. package/behaviors/registry/ui/core/molecules/ui-code-block.orb +687 -1
  28. package/behaviors/registry/ui/core/molecules/ui-pagination.orb +6 -1
  29. package/behaviors/registry/ui/game/atoms/std-choice-gate.orb +82 -2
  30. package/behaviors/registry/ui/game/atoms/std-fx-narrative.orb +1 -1
  31. package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +82 -2
  32. package/behaviors/registry/ui/game/atoms/std-game-design-sheet.orb +527 -0
  33. package/behaviors/registry/ui/game/atoms/std-gate-lock.orb +48 -2
  34. package/behaviors/registry/ui/game/atoms/std-lives.orb +26 -2
  35. package/behaviors/registry/ui/game/atoms/std-loop-lock.orb +56 -2
  36. package/behaviors/registry/ui/game/atoms/std-objective-flow.orb +1 -1
  37. package/behaviors/registry/ui/game/atoms/std-pad-lock.orb +30 -2
  38. package/behaviors/registry/ui/game/atoms/std-patrol-hazard.orb +63 -2
  39. package/behaviors/registry/ui/game/atoms/std-pickup.orb +1 -1
  40. package/behaviors/registry/ui/game/atoms/std-platformer-body.orb +1 -1
  41. package/behaviors/registry/ui/game/atoms/std-tutorial-overlay.orb +24 -2
  42. package/behaviors/registry/ui/game/atoms/std-velocity-gate.orb +75 -2
  43. package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +1 -0
  44. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +1 -0
  45. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +1 -0
  46. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +1 -0
  47. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +1 -0
  48. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +3 -0
  49. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +1 -0
  50. package/dist/behaviors/exports-reader.js +2589 -2501
  51. package/dist/behaviors/functions/index.d.ts +244 -16
  52. package/dist/behaviors/functions/index.js +2584 -2502
  53. package/dist/behaviors/index.d.ts +1 -1
  54. package/dist/behaviors/index.js +2590 -2502
  55. package/dist/behaviors/query.js +2589 -2501
  56. package/dist/behaviors-embeddings.hash.json +3 -3
  57. package/dist/behaviors-embeddings.json +35 -27
  58. package/dist/behaviors-registry.json +1729 -212
  59. package/dist/index.d.ts +1 -1
  60. package/dist/index.js +2590 -2502
  61. package/dist/knob-embeddings.hash.json +3 -3
  62. package/dist/knob-embeddings.json +1 -1
  63. package/dist/registry/factory-signatures.json +1 -1
  64. package/package.json +2 -2
@@ -0,0 +1,230 @@
1
+ app std-modal-editor "0.1.0"
2
+ "UI substrate: modal keyboard editing over any editable CodeBlock. The topology is fixed (NORMAL / INSERT / VISUAL / OPERATOR_PENDING / COMMAND) and every binding is config: mode-entry keys, motions, operators, ex-commands, the digit table that accumulates a repeat count, and the per-mode captured-key table the host's keyboard router reads. Vim ships as the default flavor; a Kakoune/Helix binding is the same topology with different config, never a fork. Emits are the mechanical vocabulary an editable CodeBlock listens to (SET_MODE / MOTION / OPERATE / INSERT_TEXT) plus one neutral EX_COMMAND for a buffered ':' line — std names no host command; a realization maps EX_COMMAND.name onto its own host vocabulary."
3
+ orbital ModalEditorOrbital {
4
+ entity EditorMode [runtime] {
5
+ id : string!
6
+ editorId : string = ""
7
+ count : number = 0
8
+ operator : string = ""
9
+ operatorKey : string = ""
10
+ cmdline : string = ""
11
+ }
12
+
13
+ trait Modes -> @rebindable EditorMode [lifecycle, instance] {
14
+ initial: NORMAL
15
+
16
+ state NORMAL {
17
+ INIT -> NORMAL
18
+ (set @entity.count 0)
19
+
20
+ KEY -> INSERT when ["=", ?key, @config.insertKey]
21
+ (set @entity.editorId ?editorId)
22
+ (set @entity.count 0)
23
+ (emit SET_MODE { editorId: ?editorId, mode: "INSERT", caret: "bar" })
24
+
25
+ KEY -> INSERT when ["=", ?key, @config.appendKey]
26
+ (set @entity.editorId ?editorId)
27
+ (set @entity.count 0)
28
+ (emit MOTION { editorId: ?editorId, motion: "right", count: 1 })
29
+ (emit SET_MODE { editorId: ?editorId, mode: "INSERT", caret: "bar" })
30
+
31
+ KEY -> INSERT when ["=", ?key, @config.openLineKey]
32
+ (set @entity.editorId ?editorId)
33
+ (set @entity.count 0)
34
+ (emit MOTION { editorId: ?editorId, motion: "line-end", count: 1 })
35
+ (emit INSERT_TEXT { editorId: ?editorId, text: "\n" })
36
+ (emit SET_MODE { editorId: ?editorId, mode: "INSERT", caret: "bar" })
37
+
38
+ KEY -> VISUAL when ["=", ?key, @config.visualKey]
39
+ (set @entity.editorId ?editorId)
40
+ (emit SET_MODE { editorId: ?editorId, mode: "VISUAL", caret: "block" })
41
+
42
+ KEY -> COMMAND when ["=", ?key, @config.commandKey]
43
+ (set @entity.editorId ?editorId)
44
+ (set @entity.cmdline "")
45
+ (emit SET_MODE { editorId: ?editorId, mode: "COMMAND", caret: "block" })
46
+
47
+ KEY -> OPERATOR_PENDING when (object/has @config.operators ?key)
48
+ (set @entity.editorId ?editorId)
49
+ (set @entity.operator (object/get @config.operators ?key))
50
+ (set @entity.operatorKey ?key)
51
+
52
+ KEY -> NORMAL when (and (object/has @config.digits ?key) (or ["!=", ?key, "0"] [">", @entity.count, 0]))
53
+ (set @entity.count (+ (* @entity.count 10) (object/get @config.digits ?key)))
54
+
55
+ KEY -> NORMAL when (object/has @config.motions ?key)
56
+ (set @entity.editorId ?editorId)
57
+ (emit MOTION { editorId: ?editorId, motion: (object/get @config.motions ?key), count: (if [">", @entity.count, 0] @entity.count 1) })
58
+ (set @entity.count 0)
59
+
60
+ KEY -> NORMAL when ["=", ?key, "Escape"]
61
+ (set @entity.count 0)
62
+ (set @entity.operator "")
63
+ (set @entity.operatorKey "")
64
+ }
65
+
66
+ state INSERT {
67
+ KEY -> NORMAL when ["=", ?key, "Escape"]
68
+ (emit SET_MODE { editorId: ?editorId, mode: "NORMAL", caret: "block" })
69
+ }
70
+
71
+ state VISUAL {
72
+ KEY -> NORMAL when ["=", ?key, "Escape"]
73
+ (set @entity.count 0)
74
+ (emit SET_MODE { editorId: ?editorId, mode: "NORMAL", caret: "block" })
75
+
76
+ KEY -> NORMAL when (object/has @config.operators ?key)
77
+ (set @entity.count 0)
78
+ (emit OPERATE { editorId: ?editorId, operator: (object/get @config.operators ?key), motion: "selection", count: 1 })
79
+ (emit SET_MODE { editorId: ?editorId, mode: "NORMAL", caret: "block" })
80
+
81
+ KEY -> VISUAL when (object/has @config.motions ?key)
82
+ (emit MOTION { editorId: ?editorId, motion: (object/get @config.motions ?key), count: (if [">", @entity.count, 0] @entity.count 1) })
83
+ (set @entity.count 0)
84
+ }
85
+
86
+ state OPERATOR_PENDING {
87
+ KEY -> NORMAL when ["=", ?key, @entity.operatorKey]
88
+ (emit OPERATE { editorId: ?editorId, operator: @entity.operator, motion: "line", count: (if [">", @entity.count, 0] @entity.count 1) })
89
+ (set @entity.operator "")
90
+ (set @entity.operatorKey "")
91
+ (set @entity.count 0)
92
+
93
+ KEY -> NORMAL when (object/has @config.motions ?key)
94
+ (emit OPERATE { editorId: ?editorId, operator: @entity.operator, motion: (object/get @config.motions ?key), count: (if [">", @entity.count, 0] @entity.count 1) })
95
+ (set @entity.operator "")
96
+ (set @entity.operatorKey "")
97
+ (set @entity.count 0)
98
+
99
+ KEY -> NORMAL when ["=", ?key, "Escape"]
100
+ (set @entity.operator "")
101
+ (set @entity.operatorKey "")
102
+ (set @entity.count 0)
103
+ }
104
+
105
+ state COMMAND {
106
+ KEY -> COMMAND when ["=", ?key, "Backspace"]
107
+ (set @entity.cmdline (str/slice @entity.cmdline 0 (- (str/len @entity.cmdline) 1)))
108
+
109
+ KEY -> NORMAL when (and ["=", ?key, "Enter"] (object/has @config.exCommands @entity.cmdline))
110
+ (emit EX_COMMAND { editorId: ?editorId, name: (object/get @config.exCommands @entity.cmdline) })
111
+ (set @entity.cmdline "")
112
+ (emit SET_MODE { editorId: ?editorId, mode: "NORMAL", caret: "block" })
113
+
114
+ KEY -> NORMAL when (and ["=", ?key, "Enter"] (not (object/has @config.exCommands @entity.cmdline)))
115
+ (set @entity.cmdline "")
116
+ (emit SET_MODE { editorId: ?editorId, mode: "NORMAL", caret: "block" })
117
+
118
+ KEY -> NORMAL when ["=", ?key, "Escape"]
119
+ (set @entity.cmdline "")
120
+ (emit SET_MODE { editorId: ?editorId, mode: "NORMAL", caret: "block" })
121
+
122
+ KEY -> COMMAND when (and ["!=", ?key, "Enter"] ["!=", ?key, "Escape"] ["!=", ?key, "Backspace"])
123
+ (set @entity.cmdline (str/concat @entity.cmdline ?key))
124
+ }
125
+
126
+ listens {
127
+ KEY {
128
+ editorId : string
129
+ key : string
130
+ code : string
131
+ ctrl : boolean
132
+ alt : boolean
133
+ shift : boolean
134
+ meta : boolean
135
+ repeat : boolean
136
+ }
137
+ @description "One physical keydown, delivered by the host's keyboard router. The host decides preventDefault from config.keymap; this trait only reads key + editorId."
138
+ }
139
+
140
+ emits {
141
+ SET_MODE -> external {
142
+ editorId : string
143
+ mode : string
144
+ caret : string
145
+ }
146
+ @description "Mode + caret instruction for the editor surface (bar | block). Also the fact a realization reads to drive a mode indicator."
147
+ @tier "primary"
148
+ MOTION -> external {
149
+ editorId : string
150
+ motion : string
151
+ count : number
152
+ }
153
+ @description "Move the caret (or extend the selection in VISUAL) by a closed motion name, `count` times."
154
+ @tier "primary"
155
+ OPERATE -> external {
156
+ editorId : string
157
+ operator : string
158
+ motion : string
159
+ count : number
160
+ }
161
+ @description "Apply a config-declared operator (delete | yank | change) over the range a motion describes; `line` for doubled operators, `selection` in VISUAL."
162
+ @tier "primary"
163
+ INSERT_TEXT -> external {
164
+ editorId : string
165
+ text : string
166
+ }
167
+ @description "Insert literal text at the caret (e.g. the newline `o` opens before entering INSERT)."
168
+ @tier "secondary"
169
+ EX_COMMAND -> external {
170
+ editorId : string
171
+ name : string
172
+ }
173
+ @description "A buffered ':' line resolved through config.exCommands. `name` is a neutral config-declared string; a realization maps it onto its host's command vocabulary."
174
+ @tier "secondary"
175
+ }
176
+
177
+ config {
178
+ insertKey : string = "i"
179
+ @label "Enter INSERT before the caret"
180
+ @description "Key that switches NORMAL to INSERT with the caret unchanged."
181
+ @synonyms "insert mode, insert key"
182
+ @tier "presentation"
183
+ appendKey : string = "a"
184
+ @label "Enter INSERT after the caret"
185
+ @description "Key that nudges the caret one column right, then switches to INSERT."
186
+ @synonyms "append, append mode"
187
+ @tier "presentation"
188
+ openLineKey : string = "o"
189
+ @label "Open a line below and insert"
190
+ @description "Key that moves to line end, inserts a newline, then switches to INSERT."
191
+ @synonyms "open line, new line below"
192
+ @tier "presentation"
193
+ visualKey : string = "v"
194
+ @label "Enter VISUAL"
195
+ @description "Key that switches NORMAL to VISUAL; motions then extend the selection and an operator acts on it."
196
+ @synonyms "visual mode, select mode"
197
+ @tier "presentation"
198
+ commandKey : string = ":"
199
+ @label "Enter COMMAND"
200
+ @description "Key that switches NORMAL to COMMAND and starts buffering an ex-command line."
201
+ @synonyms "ex mode, command line, colon"
202
+ @tier "presentation"
203
+ operators : Map string string = { d: "delete", y: "yank", c: "change" }
204
+ @label "Operator keys"
205
+ @description "Keys that arm OPERATOR_PENDING, mapped to the operator name carried on OPERATE. Pressing the same key again operates on the whole line."
206
+ @synonyms "operators, delete, yank, change"
207
+ @tier "domain"
208
+ motions : Map string string = { h: "left", j: "down", k: "up", l: "right", w: "word-forward", b: "word-back", e: "word-end", "0": "line-start", "$": "line-end", "^": "first-nonblank", G: "doc-end", "{": "paragraph-back", "}": "paragraph-forward" }
209
+ @label "Motion keys"
210
+ @description "Keys recognized in NORMAL, VISUAL and OPERATOR_PENDING, mapped to the closed motion vocabulary the editor surface understands."
211
+ @synonyms "motions, movement, hjkl, word motion"
212
+ @tier "domain"
213
+ digits : Map string number = { "0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9 }
214
+ @label "Count digits"
215
+ @description "Digit keys accumulated into a repeat count before a motion or operator fires; each digit's integer value is a lookup because the language has no string-to-int operator."
216
+ @tier "internal"
217
+ exCommands : Map string string = { w: "save", q: "close-tab", wq: "save-close-tab" }
218
+ @label "Ex-commands"
219
+ @description "Buffered COMMAND-mode lines (typed after ':') mapped to a neutral command name carried on EX_COMMAND."
220
+ @synonyms "ex commands, colon commands"
221
+ @tier "domain"
222
+ keymap : Map string [string] = { NORMAL: ["i", "a", "o", "v", ":", "d", "y", "c", "h", "j", "k", "l", "w", "b", "e", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "$", "^", "G", "{", "}", "Escape"], INSERT: ["Escape"], VISUAL: ["Escape", "d", "y", "c", "h", "j", "k", "l", "w", "b", "e", "0", "$", "^", "G", "{", "}"], OPERATOR_PENDING: ["Escape", "d", "y", "c", "h", "j", "k", "l", "w", "b", "e", "0", "$", "^", "G", "{", "}"], COMMAND: ["Escape", "Enter", "Backspace", "w", "q"] }
223
+ @label "Captured keys per mode"
224
+ @description "The declared key set the host's keyboard router reads synchronously to decide preventDefault, keyed by this trait's current state name. A key not listed reaches the underlying textarea untouched. Keep in sync with the other knobs."
225
+ @tier "internal"
226
+ }
227
+ }
228
+
229
+ page "/modal-editor" as ModalEditorPage -> Modes
230
+ }
@@ -28,6 +28,7 @@ orbital CodeBlockOrbital {
28
28
  entity CodeBlockItem [runtime] {
29
29
  id : string!
30
30
  code : string
31
+ editorId : string
31
32
  }
32
33
 
33
34
  trait CodeBlockRender -> @rebindable CodeBlockItem [interaction, instance] {
@@ -36,6 +37,7 @@ orbital CodeBlockOrbital {
36
37
  state idle {
37
38
  INIT -> idle
38
39
  (set @entity.code @config.code)
40
+ (set @entity.editorId @config.editorId)
39
41
  (render-ui main {
40
42
  code: @entity.code
41
43
  language: @config.language
@@ -58,6 +60,15 @@ orbital CodeBlockOrbital {
58
60
  isLoading: @config.isLoading
59
61
  error: @config.error
60
62
  showCopy: @config.showCopy
63
+ editorId: @entity.editorId
64
+ onEditorFocus: @config.onEditorFocus
65
+ onEditorBlur: @config.onEditorBlur
66
+ onMotion: @config.onMotion
67
+ onOperate: @config.onOperate
68
+ onInsertText: @config.onInsertText
69
+ onSetMode: @config.onSetMode
70
+ motions: @config.motions
71
+ operators: @config.operators
61
72
  type: code-block
62
73
  })
63
74
  CHANGE -> idle
@@ -84,6 +95,225 @@ orbital CodeBlockOrbital {
84
95
  isLoading: @config.isLoading
85
96
  error: @config.error
86
97
  showCopy: @config.showCopy
98
+ editorId: @entity.editorId
99
+ onEditorFocus: @config.onEditorFocus
100
+ onEditorBlur: @config.onEditorBlur
101
+ onMotion: @config.onMotion
102
+ onOperate: @config.onOperate
103
+ onInsertText: @config.onInsertText
104
+ onSetMode: @config.onSetMode
105
+ motions: @config.motions
106
+ operators: @config.operators
107
+ type: code-block
108
+ })
109
+ EDITOR_FOCUS -> idle
110
+ (set @entity.editorId ?editorId)
111
+ (render-ui main {
112
+ code: @entity.code
113
+ language: @config.language
114
+ showCopyButton: @config.showCopyButton
115
+ showLanguageBadge: @config.showLanguageBadge
116
+ maxHeight: @config.maxHeight
117
+ foldable: @config.foldable
118
+ className: @config.className
119
+ editable: @config.editable
120
+ onChange: @config.onChange
121
+ title: @config.title
122
+ mode: @config.mode
123
+ diff: @config.diff
124
+ oldValue: @config.oldValue
125
+ newValue: @config.newValue
126
+ showLineNumbers: @config.showLineNumbers
127
+ wordWrap: @config.wordWrap
128
+ files: @config.files
129
+ actions: @config.actions
130
+ isLoading: @config.isLoading
131
+ error: @config.error
132
+ showCopy: @config.showCopy
133
+ editorId: @entity.editorId
134
+ onEditorFocus: @config.onEditorFocus
135
+ onEditorBlur: @config.onEditorBlur
136
+ onMotion: @config.onMotion
137
+ onOperate: @config.onOperate
138
+ onInsertText: @config.onInsertText
139
+ onSetMode: @config.onSetMode
140
+ motions: @config.motions
141
+ operators: @config.operators
142
+ type: code-block
143
+ })
144
+ EDITOR_BLUR -> idle
145
+ (set @entity.editorId ?editorId)
146
+ (render-ui main {
147
+ code: @entity.code
148
+ language: @config.language
149
+ showCopyButton: @config.showCopyButton
150
+ showLanguageBadge: @config.showLanguageBadge
151
+ maxHeight: @config.maxHeight
152
+ foldable: @config.foldable
153
+ className: @config.className
154
+ editable: @config.editable
155
+ onChange: @config.onChange
156
+ title: @config.title
157
+ mode: @config.mode
158
+ diff: @config.diff
159
+ oldValue: @config.oldValue
160
+ newValue: @config.newValue
161
+ showLineNumbers: @config.showLineNumbers
162
+ wordWrap: @config.wordWrap
163
+ files: @config.files
164
+ actions: @config.actions
165
+ isLoading: @config.isLoading
166
+ error: @config.error
167
+ showCopy: @config.showCopy
168
+ editorId: @entity.editorId
169
+ onEditorFocus: @config.onEditorFocus
170
+ onEditorBlur: @config.onEditorBlur
171
+ onMotion: @config.onMotion
172
+ onOperate: @config.onOperate
173
+ onInsertText: @config.onInsertText
174
+ onSetMode: @config.onSetMode
175
+ motions: @config.motions
176
+ operators: @config.operators
177
+ type: code-block
178
+ })
179
+ MOTION -> idle
180
+ (set @entity.editorId ?editorId)
181
+ (render-ui main {
182
+ code: @entity.code
183
+ language: @config.language
184
+ showCopyButton: @config.showCopyButton
185
+ showLanguageBadge: @config.showLanguageBadge
186
+ maxHeight: @config.maxHeight
187
+ foldable: @config.foldable
188
+ className: @config.className
189
+ editable: @config.editable
190
+ onChange: @config.onChange
191
+ title: @config.title
192
+ mode: @config.mode
193
+ diff: @config.diff
194
+ oldValue: @config.oldValue
195
+ newValue: @config.newValue
196
+ showLineNumbers: @config.showLineNumbers
197
+ wordWrap: @config.wordWrap
198
+ files: @config.files
199
+ actions: @config.actions
200
+ isLoading: @config.isLoading
201
+ error: @config.error
202
+ showCopy: @config.showCopy
203
+ editorId: @entity.editorId
204
+ onEditorFocus: @config.onEditorFocus
205
+ onEditorBlur: @config.onEditorBlur
206
+ onMotion: @config.onMotion
207
+ onOperate: @config.onOperate
208
+ onInsertText: @config.onInsertText
209
+ onSetMode: @config.onSetMode
210
+ motions: @config.motions
211
+ operators: @config.operators
212
+ type: code-block
213
+ })
214
+ OPERATE -> idle
215
+ (set @entity.editorId ?editorId)
216
+ (render-ui main {
217
+ code: @entity.code
218
+ language: @config.language
219
+ showCopyButton: @config.showCopyButton
220
+ showLanguageBadge: @config.showLanguageBadge
221
+ maxHeight: @config.maxHeight
222
+ foldable: @config.foldable
223
+ className: @config.className
224
+ editable: @config.editable
225
+ onChange: @config.onChange
226
+ title: @config.title
227
+ mode: @config.mode
228
+ diff: @config.diff
229
+ oldValue: @config.oldValue
230
+ newValue: @config.newValue
231
+ showLineNumbers: @config.showLineNumbers
232
+ wordWrap: @config.wordWrap
233
+ files: @config.files
234
+ actions: @config.actions
235
+ isLoading: @config.isLoading
236
+ error: @config.error
237
+ showCopy: @config.showCopy
238
+ editorId: @entity.editorId
239
+ onEditorFocus: @config.onEditorFocus
240
+ onEditorBlur: @config.onEditorBlur
241
+ onMotion: @config.onMotion
242
+ onOperate: @config.onOperate
243
+ onInsertText: @config.onInsertText
244
+ onSetMode: @config.onSetMode
245
+ motions: @config.motions
246
+ operators: @config.operators
247
+ type: code-block
248
+ })
249
+ INSERT_TEXT -> idle
250
+ (set @entity.editorId ?editorId)
251
+ (render-ui main {
252
+ code: @entity.code
253
+ language: @config.language
254
+ showCopyButton: @config.showCopyButton
255
+ showLanguageBadge: @config.showLanguageBadge
256
+ maxHeight: @config.maxHeight
257
+ foldable: @config.foldable
258
+ className: @config.className
259
+ editable: @config.editable
260
+ onChange: @config.onChange
261
+ title: @config.title
262
+ mode: @config.mode
263
+ diff: @config.diff
264
+ oldValue: @config.oldValue
265
+ newValue: @config.newValue
266
+ showLineNumbers: @config.showLineNumbers
267
+ wordWrap: @config.wordWrap
268
+ files: @config.files
269
+ actions: @config.actions
270
+ isLoading: @config.isLoading
271
+ error: @config.error
272
+ showCopy: @config.showCopy
273
+ editorId: @entity.editorId
274
+ onEditorFocus: @config.onEditorFocus
275
+ onEditorBlur: @config.onEditorBlur
276
+ onMotion: @config.onMotion
277
+ onOperate: @config.onOperate
278
+ onInsertText: @config.onInsertText
279
+ onSetMode: @config.onSetMode
280
+ motions: @config.motions
281
+ operators: @config.operators
282
+ type: code-block
283
+ })
284
+ SET_MODE -> idle
285
+ (set @entity.editorId ?editorId)
286
+ (render-ui main {
287
+ code: @entity.code
288
+ language: @config.language
289
+ showCopyButton: @config.showCopyButton
290
+ showLanguageBadge: @config.showLanguageBadge
291
+ maxHeight: @config.maxHeight
292
+ foldable: @config.foldable
293
+ className: @config.className
294
+ editable: @config.editable
295
+ onChange: @config.onChange
296
+ title: @config.title
297
+ mode: @config.mode
298
+ diff: @config.diff
299
+ oldValue: @config.oldValue
300
+ newValue: @config.newValue
301
+ showLineNumbers: @config.showLineNumbers
302
+ wordWrap: @config.wordWrap
303
+ files: @config.files
304
+ actions: @config.actions
305
+ isLoading: @config.isLoading
306
+ error: @config.error
307
+ showCopy: @config.showCopy
308
+ editorId: @entity.editorId
309
+ onEditorFocus: @config.onEditorFocus
310
+ onEditorBlur: @config.onEditorBlur
311
+ onMotion: @config.onMotion
312
+ onOperate: @config.onOperate
313
+ onInsertText: @config.onInsertText
314
+ onSetMode: @config.onSetMode
315
+ motions: @config.motions
316
+ operators: @config.operators
87
317
  type: code-block
88
318
  })
89
319
  }
@@ -94,12 +324,48 @@ orbital CodeBlockOrbital {
94
324
  }
95
325
  @description "GAP-51: called with the new code on every keystroke when `editable === true`. Consumers should debounce + parse downstream — `CodeBlock` does not."
96
326
  @tier "essential"
327
+ @config.onEditorFocus -> external {
328
+ editorId : string!
329
+ }
330
+ @description "Declarative bus emit fired when this editor gains focus."
331
+ @tier "essential"
332
+ @config.onEditorBlur -> external {
333
+ editorId : string!
334
+ }
335
+ @description "Declarative bus emit fired when this editor loses focus."
336
+ @tier "essential"
97
337
  }
98
338
 
99
339
  listens {
340
+ MOTION {
341
+ editorId : string!
342
+ motion : "left" | "right" | "up" | "down" | "word-forward" | "word-back" | "word-end" | "line-start" | "line-end" | "first-nonblank" | "doc-start" | "doc-end" | "paragraph-forward" | "paragraph-back" | "line" | "selection"!
343
+ count : number!
344
+ }
345
+ OPERATE {
346
+ editorId : string!
347
+ operator : "delete" | "yank" | "change"!
348
+ motion : "left" | "right" | "up" | "down" | "word-forward" | "word-back" | "word-end" | "line-start" | "line-end" | "first-nonblank" | "doc-start" | "doc-end" | "paragraph-forward" | "paragraph-back" | "line" | "selection"!
349
+ count : number!
350
+ }
351
+ INSERT_TEXT {
352
+ editorId : string!
353
+ text : string!
354
+ }
355
+ SET_MODE {
356
+ editorId : string!
357
+ mode : string!
358
+ caret : "bar" | "block" | "underline"!
359
+ }
100
360
  CHANGE {
101
361
  code : string
102
362
  }
363
+ EDITOR_FOCUS {
364
+ editorId : string!
365
+ }
366
+ EDITOR_BLUR {
367
+ editorId : string!
368
+ }
103
369
  }
104
370
 
105
371
  config {
@@ -187,6 +453,42 @@ orbital CodeBlockOrbital {
187
453
  @label "Show Copy"
188
454
  @description "Show copy button (viewer alias for showCopyButton)"
189
455
  @tier "presentation"
456
+ editorId : string
457
+ @label "Editor Id"
458
+ @description "Stable identity for the keyboard router / plugin host to target this editor. Unset = this instance never receives capability events."
459
+ @tier "presentation"
460
+ onEditorFocus : event = "EDITOR_FOCUS"
461
+ @label "On Editor Focus"
462
+ @description "Declarative bus emit fired when this editor gains focus."
463
+ @tier "presentation"
464
+ onEditorBlur : event = "EDITOR_BLUR"
465
+ @label "On Editor Blur"
466
+ @description "Declarative bus emit fired when this editor loses focus."
467
+ @tier "presentation"
468
+ onMotion : event = "MOTION"
469
+ @label "On Motion"
470
+ @description "Declarative bus listen: move the cursor per the vim-style motion vocabulary."
471
+ @tier "presentation"
472
+ onOperate : event = "OPERATE"
473
+ @label "On Operate"
474
+ @description "Declarative bus listen: apply a text operator over a motion's range."
475
+ @tier "presentation"
476
+ onInsertText : event = "INSERT_TEXT"
477
+ @label "On Insert Text"
478
+ @description "Declarative bus listen: insert literal text at the cursor."
479
+ @tier "presentation"
480
+ onSetMode : event = "SET_MODE"
481
+ @label "On Set Mode"
482
+ @description "Declarative bus listen: switch editor mode and caret style."
483
+ @tier "presentation"
484
+ motions : ["left" | "right" | "up" | "down" | "word-forward" | "word-back" | "word-end" | "line-start" | "line-end" | "first-nonblank" | "doc-start" | "doc-end" | "paragraph-forward" | "paragraph-back" | "line" | "selection"] = ["left", "right", "up", "down", "word-forward", "word-back", "word-end", "line-start", "line-end", "first-nonblank", "doc-start", "doc-end", "paragraph-forward", "paragraph-back", "line", "selection"]
485
+ @label "Motions"
486
+ @description "Motion vocabulary this editor accepts. Default: the full `EditorMotion` set."
487
+ @tier "presentation"
488
+ operators : ["delete" | "yank" | "change"] = ["delete", "yank", "change"]
489
+ @label "Operators"
490
+ @description "Operator vocabulary this editor accepts. Default: the full `EditorOperator` set."
491
+ @tier "presentation"
190
492
  }
191
493
  }
192
494
 
@@ -88,7 +88,7 @@ orbital PaginationOrbital {
88
88
  @label "Show Page Size"
89
89
  @description "Show page size selector"
90
90
  @tier "presentation"
91
- pageSizeOptions : [number] = []
91
+ pageSizeOptions : [number] = [10, 20, 50, 100]
92
92
  @label "Page Size Options"
93
93
  @description "Page size options"
94
94
  @tier "presentation"
@@ -154,7 +154,7 @@ orbital TableViewOrbital {
154
154
  @tier "essential"
155
155
  @config.sortEvent -> external {
156
156
  column : string!
157
- direction : string!
157
+ direction : "asc" | "desc"!
158
158
  }
159
159
  @description "Event emitted on sortable-header click: UI:{sortEvent} with { column, direction }."
160
160
  @tier "essential"
@@ -1,5 +1,5 @@
1
1
  app std-choice-gate "1.0.0"
2
- "Headless choice-gate mechanic for side-view boards: a gate of N labeled option platforms where progress stops until the player commits to an answer. Listens BODY_MOVED and judges a gate when the player stands grounded on one of its option platforms (|dx| <= reachX of the option center, |dy| <= reachY of the gate's option plane — the pad-lock touch pattern): the correct option stamps the gate solved + chosen on the shared entity and emits CHOICE_CORRECT once (a solved gate never judges again, so the path stays open); a wrong option emits CHOICE_WRONG carrying the gate id, the chosen optionId, and the option's world position, so the board can bounce the player back and float the gate's hint (the board owns the bounce — the atom only reports). RESTART unsolves every gate. Renders nothing; boards draw the option platforms and labels from the shared entity (the render authority)."
2
+ "Headless choice-gate mechanic for side-view boards: a gate of N labeled option platforms where progress stops until the player commits to an answer. Listens BODY_MOVED and judges a gate when the player stands grounded on one of its option platforms (|dx| <= reachX of the option center, |dy| <= reachY of the gate's option plane — the pad-lock touch pattern): the correct option stamps the gate solved + chosen on the shared entity and emits CHOICE_CORRECT once (a solved gate never judges again, so the path stays open); a wrong option emits CHOICE_WRONG carrying the gate id, the chosen optionId, and the option's world position, so the board can bounce the player back and float the gate's hint (the board owns the bounce — the atom only reports). RESTART unsolves every gate. Renders nothing; boards draw the option platforms and labels from the shared entity (the render authority). Corresponds to the design-sheet field(s): challenge, agency."
3
3
  orbital ChoiceGateOrbital {
4
4
  type ChoiceOption = {
5
5
  id : string!
@@ -1,5 +1,5 @@
1
1
  app std-fx-narrative "1.0.0"
2
- "Headless pedagogy→fx translator for game boards and learning shells: turns high-level narrative events into big transient screen-space or world-space text effects consumed by std-fx-particles / fx-overlay. Levels emit NARRATE { text, style } and get a correctly styled, centered (or positioned) floating text burst without hand-rolling particle structs. Tutorials emit TUTORIAL_SHOW and the atom forwards SHOW to a composed std-tutorial-overlay trait. Renders nothing; centralizes the FX vocabulary so every level's teaching text looks and behaves the same."
2
+ "Headless pedagogy→fx translator for game boards and learning shells: turns high-level narrative events into big transient screen-space or world-space text effects consumed by std-fx-particles / fx-overlay. Levels emit NARRATE { text, style } and get a correctly styled, centered (or positioned) floating text burst without hand-rolling particle structs. Tutorials emit TUTORIAL_SHOW and the atom forwards SHOW to a composed std-tutorial-overlay trait. Renders nothing; centralizes the FX vocabulary so every level's teaching text looks and behaves the same. Corresponds to the design-sheet field(s): feedback."
3
3
 
4
4
  orbital FxNarrativeOrbital {
5
5
  type NarrativeCue = {
@@ -1,5 +1,5 @@
1
1
  app std-fx-particles "1.1.0"
2
- "Headless transient-fx mechanic serving BOTH game boards and learning shells: appends spawned particles on BURST — stamping maxTtl (fade envelope) and bornAt (epoch ms, smooth render interpolation) when absent — decays each entry's ttl every tick, drops the dead ones, and clears on RESTART. Name-blind mechanism: the effect-kind vocabulary is consumer-declared (FxPreset tables at the render call sites). Composed onto a [runtime, shared] entity; renders nothing — the board/shell owns the single render authority (draw-fx-layer for space \"world\", fx-overlay for space \"screen\")."
2
+ "Headless transient-fx mechanic serving BOTH game boards and learning shells: appends spawned particles on BURST — stamping maxTtl (fade envelope) and bornAt (epoch ms, smooth render interpolation) when absent — decays each entry's ttl every tick, drops the dead ones, and clears on RESTART. Name-blind mechanism: the effect-kind vocabulary is consumer-declared (FxPreset tables at the render call sites). Composed onto a [runtime, shared] entity; renders nothing — the board/shell owns the single render authority (draw-fx-layer for space \"world\", fx-overlay for space \"screen\"). Corresponds to the design-sheet field(s): feedback, rewards."
3
3
  orbital FxParticlesOrbital {
4
4
  type Fx = {
5
5
  id : string!