akanjs 3.0.0-alpha.11 → 3.0.0-alpha.13

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 (69) hide show
  1. package/base/symbols.ts +4 -0
  2. package/constant/index.ts +1 -0
  3. package/constant/mask.ts +60 -0
  4. package/dictionary/dictInfo.ts +12 -1
  5. package/fetch/client/fetchClient.ts +9 -0
  6. package/package.json +1 -1
  7. package/server/akanApp.ts +3 -1
  8. package/service/predefinedAdaptor/index.ts +1 -0
  9. package/service/predefinedAdaptor/insightQuery.ts +183 -0
  10. package/signal/mcp/Msg.ts +5 -33
  11. package/store/action.ts +9 -20
  12. package/store/actionTag.ts +28 -0
  13. package/store/agent/AgentBridge.ts +281 -0
  14. package/store/agent/StoreCatalogue.ts +296 -0
  15. package/store/agent/index.ts +3 -0
  16. package/store/agent/types.ts +50 -0
  17. package/store/databaseStateNames.ts +31 -0
  18. package/store/formSetterNames.ts +21 -0
  19. package/store/index.ts +7 -0
  20. package/store/rootStore.ts +2 -1
  21. package/store/sliceRole.ts +36 -0
  22. package/store/state.ts +2 -12
  23. package/store/store.ts +5 -0
  24. package/store/storeInstance.ts +54 -16
  25. package/store/storeRegistry.ts +10 -0
  26. package/types/base/symbols.d.ts +4 -0
  27. package/types/constant/index.d.ts +1 -0
  28. package/types/constant/mask.d.ts +34 -0
  29. package/types/dictionary/dictInfo.d.ts +9 -2
  30. package/types/fetch/client/fetchClient.d.ts +9 -0
  31. package/types/service/predefinedAdaptor/index.d.ts +1 -0
  32. package/types/service/predefinedAdaptor/insightQuery.d.ts +50 -0
  33. package/types/signal/mcp/Msg.d.ts +3 -4
  34. package/types/store/actionTag.d.ts +17 -0
  35. package/types/store/agent/AgentBridge.d.ts +70 -0
  36. package/types/store/agent/StoreCatalogue.d.ts +21 -0
  37. package/types/store/agent/index.d.ts +3 -0
  38. package/types/store/agent/types.d.ts +49 -0
  39. package/types/store/agent.d.ts +1 -0
  40. package/types/store/databaseStateNames.d.ts +25 -0
  41. package/types/store/formSetterNames.d.ts +16 -0
  42. package/types/store/index.d.ts +6 -0
  43. package/types/store/rootStore.d.ts +4 -1
  44. package/types/store/sliceRole.d.ts +25 -0
  45. package/types/store/store.d.ts +4 -1
  46. package/types/store/storeInstance.d.ts +16 -0
  47. package/types/store/storeRegistry.d.ts +3 -0
  48. package/types/ui/Agent/Dock.d.ts +16 -0
  49. package/types/ui/Agent/Section.d.ts +10 -0
  50. package/types/ui/Agent/StateKey.d.ts +15 -0
  51. package/types/ui/Agent/Tool.d.ts +15 -0
  52. package/types/ui/Agent/Transcript.d.ts +13 -0
  53. package/types/ui/Agent/index.d.ts +11 -0
  54. package/types/ui/Agent.d.ts +1 -0
  55. package/types/ui/agentAttrs.d.ts +14 -0
  56. package/types/ui/index.d.ts +2 -0
  57. package/ui/Agent/Dock.tsx +61 -0
  58. package/ui/Agent/Section.tsx +24 -0
  59. package/ui/Agent/StateKey.tsx +42 -0
  60. package/ui/Agent/Tool.tsx +66 -0
  61. package/ui/Agent/Transcript.tsx +33 -0
  62. package/ui/Agent/index.ts +7 -0
  63. package/ui/Button.tsx +2 -0
  64. package/ui/Field.tsx +15 -7
  65. package/ui/Input.tsx +7 -0
  66. package/ui/Select.tsx +2 -1
  67. package/ui/Switch.tsx +2 -0
  68. package/ui/agentAttrs.ts +19 -0
  69. package/ui/index.ts +2 -0
package/ui/Field.tsx CHANGED
@@ -9,6 +9,7 @@ import { AiOutlinePlus } from "react-icons/ai";
9
9
  import { BiHelpCircle, BiTrash, BiX } from "react-icons/bi";
10
10
  import { MdDragIndicator } from "react-icons/md";
11
11
 
12
+ import { agentAttrs } from "./agentAttrs";
12
13
  import { badgeRecipe } from "./Badge";
13
14
  import { buttonRecipe } from "./Button";
14
15
  import { DraggableList } from "./DraggableList";
@@ -186,6 +187,7 @@ const Text = ({
186
187
  <div className={cn("flex flex-col", className)}>
187
188
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
188
189
  <Input
190
+ {...agentAttrs(onChange)}
189
191
  cacheKey={cache ? `${label}-${desc}-text` : undefined}
190
192
  inputStyleType={inputStyleType}
191
193
  value={value ?? ""}
@@ -250,6 +252,7 @@ const Price = ({
250
252
  <div className={cn("flex flex-col", className)}>
251
253
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
252
254
  <Input
255
+ {...agentAttrs(onChange)}
253
256
  inputStyleType={inputStyleType}
254
257
  value={value ?? ""}
255
258
  nullable={nullable}
@@ -316,6 +319,7 @@ const TextArea = ({
316
319
  <div className={cn("flex flex-col", className)}>
317
320
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
318
321
  <Input.TextArea
322
+ {...agentAttrs(onChange)}
319
323
  value={value ?? ""}
320
324
  cacheKey={cache ? `${label}-${desc}-textArea` : undefined}
321
325
  nullable={nullable}
@@ -364,7 +368,7 @@ const Switch = ({
364
368
  offDesc,
365
369
  }: SwitchProps) => {
366
370
  return (
367
- <div className={cn("flex flex-col", className)}>
371
+ <div {...agentAttrs(onChange)} className={cn("flex flex-col", className)}>
368
372
  {label ? <Label className={labelClassName} nullable label={label} desc={desc} /> : null}
369
373
  <div className="flex items-center gap-2">
370
374
  <UiSwitch
@@ -414,7 +418,7 @@ const ToggleSelect = <I extends string | number | boolean | null>({
414
418
  const { l } = usePage();
415
419
  const isEnumValue = isEnum(items as EnumInstance<string, I>);
416
420
  return (
417
- <div className={cn("flex flex-col", className)}>
421
+ <div {...agentAttrs(onChange)} className={cn("flex flex-col", className)}>
418
422
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
419
423
  <UtilToggleSelect
420
424
  className="mt-2"
@@ -471,7 +475,7 @@ const MultiToggleSelect = <I extends string | number | boolean>({
471
475
  const { l } = usePage();
472
476
  const isEnumValue = isEnum(items as EnumInstance<string, I>);
473
477
  return (
474
- <div className={cn("flex flex-col", className)}>
478
+ <div {...agentAttrs(onChange)} className={cn("flex flex-col", className)}>
475
479
  {label ? <Label className={labelClassName} nullable={!!minlength} label={label} desc={desc} /> : null}
476
480
  <UtilToggleSelect.Multi
477
481
  nullable={!minlength}
@@ -538,7 +542,7 @@ const TextList = ({
538
542
  const { l } = usePage();
539
543
  const recipe = useUiRecipe("button") ?? buttonRecipe;
540
544
  return (
541
- <div className={cn("flex flex-col", className)}>
545
+ <div {...agentAttrs(onChange)} className={cn("flex flex-col", className)}>
542
546
  {label ? <Label className={labelClassName} nullable={!minlength} label={label} desc={desc} /> : null}
543
547
  <div className="mb-5 h-full gap-2 rounded-md border border-border p-2">
544
548
  <DraggableList
@@ -653,7 +657,7 @@ const Tags = ({
653
657
  };
654
658
 
655
659
  return (
656
- <div className={cn("flex flex-col", className)}>
660
+ <div {...agentAttrs(onChange)} className={cn("flex flex-col", className)}>
657
661
  {label ? <Label className={labelClassName} nullable={!minlength} label={label} desc={desc} /> : null}
658
662
  <div className="flex w-full flex-wrap items-center gap-1 rounded-md border border-foreground/20 p-2">
659
663
  {value.map((val, idx) => (
@@ -736,7 +740,7 @@ const Date = <Nullable extends boolean>({
736
740
  dateClassName,
737
741
  }: DateProps<Nullable>) => {
738
742
  return (
739
- <div className={cn("flex flex-col", className)}>
743
+ <div {...agentAttrs(onChange)} className={cn("flex flex-col", className)}>
740
744
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
741
745
  {/* FIXME: daysi UI datetime-local 컴포넌트에 max 값 넣으면 오른쪽 끝 짤리는 버그 있음.*/}
742
746
  <input
@@ -874,6 +878,7 @@ const Number = ({
874
878
  <div className={cn("flex flex-col", className)}>
875
879
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} unit={unit} /> : null}
876
880
  <Input.Number
881
+ {...agentAttrs(onChange)}
877
882
  min={min}
878
883
  max={max}
879
884
  cacheKey={cache ? `${label}-${desc}-number` : undefined}
@@ -941,7 +946,7 @@ const DoubleNumber = ({
941
946
  }: DoubleNumberProps) => {
942
947
  const { l } = usePage();
943
948
  return (
944
- <div className={cn("flex flex-col", className)}>
949
+ <div {...agentAttrs(onChange)} className={cn("flex flex-col", className)}>
945
950
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
946
951
  <div className="flex items-center gap-2">
947
952
  <Input.Number
@@ -1031,6 +1036,7 @@ const Email = ({
1031
1036
  <div className={cn("flex flex-col", className)}>
1032
1037
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
1033
1038
  <Input.Email
1039
+ {...agentAttrs(onChange)}
1034
1040
  value={value ?? ""}
1035
1041
  cacheKey={cache ? `${label}-${desc}-email` : undefined}
1036
1042
  nullable={nullable}
@@ -1095,6 +1101,7 @@ const Phone = ({
1095
1101
  <div className={cn("flex flex-col", className)}>
1096
1102
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
1097
1103
  <Input
1104
+ {...agentAttrs(onChange)}
1098
1105
  value={value ?? ""}
1099
1106
  cacheKey={cache ? `${label}-${desc}-phone` : undefined}
1100
1107
  nullable={nullable}
@@ -1165,6 +1172,7 @@ const Password = ({
1165
1172
  {label ? <Label className={labelClassName} nullable={nullable} label={label} desc={desc} /> : null}
1166
1173
  <div className="flex flex-col gap-2">
1167
1174
  <Input.Password
1175
+ {...agentAttrs(onChange)}
1168
1176
  cacheKey={cache ? `${label}-${desc}-password` : undefined}
1169
1177
  value={value ?? ""}
1170
1178
  nullable={nullable}
package/ui/Input.tsx CHANGED
@@ -13,6 +13,7 @@ import React, {
13
13
  } from "react";
14
14
  import { AiOutlineEye, AiOutlineEyeInvisible } from "react-icons/ai";
15
15
 
16
+ import { agentAttrs } from "./agentAttrs";
16
17
  import { inputRecipe } from "./recipe";
17
18
  import { createOverridable, useUiRecipe } from "./UiOverride";
18
19
 
@@ -108,6 +109,7 @@ const DefaultInput = ({
108
109
  {icon ? <div className={cn("flex items-center justify-center", iconClassName)}>{icon}</div> : null}
109
110
  <input
110
111
  {...rest}
112
+ {...agentAttrs(onChange)}
111
113
  ref={inputRef}
112
114
  value={value}
113
115
  onChange={(e) => {
@@ -201,6 +203,7 @@ const DefaultTextArea = ({
201
203
  <div className={cn("relative mb-5", className)}>
202
204
  <textarea
203
205
  {...rest}
206
+ {...agentAttrs(onChange)}
204
207
  ref={inputRef}
205
208
  value={value}
206
209
  onChange={(e) => {
@@ -301,6 +304,7 @@ const DefaultPassword = ({
301
304
  ) : null}
302
305
  <input
303
306
  {...rest}
307
+ {...agentAttrs(onChange)}
304
308
  type={showPassword ? "text" : "password"}
305
309
  ref={inputRef}
306
310
  value={value}
@@ -419,6 +423,7 @@ const DefaultEmail = ({
419
423
  ) : null}
420
424
  <input
421
425
  {...rest}
426
+ {...agentAttrs(onChange)}
422
427
  type="email"
423
428
  value={value}
424
429
  ref={inputRef}
@@ -586,6 +591,7 @@ const DefaultNumber = ({
586
591
  ) : null}
587
592
  <input
588
593
  {...rest}
594
+ {...agentAttrs(onChange)}
589
595
  ref={inputRef}
590
596
  value={formatValue}
591
597
  onKeyDown={handleKeyDown}
@@ -623,6 +629,7 @@ const DefaultCheckbox = ({ checked, onChange, className, ...rest }: CheckboxProp
623
629
  return (
624
630
  <input
625
631
  {...rest}
632
+ {...agentAttrs(onChange)}
626
633
  type="checkbox"
627
634
  checked={checked}
628
635
  className={cn("size-5 accent-primary", className)}
package/ui/Select.tsx CHANGED
@@ -7,6 +7,7 @@ import { BiCheck, BiChevronDown, BiX } from "react-icons/bi";
7
7
  import { BsQuestionCircleFill } from "react-icons/bs";
8
8
  import { TiDelete } from "react-icons/ti";
9
9
 
10
+ import { agentAttrs } from "./agentAttrs";
10
11
  import { useUiOverride } from "./UiOverride";
11
12
 
12
13
  interface LabelOption<T> {
@@ -164,7 +165,7 @@ const DefaultSelect = <
164
165
  }, [value]);
165
166
 
166
167
  return (
167
- <div className={cn("relative min-w-[150px]", className)} ref={dropdownRef}>
168
+ <div {...agentAttrs(onChange)} className={cn("relative min-w-[150px]", className)} ref={dropdownRef}>
168
169
  <div
169
170
  data-open={isOpen}
170
171
  className={cn(
package/ui/Switch.tsx CHANGED
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "akanjs/client";
3
3
  import { useState } from "react";
4
+ import { agentAttrs } from "./agentAttrs";
4
5
 
5
6
  export interface SwitchProps {
6
7
  checked?: boolean;
@@ -36,6 +37,7 @@ export const Switch = ({
36
37
  const state = isChecked ? "checked" : "unchecked";
37
38
  return (
38
39
  <button
40
+ {...agentAttrs(onChange)}
39
41
  type="button"
40
42
  role="switch"
41
43
  aria-checked={isChecked}
@@ -0,0 +1,19 @@
1
+ import { actionTagOf } from "akanjs/store";
2
+
3
+ /**
4
+ * The `data-akan-*` attributes for a handler the caller passed by reference.
5
+ *
6
+ * `{}` when the handler is an inline arrow, which is the honest answer: a closure the caller wrote says nothing
7
+ * about what it does, and a guessed annotation is worse than none. The house form for a model field is the setter
8
+ * itself (`onChange={st.do.setNameOnUser}`), so the fields that matter are annotated without an app writing anything.
9
+ *
10
+ * What it buys, beyond an in-page agent: an accessibility tree and E2E selectors that name the action rather than a
11
+ * class, and an external browser agent — one this framework has no bridge into — reading the same names.
12
+ */
13
+ export const agentAttrs = (
14
+ handler: unknown,
15
+ ): { "data-akan-action"?: string; "data-akan-state"?: string } | Record<string, never> => {
16
+ const tag = actionTagOf(handler);
17
+ if (!tag) return {};
18
+ return { "data-akan-action": tag.action, ...(tag.state ? { "data-akan-state": tag.state } : {}) };
19
+ };
package/ui/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { Agent } from "./Agent";
2
+ export { agentAttrs } from "./agentAttrs";
1
3
  export { animated } from "./animated";
2
4
  export { Badge } from "./Badge";
3
5
  export { BottomSheet, type BottomSheetRef } from "./BottomSheet";