tina4ruby 3.10.42 → 3.10.44

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2ef9ca3ce2b80dad4b7179527bf4b3cc2de210e8fd5b5df4922337e84e56beb
4
- data.tar.gz: 7bda41dbe6ef16d81e1a1f6e6b262ac3027ea71afdc0cc0c85546fda4582181d
3
+ metadata.gz: ec47f9dbe61a4b79452909076bd16a76c6b8e01dd928ca117ed69318dec9a601
4
+ data.tar.gz: e9d20212ae627c9a905807453a7a01cfa4e9d8c39808b6e6e31d27748d139848
5
5
  SHA512:
6
- metadata.gz: eeb6b96351e27089eb7b4e8bd7b5bcbb4fc3cbba5c178f7f188ae91f41c28c9d3445af52338a2968a701abe7a86eabb51b0b1085c629a270611539b47eeaabb3
7
- data.tar.gz: 20c4e4be361fe1b2a7f3ad402a4e8f5ce81e991effcb7af5142e1b1c4d2dbed9f7dc73b3133f1431155c73c3680978717ec109c7784163cf7300a6e6aa257377
6
+ metadata.gz: 5a69a10210660179142b9fe93cd2a81eff16a40744fc94805e4c4103c5402e9a73980d4d753f5b45580cd6f34775b125dc51d0419921f06f074294047b29e2a6
7
+ data.tar.gz: 99e9d9ce315dfe0962600d326ca2e79d55002186e4077038bdac47368184fc8bd2965b2927727b85168869e5b0ed20e9023b86e4e390ca536967dd1a32b5e4bd
data/lib/tina4/ai.rb CHANGED
@@ -84,10 +84,9 @@ module Tina4
84
84
  end
85
85
  end
86
86
 
87
- context = generate_context
88
-
89
87
  indices.each do |idx|
90
88
  tool = AI_TOOLS[idx]
89
+ context = generate_context(tool[:name])
91
90
  files = install_for_tool(root_path, tool, context)
92
91
  created.concat(files)
93
92
  end
@@ -105,140 +104,29 @@ module Tina4
105
104
  install_selected(root, "all")
106
105
  end
107
106
 
108
- # Generate the universal Tina4 Ruby context document for any AI assistant.
107
+ # Generate per-tool Tina4 Ruby context document.
109
108
  #
109
+ # @param tool_name [String] AI tool name (default: "claude-code")
110
110
  # @return [String]
111
- def generate_context
112
- <<~CONTEXT
113
- # Tina4 Ruby -- AI Context
114
-
115
- This project uses **Tina4 Ruby**, a lightweight, batteries-included web framework
116
- with zero third-party dependencies for core features.
117
-
118
- **Documentation:** https://tina4.com
119
-
120
- ## Quick Start
121
-
122
- ```bash
123
- tina4ruby init . # Scaffold project
124
- tina4ruby serve # Start dev server on port 7147
125
- tina4ruby migrate # Run database migrations
126
- tina4ruby test # Run test suite
127
- tina4ruby routes # List all registered routes
128
- ```
129
-
130
- ## Project Structure
131
-
132
- ```
133
- lib/tina4/ -- Core framework modules
134
- src/routes/ -- Route handlers (auto-discovered, one per resource)
135
- src/orm/ -- ORM models (one per file, filename = class name)
136
- src/templates/ -- Twig/ERB templates (extends base template)
137
- src/app/ -- Shared helpers and service classes
138
- src/scss/ -- SCSS files (auto-compiled to public/css/)
139
- src/public/ -- Static assets served at /
140
- src/locales/ -- Translation JSON files
141
- src/seeds/ -- Database seeder scripts
142
- migrations/ -- SQL migration files (sequential numbered)
143
- spec/ -- RSpec test files
144
- ```
145
-
146
- ## Built-in Features (No External Gems Needed for Core)
147
-
148
- | Feature | Module | Require |
149
- |---------|--------|---------|
150
- | Routing | Tina4::Router | `require "tina4/router"` |
151
- | ORM | Tina4::ORM | `require "tina4/orm"` |
152
- | Database | Tina4::Database | `require "tina4/database"` |
153
- | Templates | Tina4::Template | `require "tina4/template"` |
154
- | JWT Auth | Tina4::Auth | `require "tina4/auth"` |
155
- | REST API Client | Tina4::API | `require "tina4/api"` |
156
- | GraphQL | Tina4::GraphQL | `require "tina4/graphql"` |
157
- | WebSocket | Tina4::WebSocket | `require "tina4/websocket"` |
158
- | SOAP/WSDL | Tina4::WSDL | `require "tina4/wsdl"` |
159
- | Email (SMTP+IMAP) | Tina4::Messenger | `require "tina4/messenger"` |
160
- | Background Queue | Tina4::Queue | `require "tina4/queue"` |
161
- | SCSS Compilation | Tina4::ScssCompiler | `require "tina4/scss_compiler"` |
162
- | Migrations | Tina4::Migration | `require "tina4/migration"` |
163
- | Seeder | Tina4::FakeData | `require "tina4/seeder"` |
164
- | i18n | Tina4::Localization | `require "tina4/localization"` |
165
- | Swagger/OpenAPI | Tina4::Swagger | `require "tina4/swagger"` |
166
- | Sessions | Tina4::Session | `require "tina4/session"` |
167
- | Middleware | Tina4::Middleware | `require "tina4/middleware"` |
168
- | HTML Builder | Tina4::HtmlElement | `require "tina4/html_element"` |
169
- | Form Tokens | Tina4::Template | `{{ form_token() }}` in Twig |
170
-
171
- ## Key Conventions
172
-
173
- 1. **Routes use block handlers** with `|request, response|` params
174
- 2. **GET routes are public**, POST/PUT/PATCH/DELETE require auth by default
175
- 3. **Use `auth: false`** to make write routes public, `secure_get` to protect GET routes
176
- 4. **Every template extends a base template** -- no standalone HTML pages
177
- 5. **No inline styles** -- use SCSS with CSS variables
178
- 6. **All schema changes via migrations** -- never create tables in route code
179
- 7. **Service pattern** -- complex logic goes in service classes, routes stay thin
180
- 8. **Use built-in features** -- never install gems for things Tina4 already provides
181
-
182
- ## AI Workflow -- Available Skills
183
-
184
- When using an AI coding assistant with Tina4, these skills are available:
185
-
186
- | Skill | Description |
187
- |-------|-------------|
188
- | `/tina4-route` | Create a new route with proper decorators and auth |
189
- | `/tina4-orm` | Create an ORM model with migration |
190
- | `/tina4-crud` | Generate complete CRUD (migration, ORM, routes, template, tests) |
191
- | `/tina4-auth` | Set up JWT authentication with login/register |
192
- | `/tina4-api` | Create an external API integration |
193
- | `/tina4-queue` | Set up background job processing |
194
- | `/tina4-template` | Create a server-rendered template page |
195
- | `/tina4-graphql` | Set up a GraphQL endpoint |
196
- | `/tina4-websocket` | Set up WebSocket communication |
197
- | `/tina4-wsdl` | Create a SOAP/WSDL service |
198
- | `/tina4-messenger` | Set up email send/receive |
199
- | `/tina4-test` | Write tests for a feature |
200
- | `/tina4-migration` | Create a database migration |
201
- | `/tina4-seed` | Generate fake data for development |
202
- | `/tina4-i18n` | Set up internationalization |
203
- | `/tina4-scss` | Set up SCSS stylesheets |
204
- | `/tina4-frontend` | Set up a frontend framework |
205
-
206
- ## Common Patterns
207
-
208
- ### Route
209
- ```ruby
210
- Tina4.get "/api/widgets" do |request, response|
211
- response.json({ widgets: Widget.all })
212
- end
213
-
214
- Tina4.post "/api/widgets", auth: false do |request, response|
215
- widget = Widget.create(request.body)
216
- response.json({ created: true }, 201)
217
- end
218
- ```
219
-
220
- ### ORM Model
221
- ```ruby
222
- class Widget < Tina4::ORM
223
- integer_field :id, primary_key: true, auto_increment: true
224
- string_field :name
225
- numeric_field :price
226
- end
227
- ```
228
-
229
- ### Template
230
- ```twig
231
- {% extends "base.twig" %}
232
- {% block content %}
233
- <div class="container">
234
- <h1>{{ title }}</h1>
235
- {% for item in items %}
236
- <p>{{ item.name }}</p>
237
- {% endfor %}
238
- </div>
239
- {% endblock %}
240
- ```
241
- CONTEXT
111
+ def generate_context(tool_name = "claude-code")
112
+ case tool_name
113
+ when "claude-code"
114
+ generate_claude_code_context
115
+ when "cursor"
116
+ generate_cursor_context
117
+ when "copilot"
118
+ generate_copilot_context
119
+ when "windsurf"
120
+ generate_windsurf_context
121
+ when "aider"
122
+ generate_aider_context
123
+ when "cline"
124
+ generate_cline_context
125
+ when "codex"
126
+ generate_codex_context
127
+ else
128
+ generate_claude_code_context
129
+ end
242
130
  end
243
131
 
244
132
  # Install context file for a single tool.
@@ -333,6 +221,476 @@ module Tina4
333
221
  end
334
222
  puts " \e[33m!\e[0m Python/pip not available -- skip tina4-ai"
335
223
  end
224
+
225
+ private
226
+
227
+ # Read existing CLAUDE.md from the framework root.
228
+ #
229
+ # @return [String]
230
+ def generate_claude_code_context
231
+ framework_root = File.expand_path("../../..", __FILE__)
232
+ claude_md = File.join(framework_root, "CLAUDE.md")
233
+ if File.exist?(claude_md)
234
+ File.read(claude_md)
235
+ else
236
+ "# Tina4 Ruby #{Tina4::VERSION}\n\nSee https://tina4.com for documentation.\n"
237
+ end
238
+ end
239
+
240
+ # Cursor context (~45 lines).
241
+ #
242
+ # @return [String]
243
+ def generate_cursor_context
244
+ <<~CONTEXT
245
+ # Tina4 Ruby #{Tina4::VERSION} — Cursor Rules
246
+
247
+ You are working in a **Tina4 Ruby** project — a zero-dependency, batteries-included web framework.
248
+ Documentation: https://tina4.com
249
+
250
+ ## Project Structure
251
+
252
+ ```
253
+ src/routes/ — Route handlers (auto-discovered)
254
+ src/orm/ — ORM models
255
+ src/templates/ — Twig templates
256
+ src/app/ — Service classes
257
+ src/scss/ — SCSS (auto-compiled)
258
+ src/public/ — Static assets
259
+ src/seeds/ — Database seeders
260
+ migrations/ — SQL migration files
261
+ spec/ — RSpec tests
262
+ ```
263
+
264
+ ## Route Pattern
265
+
266
+ ```ruby
267
+ Tina4.get "/api/users" do |request, response|
268
+ response.call({ users: [] }, Tina4::HTTP_OK)
269
+ end
270
+
271
+ Tina4.post "/api/users" do |request, response|
272
+ response.call({ created: request.body["name"] }, 201)
273
+ end
274
+ ```
275
+
276
+ ## ORM Pattern
277
+
278
+ ```ruby
279
+ class User < Tina4::ORM
280
+ table_name "users"
281
+ integer_field :id, primary_key: true, auto_increment: true
282
+ string_field :name, required: true
283
+ string_field :email
284
+ end
285
+ ```
286
+
287
+ ## Conventions
288
+
289
+ 1. Routes return `response.call(data, status)` — never `puts` or `render`
290
+ 2. GET routes are public; POST/PUT/PATCH/DELETE require auth by default
291
+ 3. Every template extends `base.twig`
292
+ 4. All schema changes via migrations — never create tables in route code
293
+ 5. Use built-in features — never install gems for things Tina4 already provides
294
+ 6. Service pattern — complex logic in `src/app/`, routes stay thin
295
+ 7. Use `snake_case` for methods and variables
296
+
297
+ ## Built-in Features (No Gems Needed)
298
+
299
+ Router, ORM, Database (SQLite/PostgreSQL/MySQL/MSSQL/Firebird), Frond templates (Twig-compatible), JWT auth, Sessions (File/Redis/Valkey/MongoDB/DB), GraphQL + GraphiQL, WebSocket + Redis backplane, WSDL/SOAP, Queue (File/RabbitMQ/Kafka/MongoDB), HTTP client, Messenger (SMTP/IMAP), FakeData/Seeder, Migrations, SCSS compiler, Swagger/OpenAPI, i18n, Events, Container/DI, HtmlElement, Inline testing, Error overlay, Dev dashboard, Rate limiter, Response cache, Logging, MCP server
300
+ CONTEXT
301
+ end
302
+
303
+ # GitHub Copilot context (~30 lines).
304
+ #
305
+ # @return [String]
306
+ def generate_copilot_context
307
+ <<~CONTEXT
308
+ # Tina4 Ruby #{Tina4::VERSION} — Copilot Instructions
309
+
310
+ This is a **Tina4 Ruby** project. Tina4 is a zero-dependency web framework. Docs: https://tina4.com
311
+
312
+ ## Structure
313
+
314
+ Routes in `src/routes/`, ORM models in `src/orm/`, templates in `src/templates/`, services in `src/app/`, tests in `spec/`.
315
+
316
+ ## Route Example
317
+
318
+ ```ruby
319
+ Tina4.get "/api/users" do |request, response|
320
+ response.call({ users: [] }, Tina4::HTTP_OK)
321
+ end
322
+
323
+ Tina4.post "/api/users" do |request, response|
324
+ response.call({ created: request.body["name"] }, 201)
325
+ end
326
+ ```
327
+
328
+ ## ORM Example
329
+
330
+ ```ruby
331
+ class User < Tina4::ORM
332
+ table_name "users"
333
+ integer_field :id, primary_key: true, auto_increment: true
334
+ string_field :name, required: true
335
+ string_field :email
336
+ end
337
+ ```
338
+
339
+ ## Rules
340
+
341
+ - Always return `response.call(data, status)` from routes
342
+ - GET is public; POST/PUT/PATCH/DELETE require auth by default
343
+ - Templates extend `base.twig`; schema changes via migrations only
344
+ - Use `snake_case`; never install gems for built-in features
345
+ - Built-in: Router, ORM, Database, JWT auth, Sessions, GraphQL, WebSocket, Queue, Messenger, Migrations, SCSS, Swagger, i18n, Events, DI, Testing
346
+ CONTEXT
347
+ end
348
+
349
+ # Windsurf context (~60 lines).
350
+ #
351
+ # @return [String]
352
+ def generate_windsurf_context
353
+ <<~CONTEXT
354
+ # Tina4 Ruby #{Tina4::VERSION} — Windsurf Rules
355
+
356
+ You are working in a **Tina4 Ruby** project — a zero-dependency, batteries-included web framework.
357
+ Documentation: https://tina4.com
358
+
359
+ ## Project Structure
360
+
361
+ ```
362
+ src/routes/ — Route handlers (auto-discovered)
363
+ src/orm/ — ORM models
364
+ src/templates/ — Twig templates
365
+ src/app/ — Service classes
366
+ src/scss/ — SCSS (auto-compiled)
367
+ src/public/ — Static assets
368
+ src/seeds/ — Database seeders
369
+ migrations/ — SQL migration files
370
+ spec/ — RSpec tests
371
+ ```
372
+
373
+ ## CLI Commands
374
+
375
+ ```bash
376
+ tina4ruby init . # Scaffold project
377
+ tina4ruby serve # Start dev server on port 7147
378
+ tina4ruby migrate # Run database migrations
379
+ tina4ruby test # Run test suite
380
+ tina4ruby routes # List all registered routes
381
+ ```
382
+
383
+ ## Route Pattern
384
+
385
+ ```ruby
386
+ Tina4.get "/api/users" do |request, response|
387
+ response.call({ users: [] }, Tina4::HTTP_OK)
388
+ end
389
+
390
+ Tina4.post "/api/users" do |request, response|
391
+ response.call({ created: request.body["name"] }, 201)
392
+ end
393
+ ```
394
+
395
+ ## ORM Pattern
396
+
397
+ ```ruby
398
+ class User < Tina4::ORM
399
+ table_name "users"
400
+ integer_field :id, primary_key: true, auto_increment: true
401
+ string_field :name, required: true
402
+ string_field :email
403
+ end
404
+ ```
405
+
406
+ ## Template Pattern
407
+
408
+ ```twig
409
+ {% extends "base.twig" %}
410
+ {% block content %}
411
+ <div class="container">
412
+ <h1>{{ title }}</h1>
413
+ {% for item in items %}
414
+ <p>{{ item.name }}</p>
415
+ {% endfor %}
416
+ </div>
417
+ {% endblock %}
418
+ ```
419
+
420
+ ## Conventions
421
+
422
+ 1. Routes return `response.call(data, status)` — never `puts` or `render`
423
+ 2. GET routes are public; POST/PUT/PATCH/DELETE require auth by default
424
+ 3. Every template extends `base.twig`
425
+ 4. All schema changes via migrations — never create tables in route code
426
+ 5. Use built-in features — never install gems for things Tina4 already provides
427
+ 6. Service pattern — complex logic in `src/app/`, routes stay thin
428
+ 7. Use `snake_case` for methods and variables
429
+
430
+ ## Built-in Features (No Gems Needed)
431
+
432
+ Router, ORM, Database (SQLite/PostgreSQL/MySQL/MSSQL/Firebird), Frond templates (Twig-compatible), JWT auth, Sessions (File/Redis/Valkey/MongoDB/DB), GraphQL + GraphiQL, WebSocket + Redis backplane, WSDL/SOAP, Queue (File/RabbitMQ/Kafka/MongoDB), HTTP client, Messenger (SMTP/IMAP), FakeData/Seeder, Migrations, SCSS compiler, Swagger/OpenAPI, i18n, Events, Container/DI, HtmlElement, Inline testing, Error overlay, Dev dashboard, Rate limiter, Response cache, Logging, MCP server
433
+
434
+ ## Database Drivers
435
+
436
+ SQLite, PostgreSQL, MySQL, MSSQL, Firebird. Connection string format: `driver://host:port/database`.
437
+
438
+ ## Auth
439
+
440
+ JWT auth built-in via `Tina4::Auth`. `secure_get` / `secure_post` for protected routes. Password hashing via `Tina4::Auth.hash_password` / `check_password`.
441
+ CONTEXT
442
+ end
443
+
444
+ # Aider context (~58 lines).
445
+ #
446
+ # @return [String]
447
+ def generate_aider_context
448
+ <<~CONTEXT
449
+ # Tina4 Ruby #{Tina4::VERSION} — Conventions
450
+
451
+ ## Framework
452
+
453
+ Tina4 Ruby is a zero-dependency, batteries-included web framework. Docs: https://tina4.com
454
+
455
+ ## Project Structure
456
+
457
+ ```
458
+ src/routes/ — Route handlers (auto-discovered)
459
+ src/orm/ — ORM models
460
+ src/templates/ — Twig templates
461
+ src/app/ — Service classes
462
+ src/scss/ — SCSS (auto-compiled)
463
+ src/public/ — Static assets
464
+ src/seeds/ — Database seeders
465
+ migrations/ — SQL migration files
466
+ spec/ — RSpec tests
467
+ ```
468
+
469
+ ## CLI
470
+
471
+ ```bash
472
+ tina4ruby init . # Scaffold project
473
+ tina4ruby serve # Start dev server on port 7147
474
+ tina4ruby migrate # Run database migrations
475
+ tina4ruby test # Run test suite
476
+ tina4ruby routes # List all registered routes
477
+ ```
478
+
479
+ ## Route Pattern
480
+
481
+ ```ruby
482
+ Tina4.get "/api/users" do |request, response|
483
+ response.call({ users: [] }, Tina4::HTTP_OK)
484
+ end
485
+
486
+ Tina4.post "/api/users" do |request, response|
487
+ response.call({ created: request.body["name"] }, 201)
488
+ end
489
+ ```
490
+
491
+ ## ORM Pattern
492
+
493
+ ```ruby
494
+ class User < Tina4::ORM
495
+ table_name "users"
496
+ integer_field :id, primary_key: true, auto_increment: true
497
+ string_field :name, required: true
498
+ string_field :email
499
+ end
500
+ ```
501
+
502
+ ## Conventions
503
+
504
+ 1. Routes return `response.call(data, status)` — never `puts` or `render`
505
+ 2. GET routes are public; POST/PUT/PATCH/DELETE require auth by default
506
+ 3. Every template extends `base.twig`
507
+ 4. All schema changes via migrations — never create tables in route code
508
+ 5. Use built-in features — never install gems for things Tina4 already provides
509
+ 6. Service pattern — complex logic in `src/app/`, routes stay thin
510
+ 7. Use `snake_case` for methods and variables
511
+ 8. Wrap route logic in `begin/rescue`, log with `Tina4::Log.error()`
512
+
513
+ ## Built-in Features
514
+
515
+ Router, ORM, Database (SQLite/PostgreSQL/MySQL/MSSQL/Firebird), Frond templates (Twig-compatible), JWT auth, Sessions (File/Redis/Valkey/MongoDB/DB), GraphQL + GraphiQL, WebSocket + Redis backplane, WSDL/SOAP, Queue (File/RabbitMQ/Kafka/MongoDB), HTTP client, Messenger (SMTP/IMAP), FakeData/Seeder, Migrations, SCSS compiler, Swagger/OpenAPI, i18n, Events, Container/DI, HtmlElement, Inline testing, Error overlay, Dev dashboard, Rate limiter, Response cache, Logging, MCP server
516
+
517
+ ## Testing
518
+
519
+ Run: `bundle exec rspec` or `tina4ruby test`. Tests in `spec/`.
520
+ CONTEXT
521
+ end
522
+
523
+ # Cline context (~42 lines).
524
+ #
525
+ # @return [String]
526
+ def generate_cline_context
527
+ <<~CONTEXT
528
+ # Tina4 Ruby #{Tina4::VERSION} — Cline Rules
529
+
530
+ Tina4 Ruby is a zero-dependency web framework. Docs: https://tina4.com
531
+
532
+ ## Structure
533
+
534
+ ```
535
+ src/routes/ — Route handlers (auto-discovered)
536
+ src/orm/ — ORM models
537
+ src/templates/ — Twig templates
538
+ src/app/ — Service classes
539
+ src/scss/ — SCSS (auto-compiled)
540
+ src/public/ — Static assets
541
+ src/seeds/ — Database seeders
542
+ migrations/ — SQL migration files
543
+ spec/ — RSpec tests
544
+ ```
545
+
546
+ ## Route Pattern
547
+
548
+ ```ruby
549
+ Tina4.get "/api/users" do |request, response|
550
+ response.call({ users: [] }, Tina4::HTTP_OK)
551
+ end
552
+
553
+ Tina4.post "/api/users" do |request, response|
554
+ response.call({ created: request.body["name"] }, 201)
555
+ end
556
+ ```
557
+
558
+ ## ORM Pattern
559
+
560
+ ```ruby
561
+ class User < Tina4::ORM
562
+ table_name "users"
563
+ integer_field :id, primary_key: true, auto_increment: true
564
+ string_field :name, required: true
565
+ string_field :email
566
+ end
567
+ ```
568
+
569
+ ## Conventions
570
+
571
+ 1. Routes return `response.call(data, status)` — never `puts` or `render`
572
+ 2. GET routes are public; POST/PUT/PATCH/DELETE require auth by default
573
+ 3. Every template extends `base.twig`
574
+ 4. All schema changes via migrations — never create tables in route code
575
+ 5. Use built-in features — never install gems for things Tina4 already provides
576
+ 6. Service pattern — complex logic in `src/app/`, routes stay thin
577
+ 7. Use `snake_case` for methods and variables
578
+
579
+ ## Built-in Features
580
+
581
+ Router, ORM, Database (SQLite/PostgreSQL/MySQL/MSSQL/Firebird), Frond templates (Twig-compatible), JWT auth, Sessions, GraphQL, WebSocket, Queue, Messenger, Migrations, SCSS, Swagger, i18n, Events, Container/DI, Testing, Error overlay, Dev dashboard, Rate limiter, Response cache, Logging, MCP server
582
+ CONTEXT
583
+ end
584
+
585
+ # OpenAI Codex context (~70 lines).
586
+ #
587
+ # @return [String]
588
+ def generate_codex_context
589
+ <<~CONTEXT
590
+ # Tina4 Ruby #{Tina4::VERSION} — Codex Agent Instructions
591
+
592
+ You are working in a **Tina4 Ruby** project — a zero-dependency, batteries-included web framework.
593
+ Documentation: https://tina4.com
594
+
595
+ ## Project Structure
596
+
597
+ ```
598
+ src/routes/ — Route handlers (auto-discovered)
599
+ src/orm/ — ORM models
600
+ src/templates/ — Twig templates
601
+ src/app/ — Service classes
602
+ src/scss/ — SCSS (auto-compiled)
603
+ src/public/ — Static assets
604
+ src/seeds/ — Database seeders
605
+ migrations/ — SQL migration files
606
+ spec/ — RSpec tests
607
+ ```
608
+
609
+ ## CLI Commands
610
+
611
+ ```bash
612
+ tina4ruby init . # Scaffold project
613
+ tina4ruby serve # Start dev server on port 7147
614
+ tina4ruby serve --dev # Dev mode with auto-reload
615
+ tina4ruby migrate # Run database migrations
616
+ tina4ruby test # Run test suite
617
+ tina4ruby routes # List all registered routes
618
+ tina4ruby seed # Run database seeders
619
+ ```
620
+
621
+ ## Route Pattern
622
+
623
+ ```ruby
624
+ Tina4.get "/api/users" do |request, response|
625
+ response.call({ users: [] }, Tina4::HTTP_OK)
626
+ end
627
+
628
+ Tina4.post "/api/users" do |request, response|
629
+ response.call({ created: request.body["name"] }, 201)
630
+ end
631
+
632
+ # Protected GET route
633
+ Tina4.secure_get "/api/admin/users" do |request, response|
634
+ response.call({ users: User.all }, Tina4::HTTP_OK)
635
+ end
636
+
637
+ # Route with template rendering
638
+ Tina4::Router.get "/dashboard", template: "dashboard.twig" do |request, response|
639
+ response.call({ title: "Dashboard" }, Tina4::HTTP_OK)
640
+ end
641
+ ```
642
+
643
+ ## ORM Pattern
644
+
645
+ ```ruby
646
+ class User < Tina4::ORM
647
+ table_name "users"
648
+ integer_field :id, primary_key: true, auto_increment: true
649
+ string_field :name, required: true
650
+ string_field :email
651
+ end
652
+
653
+ # Usage
654
+ user = User.create(name: "Alice", email: "alice@example.com")
655
+ users = User.where("name LIKE ?", ["%ali%"])
656
+ user = User.find(1)
657
+ ```
658
+
659
+ ## Template Pattern
660
+
661
+ ```twig
662
+ {% extends "base.twig" %}
663
+ {% block content %}
664
+ <div class="container">
665
+ <h1>{{ title }}</h1>
666
+ {% for item in items %}
667
+ <p>{{ item.name }}</p>
668
+ {% endfor %}
669
+ </div>
670
+ {% endblock %}
671
+ ```
672
+
673
+ ## Conventions
674
+
675
+ 1. Routes return `response.call(data, status)` — never `puts` or `render`
676
+ 2. GET routes are public; POST/PUT/PATCH/DELETE require auth by default
677
+ 3. Every template extends `base.twig`
678
+ 4. All schema changes via migrations — never create tables in route code
679
+ 5. Use built-in features — never install gems for things Tina4 already provides
680
+ 6. Service pattern — complex logic in `src/app/`, routes stay thin
681
+ 7. Use `snake_case` for methods and variables
682
+ 8. Wrap route logic in `begin/rescue`, log with `Tina4::Log.error()`
683
+ 9. Database drivers: SQLite, PostgreSQL, MySQL, MSSQL, Firebird
684
+
685
+ ## Built-in Features (No Gems Needed)
686
+
687
+ Router, ORM, Database (SQLite/PostgreSQL/MySQL/MSSQL/Firebird), Frond templates (Twig-compatible), JWT auth, Sessions (File/Redis/Valkey/MongoDB/DB), GraphQL + GraphiQL, WebSocket + Redis backplane, WSDL/SOAP, Queue (File/RabbitMQ/Kafka/MongoDB), HTTP client, Messenger (SMTP/IMAP), FakeData/Seeder, Migrations, SCSS compiler, Swagger/OpenAPI, i18n, Events, Container/DI, HtmlElement, Inline testing, Error overlay, Dev dashboard, Rate limiter, Response cache, Logging, MCP server
688
+
689
+ ## Testing
690
+
691
+ Run: `bundle exec rspec` or `tina4ruby test`. Tests live in `spec/`. Use `Tina4::Testing` for inline tests.
692
+ CONTEXT
693
+ end
336
694
  end
337
695
  end
338
696
  end