myaiforone 1.0.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.
- package/README.md +113 -0
- package/agents/_template/CLAUDE.md +18 -0
- package/agents/_template/agent.json +7 -0
- package/agents/platform/agentcreator/CLAUDE.md +300 -0
- package/agents/platform/appcreator/CLAUDE.md +158 -0
- package/agents/platform/gym/CLAUDE.md +486 -0
- package/agents/platform/gym/agent.json +40 -0
- package/agents/platform/gym/programs/agent-building/program.json +160 -0
- package/agents/platform/gym/programs/automations-mastery/program.json +129 -0
- package/agents/platform/gym/programs/getting-started/program.json +124 -0
- package/agents/platform/gym/programs/mcp-integrations/program.json +116 -0
- package/agents/platform/gym/programs/multi-model-strategy/program.json +115 -0
- package/agents/platform/gym/programs/prompt-engineering/program.json +136 -0
- package/agents/platform/gym/souls/alex.md +12 -0
- package/agents/platform/gym/souls/jordan.md +12 -0
- package/agents/platform/gym/souls/morgan.md +12 -0
- package/agents/platform/gym/souls/riley.md +12 -0
- package/agents/platform/gym/souls/sam.md +12 -0
- package/agents/platform/hub/CLAUDE.md +372 -0
- package/agents/platform/promptcreator/CLAUDE.md +130 -0
- package/agents/platform/skillcreator/CLAUDE.md +163 -0
- package/bin/cli.js +566 -0
- package/config.example.json +310 -0
- package/dist/agent-registry.d.ts +32 -0
- package/dist/agent-registry.d.ts.map +1 -0
- package/dist/agent-registry.js +144 -0
- package/dist/agent-registry.js.map +1 -0
- package/dist/channels/discord.d.ts +17 -0
- package/dist/channels/discord.d.ts.map +1 -0
- package/dist/channels/discord.js +114 -0
- package/dist/channels/discord.js.map +1 -0
- package/dist/channels/imessage.d.ts +23 -0
- package/dist/channels/imessage.d.ts.map +1 -0
- package/dist/channels/imessage.js +214 -0
- package/dist/channels/imessage.js.map +1 -0
- package/dist/channels/slack.d.ts +19 -0
- package/dist/channels/slack.d.ts.map +1 -0
- package/dist/channels/slack.js +167 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/telegram.d.ts +19 -0
- package/dist/channels/telegram.d.ts.map +1 -0
- package/dist/channels/telegram.js +274 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/types.d.ts +44 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +18 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/channels/whatsapp.d.ts +23 -0
- package/dist/channels/whatsapp.d.ts.map +1 -0
- package/dist/channels/whatsapp.js +189 -0
- package/dist/channels/whatsapp.js.map +1 -0
- package/dist/config.d.ts +134 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +127 -0
- package/dist/config.js.map +1 -0
- package/dist/cron.d.ts +8 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +35 -0
- package/dist/cron.js.map +1 -0
- package/dist/decrypt-keys.d.ts +7 -0
- package/dist/decrypt-keys.d.ts.map +1 -0
- package/dist/decrypt-keys.js +53 -0
- package/dist/decrypt-keys.js.map +1 -0
- package/dist/encrypt-keys.d.ts +8 -0
- package/dist/encrypt-keys.d.ts.map +1 -0
- package/dist/encrypt-keys.js +62 -0
- package/dist/encrypt-keys.js.map +1 -0
- package/dist/executor.d.ts +31 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +2009 -0
- package/dist/executor.js.map +1 -0
- package/dist/gemini-executor.d.ts +27 -0
- package/dist/gemini-executor.d.ts.map +1 -0
- package/dist/gemini-executor.js +160 -0
- package/dist/gemini-executor.js.map +1 -0
- package/dist/goals.d.ts +24 -0
- package/dist/goals.d.ts.map +1 -0
- package/dist/goals.js +189 -0
- package/dist/goals.js.map +1 -0
- package/dist/gym/activity-digest.d.ts +30 -0
- package/dist/gym/activity-digest.d.ts.map +1 -0
- package/dist/gym/activity-digest.js +506 -0
- package/dist/gym/activity-digest.js.map +1 -0
- package/dist/gym/dimension-scorer.d.ts +76 -0
- package/dist/gym/dimension-scorer.d.ts.map +1 -0
- package/dist/gym/dimension-scorer.js +236 -0
- package/dist/gym/dimension-scorer.js.map +1 -0
- package/dist/gym/gym-router.d.ts +7 -0
- package/dist/gym/gym-router.d.ts.map +1 -0
- package/dist/gym/gym-router.js +718 -0
- package/dist/gym/gym-router.js.map +1 -0
- package/dist/gym/index.d.ts +11 -0
- package/dist/gym/index.d.ts.map +1 -0
- package/dist/gym/index.js +11 -0
- package/dist/gym/index.js.map +1 -0
- package/dist/heartbeat.d.ts +21 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +163 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +254 -0
- package/dist/index.js.map +1 -0
- package/dist/keystore.d.ts +22 -0
- package/dist/keystore.d.ts.map +1 -0
- package/dist/keystore.js +178 -0
- package/dist/keystore.js.map +1 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +45 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory/daily.d.ts +22 -0
- package/dist/memory/daily.d.ts.map +1 -0
- package/dist/memory/daily.js +82 -0
- package/dist/memory/daily.js.map +1 -0
- package/dist/memory/embeddings.d.ts +15 -0
- package/dist/memory/embeddings.d.ts.map +1 -0
- package/dist/memory/embeddings.js +154 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/index.d.ts +32 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +159 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/search.d.ts +21 -0
- package/dist/memory/search.d.ts.map +1 -0
- package/dist/memory/search.js +77 -0
- package/dist/memory/search.js.map +1 -0
- package/dist/memory/store.d.ts +23 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +144 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/ollama-executor.d.ts +17 -0
- package/dist/ollama-executor.d.ts.map +1 -0
- package/dist/ollama-executor.js +112 -0
- package/dist/ollama-executor.js.map +1 -0
- package/dist/openai-executor.d.ts +38 -0
- package/dist/openai-executor.d.ts.map +1 -0
- package/dist/openai-executor.js +197 -0
- package/dist/openai-executor.js.map +1 -0
- package/dist/router.d.ts +11 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +185 -0
- package/dist/router.js.map +1 -0
- package/dist/test-message.d.ts +2 -0
- package/dist/test-message.d.ts.map +1 -0
- package/dist/test-message.js +60 -0
- package/dist/test-message.js.map +1 -0
- package/dist/utils/imsg-db-reader.d.ts +24 -0
- package/dist/utils/imsg-db-reader.d.ts.map +1 -0
- package/dist/utils/imsg-db-reader.js +92 -0
- package/dist/utils/imsg-db-reader.js.map +1 -0
- package/dist/utils/imsg-rpc.d.ts +25 -0
- package/dist/utils/imsg-rpc.d.ts.map +1 -0
- package/dist/utils/imsg-rpc.js +149 -0
- package/dist/utils/imsg-rpc.js.map +1 -0
- package/dist/utils/message-formatter.d.ts +3 -0
- package/dist/utils/message-formatter.d.ts.map +1 -0
- package/dist/utils/message-formatter.js +69 -0
- package/dist/utils/message-formatter.js.map +1 -0
- package/dist/web-ui.d.ts +12 -0
- package/dist/web-ui.d.ts.map +1 -0
- package/dist/web-ui.js +5784 -0
- package/dist/web-ui.js.map +1 -0
- package/dist/whatsapp-chats.d.ts +2 -0
- package/dist/whatsapp-chats.d.ts.map +1 -0
- package/dist/whatsapp-chats.js +76 -0
- package/dist/whatsapp-chats.js.map +1 -0
- package/dist/whatsapp-login.d.ts +2 -0
- package/dist/whatsapp-login.d.ts.map +1 -0
- package/dist/whatsapp-login.js +90 -0
- package/dist/whatsapp-login.js.map +1 -0
- package/dist/wiki-sync.d.ts +21 -0
- package/dist/wiki-sync.d.ts.map +1 -0
- package/dist/wiki-sync.js +147 -0
- package/dist/wiki-sync.js.map +1 -0
- package/docs/AddNewAgentGuide.md +100 -0
- package/docs/AddNewMcpGuide.md +72 -0
- package/docs/Architecture.md +795 -0
- package/docs/CLAUDE-AI-SETUP.md +166 -0
- package/docs/Setup.md +297 -0
- package/docs/ai-gym-architecture.md +1040 -0
- package/docs/ai-gym-build-plan.md +343 -0
- package/docs/ai-gym-onboarding.md +122 -0
- package/docs/appcreator_plan.md +348 -0
- package/docs/platform-mcp-audit.md +320 -0
- package/docs/server-deployment-plan.md +503 -0
- package/docs/superpowers/plans/2026-03-25-marketplace.md +1281 -0
- package/docs/superpowers/specs/2026-03-25-marketplace-design.md +287 -0
- package/docs/user-guide.md +2016 -0
- package/mcp-catalog.json +628 -0
- package/package.json +63 -0
- package/public/MyAIforOne-logomark-512.svg +16 -0
- package/public/MyAIforOne-logomark-transparent.svg +15 -0
- package/public/activity.html +314 -0
- package/public/admin.html +1674 -0
- package/public/agent-dashboard.html +670 -0
- package/public/api-docs.html +1106 -0
- package/public/automations.html +722 -0
- package/public/canvas.css +223 -0
- package/public/canvas.js +588 -0
- package/public/changelog.html +231 -0
- package/public/gym.html +2766 -0
- package/public/home.html +1930 -0
- package/public/index.html +2809 -0
- package/public/lab.html +1643 -0
- package/public/library.html +1442 -0
- package/public/marketplace.html +1101 -0
- package/public/mcp-docs.html +441 -0
- package/public/mini.html +390 -0
- package/public/monitor.html +584 -0
- package/public/org.html +4304 -0
- package/public/projects.html +734 -0
- package/public/settings.html +645 -0
- package/public/tasks.html +932 -0
- package/public/trainers/alex.svg +12 -0
- package/public/trainers/jordan.svg +12 -0
- package/public/trainers/morgan.svg +12 -0
- package/public/trainers/riley.svg +12 -0
- package/public/trainers/sam.svg +12 -0
- package/public/user-guide.html +218 -0
- package/registry/agents.json +3 -0
- package/registry/apps.json +20 -0
- package/registry/installed-drafts.json +3 -0
- package/registry/mcps.json +1084 -0
- package/registry/prompts/personal/mcp-test-prompt.md +6 -0
- package/registry/prompts/personal/memory-recall.md +6 -0
- package/registry/prompts/platform/brainstorm.md +15 -0
- package/registry/prompts/platform/code-review.md +16 -0
- package/registry/prompts/platform/explain.md +16 -0
- package/registry/prompts.json +58 -0
- package/registry/skills/external/brainstorming.md +5 -0
- package/registry/skills/external/code-review.md +40 -0
- package/registry/skills/external/frontend-patterns.md +642 -0
- package/registry/skills/external/frontend-slides.md +184 -0
- package/registry/skills/external/systematic-debugging.md +5 -0
- package/registry/skills/external/tdd.md +328 -0
- package/registry/skills/external/verification-before-completion.md +5 -0
- package/registry/skills/external/writing-plans.md +5 -0
- package/registry/skills/platform/ai41_app_build.md +930 -0
- package/registry/skills/platform/ai41_app_deploy.md +168 -0
- package/registry/skills/platform/ai41_app_orchestrator.md +239 -0
- package/registry/skills/platform/ai41_app_patterns.md +359 -0
- package/registry/skills/platform/ai41_app_register.md +85 -0
- package/registry/skills/platform/ai41_app_scaffold.md +421 -0
- package/registry/skills/platform/ai41_app_verify.md +107 -0
- package/registry/skills/platform/opProjectCreate.md +239 -0
- package/registry/skills/platform/op_devbrowser.md +136 -0
- package/registry/skills/platform/sop_brandguidelines.md +103 -0
- package/registry/skills/platform/sop_docx.md +117 -0
- package/registry/skills/platform/sop_frontenddesign.md +44 -0
- package/registry/skills/platform/sop_frontenddesign_v2.md +659 -0
- package/registry/skills/platform/sop_mcpbuilder.md +133 -0
- package/registry/skills/platform/sop_pdf.md +172 -0
- package/registry/skills/platform/sop_pptx.md +133 -0
- package/registry/skills/platform/sop_skillcreator.md +104 -0
- package/registry/skills/platform/sop_themefactory.md +128 -0
- package/registry/skills/platform/sop_webapptesting.md +75 -0
- package/registry/skills/platform/sop_webartifactsbuilder.md +97 -0
- package/registry/skills/platform/sop_xlsx.md +134 -0
- package/registry/skills.json +1055 -0
- package/scripts/discover-chats.sh +11 -0
- package/scripts/install-service-windows.ps1 +87 -0
- package/scripts/install-service.sh +52 -0
- package/scripts/seed-registry.ts +195 -0
- package/scripts/test-send.sh +5 -0
- package/scripts/tray-indicator.ps1 +35 -0
- package/scripts/uninstall-service-windows.ps1 +23 -0
- package/scripts/uninstall-service.sh +15 -0
- package/scripts/xbar-myagent.5s.sh +32 -0
- package/server/mcp-server/dist/index.d.ts +11 -0
- package/server/mcp-server/dist/index.js +1332 -0
- package/server/mcp-server/dist/lib/api-client.d.ts +165 -0
- package/server/mcp-server/dist/lib/api-client.js +241 -0
- package/server/mcp-server/index.ts +1545 -0
- package/server/mcp-server/lib/api-client.ts +366 -0
- package/server/mcp-server/tsconfig.json +14 -0
- package/src/agent-registry.ts +180 -0
- package/src/channels/discord.ts +129 -0
- package/src/channels/imessage.ts +261 -0
- package/src/channels/slack.ts +208 -0
- package/src/channels/telegram.ts +307 -0
- package/src/channels/types.ts +62 -0
- package/src/channels/whatsapp.ts +227 -0
- package/src/config.ts +281 -0
- package/src/cron.ts +43 -0
- package/src/decrypt-keys.ts +60 -0
- package/src/encrypt-keys.ts +70 -0
- package/src/executor.ts +2190 -0
- package/src/gemini-executor.ts +212 -0
- package/src/goals.ts +240 -0
- package/src/gym/activity-digest.ts +546 -0
- package/src/gym/dimension-scorer.ts +297 -0
- package/src/gym/gym-router.ts +801 -0
- package/src/gym/index.ts +19 -0
- package/src/heartbeat.ts +220 -0
- package/src/index.ts +275 -0
- package/src/keystore.ts +190 -0
- package/src/logger.ts +51 -0
- package/src/memory/daily.ts +101 -0
- package/src/memory/embeddings.ts +185 -0
- package/src/memory/index.ts +218 -0
- package/src/memory/search.ts +124 -0
- package/src/memory/store.ts +189 -0
- package/src/ollama-executor.ts +126 -0
- package/src/openai-executor.ts +259 -0
- package/src/router.ts +230 -0
- package/src/test-message.ts +72 -0
- package/src/utils/imsg-db-reader.ts +109 -0
- package/src/utils/imsg-rpc.ts +178 -0
- package/src/utils/message-formatter.ts +90 -0
- package/src/web-ui.ts +5778 -0
- package/src/whatsapp-chats.ts +91 -0
- package/src/whatsapp-login.ts +110 -0
- package/src/wiki-sync.ts +199 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai41_app_patterns
|
|
3
|
+
description: >-
|
|
4
|
+
Architecture patterns and coding conventions for building full-stack Express + React apps. Extracted from production apps (P&L Analyzer, EscrowService). Called by ai41_app_orchestrator Phase 3.
|
|
5
|
+
allowed-tools: Read Write Edit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# App Patterns
|
|
9
|
+
|
|
10
|
+
These are the architecture patterns to follow when building apps. They are extracted from production-quality apps and represent proven conventions. Follow them exactly.
|
|
11
|
+
|
|
12
|
+
## Project Structure
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
{app-slug}/
|
|
16
|
+
├── backend/
|
|
17
|
+
│ ├── src/
|
|
18
|
+
│ │ ├── index.ts # Express app entry — registers middleware + routes
|
|
19
|
+
│ │ ├── routes/
|
|
20
|
+
│ │ │ ├── health.ts # GET /api/health
|
|
21
|
+
│ │ │ ├── {domain}.ts # One file per domain (expenses.ts, users.ts, etc.)
|
|
22
|
+
│ │ │ └── index.ts # Re-exports all route registrations
|
|
23
|
+
│ │ ├── middleware/
|
|
24
|
+
│ │ │ ├── auth.ts # Auth middleware (if needed)
|
|
25
|
+
│ │ │ ├── errorHandler.ts # Global error handler
|
|
26
|
+
│ │ │ └── validate.ts # Zod validation middleware
|
|
27
|
+
│ │ └── lib/
|
|
28
|
+
│ │ └── prisma.ts # Prisma client singleton
|
|
29
|
+
│ ├── prisma/
|
|
30
|
+
│ │ ├── schema.prisma # Database schema
|
|
31
|
+
│ │ └── seed.ts # Seed data
|
|
32
|
+
│ └── package.json
|
|
33
|
+
├── frontend/
|
|
34
|
+
│ ├── src/
|
|
35
|
+
│ │ ├── App.tsx # Router
|
|
36
|
+
│ │ ├── main.tsx # Entry point
|
|
37
|
+
│ │ ├── index.css # Tailwind imports
|
|
38
|
+
│ │ ├── components/
|
|
39
|
+
│ │ │ ├── ui/ # shadcn/ui components
|
|
40
|
+
│ │ │ ├── layout/ # Layout components (Navbar, Sidebar, PageHeader)
|
|
41
|
+
│ │ │ └── {domain}/ # Domain components (ExpenseForm, ExpenseCard)
|
|
42
|
+
│ │ ├── pages/
|
|
43
|
+
│ │ │ ├── Dashboard.tsx # Main landing page
|
|
44
|
+
│ │ │ └── {Domain}Page.tsx # One page per major view
|
|
45
|
+
│ │ ├── hooks/
|
|
46
|
+
│ │ │ └── use{Domain}.ts # Custom hooks per domain
|
|
47
|
+
│ │ └── lib/
|
|
48
|
+
│ │ ├── api.ts # API client (fetch wrapper)
|
|
49
|
+
│ │ └── utils.ts # cn() helper for Tailwind
|
|
50
|
+
│ └── package.json
|
|
51
|
+
└── .gitignore
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Backend Conventions
|
|
55
|
+
|
|
56
|
+
### Express App Setup (`src/index.ts`)
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import "dotenv/config";
|
|
60
|
+
import express from "express";
|
|
61
|
+
import cors from "cors";
|
|
62
|
+
import helmet from "helmet";
|
|
63
|
+
import morgan from "morgan";
|
|
64
|
+
import { registerRoutes } from "./routes/index.js";
|
|
65
|
+
|
|
66
|
+
const app = express();
|
|
67
|
+
const PORT = parseInt(process.env.PORT || "3001");
|
|
68
|
+
|
|
69
|
+
app.use(helmet());
|
|
70
|
+
app.use(cors({ origin: process.env.CORS_ORIGIN || "http://localhost:5173", credentials: true }));
|
|
71
|
+
app.use(express.json());
|
|
72
|
+
app.use(morgan("dev"));
|
|
73
|
+
|
|
74
|
+
// Register all routes
|
|
75
|
+
registerRoutes(app);
|
|
76
|
+
|
|
77
|
+
// Global error handler (must be LAST)
|
|
78
|
+
app.use((err: Error, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
|
|
79
|
+
console.error(err.stack);
|
|
80
|
+
res.status(500).json({ error: process.env.NODE_ENV === "production" ? "Internal server error" : err.message });
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Route Files (`src/routes/{domain}.ts`)
|
|
87
|
+
|
|
88
|
+
One file per domain. Each exports a `register` function:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { Router } from "express";
|
|
92
|
+
import { prisma } from "../lib/prisma.js";
|
|
93
|
+
import { z } from "zod";
|
|
94
|
+
|
|
95
|
+
const router = Router();
|
|
96
|
+
|
|
97
|
+
// Schema validation
|
|
98
|
+
const CreateExpenseSchema = z.object({
|
|
99
|
+
description: z.string().min(1),
|
|
100
|
+
amount: z.number().positive(),
|
|
101
|
+
category: z.string().optional(),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// GET /api/expenses
|
|
105
|
+
router.get("/", async (_req, res) => {
|
|
106
|
+
const expenses = await prisma.expense.findMany({
|
|
107
|
+
orderBy: { createdAt: "desc" },
|
|
108
|
+
});
|
|
109
|
+
res.json(expenses);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// POST /api/expenses
|
|
113
|
+
router.post("/", async (req, res) => {
|
|
114
|
+
const parsed = CreateExpenseSchema.safeParse(req.body);
|
|
115
|
+
if (!parsed.success) return res.status(400).json({ error: parsed.error.flatten() });
|
|
116
|
+
|
|
117
|
+
const expense = await prisma.expense.create({ data: parsed.data });
|
|
118
|
+
res.status(201).json(expense);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// DELETE /api/expenses/:id
|
|
122
|
+
router.delete("/:id", async (req, res) => {
|
|
123
|
+
await prisma.expense.delete({ where: { id: req.params.id } });
|
|
124
|
+
res.json({ ok: true });
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export default router;
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Route Registration (`src/routes/index.ts`)
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import type { Express } from "express";
|
|
134
|
+
import expenses from "./expenses.js";
|
|
135
|
+
import health from "./health.js";
|
|
136
|
+
|
|
137
|
+
export function registerRoutes(app: Express) {
|
|
138
|
+
app.use("/api/health", health);
|
|
139
|
+
app.use("/api/expenses", expenses);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Prisma Client Singleton (`src/lib/prisma.ts`)
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { PrismaClient } from "@prisma/client";
|
|
147
|
+
|
|
148
|
+
export const prisma = new PrismaClient({
|
|
149
|
+
log: process.env.NODE_ENV === "development" ? ["query"] : ["error"],
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Prisma Schema Conventions
|
|
154
|
+
|
|
155
|
+
```prisma
|
|
156
|
+
model Expense {
|
|
157
|
+
id String @id @default(cuid())
|
|
158
|
+
description String
|
|
159
|
+
amount Float
|
|
160
|
+
category String?
|
|
161
|
+
createdAt DateTime @default(now())
|
|
162
|
+
updatedAt DateTime @updatedAt
|
|
163
|
+
|
|
164
|
+
// Relations use camelCase field name, PascalCase model reference
|
|
165
|
+
userId String?
|
|
166
|
+
user User? @relation(fields: [userId], references: [id])
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Conventions:**
|
|
171
|
+
- `id` is always `String @id @default(cuid())`
|
|
172
|
+
- Always include `createdAt DateTime @default(now())`
|
|
173
|
+
- Always include `updatedAt DateTime @updatedAt`
|
|
174
|
+
- Use `String?` for optional fields (not separate null checks)
|
|
175
|
+
- Relation fields: `userId String` + `user User @relation(...)`
|
|
176
|
+
|
|
177
|
+
### Zod Validation
|
|
178
|
+
|
|
179
|
+
Validate request bodies with Zod at the route level. Never trust client data:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const schema = z.object({ ... });
|
|
183
|
+
const parsed = schema.safeParse(req.body);
|
|
184
|
+
if (!parsed.success) return res.status(400).json({ error: parsed.error.flatten() });
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Frontend Conventions
|
|
188
|
+
|
|
189
|
+
### Page Components (`src/pages/*.tsx`)
|
|
190
|
+
|
|
191
|
+
Each page is a self-contained view:
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
import { useState, useEffect } from "react";
|
|
195
|
+
import { api } from "@/lib/api";
|
|
196
|
+
import { Button } from "@/components/ui/button";
|
|
197
|
+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
198
|
+
import { PageHeader } from "@/components/layout/PageHeader";
|
|
199
|
+
|
|
200
|
+
export default function ExpensesPage() {
|
|
201
|
+
const [expenses, setExpenses] = useState<Expense[]>([]);
|
|
202
|
+
const [loading, setLoading] = useState(true);
|
|
203
|
+
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
api.get<Expense[]>("/expenses")
|
|
206
|
+
.then(setExpenses)
|
|
207
|
+
.finally(() => setLoading(false));
|
|
208
|
+
}, []);
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<div className="container mx-auto py-8 px-4">
|
|
212
|
+
<PageHeader title="Expenses" description="Track your spending" />
|
|
213
|
+
{loading ? (
|
|
214
|
+
<div className="text-center text-muted-foreground py-12">Loading...</div>
|
|
215
|
+
) : (
|
|
216
|
+
<div className="grid gap-4">
|
|
217
|
+
{expenses.map(e => (
|
|
218
|
+
<Card key={e.id}>
|
|
219
|
+
<CardContent className="flex items-center justify-between p-4">
|
|
220
|
+
<div>
|
|
221
|
+
<p className="font-medium">{e.description}</p>
|
|
222
|
+
<p className="text-sm text-muted-foreground">{e.category}</p>
|
|
223
|
+
</div>
|
|
224
|
+
<p className="text-lg font-bold">${e.amount.toFixed(2)}</p>
|
|
225
|
+
</CardContent>
|
|
226
|
+
</Card>
|
|
227
|
+
))}
|
|
228
|
+
</div>
|
|
229
|
+
)}
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Layout Components
|
|
236
|
+
|
|
237
|
+
**Navbar (`src/components/layout/Navbar.tsx`):**
|
|
238
|
+
```tsx
|
|
239
|
+
import { Link, useLocation } from "react-router-dom";
|
|
240
|
+
import { cn } from "@/lib/utils";
|
|
241
|
+
|
|
242
|
+
const navItems = [
|
|
243
|
+
{ label: "Dashboard", path: "/" },
|
|
244
|
+
{ label: "Expenses", path: "/expenses" },
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
export function Navbar() {
|
|
248
|
+
const { pathname } = useLocation();
|
|
249
|
+
return (
|
|
250
|
+
<nav className="border-b bg-white">
|
|
251
|
+
<div className="container mx-auto flex h-14 items-center px-4 gap-6">
|
|
252
|
+
<Link to="/" className="font-bold text-lg">{APP_NAME}</Link>
|
|
253
|
+
{navItems.map(item => (
|
|
254
|
+
<Link
|
|
255
|
+
key={item.path}
|
|
256
|
+
to={item.path}
|
|
257
|
+
className={cn(
|
|
258
|
+
"text-sm font-medium transition-colors hover:text-foreground",
|
|
259
|
+
pathname === item.path ? "text-foreground" : "text-muted-foreground"
|
|
260
|
+
)}
|
|
261
|
+
>
|
|
262
|
+
{item.label}
|
|
263
|
+
</Link>
|
|
264
|
+
))}
|
|
265
|
+
</div>
|
|
266
|
+
</nav>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**PageHeader (`src/components/layout/PageHeader.tsx`):**
|
|
272
|
+
```tsx
|
|
273
|
+
export function PageHeader({ title, description, action }: {
|
|
274
|
+
title: string;
|
|
275
|
+
description?: string;
|
|
276
|
+
action?: React.ReactNode;
|
|
277
|
+
}) {
|
|
278
|
+
return (
|
|
279
|
+
<div className="flex items-center justify-between mb-8">
|
|
280
|
+
<div>
|
|
281
|
+
<h1 className="text-2xl font-bold tracking-tight">{title}</h1>
|
|
282
|
+
{description && <p className="text-muted-foreground">{description}</p>}
|
|
283
|
+
</div>
|
|
284
|
+
{action}
|
|
285
|
+
</div>
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### App Router (`src/App.tsx`)
|
|
291
|
+
|
|
292
|
+
```tsx
|
|
293
|
+
import { Routes, Route } from "react-router-dom";
|
|
294
|
+
import { Navbar } from "@/components/layout/Navbar";
|
|
295
|
+
import Dashboard from "@/pages/Dashboard";
|
|
296
|
+
import ExpensesPage from "@/pages/ExpensesPage";
|
|
297
|
+
|
|
298
|
+
export default function App() {
|
|
299
|
+
return (
|
|
300
|
+
<div className="min-h-screen bg-gray-50">
|
|
301
|
+
<Navbar />
|
|
302
|
+
<Routes>
|
|
303
|
+
<Route path="/" element={<Dashboard />} />
|
|
304
|
+
<Route path="/expenses" element={<ExpensesPage />} />
|
|
305
|
+
</Routes>
|
|
306
|
+
</div>
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### shadcn/ui Usage
|
|
312
|
+
|
|
313
|
+
ALWAYS use shadcn/ui components for UI elements. Install as needed during BUILD:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
npx shadcn@latest add {component} --yes
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Common components to install:
|
|
320
|
+
- `button` — always
|
|
321
|
+
- `card` — always
|
|
322
|
+
- `input` + `label` — for forms
|
|
323
|
+
- `table` — for data tables
|
|
324
|
+
- `dialog` — for modals
|
|
325
|
+
- `select` — for dropdowns
|
|
326
|
+
- `badge` — for status indicators
|
|
327
|
+
- `tabs` — for tabbed views
|
|
328
|
+
- `toast` + `sonner` — for notifications
|
|
329
|
+
- `dropdown-menu` — for action menus
|
|
330
|
+
- `separator` — for visual dividers
|
|
331
|
+
|
|
332
|
+
**Import pattern:**
|
|
333
|
+
```tsx
|
|
334
|
+
import { Button } from "@/components/ui/button";
|
|
335
|
+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
336
|
+
import { Input } from "@/components/ui/input";
|
|
337
|
+
import { Label } from "@/components/ui/label";
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Styling Rules
|
|
341
|
+
|
|
342
|
+
- Use Tailwind utility classes exclusively — no custom CSS
|
|
343
|
+
- Use `cn()` for conditional classes: `className={cn("base", condition && "variant")}`
|
|
344
|
+
- Spacing: `p-4` for card padding, `gap-4` for grid/flex gaps, `py-8 px-4` for page padding
|
|
345
|
+
- Container: `container mx-auto` for page-width content
|
|
346
|
+
- Colors: use Tailwind's semantic colors (`text-foreground`, `text-muted-foreground`, `bg-card`, `border`)
|
|
347
|
+
- Font: `font-bold` for headings, `font-medium` for labels, `text-sm` for secondary text
|
|
348
|
+
- Responsive: always include responsive breakpoints for grids (`grid-cols-1 md:grid-cols-2 lg:grid-cols-3`)
|
|
349
|
+
|
|
350
|
+
## General Rules
|
|
351
|
+
|
|
352
|
+
1. **No console.log in production code** — use `morgan` for request logging, `console.error` only for errors
|
|
353
|
+
2. **Always use TypeScript types** — define interfaces for API responses, component props, and database models
|
|
354
|
+
3. **API responses are always JSON** — `res.json(data)`, never raw text
|
|
355
|
+
4. **Error responses have consistent shape** — `{ error: string }` or `{ error: ZodFlattened }`
|
|
356
|
+
5. **Prisma models drive types** — import generated types from `@prisma/client`
|
|
357
|
+
6. **One route file per domain** — don't put all routes in index.ts
|
|
358
|
+
7. **One page component per major view** — don't put all views in App.tsx
|
|
359
|
+
8. **Forms use controlled components** — `useState` for form state, not uncontrolled refs
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai41_app_register
|
|
3
|
+
description: >-
|
|
4
|
+
Register a deployed app in the MyAIforOne platform and create a developer agent for ongoing maintenance. Called by ai41_app_orchestrator Phase 7.
|
|
5
|
+
allowed-tools: Read
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# App Register
|
|
9
|
+
|
|
10
|
+
Register the deployed app in the platform and create a developer agent. Uses MCP tools — no manual file editing.
|
|
11
|
+
|
|
12
|
+
## Step 1: Register the App
|
|
13
|
+
|
|
14
|
+
Use the `create_app` MCP tool with:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"name": "{APP_NAME}",
|
|
19
|
+
"url": "{DEPLOY_URL}",
|
|
20
|
+
"category": "{CATEGORY}",
|
|
21
|
+
"githubRepo": "{GITHUB_REPO_URL}",
|
|
22
|
+
"provider": "me"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Categories: `finance`, `productivity`, `engineering`, `operations`, `infrastructure`, `devtools`, `communication`, `analytics`
|
|
27
|
+
|
|
28
|
+
Choose the category that best matches the app's purpose.
|
|
29
|
+
|
|
30
|
+
## Step 2: Create a Developer Agent
|
|
31
|
+
|
|
32
|
+
Use the `create_agent` MCP tool with:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"agentId": "{APP_SLUG}-dev",
|
|
37
|
+
"name": "{APP_NAME} Developer",
|
|
38
|
+
"alias": "@{APP_SLUG}-dev",
|
|
39
|
+
"description": "Develops and maintains {APP_NAME}",
|
|
40
|
+
"workspace": "{PROJECT_DIR}",
|
|
41
|
+
"persistent": true,
|
|
42
|
+
"streaming": true,
|
|
43
|
+
"advancedMemory": true,
|
|
44
|
+
"tools": ["Read", "Edit", "Write", "Glob", "Grep", "Bash"],
|
|
45
|
+
"mcps": ["github", "myaiforone"],
|
|
46
|
+
"heartbeatInstructions": "Check the GitHub repo for open issues. Check Railway deployment health at {DEPLOY_URL}/api/health. If anything needs fixing, fix it, commit, and push to trigger a redeploy."
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The developer agent:
|
|
51
|
+
- Has the app's workspace as its working directory
|
|
52
|
+
- Has GitHub MCP for repo management
|
|
53
|
+
- Has MyAIforOne MCP for platform operations
|
|
54
|
+
- Has a heartbeat that monitors the app's health
|
|
55
|
+
|
|
56
|
+
## Step 3: Update App with Developer Agent
|
|
57
|
+
|
|
58
|
+
Use the `update_app` MCP tool to set the `agentDeveloper` field:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"id": "{APP_SLUG}",
|
|
63
|
+
"status": "live"
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Step 4: Final Report
|
|
68
|
+
|
|
69
|
+
Tell the user:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Your app is live!
|
|
73
|
+
|
|
74
|
+
App: {APP_NAME}
|
|
75
|
+
URL: {DEPLOY_URL}
|
|
76
|
+
GitHub: {GITHUB_REPO_URL}
|
|
77
|
+
Status: live (visible in Registry)
|
|
78
|
+
|
|
79
|
+
Developer agent created:
|
|
80
|
+
- Agent: {APP_NAME} Developer (@{APP_SLUG}-dev)
|
|
81
|
+
- Workspace: {PROJECT_DIR}
|
|
82
|
+
- Heartbeat: monitors health and GitHub issues
|
|
83
|
+
|
|
84
|
+
To make changes, chat with @{APP_SLUG}-dev or edit the code directly in the workspace.
|
|
85
|
+
```
|