@jaimevalasek/aioson 1.3.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 (288) hide show
  1. package/CHANGELOG.md +456 -0
  2. package/CODE_OF_CONDUCT.md +12 -0
  3. package/CONTRIBUTING.md +13 -0
  4. package/LICENSE +21 -0
  5. package/README.md +254 -0
  6. package/bin/aioson.js +4 -0
  7. package/docs/en/cli-reference.md +398 -0
  8. package/docs/en/i18n.md +52 -0
  9. package/docs/en/json-schemas.md +41 -0
  10. package/docs/en/mcp.md +56 -0
  11. package/docs/en/parallel.md +82 -0
  12. package/docs/en/qa-browser.md +339 -0
  13. package/docs/en/release-flow.md +22 -0
  14. package/docs/en/release-notes-template.md +41 -0
  15. package/docs/en/release.md +28 -0
  16. package/docs/en/schemas/agent-prompt.schema.json +17 -0
  17. package/docs/en/schemas/agents.schema.json +32 -0
  18. package/docs/en/schemas/context-validate.schema.json +36 -0
  19. package/docs/en/schemas/doctor.schema.json +89 -0
  20. package/docs/en/schemas/error.schema.json +24 -0
  21. package/docs/en/schemas/i18n-add.schema.json +15 -0
  22. package/docs/en/schemas/index.json +116 -0
  23. package/docs/en/schemas/info.schema.json +39 -0
  24. package/docs/en/schemas/init.schema.json +48 -0
  25. package/docs/en/schemas/install.schema.json +60 -0
  26. package/docs/en/schemas/locale-apply.schema.json +30 -0
  27. package/docs/en/schemas/mcp-doctor.schema.json +95 -0
  28. package/docs/en/schemas/mcp-init.schema.json +122 -0
  29. package/docs/en/schemas/package-test.schema.json +24 -0
  30. package/docs/en/schemas/parallel-assign.schema.json +57 -0
  31. package/docs/en/schemas/parallel-doctor.schema.json +86 -0
  32. package/docs/en/schemas/parallel-init.schema.json +53 -0
  33. package/docs/en/schemas/parallel-status.schema.json +94 -0
  34. package/docs/en/schemas/setup-context.schema.json +39 -0
  35. package/docs/en/schemas/smoke.schema.json +23 -0
  36. package/docs/en/schemas/update.schema.json +48 -0
  37. package/docs/en/schemas/workflow-plan.schema.json +30 -0
  38. package/docs/en/web3.md +54 -0
  39. package/docs/pt/README.md +46 -0
  40. package/docs/pt/advisor-spec.md +335 -0
  41. package/docs/pt/agentes.md +453 -0
  42. package/docs/pt/cenarios.md +1230 -0
  43. package/docs/pt/clientes-ai.md +224 -0
  44. package/docs/pt/comandos-cli.md +511 -0
  45. package/docs/pt/genome-3.0-spec.md +296 -0
  46. package/docs/pt/guia-engineer.md +226 -0
  47. package/docs/pt/inicio-rapido.md +138 -0
  48. package/docs/pt/profiler-system.md +214 -0
  49. package/docs/pt/runtime-observability.md +72 -0
  50. package/docs/pt/squad-genoma.md +777 -0
  51. package/docs/pt/web3.md +797 -0
  52. package/docs/testing/genome-2.0-manual-regression.md +23 -0
  53. package/docs/testing/genome-2.0-matrix.md +36 -0
  54. package/docs/testing/genome-2.0-rollout.md +184 -0
  55. package/package.json +50 -0
  56. package/src/agents.js +56 -0
  57. package/src/cli.js +497 -0
  58. package/src/commands/agents.js +142 -0
  59. package/src/commands/cloud.js +1767 -0
  60. package/src/commands/config.js +90 -0
  61. package/src/commands/context-validate.js +91 -0
  62. package/src/commands/doctor.js +123 -0
  63. package/src/commands/genome-doctor.js +41 -0
  64. package/src/commands/genome-migrate.js +49 -0
  65. package/src/commands/i18n-add.js +56 -0
  66. package/src/commands/info.js +41 -0
  67. package/src/commands/init.js +75 -0
  68. package/src/commands/install.js +68 -0
  69. package/src/commands/locale-apply.js +51 -0
  70. package/src/commands/locale-diff.js +126 -0
  71. package/src/commands/mcp-doctor.js +406 -0
  72. package/src/commands/mcp-init.js +379 -0
  73. package/src/commands/package-e2e.js +273 -0
  74. package/src/commands/parallel-assign.js +403 -0
  75. package/src/commands/parallel-doctor.js +437 -0
  76. package/src/commands/parallel-init.js +249 -0
  77. package/src/commands/parallel-status.js +290 -0
  78. package/src/commands/qa-doctor.js +185 -0
  79. package/src/commands/qa-init.js +161 -0
  80. package/src/commands/qa-report.js +58 -0
  81. package/src/commands/qa-run.js +873 -0
  82. package/src/commands/qa-scan.js +337 -0
  83. package/src/commands/runtime.js +948 -0
  84. package/src/commands/scan-project.js +1107 -0
  85. package/src/commands/setup-context.js +650 -0
  86. package/src/commands/smoke.js +426 -0
  87. package/src/commands/squad-doctor.js +358 -0
  88. package/src/commands/squad-export.js +46 -0
  89. package/src/commands/squad-pipeline.js +97 -0
  90. package/src/commands/squad-repair-genomes.js +39 -0
  91. package/src/commands/squad-status.js +424 -0
  92. package/src/commands/squad-validate.js +230 -0
  93. package/src/commands/test-agents.js +194 -0
  94. package/src/commands/update.js +55 -0
  95. package/src/commands/workflow-next.js +594 -0
  96. package/src/commands/workflow-plan.js +108 -0
  97. package/src/constants.js +314 -0
  98. package/src/context-parse-reason.js +22 -0
  99. package/src/context-writer.js +150 -0
  100. package/src/context.js +217 -0
  101. package/src/detector.js +261 -0
  102. package/src/doctor.js +289 -0
  103. package/src/execution-gateway.js +461 -0
  104. package/src/genome-files.js +198 -0
  105. package/src/genome-format.js +442 -0
  106. package/src/genome-schema.js +215 -0
  107. package/src/genomes/bindings.js +281 -0
  108. package/src/genomes.js +467 -0
  109. package/src/i18n/index.js +103 -0
  110. package/src/i18n/messages/en.js +784 -0
  111. package/src/i18n/messages/es.js +718 -0
  112. package/src/i18n/messages/fr.js +725 -0
  113. package/src/i18n/messages/pt-BR.js +818 -0
  114. package/src/i18n/scaffold.js +64 -0
  115. package/src/installer.js +232 -0
  116. package/src/lib/genomes/compat.js +206 -0
  117. package/src/lib/genomes/migrate.js +90 -0
  118. package/src/lib/squads/genome-repair.js +49 -0
  119. package/src/locales.js +84 -0
  120. package/src/onboarding.js +305 -0
  121. package/src/parser.js +53 -0
  122. package/src/prompt-tool.js +20 -0
  123. package/src/qa-html-report.js +472 -0
  124. package/src/runtime-store.js +1527 -0
  125. package/src/squads/apply-genome.js +21 -0
  126. package/src/squads/genome-binding-service.js +154 -0
  127. package/src/updater.js +32 -0
  128. package/src/utils.js +46 -0
  129. package/src/version.js +50 -0
  130. package/template/.aioson/advisors/.gitkeep +1 -0
  131. package/template/.aioson/agents/analyst.md +225 -0
  132. package/template/.aioson/agents/architect.md +221 -0
  133. package/template/.aioson/agents/dev.md +201 -0
  134. package/template/.aioson/agents/discovery-design-doc.md +196 -0
  135. package/template/.aioson/agents/genoma.md +300 -0
  136. package/template/.aioson/agents/orchestrator.md +107 -0
  137. package/template/.aioson/agents/pm.md +89 -0
  138. package/template/.aioson/agents/product.md +361 -0
  139. package/template/.aioson/agents/profiler-enricher.md +266 -0
  140. package/template/.aioson/agents/profiler-forge.md +188 -0
  141. package/template/.aioson/agents/profiler-researcher.md +245 -0
  142. package/template/.aioson/agents/qa.md +344 -0
  143. package/template/.aioson/agents/setup.md +381 -0
  144. package/template/.aioson/agents/squad.md +837 -0
  145. package/template/.aioson/agents/ux-ui.md +416 -0
  146. package/template/.aioson/config.md +56 -0
  147. package/template/.aioson/context/.gitkeep +0 -0
  148. package/template/.aioson/context/parallel/.gitkeep +0 -0
  149. package/template/.aioson/context/spec.md.template +37 -0
  150. package/template/.aioson/genomas/.gitkeep +0 -0
  151. package/template/.aioson/locales/en/agents/analyst.md +214 -0
  152. package/template/.aioson/locales/en/agents/architect.md +210 -0
  153. package/template/.aioson/locales/en/agents/dev.md +187 -0
  154. package/template/.aioson/locales/en/agents/discovery-design-doc.md +27 -0
  155. package/template/.aioson/locales/en/agents/genoma.md +212 -0
  156. package/template/.aioson/locales/en/agents/orchestrator.md +105 -0
  157. package/template/.aioson/locales/en/agents/pm.md +77 -0
  158. package/template/.aioson/locales/en/agents/product.md +310 -0
  159. package/template/.aioson/locales/en/agents/profiler-enricher.md +5 -0
  160. package/template/.aioson/locales/en/agents/profiler-forge.md +5 -0
  161. package/template/.aioson/locales/en/agents/profiler-researcher.md +5 -0
  162. package/template/.aioson/locales/en/agents/qa.md +214 -0
  163. package/template/.aioson/locales/en/agents/setup.md +342 -0
  164. package/template/.aioson/locales/en/agents/squad.md +247 -0
  165. package/template/.aioson/locales/en/agents/ux-ui.md +320 -0
  166. package/template/.aioson/locales/es/agents/analyst.md +203 -0
  167. package/template/.aioson/locales/es/agents/architect.md +208 -0
  168. package/template/.aioson/locales/es/agents/dev.md +183 -0
  169. package/template/.aioson/locales/es/agents/discovery-design-doc.md +19 -0
  170. package/template/.aioson/locales/es/agents/genoma.md +102 -0
  171. package/template/.aioson/locales/es/agents/orchestrator.md +108 -0
  172. package/template/.aioson/locales/es/agents/pm.md +81 -0
  173. package/template/.aioson/locales/es/agents/product.md +310 -0
  174. package/template/.aioson/locales/es/agents/profiler-enricher.md +5 -0
  175. package/template/.aioson/locales/es/agents/profiler-forge.md +5 -0
  176. package/template/.aioson/locales/es/agents/profiler-researcher.md +5 -0
  177. package/template/.aioson/locales/es/agents/qa.md +163 -0
  178. package/template/.aioson/locales/es/agents/setup.md +347 -0
  179. package/template/.aioson/locales/es/agents/squad.md +247 -0
  180. package/template/.aioson/locales/es/agents/ux-ui.md +201 -0
  181. package/template/.aioson/locales/fr/agents/analyst.md +203 -0
  182. package/template/.aioson/locales/fr/agents/architect.md +208 -0
  183. package/template/.aioson/locales/fr/agents/dev.md +183 -0
  184. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +19 -0
  185. package/template/.aioson/locales/fr/agents/genoma.md +102 -0
  186. package/template/.aioson/locales/fr/agents/orchestrator.md +108 -0
  187. package/template/.aioson/locales/fr/agents/pm.md +81 -0
  188. package/template/.aioson/locales/fr/agents/product.md +310 -0
  189. package/template/.aioson/locales/fr/agents/profiler-enricher.md +5 -0
  190. package/template/.aioson/locales/fr/agents/profiler-forge.md +5 -0
  191. package/template/.aioson/locales/fr/agents/profiler-researcher.md +5 -0
  192. package/template/.aioson/locales/fr/agents/qa.md +163 -0
  193. package/template/.aioson/locales/fr/agents/setup.md +347 -0
  194. package/template/.aioson/locales/fr/agents/squad.md +247 -0
  195. package/template/.aioson/locales/fr/agents/ux-ui.md +201 -0
  196. package/template/.aioson/locales/pt-BR/agents/analyst.md +217 -0
  197. package/template/.aioson/locales/pt-BR/agents/architect.md +213 -0
  198. package/template/.aioson/locales/pt-BR/agents/dev.md +198 -0
  199. package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +198 -0
  200. package/template/.aioson/locales/pt-BR/agents/genoma.md +297 -0
  201. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +108 -0
  202. package/template/.aioson/locales/pt-BR/agents/pm.md +81 -0
  203. package/template/.aioson/locales/pt-BR/agents/product.md +316 -0
  204. package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +5 -0
  205. package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +5 -0
  206. package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +5 -0
  207. package/template/.aioson/locales/pt-BR/agents/qa.md +217 -0
  208. package/template/.aioson/locales/pt-BR/agents/setup.md +371 -0
  209. package/template/.aioson/locales/pt-BR/agents/squad.md +772 -0
  210. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +322 -0
  211. package/template/.aioson/mcp/servers.md +24 -0
  212. package/template/.aioson/profiler-reports/.gitkeep +1 -0
  213. package/template/.aioson/schemas/content-blueprint.schema.json +30 -0
  214. package/template/.aioson/schemas/genome-meta.schema.json +150 -0
  215. package/template/.aioson/schemas/genome.schema.json +115 -0
  216. package/template/.aioson/schemas/readiness.schema.json +27 -0
  217. package/template/.aioson/schemas/squad-blueprint.schema.json +172 -0
  218. package/template/.aioson/schemas/squad-manifest.schema.json +276 -0
  219. package/template/.aioson/skills/dynamic/README.md +30 -0
  220. package/template/.aioson/skills/dynamic/cardano-docs.md +16 -0
  221. package/template/.aioson/skills/dynamic/ethereum-docs.md +17 -0
  222. package/template/.aioson/skills/dynamic/flux-ui-docs.md +13 -0
  223. package/template/.aioson/skills/dynamic/laravel-docs.md +41 -0
  224. package/template/.aioson/skills/dynamic/npm-packages.md +16 -0
  225. package/template/.aioson/skills/dynamic/solana-docs.md +16 -0
  226. package/template/.aioson/skills/references/premium-command-center-ui/master-application-prompt.md +79 -0
  227. package/template/.aioson/skills/references/premium-command-center-ui/operational-ux-playbook.md +253 -0
  228. package/template/.aioson/skills/references/premium-command-center-ui/quality-validation-checklist.md +82 -0
  229. package/template/.aioson/skills/references/premium-command-center-ui/visual-system-and-component-patterns.md +270 -0
  230. package/template/.aioson/skills/static/django-patterns.md +342 -0
  231. package/template/.aioson/skills/static/fastapi-patterns.md +344 -0
  232. package/template/.aioson/skills/static/filament-patterns.md +267 -0
  233. package/template/.aioson/skills/static/flux-ui-components.md +262 -0
  234. package/template/.aioson/skills/static/git-conventions.md +227 -0
  235. package/template/.aioson/skills/static/interface-design.md +372 -0
  236. package/template/.aioson/skills/static/jetstream-setup.md +200 -0
  237. package/template/.aioson/skills/static/laravel-conventions.md +491 -0
  238. package/template/.aioson/skills/static/nextjs-patterns.md +321 -0
  239. package/template/.aioson/skills/static/node-express-patterns.md +317 -0
  240. package/template/.aioson/skills/static/node-typescript-patterns.md +282 -0
  241. package/template/.aioson/skills/static/premium-command-center-ui.md +190 -0
  242. package/template/.aioson/skills/static/rails-conventions.md +307 -0
  243. package/template/.aioson/skills/static/react-motion-patterns.md +577 -0
  244. package/template/.aioson/skills/static/static-html-patterns.md +1935 -0
  245. package/template/.aioson/skills/static/tall-stack-patterns.md +286 -0
  246. package/template/.aioson/skills/static/ui-ux-modern.md +75 -0
  247. package/template/.aioson/skills/static/web3-cardano-patterns.md +337 -0
  248. package/template/.aioson/skills/static/web3-ethereum-patterns.md +310 -0
  249. package/template/.aioson/skills/static/web3-security-checklist.md +284 -0
  250. package/template/.aioson/skills/static/web3-solana-patterns.md +324 -0
  251. package/template/.aioson/squads/.artisan/.gitkeep +0 -0
  252. package/template/.aioson/squads/.gitkeep +0 -0
  253. package/template/.aioson/squads/memory.md +5 -0
  254. package/template/.aioson/tasks/squad-analyze.md +83 -0
  255. package/template/.aioson/tasks/squad-create.md +99 -0
  256. package/template/.aioson/tasks/squad-design.md +100 -0
  257. package/template/.aioson/tasks/squad-export.md +20 -0
  258. package/template/.aioson/tasks/squad-extend.md +68 -0
  259. package/template/.aioson/tasks/squad-pipeline.md +122 -0
  260. package/template/.aioson/tasks/squad-repair.md +85 -0
  261. package/template/.aioson/tasks/squad-validate.md +58 -0
  262. package/template/.aioson/templates/squads/content-basic/template.json +21 -0
  263. package/template/.aioson/templates/squads/media-channel/template.json +24 -0
  264. package/template/.aioson/templates/squads/research-analysis/template.json +22 -0
  265. package/template/.aioson/templates/squads/software-delivery/template.json +21 -0
  266. package/template/.claude/commands/aioson/analyst.md +5 -0
  267. package/template/.claude/commands/aioson/architect.md +5 -0
  268. package/template/.claude/commands/aioson/dev.md +5 -0
  269. package/template/.claude/commands/aioson/orchestrator.md +5 -0
  270. package/template/.claude/commands/aioson/pm.md +5 -0
  271. package/template/.claude/commands/aioson/qa.md +5 -0
  272. package/template/.claude/commands/aioson/setup.md +5 -0
  273. package/template/.claude/commands/aioson/ux-ui.md +5 -0
  274. package/template/.gemini/GEMINI.md +10 -0
  275. package/template/.gemini/commands/aios-analyst.toml +4 -0
  276. package/template/.gemini/commands/aios-architect.toml +7 -0
  277. package/template/.gemini/commands/aios-dev.toml +8 -0
  278. package/template/.gemini/commands/aios-discovery-design-doc.toml +4 -0
  279. package/template/.gemini/commands/aios-orchestrator.toml +8 -0
  280. package/template/.gemini/commands/aios-pm.toml +8 -0
  281. package/template/.gemini/commands/aios-product.toml +4 -0
  282. package/template/.gemini/commands/aios-qa.toml +6 -0
  283. package/template/.gemini/commands/aios-setup.toml +3 -0
  284. package/template/.gemini/commands/aios-ux-ui.toml +8 -0
  285. package/template/AGENTS.md +67 -0
  286. package/template/CLAUDE.md +31 -0
  287. package/template/OPENCODE.md +24 -0
  288. package/template/aioson-models.json +40 -0
@@ -0,0 +1,286 @@
1
+ # TALL Stack Patterns
2
+
3
+ > Tailwind + Alpine.js + Livewire + Laravel. Full-stack PHP monolith done right.
4
+
5
+ ---
6
+
7
+ ## Architecture: what goes where
8
+
9
+ ```
10
+ Livewire → stateful server-side UI (forms, tables, modals, real-time updates)
11
+ Alpine.js → lightweight client interactivity (toggles, dropdowns, local UI state)
12
+ Tailwind → all styling — never write custom CSS for layout or spacing
13
+ Blade → templating, layouts, shared components
14
+ Flux UI → pre-built component library — always check here first
15
+ ```
16
+
17
+ **Rule:** If Alpine.js logic exceeds ~20 lines, move the state to Livewire.
18
+
19
+ ---
20
+
21
+ ## Livewire component structure
22
+
23
+ ```php
24
+ // app/Livewire/Appointments/CreateForm.php
25
+ class CreateForm extends Component
26
+ {
27
+ public int $doctorId = 0;
28
+ public string $date = '';
29
+ public string $notes = '';
30
+
31
+ protected array $rules = [
32
+ 'doctorId' => 'required|exists:doctors,id',
33
+ 'date' => 'required|date|after:today',
34
+ 'notes' => 'nullable|string|max:500',
35
+ ];
36
+
37
+ // Real-time validation on field change
38
+ public function updated(string $field): void
39
+ {
40
+ $this->validateOnly($field);
41
+ }
42
+
43
+ public function submit(): void
44
+ {
45
+ $this->validate();
46
+ $appointment = (new CreateAppointmentAction)->execute(
47
+ auth()->user(),
48
+ AppointmentData::from($this->only(['doctorId', 'date', 'notes']))
49
+ );
50
+ $this->dispatch('appointment-created', id: $appointment->id);
51
+ $this->reset(['doctorId', 'date', 'notes']);
52
+ session()->flash('success', 'Appointment booked.');
53
+ }
54
+
55
+ public function render(): View
56
+ {
57
+ return view('livewire.appointments.create-form', [
58
+ 'doctors' => Doctor::orderBy('name')->get(),
59
+ ]);
60
+ }
61
+ }
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Livewire — inter-component events
67
+
68
+ ```php
69
+ // Child dispatches
70
+ $this->dispatch('appointment-created', id: $appointment->id);
71
+
72
+ // Parent listens
73
+ #[On('appointment-created')]
74
+ public function refresh(): void
75
+ {
76
+ $this->appointments = Appointment::withRelations()->latest()->paginate(20);
77
+ }
78
+
79
+ // Target a specific component
80
+ $this->dispatch('refresh')->to(AppointmentList::class);
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Livewire — lazy loading for expensive components
86
+
87
+ ```html
88
+ <!-- Defer until visible in viewport -->
89
+ <livewire:dashboard-stats lazy />
90
+ ```
91
+
92
+ ```php
93
+ // Component shows skeleton while loading
94
+ public function placeholder(): View
95
+ {
96
+ return view('livewire.placeholders.stats-skeleton');
97
+ }
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Alpine.js — keep it lightweight
103
+
104
+ Use Alpine for pure UI state that does not involve the server.
105
+
106
+ ```html
107
+ <!-- Toggle visibility -->
108
+ <div x-data="{ open: false }" @click.outside="open = false">
109
+ <button @click="open = !open">Options</button>
110
+ <div x-show="open" x-transition>
111
+ <a href="#">Edit</a>
112
+ <a href="#">Delete</a>
113
+ </div>
114
+ </div>
115
+
116
+ <!-- Confirm before destructive Livewire action -->
117
+ <button
118
+ x-data
119
+ @click="if (confirm('Delete this appointment?')) $wire.delete({{ $appointment->id }})"
120
+ class="text-red-600 hover:underline"
121
+ >
122
+ Delete
123
+ </button>
124
+
125
+ <!-- Copy to clipboard -->
126
+ <div x-data="{ copied: false }">
127
+ <button @click="navigator.clipboard.writeText('{{ $link }}'); copied = true; setTimeout(() => copied = false, 2000)">
128
+ <span x-text="copied ? 'Copied!' : 'Copy link'"></span>
129
+ </button>
130
+ </div>
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Tailwind — design system discipline
136
+
137
+ Always use Tailwind's spacing scale. Never use arbitrary values for standard spacing.
138
+
139
+ ```html
140
+ <!-- WRONG -->
141
+ <div class="p-[17px] mt-[22px] text-[15px]">
142
+
143
+ <!-- RIGHT -->
144
+ <div class="p-4 mt-6 text-sm">
145
+ ```
146
+
147
+ Define tokens in `tailwind.config.js`:
148
+
149
+ ```js
150
+ module.exports = {
151
+ theme: {
152
+ extend: {
153
+ colors: {
154
+ brand: { DEFAULT: '#4F46E5', dark: '#4338CA' },
155
+ },
156
+ spacing: {
157
+ sidebar: '280px',
158
+ },
159
+ },
160
+ },
161
+ }
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Flux UI — use before building custom
167
+
168
+ ```html
169
+ <!-- Buttons -->
170
+ <flux:button variant="primary">Save</flux:button>
171
+ <flux:button variant="ghost" icon="trash">Delete</flux:button>
172
+ <flux:button variant="danger" wire:click="delete" wire:loading.attr="disabled">
173
+ <wire:loading wire:target="delete">Deleting...</wire:loading>
174
+ <wire:loading.remove wire:target="delete">Delete</wire:loading.remove>
175
+ </flux:button>
176
+
177
+ <!-- Form inputs -->
178
+ <flux:input wire:model.live="email" label="Email" type="email" />
179
+ <flux:textarea wire:model="notes" label="Notes" rows="4" />
180
+ <flux:select wire:model="doctorId" label="Doctor">
181
+ <flux:select.option value="">Select a doctor</flux:select.option>
182
+ @foreach ($doctors as $doctor)
183
+ <flux:select.option value="{{ $doctor->id }}">{{ $doctor->name }}</flux:select.option>
184
+ @endforeach
185
+ </flux:select>
186
+
187
+ <!-- Modal with confirmation -->
188
+ <flux:modal name="confirm-delete">
189
+ <flux:heading>Delete appointment?</flux:heading>
190
+ <flux:text>This action cannot be undone.</flux:text>
191
+ <div class="flex gap-2 mt-4">
192
+ <flux:button variant="danger" wire:click="delete">Delete</flux:button>
193
+ <flux:modal.close>Cancel</flux:modal.close>
194
+ </div>
195
+ </flux:modal>
196
+ <flux:modal.trigger name="confirm-delete">
197
+ <flux:button variant="ghost" icon="trash">Delete</flux:button>
198
+ </flux:modal.trigger>
199
+
200
+ <!-- Table -->
201
+ <flux:table>
202
+ <flux:columns>
203
+ <flux:column>Patient</flux:column>
204
+ <flux:column>Date</flux:column>
205
+ <flux:column>Status</flux:column>
206
+ </flux:columns>
207
+ <flux:rows>
208
+ @foreach ($appointments as $appointment)
209
+ <flux:row>
210
+ <flux:cell>{{ $appointment->patient->name }}</flux:cell>
211
+ <flux:cell>{{ $appointment->date->format('M d, Y H:i') }}</flux:cell>
212
+ <flux:cell><flux:badge>{{ $appointment->status }}</flux:badge></flux:cell>
213
+ </flux:row>
214
+ @endforeach
215
+ </flux:rows>
216
+ </flux:table>
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Blade layout structure
222
+
223
+ ```
224
+ resources/views/
225
+ components/
226
+ layouts/
227
+ app.blade.php ← authenticated shell (nav, sidebar)
228
+ guest.blade.php ← public shell (centered, minimal)
229
+ ui/
230
+ card.blade.php ← reusable card wrapper
231
+ empty-state.blade.php
232
+ page-header.blade.php
233
+ livewire/
234
+ appointments/
235
+ create-form.blade.php
236
+ list.blade.php
237
+ placeholders/
238
+ stats-skeleton.blade.php
239
+ pages/
240
+ appointments/
241
+ index.blade.php
242
+ show.blade.php
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Performance
248
+
249
+ ```php
250
+ // Always paginate Livewire lists — never ->get() on unbounded queries
251
+ public function render(): View
252
+ {
253
+ return view('livewire.appointments.list', [
254
+ 'appointments' => Appointment::withRelations()
255
+ ->when($this->search, fn ($q) =>
256
+ $q->where('notes', 'like', "%{$this->search}%"))
257
+ ->latest()
258
+ ->paginate(20),
259
+ ]);
260
+ }
261
+
262
+ // Cache reference data with computed properties
263
+ public function getDoctorsProperty(): Collection
264
+ {
265
+ return Cache::remember('doctors.active', now()->addMinutes(5), fn () =>
266
+ Doctor::active()->orderBy('name')->get()
267
+ );
268
+ }
269
+ ```
270
+
271
+ ---
272
+
273
+ ## ALWAYS
274
+ - `wire:model.live` for real-time field validation
275
+ - `$this->validateOnly($field)` in `updated()`
276
+ - `#[On('event')]` for component communication
277
+ - `paginate()` for all list queries
278
+ - Flux UI components before custom Blade components
279
+ - `x-transition` for smooth Alpine.js reveals
280
+
281
+ ## NEVER
282
+ - Database queries in Blade templates
283
+ - Alpine.js managing server state or API calls
284
+ - `->get()` on unbounded Eloquent queries in Livewire
285
+ - Custom CSS when a Tailwind utility exists
286
+ - Unguarded public Livewire properties (validate everything)
@@ -0,0 +1,75 @@
1
+ # Modern UI/UX Guidelines
2
+
3
+ ## Goal
4
+ Ship interfaces that feel intentional, modern, and production-ready without over-designing beyond project scope.
5
+
6
+ ## Core-Lite balance
7
+ - Follow AIOS Core quality discipline (explicit decisions, consistency, UX clarity).
8
+ - Keep AIOSON delivery lean (small scope, direct implementation guidance, low artifact overhead).
9
+
10
+ ## Core principles
11
+ - Clarity before decoration: users should immediately understand the primary action.
12
+ - One visual direction per product area: typography, color, and component density must be consistent.
13
+ - Reuse before reinventing: prioritize existing stack UI libraries and primitives.
14
+ - Accessibility is default, not optional.
15
+
16
+ ## Layout and hierarchy
17
+ - Define a spacing scale (for example 4/8/12/16/24/32) and keep it consistent.
18
+ - Keep a clear reading order:
19
+ 1. Page intent
20
+ 2. Primary action
21
+ 3. Supporting data
22
+ - Prefer shallow nesting in cards and panels to reduce cognitive load.
23
+
24
+ ## Typography and color
25
+ - Use a predictable type scale with clear role mapping:
26
+ - page title
27
+ - section title
28
+ - body
29
+ - helper/meta text
30
+ - Keep contrast high for critical text and controls.
31
+ - Use semantic color roles (primary/success/warning/danger/info) instead of arbitrary one-off colors.
32
+
33
+ ## Component quality checklist
34
+ For every major component, define:
35
+ - default state
36
+ - hover/focus/active/disabled states
37
+ - loading skeleton/spinner behavior
38
+ - empty state
39
+ - error state with recovery action
40
+ - success confirmation when relevant
41
+
42
+ ## Forms and validation
43
+ - Put labels outside placeholders (placeholders are hints, not labels).
44
+ - Validate as early as possible without being noisy.
45
+ - Show inline field errors and one global summary for multi-field failures.
46
+ - Disable destructive actions while submitting and show progress feedback.
47
+
48
+ ## Responsive behavior
49
+ - Design mobile-first, then scale up.
50
+ - Ensure key actions are reachable with one hand on mobile.
51
+ - Avoid dense tables on small screens; use stacked cards or summary rows.
52
+
53
+ ## Accessibility baseline
54
+ - Semantic HTML and proper landmarks.
55
+ - Full keyboard navigation and visible focus states.
56
+ - Click/tap targets large enough for touch.
57
+ - Meaning not conveyed by color alone.
58
+
59
+ ## Motion and feedback
60
+ - Use motion to clarify transitions, not as decoration.
61
+ - Keep transitions short and consistent.
62
+ - Avoid blocking animations for critical workflows.
63
+
64
+ ## Stack-specific guidance
65
+ - Laravel + TALL: prefer Livewire + Alpine patterns and existing Blade components.
66
+ - Filament admin: prefer Resources and built-in actions before custom UI.
67
+ - Flux UI: use Flux primitives first and keep custom wrappers minimal.
68
+ - Next.js/React: keep component boundaries clean and avoid unnecessary client state.
69
+
70
+ ## Handoff quality
71
+ When passing to implementation:
72
+ - provide component mapping to real library components
73
+ - include state matrix (loading/empty/error/success/permission)
74
+ - include responsive and accessibility notes
75
+ - keep the spec concise enough for direct coding
@@ -0,0 +1,337 @@
1
+ # Web3 Cardano Patterns
2
+
3
+ > eUTxO model, Aiken validators, and off-chain transaction building. Think in UTxOs, not accounts.
4
+
5
+ ---
6
+
7
+ ## The eUTxO model — mental model first
8
+
9
+ Cardano uses the **Extended UTxO (eUTxO)** model. Before writing any validator, understand:
10
+
11
+ ```
12
+ UTxO (Unspent Transaction Output):
13
+ ├── Address → who can spend it (public key or script hash)
14
+ ├── Value → ADA + any native tokens
15
+ └── Datum → arbitrary data attached to a script UTxO
16
+
17
+ Transaction:
18
+ ├── Inputs → UTxOs being consumed (destroyed)
19
+ ├── Outputs → new UTxOs being created
20
+ ├── Redeemer → data provided to the validator when spending a script UTxO
21
+ └── Validity → time range, signatures, mint/burn
22
+
23
+ Validator:
24
+ → A Plutus/Aiken script that decides if a UTxO can be spent
25
+ → Receives: Datum, Redeemer, ScriptContext
26
+ → Returns: True (allow) or raises error (deny)
27
+ ```
28
+
29
+ **Key difference from Ethereum:** State is not stored in the contract — it is stored in UTxOs sitting at the script address. The validator only validates whether a spend is legitimate.
30
+
31
+ ---
32
+
33
+ ## Aiken project structure
34
+
35
+ ```
36
+ lib/
37
+ validators/
38
+ marketplace.ak ← spending validator
39
+ minting.ak ← minting policy
40
+ utils/
41
+ math.ak
42
+ value.ak
43
+ types.ak ← shared type definitions
44
+ validators/
45
+ marketplace.ak ← entry points (must be here for compilation)
46
+ minting.ak
47
+ tests/
48
+ marketplace_test.ak
49
+ minting_test.ak
50
+ scripts/
51
+ build.sh
52
+ deploy.sh
53
+ aiken.toml
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Types — define datum and redeemer first
59
+
60
+ ```rust
61
+ // lib/types.ak
62
+ pub type AssetClass {
63
+ policy_id: ByteArray,
64
+ asset_name: ByteArray,
65
+ }
66
+
67
+ pub type ListingDatum {
68
+ seller: VerificationKeyHash,
69
+ price_lovelace: Int,
70
+ royalty_recipient: VerificationKeyHash,
71
+ royalty_bps: Int, // basis points: 100 = 1%, max 1000
72
+ asset: AssetClass,
73
+ }
74
+
75
+ pub type MarketplaceRedeemer {
76
+ Buy
77
+ Cancel
78
+ UpdatePrice { new_price: Int }
79
+ }
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Spending validator
85
+
86
+ ```rust
87
+ // validators/marketplace.ak
88
+ use aiken/transaction.{ScriptContext, Spend, Transaction}
89
+ use aiken/transaction/credential.{VerificationKeyHash}
90
+ use aiken/transaction/value
91
+ use lib/types.{ListingDatum, MarketplaceRedeemer}
92
+
93
+ // Constants
94
+ const max_royalty_bps: Int = 1000 // 10%
95
+
96
+ validator {
97
+ fn marketplace(
98
+ datum: ListingDatum,
99
+ redeemer: MarketplaceRedeemer,
100
+ ctx: ScriptContext
101
+ ) -> Bool {
102
+ when redeemer is {
103
+ Buy -> {
104
+ let tx = ctx.transaction
105
+ validate_purchase(datum, tx)
106
+ }
107
+ Cancel -> {
108
+ // Only seller can cancel
109
+ must_be_signed_by(ctx.transaction, datum.seller)
110
+ }
111
+ UpdatePrice { new_price } -> {
112
+ and {
113
+ must_be_signed_by(ctx.transaction, datum.seller),
114
+ new_price > 0,
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ fn validate_purchase(datum: ListingDatum, tx: Transaction) -> Bool {
122
+ // Validate royalty does not exceed maximum
123
+ expect datum.royalty_bps <= max_royalty_bps
124
+
125
+ let royalty_amount = datum.price_lovelace * datum.royalty_bps / 10000
126
+ let seller_amount = datum.price_lovelace - royalty_amount
127
+
128
+ and {
129
+ // Seller receives their share
130
+ output_to_address_has_value(tx, datum.seller, seller_amount),
131
+ // Royalty recipient receives their share (if any)
132
+ if royalty_amount > 0 {
133
+ output_to_address_has_value(tx, datum.royalty_recipient, royalty_amount)
134
+ } else {
135
+ True
136
+ },
137
+ }
138
+ }
139
+
140
+ fn output_to_address_has_value(
141
+ tx: Transaction,
142
+ recipient: VerificationKeyHash,
143
+ min_lovelace: Int
144
+ ) -> Bool {
145
+ list.any(tx.outputs, fn(output) {
146
+ when output.address.payment_credential is {
147
+ credential.VerificationKey(vk_hash) ->
148
+ vk_hash == recipient &&
149
+ value.lovelace_of(output.value) >= min_lovelace
150
+ _ -> False
151
+ }
152
+ })
153
+ }
154
+
155
+ fn must_be_signed_by(tx: Transaction, vk_hash: VerificationKeyHash) -> Bool {
156
+ list.has(tx.extra_signatories, vk_hash)
157
+ }
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Minting policy
163
+
164
+ ```rust
165
+ // validators/minting.ak
166
+ use aiken/transaction.{ScriptContext, Mint}
167
+ use aiken/transaction/value
168
+
169
+ pub type MintRedeemer {
170
+ Mint { recipient: VerificationKeyHash }
171
+ Burn
172
+ }
173
+
174
+ validator {
175
+ fn nft_policy(redeemer: MintRedeemer, ctx: ScriptContext) -> Bool {
176
+ when ctx.purpose is {
177
+ Mint(policy_id) -> {
178
+ when redeemer is {
179
+ Mint { recipient } -> {
180
+ let tx = ctx.transaction
181
+ // Exactly one token minted with this policy
182
+ let minted = value.tokens(tx.mint, policy_id)
183
+ expect list.length(dict.to_list(minted)) == 1
184
+
185
+ // Transaction signed by recipient
186
+ must_be_signed_by(tx, recipient)
187
+ }
188
+ Burn -> {
189
+ // Validate burning: all minted amounts are negative
190
+ let minted = value.tokens(ctx.transaction.mint, policy_id)
191
+ list.all(dict.values(minted), fn(qty) { qty < 0 })
192
+ }
193
+ }
194
+ }
195
+ _ -> False
196
+ }
197
+ }
198
+ }
199
+ ```
200
+
201
+ ---
202
+
203
+ ## Tests in Aiken
204
+
205
+ ```rust
206
+ // tests/marketplace_test.ak
207
+ use lib/types.{ListingDatum, MarketplaceRedeemer}
208
+
209
+ test royalty_must_not_exceed_maximum() {
210
+ let datum = ListingDatum {
211
+ seller: #"abcd1234",
212
+ price_lovelace: 10_000_000,
213
+ royalty_recipient: #"efgh5678",
214
+ royalty_bps: 1001, // 10.01% — should FAIL
215
+ asset: AssetClass { policy_id: #"", asset_name: #"" },
216
+ }
217
+ // Test that validator rejects this datum
218
+ !validate_purchase(datum, mock_buy_transaction())
219
+ }
220
+
221
+ test seller_receives_correct_amount() {
222
+ let datum = ListingDatum {
223
+ seller: #"abcd1234",
224
+ price_lovelace: 10_000_000, // 10 ADA
225
+ royalty_recipient: #"efgh5678",
226
+ royalty_bps: 300, // 3% = 300_000 lovelace
227
+ asset: AssetClass { policy_id: #"", asset_name: #"" },
228
+ }
229
+ // Seller should receive 9_700_000 lovelace (97%)
230
+ let expected_seller_amount = 9_700_000
231
+ validate_purchase(datum, mock_buy_with_outputs(datum.seller, expected_seller_amount))
232
+ }
233
+ ```
234
+
235
+ Run tests: `aiken check`
236
+
237
+ ---
238
+
239
+ ## Off-chain transaction building (Lucid or Mesh)
240
+
241
+ ```ts
242
+ // scripts/list-nft.ts — using Lucid
243
+ import { Lucid, Blockfrost, fromText, Data } from 'lucid-cardano';
244
+ import { ListingDatum } from './types';
245
+
246
+ const lucid = await Lucid.new(
247
+ new Blockfrost('https://cardano-mainnet.blockfrost.io/api/v0', process.env.BLOCKFROST_API_KEY!),
248
+ 'Mainnet'
249
+ );
250
+
251
+ lucid.selectWalletFromPrivateKey(process.env.SELLER_KEY!);
252
+
253
+ async function listNFT(
254
+ policyId: string,
255
+ assetName: string,
256
+ priceLovelace: bigint,
257
+ royaltyBps: number
258
+ ) {
259
+ const sellerAddress = await lucid.wallet.address();
260
+ const datum: ListingDatum = {
261
+ seller: lucid.utils.getAddressDetails(sellerAddress).paymentCredential!.hash,
262
+ price_lovelace: priceLovelace,
263
+ royalty_recipient: lucid.utils.getAddressDetails(sellerAddress).paymentCredential!.hash,
264
+ royalty_bps: royaltyBps,
265
+ asset: { policy_id: policyId, asset_name: fromText(assetName) },
266
+ };
267
+
268
+ const tx = await lucid.newTx()
269
+ .payToContract(
270
+ MARKETPLACE_SCRIPT_ADDRESS,
271
+ { inline: Data.to(datum, ListingDatum) },
272
+ { [policyId + fromText(assetName)]: 1n }
273
+ )
274
+ .complete();
275
+
276
+ const signedTx = await tx.sign().complete();
277
+ const txHash = await signedTx.submit();
278
+ console.log(`Listed NFT. Tx hash: ${txHash}`);
279
+ return txHash;
280
+ }
281
+ ```
282
+
283
+ ---
284
+
285
+ ## Datum versioning — plan before deploying
286
+
287
+ ```rust
288
+ // Version your datum from day one — cannot change on-chain data after deployment
289
+ pub type DatumV1 {
290
+ seller: VerificationKeyHash,
291
+ price_lovelace: Int,
292
+ }
293
+
294
+ // Future version — add new fields, keep old validator working
295
+ pub type DatumV2 {
296
+ seller: VerificationKeyHash,
297
+ price_lovelace: Int,
298
+ royalty_bps: Int, // new in V2
299
+ royalty_recipient: Option<VerificationKeyHash>,
300
+ }
301
+
302
+ // Validator supports both versions via union type
303
+ pub type AnyDatum {
304
+ V1(DatumV1)
305
+ V2(DatumV2)
306
+ }
307
+ ```
308
+
309
+ ---
310
+
311
+ ## Deployment checklist
312
+
313
+ - [ ] Compile: `aiken build` — no warnings
314
+ - [ ] Tests pass: `aiken check`
315
+ - [ ] Script hash documented in `docs/deployment.md`
316
+ - [ ] Datum/redeemer schemas versioned
317
+ - [ ] Off-chain code tested against preview testnet
318
+ - [ ] `min-ada` calculation verified for all output types
319
+ - [ ] Transaction fee estimates verified with realistic UTxO sizes
320
+ - [ ] Emergency cancel mechanism exists for stuck UTxOs
321
+
322
+ ---
323
+
324
+ ## ALWAYS
325
+ - Design datum and redeemer types before writing validator logic
326
+ - Store the script hash in deployment notes — cannot recover it otherwise
327
+ - Test with `aiken check` before any on-chain deployment
328
+ - Use `must_be_signed_by` for any privileged action
329
+ - Plan datum versioning from day one
330
+ - Calculate `min-ada` requirements for outputs with tokens/datums
331
+
332
+ ## NEVER
333
+ - Deploy a validator you haven't tested with edge-case redeemers
334
+ - Store secrets or private keys in datum (all on-chain data is public)
335
+ - Assume UTxO values — always check with `value.lovelace_of()`
336
+ - Forget that failed validator = UTxO locked forever (no admin override)
337
+ - Use `expect` in production validators without understanding it causes script failure