@africode/core 5.0.5 → 5.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md ADDED
@@ -0,0 +1,583 @@
1
+ # 🤖 AGENTS.md — AfriCode v5.0.0 Robot-First Specification
2
+
3
+ **Purpose**: This document defines the canonical technology stack, coding conventions, and framework grammar for all AI agents building on AfriCode. It ensures generated code is "native" and secure.
4
+
5
+ **Last Updated**: May 2, 2026
6
+ **Framework Version**: 5.0.0
7
+ **Target Deployment**: Bun Runtime (v1.3.12+) on AMD AI Cloud & Alibaba Cloud Assets
8
+
9
+ ---
10
+
11
+ ## 🏗️ Canonical Technology Stack
12
+
13
+ ### Runtime & Build
14
+ - **Runtime**: Bun v1.3.12+ (native, all-in-one: runtime + bundler + test runner)
15
+ - **Language**: ES2024 JavaScript (native, no transpilation needed for modern syntax)
16
+ - **Module Format**: ESM (native Bun import/export)
17
+ - **Build System**: Bun.build() with custom plugins for SVG optimization
18
+ - **Development Server**: Bun.serve() with FileSystemRouter for automatic routing
19
+
20
+ ### UI & Components
21
+ - **Component Model**: Web Components (Custom Elements + Shadow DOM + Slots)
22
+ - **State Management**: Proxy-based reactivity (core/state.js) — zero virtual DOM
23
+ - **Styling**: CSS Variables + Logical Properties (CSS Containment Level 3)
24
+ - **Pattern Generation**: Procedural SVG (no asset uploads needed)
25
+ - **Message Protocol**: A2UI v1.0 (core/a2ui.js) for AI-generated interfaces
26
+
27
+ ### Data & Persistence
28
+ - **Primary Store**: Bun.SQLite (synchronous API, ultra-fast)
29
+ - **Migration System**: Bun-native SQL scripts in migrations/ folder
30
+ - **Query Pattern**: Direct SQL with type-safe parameter binding
31
+ - **Cache Layer**: In-memory Proxy objects with automatic expiry
32
+
33
+ ### Security & Compliance
34
+ - **Authentication**: Session-based (HttpOnly cookies + SameSite=Strict)
35
+ - **Hashing**: Argon2id (built into Bun)
36
+ - **Fintech Compliance**: NIDA CIG + TIPS + AML/FIU middleware
37
+ - **Cryptography**: Ed25519 for message signing (Bun.crypto)
38
+ - **CORS**: Frame-based origin isolation via Web Components
39
+
40
+ ---
41
+
42
+ ## 📐 Canonical Directory Structure
43
+
44
+ ```
45
+ AfriCode/
46
+ ├── bin/ # CLI entry points
47
+ │ ├── africode.js # Main CLI
48
+ │ └── create-africode.js # Project scaffolder
49
+ ├── core/ # Framework internals (do not modify)
50
+ │ ├── sdk.js # Main export
51
+ │ ├── state.js # Reactive state engine
52
+ │ ├── store.js # Global store singleton
53
+ │ ├── a2ui.js # AI message protocol
54
+ │ ├── compliance.js # Fintech middleware
55
+ │ ├── bun-runtime.js # Bun server initialization
56
+ │ ├── router.js # FileSystemRouter
57
+ │ ├── html.js # HTML template utilities
58
+ │ ├── patterns.js # SVG procedural generation
59
+ │ ├── validation.js # Input validation schemas
60
+ │ ├── server/ # Server utilities
61
+ │ │ ├── auth.js # Session management
62
+ │ │ ├── db.js # Database layer
63
+ │ │ ├── render.js # SSR template rendering
64
+ │ │ └── router.js # Route handler utilities
65
+ │ └── cli/ # CLI implementation
66
+ │ └── commands/ # Command handlers
67
+ ├── components/ # Web Components (pre-approved)
68
+ │ ├── index.js # Component registry & exports
69
+ │ ├── base.js # BaseElement class
70
+ │ ├── button.js # Button component
71
+ │ ├── card.js # Card component
72
+ │ ├── cultural-card.js # Cultural card variant
73
+ │ ├── kanga-card.js # Kanga pattern card
74
+ │ ├── form.js # Form wrapper
75
+ │ ├── input.js # Input control
76
+ │ ├── select.js # Select dropdown
77
+ │ ├── modal.js # Modal dialog
78
+ │ ├── navbar.js # Navigation bar
79
+ │ └── [33 total components]
80
+ ├── patterns/ # Procedural SVG generators
81
+ │ ├── kente.js # Kente weaving patterns
82
+ │ ├── shuka.js # Maasai Shuka tartan
83
+ │ ├── ndebele.js # Ndebele geometric
84
+ │ ├── kitenge.js # Kitenge florals
85
+ │ └── [8 regional patterns]
86
+ ├── samples/ # 🆕 Hand-curated LLM examples
87
+ │ ├── README.md # Usage guide for agents
88
+ │ ├── basic-app/ # Minimal app (5 files)
89
+ │ │ ├── package.json
90
+ │ │ ├── pages/index.html
91
+ │ │ ├── styles/theme.css
92
+ │ │ └── core/app.js
93
+ │ ├── fintech-kiosk/ # Payment flow (Lipa Namba)
94
+ │ │ ├── pages/
95
+ │ │ │ ├── index.html # Entry
96
+ │ │ │ ├── [payment-id].html # Dynamic route
97
+ │ │ │ └── api/payment.js
98
+ │ │ ├── components/
99
+ │ │ │ ├── payment-form.js
100
+ │ │ │ ├── nida-verify.js
101
+ │ │ │ └── confirmation.js
102
+ │ │ └── core/
103
+ │ │ ├── merchant-service.js
104
+ │ │ └── compliance-check.js
105
+ │ ├── cultural-showcase/ # Pattern display
106
+ │ │ ├── pages/
107
+ │ │ ├── components/
108
+ │ │ └── core/pattern-service.js
109
+ │ ├── admin-dashboard/ # Multi-user app
110
+ │ │ ├── pages/auth/login.html
111
+ │ │ ├── pages/dashboard/
112
+ │ │ ├── components/data-table.js
113
+ │ │ └── middleware/auth-check.js
114
+ │ └── [8+ regional examples]
115
+ ├── migrations/ # SQL schema versioning
116
+ │ └── 001_initial_schema.sql # Base schema with compliance fields
117
+ ├── styles/ # Design tokens
118
+ │ ├── africanity.css # Main theme
119
+ │ └── typography.css # Type scale
120
+ ├── tests/ # Test pyramid (70/20/10)
121
+ │ ├── unit/ # 70% unit tests
122
+ │ │ ├── state.test.js
123
+ │ │ ├── patterns.test.js
124
+ │ │ ├── validation.test.js
125
+ │ │ └── [compliance tests]
126
+ │ ├── integration/ # 20% integration tests
127
+ │ │ ├── a2ui.test.js
128
+ │ │ ├── router.test.js
129
+ │ │ ├── nida-flow.test.js # NIDA verification
130
+ │ │ ├── tips-payment.test.js # TIPS payment
131
+ │ │ └── aml-screening.test.js
132
+ │ └── e2e/ # 10% critical journeys
133
+ │ ├── signup-nida.test.js # Register + verify
134
+ │ ├── lipa-namba.test.js # Payment flow
135
+ │ └── merchant-checkout.test.js
136
+ ├── package.json # Main entry point metadata
137
+ ├── bunfig.toml # Bun configuration
138
+ ├── tsconfig.json # TypeScript settings (optional)
139
+ ├── AGENTS.md # 🆕 This file — AI training spec
140
+ ├── COMPONENT_SCHEMA.json # 🆕 Auto-generated component manifest
141
+ └── README.md # User documentation
142
+ ```
143
+
144
+ ---
145
+
146
+ ## 🎯 Coding Conventions (AI Must Follow)
147
+
148
+ ### File Naming & Structure
149
+ - **Component files**: `kebab-case.js` (e.g., `payment-form.js`)
150
+ - **Utility/service files**: `kebab-case.js` (e.g., `merchant-service.js`)
151
+ - **Test files**: `*.test.js` (e.g., `nida-flow.test.js`)
152
+ - **One component per file** (no monoliths)
153
+ - **Named exports for utilities**, default export for components
154
+
155
+ ### JavaScript Patterns
156
+
157
+ #### ✅ CORRECT
158
+ ```javascript
159
+ // components/payment-form.js
160
+ export class PaymentForm extends HTMLElement {
161
+ constructor() {
162
+ super();
163
+ this.attachShadow({ mode: 'open' });
164
+ }
165
+
166
+ connectedCallback() {
167
+ this.render();
168
+ this.setupEventListeners();
169
+ }
170
+
171
+ render() {
172
+ this.shadowRoot.innerHTML = `...`;
173
+ }
174
+
175
+ setupEventListeners() {
176
+ this.addEventListener('submit', (e) => this.handleSubmit(e));
177
+ }
178
+
179
+ async handleSubmit(e) {
180
+ e.preventDefault();
181
+ const result = await this.validate();
182
+ if (result.ok) this.dispatchEvent(new CustomEvent('success', { detail: result }));
183
+ }
184
+ }
185
+
186
+ customElements.define('af-payment-form', PaymentForm);
187
+ ```
188
+
189
+ #### ❌ AVOID
190
+ ```javascript
191
+ // DON'T use React JSX
192
+ const PaymentForm = () => <form>...</form>;
193
+
194
+ // DON'T use Vue/Svelte syntax
195
+ <script setup>
196
+ const form = ref(null);
197
+ </script>
198
+
199
+ // DON'T use external state libraries (Redux, Zustand)
200
+ import { store } from '@stores/payment';
201
+
202
+ // DON'T use DOM selectors without scoping
203
+ document.querySelector('.form'); // ❌ Global scope
204
+
205
+ // DO scope to Shadow DOM
206
+ this.shadowRoot.querySelector('.form'); // ✅ Encapsulated
207
+ ```
208
+
209
+ ### State Management Pattern
210
+ ```javascript
211
+ // core/app-state.js (CORRECT)
212
+ import { createReactiveState } from 'africode/core/state.js';
213
+
214
+ export const appState = createReactiveState({
215
+ user: null,
216
+ payment: { amount: 0, status: 'idle' },
217
+ nida: { verified: false, nin: null }
218
+ });
219
+
220
+ // Subscribe to changes
221
+ appState.subscribe('payment.status', (newStatus) => {
222
+ console.log('Payment status changed:', newStatus);
223
+ });
224
+ ```
225
+
226
+ ### API Route Pattern
227
+ ```javascript
228
+ // pages/api/payment.js (CORRECT)
229
+ export async function POST(request) {
230
+ const body = await request.json();
231
+
232
+ // Validate input
233
+ const validation = validatePayload(body, paymentSchema);
234
+ if (!validation.ok) return new Response(validation.error, { status: 400 });
235
+
236
+ // Check compliance
237
+ const amlResult = await checkAMLScreening(body.amount);
238
+ if (!amlResult.ok) return new Response('Transaction blocked', { status: 403 });
239
+
240
+ // Process payment
241
+ const tx = await processPayment(body);
242
+ return new Response(JSON.stringify(tx), { status: 200 });
243
+ }
244
+ ```
245
+
246
+ ### Component Composition
247
+ ```javascript
248
+ // pages/checkout.html (CORRECT)
249
+ <af-payment-form id="form">
250
+ <af-nida-verify slot="identity"></af-nida-verify>
251
+ <af-card slot="summary">
252
+ <h2>Order Summary</h2>
253
+ <af-price amount="50000"></af-price>
254
+ </af-card>
255
+ </af-payment-form>
256
+
257
+ <script type="module">
258
+ import 'africode/components/index.js';
259
+
260
+ const form = document.querySelector('af-payment-form');
261
+ form.addEventListener('success', (e) => {
262
+ console.log('Payment confirmed:', e.detail);
263
+ });
264
+ </script>
265
+ ```
266
+
267
+ ### Error Handling
268
+ ```javascript
269
+ // Middleware pattern
270
+ export function complianceCheck(handler) {
271
+ return async (request) => {
272
+ try {
273
+ const compliant = await validateCompliance(request);
274
+ if (!compliant) throw new Error('Compliance failed');
275
+ return await handler(request);
276
+ } catch (error) {
277
+ console.error('Compliance error:', error);
278
+ return new Response(
279
+ JSON.stringify({ error: error.message, code: 'COMPLIANCE_ERROR' }),
280
+ { status: 403 }
281
+ );
282
+ }
283
+ };
284
+ }
285
+ ```
286
+
287
+ ---
288
+
289
+ ## 🔐 Fintech Compliance Grammar
290
+
291
+ ### NIDA Verification Flow
292
+ ```javascript
293
+ // core/server/nida-flow.js
294
+ export async function verifyNIDA(nin, pin) {
295
+ // Step 1: Sign request with Ed25519 private key
296
+ const signature = await signRequest({ nin, timestamp: Date.now() }, privateKey);
297
+
298
+ // Step 2: Call CIG endpoint over TLS 1.3
299
+ const response = await fetch('https://api.nida.go.tz/cig/verify', {
300
+ method: 'POST',
301
+ headers: {
302
+ 'Content-Type': 'application/json',
303
+ 'X-Signature': signature,
304
+ 'X-Client-Id': 'africode-v5'
305
+ },
306
+ body: JSON.stringify({ nin, pin })
307
+ });
308
+
309
+ // Step 3: Validate response signature
310
+ const data = await response.json();
311
+ const isValid = await verifySignature(data, data.signature, nidaPublicKey);
312
+
313
+ if (!isValid) throw new Error('Invalid signature from NIDA');
314
+ return data;
315
+ }
316
+ ```
317
+
318
+ ### TIPS Payment Flow
319
+ ```javascript
320
+ // core/server/tips-flow.js
321
+ export async function initiateP2PPayment(sender, receiver, amount) {
322
+ // Validate both parties exist in NIDA
323
+ await verifyNIDA(sender.nin);
324
+ await verifyNIDA(receiver.nin);
325
+
326
+ // Create TIPS transaction
327
+ const tipsPayload = {
328
+ transactionType: 'P2P',
329
+ senderNIN: sender.nin,
330
+ receiverNIN: receiver.nin,
331
+ amount: amount,
332
+ currency: 'TZS',
333
+ reference: generateReference(),
334
+ timestamp: new Date().toISOString()
335
+ };
336
+
337
+ // Sign and send to TIPS
338
+ const tipsResponse = await callTIPS('/p2p/initiate', tipsPayload);
339
+
340
+ // Log for AML/FIU reporting
341
+ await logAMLTransaction(tipsResponse.transactionId, tipsPayload);
342
+
343
+ return tipsResponse;
344
+ }
345
+ ```
346
+
347
+ ### AML Screening
348
+ ```javascript
349
+ // core/server/aml-check.js
350
+ export async function screenTransaction(amount, nin) {
351
+ // Query FIU's AML database
352
+ const suspicious = await queryFIUList(nin);
353
+ if (suspicious) return { ok: false, reason: 'SUSPICIOUS_PARTY' };
354
+
355
+ // Check transaction limits
356
+ const dailyTotal = await getDailyTransactionTotal(nin);
357
+ if (dailyTotal + amount > 50_000_000) { // 50M TZS daily limit
358
+ return { ok: false, reason: 'AMOUNT_EXCEEDS_LIMIT' };
359
+ }
360
+
361
+ // Queue for AML reporting (24-hour window)
362
+ await queueAMLReport({
363
+ transactionId: generateId(),
364
+ amount,
365
+ nin,
366
+ timestamp: new Date()
367
+ });
368
+
369
+ return { ok: true };
370
+ }
371
+ ```
372
+
373
+ ---
374
+
375
+ ## 📦 Component Manifest (COMPONENT_SCHEMA.json)
376
+
377
+ **Purpose**: Auto-generated JSON schema that whitelists safe components for AI generation. Prevents hallucinated HTML and enforces A2UI compliance.
378
+
379
+ **Generated by**: `scripts/generate-component-schema.js`
380
+
381
+ ```json
382
+ {
383
+ "version": "5.0.0",
384
+ "timestamp": "2026-05-02T00:00:00Z",
385
+ "components": [
386
+ {
387
+ "tagName": "af-button",
388
+ "filePath": "components/button.js",
389
+ "slots": ["default"],
390
+ "attributes": {
391
+ "variant": { "type": "string", "enum": ["primary", "secondary", "ghost"], "default": "primary" },
392
+ "size": { "type": "string", "enum": ["sm", "md", "lg"], "default": "md" },
393
+ "disabled": { "type": "boolean", "default": false }
394
+ },
395
+ "events": [
396
+ { "name": "click", "detail": { "type": "object" } }
397
+ ],
398
+ "cssCustomProperties": [
399
+ "--af-button-bg",
400
+ "--af-button-text",
401
+ "--af-button-border"
402
+ ],
403
+ "example": "<af-button variant=\"primary\" size=\"lg\">Click Me</af-button>",
404
+ "securityNotes": "Sanitizes slot content"
405
+ },
406
+ {
407
+ "tagName": "af-nida-verify",
408
+ "filePath": "components/nida-verify.js",
409
+ "slots": [],
410
+ "attributes": {
411
+ "nin": { "type": "string", "required": true, "pattern": "^[0-9]{20}$" },
412
+ "pin": { "type": "string", "required": true }
413
+ },
414
+ "events": [
415
+ { "name": "verified", "detail": { "verified": true, "user": {} } }
416
+ ],
417
+ "complianceNotes": "NIDA CIG v2.1 compliant, Ed25519 signed requests"
418
+ },
419
+ {
420
+ "tagName": "af-payment-form",
421
+ "filePath": "components/payment-form.js",
422
+ "slots": ["identity", "summary"],
423
+ "attributes": {
424
+ "merchant-id": { "type": "string", "required": true },
425
+ "amount": { "type": "number", "required": true }
426
+ },
427
+ "events": [
428
+ { "name": "success", "detail": { "transactionId": "", "status": "" } },
429
+ { "name": "error", "detail": { "error": "", "code": "" } }
430
+ ],
431
+ "complianceNotes": "Auto-screens AML, enforces TIPS standards"
432
+ }
433
+ ],
434
+ "forbiddenPatterns": [
435
+ "eval()",
436
+ "innerHTML = userInput",
437
+ "fetch without CORS headers",
438
+ "localStorage for sensitive data"
439
+ ]
440
+ }
441
+ ```
442
+
443
+ ---
444
+
445
+ ## ⚡ Bun-Native Optimization Rules
446
+
447
+ ### 🎯 Inversion of Control
448
+ ```javascript
449
+ // ❌ OLD: Library pattern (user calls your code)
450
+ import { PaymentForm } from 'africode/components';
451
+ const form = new PaymentForm();
452
+
453
+ // ✅ NEW: Framework pattern (framework owns lifecycle)
454
+ // Just add file: pages/checkout.html
455
+ // Bun.serve + FileSystemRouter auto-discovers and serves it
456
+ ```
457
+
458
+ ### 🎯 Asset Optimization (Bun Plugins)
459
+ ```javascript
460
+ // bunfig.toml - Bun configuration
461
+ [build]
462
+ plugins = ["./build-plugins/svg-optimizer.js"]
463
+
464
+ // build-plugins/svg-optimizer.js
465
+ export default {
466
+ name: 'svg-optimizer',
467
+ setup(build) {
468
+ build.onLoad({ filter: /\.svg$/ }, async (args) => {
469
+ const svg = await Bun.file(args.path).text();
470
+ const minified = minifySVG(svg);
471
+ return {
472
+ contents: `export default "${minified}"`,
473
+ loader: 'js'
474
+ };
475
+ });
476
+ }
477
+ };
478
+ ```
479
+
480
+ ### 🎯 5ms Startup Target
481
+ - No lazy imports in critical paths
482
+ - Bun.SQLite ready before route handling
483
+ - All validators pre-compiled at startup
484
+ - Compliance certificates pre-loaded in memory
485
+
486
+ ---
487
+
488
+ ## 🧪 Test Pyramid (70/20/10)
489
+
490
+ ### Unit Tests (70%) — core/*/
491
+ ```bash
492
+ bun test tests/unit/*.test.js
493
+ # Focus: individual functions, validators, pattern generators
494
+ # Example: patterns.test.js — verify Kente weave algorithm
495
+ ```
496
+
497
+ ### Integration Tests (20%) — pages/api/*/
498
+ ```bash
499
+ bun test tests/integration/*.test.js
500
+ # Focus: A2UI rendering, router matching, compliance middleware
501
+ # Example: nida-flow.test.js — full verification ceremony
502
+ ```
503
+
504
+ ### E2E Tests (10%) — critical user journeys
505
+ ```bash
506
+ bun test tests/e2e/*.test.js
507
+ # Focus: signup-nida, lipa-namba payment, merchant-checkout
508
+ # Example: lipa-namba.test.js — real TIPS transaction simulation
509
+ ```
510
+
511
+ ---
512
+
513
+ ## 🔥 Hot-Reload Middleware
514
+
515
+ ```javascript
516
+ // core/hmr.js (CORRECT)
517
+ export function createHMRServer() {
518
+ return new WebSocket('ws://localhost:3001/hmr');
519
+ }
520
+
521
+ // In Bun.serve, call with --hot flag:
522
+ // bun run bin/africode.js dev --hot
523
+ // This enables:
524
+ // - File watching via Bun.watch()
525
+ // - Soft reloads (no session loss)
526
+ // - Database connection persistence
527
+ // - In-memory state retained
528
+ ```
529
+
530
+ ---
531
+
532
+ ## 📋 AI Agent Constraints
533
+
534
+ When building apps with this spec, AI agents MUST:
535
+
536
+ 1. **Only use pre-approved components** from COMPONENT_SCHEMA.json
537
+ 2. **Never generate raw HTML** — use af-* Web Components
538
+ 3. **Prefer AfriCode-native patterns first**; use external libraries only when they provide a clear, justified enhancement and are already supported by the project
539
+ 4. **Always validate inputs** with schemas in core/validation.js
540
+ 5. **Always call compliance middleware** before processing payments
541
+ 6. **Always sign NIDA requests** with Ed25519 keys
542
+ 7. **Always log transactions** for AML/FIU reporting
543
+ 8. **Always use Bun-native APIs** (no Node.js polyfills)
544
+
545
+ ---
546
+
547
+ ## 🚀 Quick Verification
548
+
549
+ To verify an AI-generated app is "native" to AfriCode:
550
+
551
+ ```bash
552
+ # Check component usage
553
+ grep -r "<af-" pages/ components/ | wc -l # Should be > 0
554
+
555
+ # Check for forbidden patterns
556
+ grep -r "eval(" pages/ components/ # Should be empty
557
+ grep -r "innerHTML =" pages/ components/ # Should only be in Shadow DOM
558
+
559
+ # Check Bun-native compliance
560
+ grep -r "fetch(" pages/ | grep -v "CORS" # Should all have headers
561
+
562
+ # Run test pyramid
563
+ bun test tests/unit/ # 70% should pass instantly
564
+ bun test tests/integration/ # 20% should pass in < 5s
565
+ bun test tests/e2e/ # 10% critical journeys
566
+ ```
567
+
568
+ ---
569
+
570
+ ## 📚 Resources
571
+
572
+ - **Framework API**: https://github.com/africode/framework
573
+ - **Bun Docs**: https://bun.sh/docs
574
+ - **Web Components**: https://developer.mozilla.org/en-US/docs/Web/Web_Components
575
+ - **NIDA CIG v2.1**: https://nida.go.tz/cig/docs
576
+ - **TIPS Standards**: https://tips.go.tz/standards
577
+ - **AML/FIU**: https://fiu.go.tz/reporting
578
+
579
+ ---
580
+
581
+ **Last Reviewed**: May 2, 2026
582
+ **Next Review**: August 2, 2026 (quarterly)
583
+ **Contact**: framework@africode.dev
@@ -0,0 +1,595 @@
1
+ # AfriCode Framework - Agent Instructions
2
+
3
+ **Attach this to your IDE agent (VS Code Copilot, GitHub Copilot, Claude, etc.) for deep AfriCode assistance.**
4
+
5
+ You are an expert AfriCode framework developer. When helping developers with AfriCode projects, follow these guidelines:
6
+
7
+ ---
8
+
9
+ ## Core Framework Principles
10
+
11
+ 1. **AfriCode is sovereignty-first**: Framework decisions prioritize developer autonomy, cultural authenticity, and local-first design
12
+ 2. **Performance matters**: Built on Bun (10x faster than Node.js), use native features when available
13
+ 3. **Cultural patterns are algorithmic**: Always use procedural pattern generators, never static images
14
+ 4. **Components are framework-agnostic**: 33 Web Components work in any JavaScript project
15
+ 5. **Database is foundational**: SQLite with migrations is the primary data layer
16
+ 6. **Prefer native solutions first**: Use AfriCode-native components, Bun APIs, and web standards by default; only introduce third-party libraries when they provide a clear, justified enhancement and are already supported by the project
17
+
18
+ ---
19
+
20
+ ## Technology Stack You Must Know
21
+
22
+ ### Runtime: Bun v1.3.12+
23
+
24
+ - Fast JavaScript runtime with native TypeScript compilation
25
+ - Built-in SQLite support (no additional drivers needed)
26
+ - WebSocket support out-of-the-box
27
+ - Command: `bun dev` for development, `bun test` for testing
28
+
29
+ ### Database: SQLite (WAL Mode)
30
+
31
+ - Append-only, lightweight database perfect for edge
32
+ - Use ORM: `db.model()` for schema definition
33
+ - Query builder: `Model.where().with().paginate()`
34
+ - Migrations: Timestamp-based SQL files in `/migrations`
35
+
36
+ ### Architecture: Full-Stack
37
+
38
+ ```
39
+ core/ → SDK, middleware, ORM
40
+ components/ → 33 Web Components
41
+ pages/ → Server routes
42
+ styles/ → CSS with African color palette
43
+ migrations/ → Database schemas
44
+ ```
45
+
46
+ ---
47
+
48
+ ## 6 Procedural Pattern Generators
49
+
50
+ When users ask to "add patterns" or "style with African designs", use these:
51
+
52
+ ### PatternRenderer Class
53
+
54
+ ```javascript
55
+ PatternRenderer.generateKente(width, height); // Ghana
56
+ PatternRenderer.generateNdebele(width, height); // South Africa
57
+ PatternRenderer.generateMasai(width, height); // Kenya/Tanzania
58
+ PatternRenderer.generateZulu(width, height); // South Africa
59
+ PatternRenderer.generateHadzabe(width, height); // Tanzania
60
+ PatternRenderer.generateKuba(width, height); // DRC
61
+ ```
62
+
63
+ ### Key Points
64
+
65
+ - **All return SVG strings** (not canvas, not images)
66
+ - **Generated on-demand** (fresh pattern each time)
67
+ - **Responsive** (width/height parameters)
68
+ - **Use renderToElement()** to inject into DOM
69
+
70
+ ### Usage Example
71
+
72
+ ```javascript
73
+ // In server route
74
+ const patternSVG = PatternRenderer.generateKente(300, 300);
75
+ res.html(`<div class="hero-pattern">${patternSVG}</div>`);
76
+
77
+ // In Web Component
78
+ PatternRenderer.renderToElement('pattern-container', 'Masai', 240, 240);
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 33 Web Components You Should Reference
84
+
85
+ **Navigation:** `<af-navbar>`, `<af-sidebar>`, `<af-breadcrumb>`, `<af-pagination>`
86
+
87
+ **Forms:** `<af-input>`, `<af-select>`, `<af-checkbox>`, `<af-radio>`, `<af-textarea>`, `<af-form>`
88
+
89
+ **Data Display:** `<af-table>`, `<af-card>`, `<af-badge>`, `<af-progress>`, `<af-skeleton>`, `<af-grid>`
90
+
91
+ **Feedback:** `<af-alert>`, `<af-toast>`, `<af-modal>`, `<af-tooltip>`, `<af-dropdown>`
92
+
93
+ **Visual:** `<af-avatar>`, `<af-icon>`, `<af-button>`, `<af-hero>`, `<af-section>`, `<af-divider>`, `<af-accordion>`, `<af-tabs>`, `<af-theme-toggle>`, `<af-language-switcher>`, `<af-loader>`, `<af-pattern-showcase>`
94
+
95
+ **When to use:** Developers don't need to build these—they're production-tested, use them directly.
96
+
97
+ ---
98
+
99
+ ## Library Usage Policy
100
+
101
+ - Prefer AfriCode-native patterns, components, and styling systems first.
102
+ - Use third-party libraries only when they solve a concrete need that the core framework does not handle well, such as advanced charts, complex animation, or specialized data visualization.
103
+ - If a library is used, it should be already supported by the project dependency setup and integrated in a way that does not replace the framework’s core architecture.
104
+ - Treat libraries as optional enhancements, not the default foundation of an AfriCode app.
105
+
106
+ ## Authentication & Security
107
+
108
+ ### Default Security Middleware
109
+
110
+ ```javascript
111
+ app.use(middleware.cors());
112
+ app.use(middleware.logging());
113
+ app.use(middleware.rateLimit({ max: 100, window: 60000 }));
114
+ app.use(middleware.auth({ secret: process.env.JWT_SECRET }));
115
+ app.use(middleware.csrf());
116
+ ```
117
+
118
+ ### Password Hashing
119
+
120
+ ```javascript
121
+ import { hashPassword, verifyPassword } from 'africode/core/auth.js';
122
+
123
+ const hash = await hashPassword(password);
124
+ const isValid = await verifyPassword(password, hash);
125
+ ```
126
+
127
+ ### Protected Routes
128
+
129
+ ```javascript
130
+ app.post('/api/secure', async (req, res) => {
131
+ // req.auth.id and req.auth.role available after middleware
132
+ const userId = req.auth.id;
133
+ });
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Database Patterns
139
+
140
+ ### Define Models
141
+
142
+ ```javascript
143
+ const User = db.model('users', {
144
+ id: 'INTEGER PRIMARY KEY',
145
+ name: 'TEXT NOT NULL',
146
+ email: 'TEXT UNIQUE NOT NULL',
147
+ password: 'TEXT NOT NULL',
148
+ role: "TEXT DEFAULT 'user'",
149
+ createdAt: 'DATETIME DEFAULT CURRENT_TIMESTAMP',
150
+ posts: { relation: 'hasMany', target: 'posts' },
151
+ });
152
+
153
+ const Post = db.model('posts', {
154
+ id: 'INTEGER PRIMARY KEY',
155
+ title: 'TEXT NOT NULL',
156
+ userId: 'INTEGER NOT NULL',
157
+ content: 'TEXT',
158
+ user: { relation: 'belongsTo', target: 'users' },
159
+ });
160
+ ```
161
+
162
+ ### Query Examples
163
+
164
+ ```javascript
165
+ // Find with relations
166
+ const user = await User.find(123).with('posts');
167
+
168
+ // Where clauses
169
+ const users = await User.where('role', '=', 'admin').get();
170
+ const active = await User.where('active', true).get();
171
+
172
+ // Pagination
173
+ const { data, total, pages } = await User.paginate(10, 1);
174
+
175
+ // Order & limit
176
+ const recent = await Post.orderBy('createdAt', 'DESC').limit(5).get();
177
+
178
+ // Transactions
179
+ await db.transaction(async () => {
180
+ await User.create({ name: 'Amara' });
181
+ await Activity.log('user_created');
182
+ });
183
+ ```
184
+
185
+ ### Migrations
186
+
187
+ ```bash
188
+ # Create migration file in migrations/001_create_users.sql
189
+ # Run automatically on app.listen() or manually
190
+ bun run migrations/001_create_users.sql
191
+ ```
192
+
193
+ ---
194
+
195
+ ## WebSocket Real-Time Communication
196
+
197
+ ### Server
198
+
199
+ ```javascript
200
+ app.ws('/messages', (ws, req) => {
201
+ // Subscribe to room
202
+ ws.subscribe('room:general');
203
+
204
+ // Broadcast to room
205
+ ws.on('message', (data) => {
206
+ app.broadcast('room:general', {
207
+ event: 'message',
208
+ userId: req.auth.id,
209
+ text: data.text,
210
+ });
211
+ });
212
+
213
+ // Handle disconnect
214
+ ws.on('close', () => console.log('User left'));
215
+ });
216
+ ```
217
+
218
+ ### Client
219
+
220
+ ```javascript
221
+ const ws = new WebSocket('ws://localhost:3000/messages');
222
+
223
+ ws.addEventListener('open', () => {
224
+ ws.send(JSON.stringify({ text: 'Hello from client' }));
225
+ });
226
+
227
+ ws.addEventListener('message', (event) => {
228
+ console.log('Real-time update:', event.data);
229
+ });
230
+ ```
231
+
232
+ ---
233
+
234
+ ## Middleware Pipeline
235
+
236
+ ### Common Middleware
237
+
238
+ ```javascript
239
+ // CORS
240
+ app.use(
241
+ middleware.cors({
242
+ origin: 'https://example.com',
243
+ credentials: true,
244
+ })
245
+ );
246
+
247
+ // Logging
248
+ app.use(middleware.logging());
249
+
250
+ // Rate Limiting
251
+ app.use(
252
+ middleware.rateLimit({
253
+ max: 100, // Max requests
254
+ window: 60000, // Time window (ms)
255
+ key: 'ip', // By IP or user
256
+ })
257
+ );
258
+
259
+ // Authentication
260
+ app.use(
261
+ middleware.auth({
262
+ secret: process.env.JWT_SECRET,
263
+ algorithm: 'HS256',
264
+ })
265
+ );
266
+
267
+ // CSRF Protection
268
+ app.use(middleware.csrf());
269
+
270
+ // Caching
271
+ app.use(middleware.cache({ ttl: 3600 }));
272
+ ```
273
+
274
+ ### Create Custom Middleware
275
+
276
+ ```javascript
277
+ const authCheck = (req, res, next) => {
278
+ if (!req.auth) {
279
+ return res.status(401).json({ error: 'Unauthorized' });
280
+ }
281
+ next();
282
+ };
283
+
284
+ app.use(authCheck);
285
+ ```
286
+
287
+ ---
288
+
289
+ ## Multilingual Support (4 Languages)
290
+
291
+ ### HTML Setup
292
+
293
+ ```html
294
+ <h1 data-en="Welcome" data-sw="Karibu" data-yo="Pẹlẹ o" data-am="ደህና መጡ">Welcome</h1>
295
+
296
+ <button class="lang-btn" data-lang="en">EN</button>
297
+ <button class="lang-btn" data-lang="sw">SW</button>
298
+ <button class="lang-btn" data-lang="yo">YO</button>
299
+ <button class="lang-btn" data-lang="am">AM</button>
300
+ ```
301
+
302
+ ### JavaScript Implementation
303
+
304
+ ```javascript
305
+ function setLanguage(lang) {
306
+ document.querySelectorAll('[data-en]').forEach((el) => {
307
+ const text = el.getAttribute(`data-${lang}`) || el.getAttribute('data-en');
308
+ if (text) {
309
+ el.textContent = text;
310
+ }
311
+ });
312
+
313
+ // Update active button
314
+ document.querySelectorAll('.lang-btn').forEach((btn) => {
315
+ btn.classList.toggle('active', btn.getAttribute('data-lang') === lang);
316
+ });
317
+
318
+ // Save preference
319
+ localStorage.setItem('preferredLanguage', lang);
320
+ }
321
+
322
+ // Load on page startup
323
+ const preferred = localStorage.getItem('preferredLanguage') || 'en';
324
+ setLanguage(preferred);
325
+ ```
326
+
327
+ ---
328
+
329
+ ## Common Development Tasks
330
+
331
+ ### Task 1: Create a New API Endpoint with Database
332
+
333
+ ```javascript
334
+ // Define the route
335
+ app.post('/api/posts', async (req, res) => {
336
+ const post = await Post.create({
337
+ title: req.body.title,
338
+ userId: req.auth.id,
339
+ content: req.body.content,
340
+ });
341
+
342
+ // Broadcast to WebSocket subscribers
343
+ app.broadcast('posts:new', post);
344
+
345
+ res.json({ post }, 201);
346
+ });
347
+ ```
348
+
349
+ ### Task 2: Build a Protected Page with Pattern
350
+
351
+ ```javascript
352
+ app.get('/dashboard', async (req, res) => {
353
+ // Auth middleware ensures req.auth exists
354
+ const user = await User.find(req.auth.id).with('posts');
355
+
356
+ const html = `
357
+ <af-navbar></af-navbar>
358
+ <section class="dashboard">
359
+ <h1 data-en="Dashboard" data-sw="Dashibodi">${user.name}'s Dashboard</h1>
360
+ <div class="pattern-header">
361
+ ${PatternRenderer.generateMasai(300, 150)}
362
+ </div>
363
+ <af-table :data="${JSON.stringify(user.posts)}"></af-table>
364
+ </section>
365
+ <af-theme-toggle></af-theme-toggle>
366
+ `;
367
+
368
+ res.html(html);
369
+ });
370
+ ```
371
+
372
+ ### Task 3: Handle Form Submission with Validation
373
+
374
+ ```javascript
375
+ app.post('/api/users/register', async (req, res) => {
376
+ const { name, email, password } = req.body;
377
+
378
+ // Validate input
379
+ if (!name || !email || !password) {
380
+ return res.status(400).json({
381
+ error: 'Missing required fields',
382
+ });
383
+ }
384
+
385
+ // Hash password
386
+ const hash = await hashPassword(password);
387
+
388
+ // Create user
389
+ const user = await User.create({ name, email, password: hash });
390
+
391
+ res.json({ user }, 201);
392
+ });
393
+ ```
394
+
395
+ ### Task 4: Create Paginated Data Endpoint
396
+
397
+ ```javascript
398
+ app.get('/api/posts', async (req, res) => {
399
+ const page = parseInt(req.query.page || 1);
400
+ const limit = parseInt(req.query.limit || 10);
401
+
402
+ const { data, total, pages } = await Post.where('published', true)
403
+ .with('user')
404
+ .orderBy('createdAt', 'DESC')
405
+ .paginate(limit, page);
406
+
407
+ res.json({ posts: data, total, pages });
408
+ });
409
+ ```
410
+
411
+ ---
412
+
413
+ ## Testing Patterns
414
+
415
+ ### Test a Route
416
+
417
+ ```javascript
418
+ import { test, expect } from 'bun:test';
419
+ import { AfriCode } from 'africode/core/sdk.js';
420
+
421
+ test('POST /api/posts creates post', async () => {
422
+ const app = new AfriCode();
423
+
424
+ const res = await app.request(
425
+ 'POST',
426
+ '/api/posts',
427
+ {
428
+ title: 'My Post',
429
+ content: 'Hello world',
430
+ },
431
+ {
432
+ auth: { id: 1 }, // Mock auth
433
+ }
434
+ );
435
+
436
+ expect(res.status).toBe(201);
437
+ expect(res.data.post.title).toBe('My Post');
438
+ });
439
+ ```
440
+
441
+ ### Test Database Query
442
+
443
+ ```javascript
444
+ test('User.where() filters by role', async () => {
445
+ await User.create({ name: 'Admin User', role: 'admin' });
446
+ await User.create({ name: 'Regular User', role: 'user' });
447
+
448
+ const admins = await User.where('role', 'admin').get();
449
+ expect(admins).toHaveLength(1);
450
+ });
451
+ ```
452
+
453
+ ---
454
+
455
+ ## Common Errors & Solutions
456
+
457
+ | Error | Solution |
458
+ | ------------------------------- | --------------------------------------------- |
459
+ | "Cannot find module 'africode'" | Run `bun install africode` |
460
+ | "Database locked" | WAL mode enabled; usually temporary |
461
+ | "WebSocket connection failed" | Ensure `app.listen()` was called |
462
+ | "Component not rendering" | Check component is imported/registered |
463
+ | "Pattern showing as blank" | Ensure PatternRenderer is initialized |
464
+ | "Language not switching" | Check `data-lang` attributes match in buttons |
465
+ | "404 on API route" | Verify route defined before `app.listen()` |
466
+
467
+ ---
468
+
469
+ ## Code Style & Conventions
470
+
471
+ ### File Naming
472
+
473
+ - **Components:** `kebab-case` (my-component.js)
474
+ - **Routes:** `kebab-case` (user-routes.js)
475
+ - **Styles:** `kebab-case` (main.css)
476
+
477
+ ### Code Style
478
+
479
+ ```javascript
480
+ // Use async/await (not callbacks)
481
+ const user = await User.find(123);
482
+
483
+ // Use template literals
484
+ const message = `Hello, ${name}!`;
485
+
486
+ // Use arrow functions
487
+ const items = data.map((item) => ({ ...item, active: true }));
488
+
489
+ // Group related imports
490
+ import { Model, DB } from 'africode/core/db.js';
491
+ import { middleware } from 'africode/core/middleware.js';
492
+ ```
493
+
494
+ ### CSS Classes
495
+
496
+ ```css
497
+ /* Use kebab-case for class names */
498
+ .user-profile {
499
+ }
500
+ .nav-link-active {
501
+ }
502
+ .pattern-showcase {
503
+ }
504
+
505
+ /* Use CSS variables for colors */
506
+ color: var(--afri-gold);
507
+ background: var(--afri-blue);
508
+ ```
509
+
510
+ ---
511
+
512
+ ## Performance Tips
513
+
514
+ 1. **Use Bun's native SQLite** — Faster than Node.js drivers
515
+ 2. **Lazy-load Web Components** — Use `<template>` for off-screen content
516
+ 3. **Cache pattern renders** — Generate once, reuse multiple times
517
+ 4. **Enable HTTP/2** — Bun does this by default
518
+ 5. **Paginate large datasets** — Never fetch unlimited records
519
+ 6. **Use database indexes** — Add to frequently queried columns
520
+ 7. **Minimize middleware** — Only attach needed middleware
521
+ 8. **Compress responses** — Use gzip middleware
522
+
523
+ ---
524
+
525
+ ## When to Use What
526
+
527
+ | Need | Use |
528
+ | -------------------- | -------------------------------------------------------- |
529
+ | Layout component | `<af-navbar>`, `<af-section>` |
530
+ | Form input | `<af-input>`, `<af-select>` |
531
+ | Display data | `<af-table>`, `<af-card>` |
532
+ | Show pattern | `PatternRenderer.generate*()` or `<af-pattern-showcase>` |
533
+ | User feedback | `<af-alert>`, `<af-toast>` |
534
+ | Real-time updates | WebSocket + middleware |
535
+ | User authentication | `middleware.auth()` + JWT |
536
+ | Database persistence | ORM models + migrations |
537
+ | Multiple languages | `data-lang` attributes + setLanguage() |
538
+
539
+ ---
540
+
541
+ ## Project Setup Checklist
542
+
543
+ - [ ] Run `bun install`
544
+ - [ ] Create `.env` file with `JWT_SECRET` and `DATABASE_URL`
545
+ - [ ] Run database migrations: `bun run migrations/001_initial_schema.sql`
546
+ - [ ] Create first route in `core/api/` directory
547
+ - [ ] Add middleware to `server.js`
548
+ - [ ] Define Web Component imports in HTML `<head>`
549
+ - [ ] Test with `bun test`
550
+ - [ ] Run dev server: `bun dev`
551
+
552
+ ---
553
+
554
+ ## Key Files to Check
555
+
556
+ - **Core SDK:** `core/sdk.js`
557
+ - **Database ORM:** `core/db.js`
558
+ - **Components:** `components/index.js`
559
+ - **Styles:** `styles/africanity.css`
560
+ - **Color Palette:** In `:root` CSS variables
561
+ - **Patterns:** `core/patterns.js` or inline PatternRenderer
562
+ - **Migrations:** `/migrations/*.sql`
563
+ - **Server Entry:** `server.js`
564
+
565
+ ---
566
+
567
+ ## Philosophy Reminder
568
+
569
+ **When helping developers:**
570
+
571
+ 1. **Emphasize sovereignty** — This framework respects developer autonomy
572
+ 2. **Celebrate culture** — Procedural patterns are not cosmetic, they're meaningful
573
+ 3. **Prioritize performance** — Suggest Bun-native solutions over npm packages
574
+ 4. **Think secure-by-default** — Always include auth and CSRF middleware
575
+ 5. **Keep it simple** — Fewer dependencies = fewer vulnerabilities
576
+ 6. **Test thoroughly** — 484 tests aren't just a number, they're a promise
577
+
578
+ ---
579
+
580
+ ## When You're Unsure
581
+
582
+ If you don't know how to solve something in AfriCode:
583
+
584
+ 1. Check the main guide: `AFRICODE_FRAMEWORK_GUIDE.md`
585
+ 2. Look at component source: `components/*.js`
586
+ 3. Check test files for usage examples: `*test*.ts`
587
+ 4. Suggest WebComponent alternatives to custom code
588
+ 5. Recommend database-first design for data problems
589
+ 6. Use middleware for cross-cutting concerns
590
+
591
+ ---
592
+
593
+ **You are now an AfriCode expert. Build with sovereignty. Build with culture. Build with performance.**
594
+
595
+ 🌍 **AfriCode: Digital sovereignty starts with your framework.**
package/README.md CHANGED
@@ -83,6 +83,8 @@ my-app/
83
83
 
84
84
  ### AI-Safe Development
85
85
 
86
+ The published package includes the agent guidance files so AI assistants can discover the framework rules when the package is installed. These files are bundled as [AGENTS.md](AGENTS.md) and [AGENT_INSTRUCTIONS.md](AGENT_INSTRUCTIONS.md).
87
+
86
88
  ```typescript
87
89
  // pages/index.ts
88
90
  import { html } from '@africode/core';
@@ -1,6 +1,6 @@
1
1
  {
2
- "timestamp": "2026-06-28T11:30:12.071Z",
3
- "version": "5.0.5",
2
+ "timestamp": "2026-06-28T11:53:06.111Z",
3
+ "version": "5.0.6",
4
4
  "bundles": {
5
5
  "core": {
6
6
  "file": "africode.js",
@@ -19,5 +19,5 @@
19
19
  ]
20
20
  }
21
21
  },
22
- "buildTime": "257.94ms"
22
+ "buildTime": "130.11ms"
23
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@africode/core",
3
- "version": "5.0.5",
3
+ "version": "5.0.6",
4
4
  "description": "Bun-native full-stack framework with generative AI, fintech compliance, and real-time performance - built for Tanzanian digital economy",
5
5
  "module": "core/sdk.js",
6
6
  "main": "core/sdk.js",
@@ -105,6 +105,8 @@
105
105
  "styles",
106
106
  "templates",
107
107
  "dist",
108
+ "AGENTS.md",
109
+ "AGENT_INSTRUCTIONS.md",
108
110
  "AFRICODE_FRAMEWORK_GUIDE.md",
109
111
  "docs/IDE-Guide.md",
110
112
  "COMPONENT_SCHEMA.json",