tryassay 0.22.0 → 0.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/demo/css/style.css +495 -836
  2. package/demo/index.html +40 -184
  3. package/demo/js/chat.js +385 -142
  4. package/demo/js/preview.js +456 -0
  5. package/demo/js/sse-client.js +262 -135
  6. package/demo/js/state.js +11 -1
  7. package/demo/js/timeline.js +57 -371
  8. package/dist/api/server.d.ts +2 -0
  9. package/dist/api/server.js +63 -19
  10. package/dist/api/server.js.map +1 -1
  11. package/dist/cli.js +2 -0
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/assess.d.ts +2 -0
  14. package/dist/commands/assess.js +132 -164
  15. package/dist/commands/assess.js.map +1 -1
  16. package/dist/commands/demo.js +259 -9
  17. package/dist/commands/demo.js.map +1 -1
  18. package/dist/lib/__tests__/arithmetic-quick-test.d.ts +6 -0
  19. package/dist/lib/__tests__/arithmetic-quick-test.js +197 -0
  20. package/dist/lib/__tests__/arithmetic-quick-test.js.map +1 -0
  21. package/dist/lib/__tests__/arithmetic-real-llm-test.d.ts +13 -0
  22. package/dist/lib/__tests__/arithmetic-real-llm-test.js +284 -0
  23. package/dist/lib/__tests__/arithmetic-real-llm-test.js.map +1 -0
  24. package/dist/lib/__tests__/arithmetic-value-demo.d.ts +10 -0
  25. package/dist/lib/__tests__/arithmetic-value-demo.js +193 -0
  26. package/dist/lib/__tests__/arithmetic-value-demo.js.map +1 -0
  27. package/dist/lib/__tests__/flow-to-claims.test.d.ts +1 -0
  28. package/dist/lib/__tests__/flow-to-claims.test.js +91 -0
  29. package/dist/lib/__tests__/flow-to-claims.test.js.map +1 -0
  30. package/dist/lib/__tests__/formal-verifier-api-misuse.test.d.ts +9 -0
  31. package/dist/lib/__tests__/formal-verifier-api-misuse.test.js +391 -0
  32. package/dist/lib/__tests__/formal-verifier-api-misuse.test.js.map +1 -0
  33. package/dist/lib/__tests__/formal-verifier-arithmetic.test.d.ts +7 -0
  34. package/dist/lib/__tests__/formal-verifier-arithmetic.test.js +318 -0
  35. package/dist/lib/__tests__/formal-verifier-arithmetic.test.js.map +1 -0
  36. package/dist/lib/__tests__/intent-extractor.test.d.ts +1 -0
  37. package/dist/lib/__tests__/intent-extractor.test.js +97 -0
  38. package/dist/lib/__tests__/intent-extractor.test.js.map +1 -0
  39. package/dist/lib/__tests__/intent-reviewer.test.d.ts +1 -0
  40. package/dist/lib/__tests__/intent-reviewer.test.js +55 -0
  41. package/dist/lib/__tests__/intent-reviewer.test.js.map +1 -0
  42. package/dist/lib/__tests__/mr-gsm8k-benchmark.d.ts +11 -0
  43. package/dist/lib/__tests__/mr-gsm8k-benchmark.js +224 -0
  44. package/dist/lib/__tests__/mr-gsm8k-benchmark.js.map +1 -0
  45. package/dist/lib/anthropic.js +25 -33
  46. package/dist/lib/anthropic.js.map +1 -1
  47. package/dist/lib/assessment-reporter.js +9 -13
  48. package/dist/lib/assessment-reporter.js.map +1 -1
  49. package/dist/lib/claim-extractor.js +10 -19
  50. package/dist/lib/claim-extractor.js.map +1 -1
  51. package/dist/lib/code-verifier.js +16 -36
  52. package/dist/lib/code-verifier.js.map +1 -1
  53. package/dist/lib/constraint-engine.js +10 -19
  54. package/dist/lib/constraint-engine.js.map +1 -1
  55. package/dist/lib/formal-verifier.d.ts +1 -1
  56. package/dist/lib/formal-verifier.js +454 -0
  57. package/dist/lib/formal-verifier.js.map +1 -1
  58. package/dist/lib/guided-generator.js +19 -37
  59. package/dist/lib/guided-generator.js.map +1 -1
  60. package/dist/lib/intent-extractor.d.ts +47 -0
  61. package/dist/lib/intent-extractor.js +432 -0
  62. package/dist/lib/intent-extractor.js.map +1 -0
  63. package/dist/lib/intent-reviewer.d.ts +14 -0
  64. package/dist/lib/intent-reviewer.js +148 -0
  65. package/dist/lib/intent-reviewer.js.map +1 -0
  66. package/dist/lib/intent-types.d.ts +89 -0
  67. package/dist/lib/intent-types.js +5 -0
  68. package/dist/lib/intent-types.js.map +1 -0
  69. package/dist/lib/inventory-extractor.js +9 -22
  70. package/dist/lib/inventory-extractor.js.map +1 -1
  71. package/dist/lib/llm-provider.d.ts +23 -0
  72. package/dist/lib/llm-provider.js +130 -0
  73. package/dist/lib/llm-provider.js.map +1 -0
  74. package/dist/lib/remediator.js +20 -28
  75. package/dist/lib/remediator.js.map +1 -1
  76. package/dist/lib/requirements-generator.js +14 -19
  77. package/dist/lib/requirements-generator.js.map +1 -1
  78. package/dist/lib/spec-synthesizer.js +10 -19
  79. package/dist/lib/spec-synthesizer.js.map +1 -1
  80. package/dist/runtime/app-create-orchestrator.d.ts +5 -1
  81. package/dist/runtime/app-create-orchestrator.js +114 -39
  82. package/dist/runtime/app-create-orchestrator.js.map +1 -1
  83. package/dist/runtime/check-catalog.js +5 -3
  84. package/dist/runtime/check-catalog.js.map +1 -1
  85. package/dist/runtime/check-definitions.d.ts +10 -0
  86. package/dist/runtime/check-definitions.js +52 -2
  87. package/dist/runtime/check-definitions.js.map +1 -1
  88. package/dist/runtime/composition-verifier.js +8 -12
  89. package/dist/runtime/composition-verifier.js.map +1 -1
  90. package/dist/runtime/gap-detector.js +8 -10
  91. package/dist/runtime/gap-detector.js.map +1 -1
  92. package/dist/runtime/input-validator.d.ts +7 -0
  93. package/dist/runtime/input-validator.js +162 -0
  94. package/dist/runtime/input-validator.js.map +1 -0
  95. package/dist/runtime/model-router.d.ts +10 -0
  96. package/dist/runtime/model-router.js +42 -0
  97. package/dist/runtime/model-router.js.map +1 -0
  98. package/dist/runtime/pattern-extractor.js +8 -10
  99. package/dist/runtime/pattern-extractor.js.map +1 -1
  100. package/dist/runtime/planner.js +11 -16
  101. package/dist/runtime/planner.js.map +1 -1
  102. package/dist/runtime/prompt-guard.d.ts +2 -0
  103. package/dist/runtime/prompt-guard.js +180 -0
  104. package/dist/runtime/prompt-guard.js.map +1 -0
  105. package/dist/runtime/prompt-safety-analyzer.js +8 -13
  106. package/dist/runtime/prompt-safety-analyzer.js.map +1 -1
  107. package/dist/runtime/reasoner.js +19 -33
  108. package/dist/runtime/reasoner.js.map +1 -1
  109. package/dist/runtime/rule-meta-verifier.js +9 -11
  110. package/dist/runtime/rule-meta-verifier.js.map +1 -1
  111. package/dist/runtime/safe-executor.d.ts +23 -0
  112. package/dist/runtime/safe-executor.js +151 -0
  113. package/dist/runtime/safe-executor.js.map +1 -0
  114. package/dist/runtime/specialized-agent.js +10 -14
  115. package/dist/runtime/specialized-agent.js.map +1 -1
  116. package/dist/runtime/strategy-library.js +8 -10
  117. package/dist/runtime/strategy-library.js.map +1 -1
  118. package/dist/runtime/supabase-experience-store.js.map +1 -1
  119. package/dist/runtime/supabase-provisioner.d.ts +35 -0
  120. package/dist/runtime/supabase-provisioner.js +192 -0
  121. package/dist/runtime/supabase-provisioner.js.map +1 -0
  122. package/dist/runtime/types.d.ts +88 -0
  123. package/dist/sdk/forward-verify.js +16 -33
  124. package/dist/sdk/forward-verify.js.map +1 -1
  125. package/package.json +1 -1
  126. package/demo/data/demo-events.json +0 -103
  127. package/demo/js/demo-mode.js +0 -107
  128. package/demo/js/orb.js +0 -634
  129. package/demo/js/question-cards.js +0 -207
  130. package/demo/js/voice.js +0 -154
@@ -1,103 +0,0 @@
1
- [
2
- { "delay": 200, "type": "phase_change", "data": { "phase": "initializing" } },
3
- { "delay": 500, "type": "agent_activate", "data": { "name": "Coordinator", "role": "coordinator", "status": "active", "trust": 0.95 } },
4
- { "delay": 800, "type": "agent_activate", "data": { "name": "CodeGen", "role": "code", "status": "active", "trust": 0.90 } },
5
- { "delay": 1100, "type": "agent_activate", "data": { "name": "Reviewer", "role": "review", "status": "active", "trust": 0.92 } },
6
- { "delay": 1400, "type": "agent_activate", "data": { "name": "Tester", "role": "test", "status": "active", "trust": 0.88 } },
7
-
8
- { "delay": 2000, "type": "phase_change", "data": { "phase": "planning" } },
9
- { "delay": 2200, "type": "task_add", "data": { "id": "task-1", "title": "Design database schema", "agent": "Coordinator", "status": "in_progress" } },
10
- { "delay": 2800, "type": "task_update", "data": { "id": "task-1", "status": "completed" } },
11
- { "delay": 3000, "type": "task_add", "data": { "id": "task-2", "title": "Plan API routes", "agent": "Coordinator", "status": "in_progress" } },
12
- { "delay": 3500, "type": "task_update", "data": { "id": "task-2", "status": "completed" } },
13
- { "delay": 3700, "type": "task_add", "data": { "id": "task-3", "title": "Design auth flow", "agent": "Coordinator", "status": "in_progress" } },
14
- { "delay": 4200, "type": "task_update", "data": { "id": "task-3", "status": "completed" } },
15
- { "delay": 4400, "type": "task_add", "data": { "id": "task-4", "title": "Plan UI components", "agent": "Coordinator", "status": "in_progress" } },
16
- { "delay": 4900, "type": "task_update", "data": { "id": "task-4", "status": "completed" } },
17
- { "delay": 5100, "type": "task_add", "data": { "id": "task-5", "title": "Define page routes", "agent": "Coordinator", "status": "in_progress" } },
18
- { "delay": 5600, "type": "task_update", "data": { "id": "task-5", "status": "completed" } },
19
-
20
- { "delay": 6000, "type": "phase_change", "data": { "phase": "verifying_plan" } },
21
- { "delay": 6300, "type": "verification", "data": { "claim": "Schema defines users table with id, email, password_hash", "result": "pass", "method": "formal" } },
22
- { "delay": 6700, "type": "verification", "data": { "claim": "Schema defines todos table with user_id foreign key", "result": "pass", "method": "formal" } },
23
- { "delay": 7100, "type": "verification", "data": { "claim": "Auth flow uses bcrypt for password hashing", "result": "pass", "method": "llm" } },
24
- { "delay": 7400, "type": "verification", "data": { "claim": "API routes follow RESTful conventions", "result": "pass", "method": "llm" } },
25
- { "delay": 7800, "type": "verification", "data": { "claim": "JWT tokens have expiration set", "result": "pass", "method": "formal" } },
26
- { "delay": 8200, "type": "verification", "data": { "claim": "CRUD operations validate ownership", "result": "fail", "method": "llm" } },
27
- { "delay": 8700, "type": "verification", "data": { "claim": "SQL injection prevented in query builder", "result": "pass", "method": "formal" } },
28
- { "delay": 9200, "type": "verification", "data": { "claim": "CSRF protection on mutation endpoints", "result": "pass", "method": "llm" } },
29
-
30
- { "delay": 10000, "type": "phase_change", "data": { "phase": "scaffolding" } },
31
- { "delay": 10400, "type": "code_generated", "data": { "path": "package.json", "language": "json", "content": "{\n \"name\": \"todo-app\",\n \"version\": \"1.0.0\",\n \"scripts\": {\n \"dev\": \"tsx watch src/index.ts\",\n \"build\": \"tsc && vite build\",\n \"start\": \"node dist/index.js\",\n \"db:push\": \"prisma db push\",\n \"db:generate\": \"prisma generate\"\n },\n \"dependencies\": {\n \"express\": \"^4.18.2\",\n \"@prisma/client\": \"^5.8.0\",\n \"bcryptjs\": \"^2.4.3\",\n \"jsonwebtoken\": \"^9.0.2\",\n \"react\": \"^18.2.0\",\n \"react-dom\": \"^18.2.0\"\n },\n \"devDependencies\": {\n \"prisma\": \"^5.8.0\",\n \"typescript\": \"^5.3.3\",\n \"vite\": \"^5.0.0\"\n }\n}" } },
32
- { "delay": 11000, "type": "code_generated", "data": { "path": "tsconfig.json", "language": "json", "content": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"jsx\": \"react-jsx\",\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"skipLibCheck\": true,\n \"forceConsistentCasingInFileNames\": true\n },\n \"include\": [\"src/**/*\"]\n}" } },
33
- { "delay": 11800, "type": "code_generated", "data": { "path": "prisma/schema.prisma", "language": "prisma", "content": "generator client {\n provider = \"prisma-client-js\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel User {\n id String @id @default(cuid())\n email String @unique\n passwordHash String @map(\"password_hash\")\n createdAt DateTime @default(now())\n todos Todo[]\n}\n\nmodel Todo {\n id String @id @default(cuid())\n title String\n completed Boolean @default(false)\n userId String\n user User @relation(fields: [userId], references: [id])\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}" } },
34
-
35
- { "delay": 13000, "type": "phase_change", "data": { "phase": "building_feature" } },
36
- { "delay": 13200, "type": "task_add", "data": { "id": "task-6", "title": "Implement auth system", "agent": "CodeGen", "status": "in_progress" } },
37
- { "delay": 13800, "type": "code_generated", "data": { "path": "src/auth/register.ts", "language": "typescript", "content": "import { PrismaClient } from '@prisma/client';\nimport bcrypt from 'bcryptjs';\nimport { z } from 'zod';\n\nconst prisma = new PrismaClient();\n\nconst RegisterSchema = z.object({\n email: z.string().email(),\n password: z.string().min(8).max(128)\n});\n\nexport async function register(email: string, password: string) {\n const input = RegisterSchema.parse({ email, password });\n \n const existing = await prisma.user.findUnique({\n where: { email: input.email }\n });\n \n if (existing) {\n throw new Error('Email already registered');\n }\n \n const passwordHash = await bcrypt.hash(input.password, 12);\n \n const user = await prisma.user.create({\n data: {\n email: input.email,\n passwordHash\n },\n select: { id: true, email: true, createdAt: true }\n });\n \n return user;\n}" } },
38
- { "delay": 14500, "type": "verification", "data": { "claim": "Register validates email format", "result": "pass", "method": "formal" } },
39
- { "delay": 14900, "type": "verification", "data": { "claim": "Password hashed with bcrypt cost 12", "result": "pass", "method": "formal" } },
40
- { "delay": 15200, "type": "code_generated", "data": { "path": "src/auth/login.ts", "language": "typescript", "content": "import { PrismaClient } from '@prisma/client';\nimport bcrypt from 'bcryptjs';\nimport jwt from 'jsonwebtoken';\nimport { z } from 'zod';\n\nconst prisma = new PrismaClient();\nconst JWT_SECRET = process.env.JWT_SECRET!;\n\nconst LoginSchema = z.object({\n email: z.string().email(),\n password: z.string()\n});\n\nexport async function login(email: string, password: string) {\n const input = LoginSchema.parse({ email, password });\n \n const user = await prisma.user.findUnique({\n where: { email: input.email }\n });\n \n if (!user) {\n throw new Error('Invalid credentials');\n }\n \n const valid = await bcrypt.compare(input.password, user.passwordHash);\n if (!valid) {\n throw new Error('Invalid credentials');\n }\n \n const token = jwt.sign(\n { sub: user.id, email: user.email },\n JWT_SECRET,\n { expiresIn: '24h' }\n );\n \n return { token, user: { id: user.id, email: user.email } };\n}" } },
41
- { "delay": 15800, "type": "verification", "data": { "claim": "Login returns same error for missing user and wrong password", "result": "pass", "method": "llm" } },
42
- { "delay": 16200, "type": "code_generated", "data": { "path": "src/middleware/auth.ts", "language": "typescript", "content": "import { Request, Response, NextFunction } from 'express';\nimport jwt from 'jsonwebtoken';\n\nconst JWT_SECRET = process.env.JWT_SECRET!;\n\nexport interface AuthRequest extends Request {\n userId?: string;\n}\n\nexport function requireAuth(req: AuthRequest, res: Response, next: NextFunction) {\n const header = req.headers.authorization;\n \n if (!header || !header.startsWith('Bearer ')) {\n return res.status(401).json({ error: 'Missing authorization header' });\n }\n \n const token = header.slice(7);\n \n try {\n const payload = jwt.verify(token, JWT_SECRET) as { sub: string };\n req.userId = payload.sub;\n next();\n } catch {\n return res.status(401).json({ error: 'Invalid or expired token' });\n }\n}" } },
43
- { "delay": 16800, "type": "verification", "data": { "claim": "Auth middleware rejects missing Bearer prefix", "result": "pass", "method": "formal" } },
44
- { "delay": 17200, "type": "verification", "data": { "claim": "JWT verification catches expired tokens", "result": "pass", "method": "llm" } },
45
- { "delay": 17600, "type": "task_update", "data": { "id": "task-6", "status": "completed" } },
46
-
47
- { "delay": 18000, "type": "task_add", "data": { "id": "task-7", "title": "Implement todo CRUD", "agent": "CodeGen", "status": "in_progress" } },
48
- { "delay": 18500, "type": "code_generated", "data": { "path": "src/routes/todos.ts", "language": "typescript", "content": "import { Router } from 'express';\nimport { PrismaClient } from '@prisma/client';\nimport { requireAuth, AuthRequest } from '../middleware/auth';\nimport { z } from 'zod';\n\nconst router = Router();\nconst prisma = new PrismaClient();\n\nconst CreateTodoSchema = z.object({\n title: z.string().min(1).max(500)\n});\n\nrouter.get('/', requireAuth, async (req: AuthRequest, res) => {\n const todos = await prisma.todo.findMany({\n where: { userId: req.userId },\n orderBy: { createdAt: 'desc' },\n take: 50\n });\n res.json(todos);\n});\n\nrouter.post('/', requireAuth, async (req: AuthRequest, res) => {\n const input = CreateTodoSchema.parse(req.body);\n const todo = await prisma.todo.create({\n data: { title: input.title, userId: req.userId! }\n });\n res.status(201).json(todo);\n});\n\nrouter.patch('/:id', requireAuth, async (req: AuthRequest, res) => {\n const todo = await prisma.todo.findFirst({\n where: { id: req.params.id, userId: req.userId }\n });\n if (!todo) return res.status(404).json({ error: 'Not found' });\n \n const updated = await prisma.todo.update({\n where: { id: todo.id },\n data: { completed: !todo.completed }\n });\n res.json(updated);\n});\n\nrouter.delete('/:id', requireAuth, async (req: AuthRequest, res) => {\n const todo = await prisma.todo.findFirst({\n where: { id: req.params.id, userId: req.userId }\n });\n if (!todo) return res.status(404).json({ error: 'Not found' });\n \n await prisma.todo.delete({ where: { id: todo.id } });\n res.status(204).send();\n});\n\nexport default router;" } },
49
- { "delay": 19200, "type": "verification", "data": { "claim": "GET /todos filters by authenticated userId", "result": "pass", "method": "formal" } },
50
- { "delay": 19600, "type": "verification", "data": { "claim": "PATCH validates ownership before toggling", "result": "pass", "method": "formal" } },
51
- { "delay": 20000, "type": "code_generated", "data": { "path": "src/models/todo.ts", "language": "typescript", "content": "import { PrismaClient, Todo } from '@prisma/client';\n\nconst prisma = new PrismaClient();\n\nexport type TodoWithoutUser = Omit<Todo, 'userId'>;\n\nexport async function getUserTodos(\n userId: string,\n limit = 50,\n offset = 0\n): Promise<TodoWithoutUser[]> {\n return prisma.todo.findMany({\n where: { userId },\n orderBy: { createdAt: 'desc' },\n take: limit,\n skip: offset,\n select: {\n id: true,\n title: true,\n completed: true,\n createdAt: true,\n updatedAt: true\n }\n });\n}\n\nexport async function countUserTodos(userId: string): Promise<number> {\n return prisma.todo.count({ where: { userId } });\n}\n\nexport async function toggleTodo(\n id: string,\n userId: string\n): Promise<Todo | null> {\n const todo = await prisma.todo.findFirst({ where: { id, userId } });\n if (!todo) return null;\n return prisma.todo.update({\n where: { id },\n data: { completed: !todo.completed }\n });\n}" } },
52
- { "delay": 20600, "type": "verification", "data": { "claim": "getUserTodos applies pagination with limit and offset", "result": "pass", "method": "llm" } },
53
- { "delay": 21000, "type": "verification", "data": { "claim": "toggleTodo checks ownership before update", "result": "pass", "method": "formal" } },
54
- { "delay": 21400, "type": "verification", "data": { "claim": "Missing pagination on list endpoint", "result": "fail", "method": "llm" } },
55
- { "delay": 21800, "type": "verification", "data": { "claim": "DELETE validates ownership before removal", "result": "pass", "method": "formal" } },
56
- { "delay": 22200, "type": "task_update", "data": { "id": "task-7", "status": "completed" } },
57
-
58
- { "delay": 23000, "type": "task_add", "data": { "id": "task-8", "title": "Build UI pages", "agent": "CodeGen", "status": "in_progress" } },
59
- { "delay": 23500, "type": "code_generated", "data": { "path": "src/pages/LoginPage.tsx", "language": "tsx", "content": "import { useState, FormEvent } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nexport function LoginPage() {\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const navigate = useNavigate();\n\n async function handleSubmit(e: FormEvent) {\n e.preventDefault();\n setError(null);\n setLoading(true);\n try {\n const res = await fetch('/api/auth/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password })\n });\n if (!res.ok) {\n const data = await res.json();\n throw new Error(data.error || 'Login failed');\n }\n const { token } = await res.json();\n localStorage.setItem('token', token);\n navigate('/todos');\n } catch (err: any) {\n setError(err.message);\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <form onSubmit={handleSubmit}>\n <h1>Sign In</h1>\n {error && <p className=\"error\">{error}</p>}\n <input type=\"email\" value={email} onChange={e => setEmail(e.target.value)} placeholder=\"Email\" required />\n <input type=\"password\" value={password} onChange={e => setPassword(e.target.value)} placeholder=\"Password\" required />\n <button type=\"submit\" disabled={loading}>{loading ? 'Signing in...' : 'Sign In'}</button>\n </form>\n );\n}" } },
60
- { "delay": 24200, "type": "verification", "data": { "claim": "Login form disables button during submission", "result": "pass", "method": "llm" } },
61
- { "delay": 24600, "type": "verification", "data": { "claim": "Token stored in localStorage after login", "result": "pass", "method": "formal" } },
62
- { "delay": 25200, "type": "code_generated", "data": { "path": "src/pages/TodoList.tsx", "language": "tsx", "content": "import { useState, useEffect } from 'react';\n\ninterface Todo {\n id: string;\n title: string;\n completed: boolean;\n createdAt: string;\n}\n\nexport function TodoList() {\n const [todos, setTodos] = useState<Todo[]>([]);\n const [newTitle, setNewTitle] = useState('');\n const token = localStorage.getItem('token');\n const headers = { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' };\n\n useEffect(() => {\n fetch('/api/todos', { headers }).then(r => r.json()).then(setTodos);\n }, []);\n\n async function addTodo() {\n if (!newTitle.trim()) return;\n const res = await fetch('/api/todos', {\n method: 'POST', headers,\n body: JSON.stringify({ title: newTitle })\n });\n const todo = await res.json();\n setTodos(prev => [todo, ...prev]);\n setNewTitle('');\n }\n\n async function toggle(id: string) {\n const res = await fetch(`/api/todos/${id}`, { method: 'PATCH', headers });\n const updated = await res.json();\n setTodos(prev => prev.map(t => t.id === id ? updated : t));\n }\n\n async function remove(id: string) {\n await fetch(`/api/todos/${id}`, { method: 'DELETE', headers });\n setTodos(prev => prev.filter(t => t.id !== id));\n }\n\n return (\n <div>\n <h1>My Todos</h1>\n <div className=\"add-form\">\n <input value={newTitle} onChange={e => setNewTitle(e.target.value)} placeholder=\"What needs to be done?\" onKeyDown={e => e.key === 'Enter' && addTodo()} />\n <button onClick={addTodo}>Add</button>\n </div>\n <ul className=\"todo-list\">\n {todos.map(todo => (\n <li key={todo.id} className={todo.completed ? 'completed' : ''}>\n <input type=\"checkbox\" checked={todo.completed} onChange={() => toggle(todo.id)} />\n <span>{todo.title}</span>\n <button onClick={() => remove(todo.id)}>Delete</button>\n </li>\n ))}\n </ul>\n </div>\n );\n}" } },
63
- { "delay": 25800, "type": "verification", "data": { "claim": "TodoList includes Authorization header on all requests", "result": "pass", "method": "formal" } },
64
- { "delay": 26200, "type": "verification", "data": { "claim": "Optimistic UI update after toggle", "result": "pass", "method": "llm" } },
65
- { "delay": 26600, "type": "verification", "data": { "claim": "Delete removes item from local state", "result": "pass", "method": "llm" } },
66
- { "delay": 27200, "type": "task_update", "data": { "id": "task-8", "status": "completed" } },
67
-
68
- { "delay": 28000, "type": "phase_change", "data": { "phase": "build_verifying" } },
69
- { "delay": 28300, "type": "verification", "data": { "claim": "All routes use requireAuth middleware", "result": "pass", "method": "formal" } },
70
- { "delay": 28600, "type": "verification", "data": { "claim": "Prisma schema matches API field names", "result": "pass", "method": "formal" } },
71
- { "delay": 28900, "type": "verification", "data": { "claim": "Error responses use consistent JSON format", "result": "pass", "method": "llm" } },
72
- { "delay": 29200, "type": "verification", "data": { "claim": "No raw SQL — all queries via Prisma ORM", "result": "pass", "method": "formal" } },
73
- { "delay": 29500, "type": "verification", "data": { "claim": "Input validation on all POST/PATCH endpoints", "result": "pass", "method": "formal" } },
74
- { "delay": 29800, "type": "verification", "data": { "claim": "JWT_SECRET loaded from environment variable", "result": "pass", "method": "formal" } },
75
- { "delay": 30200, "type": "verification", "data": { "claim": "Password not included in user response objects", "result": "pass", "method": "llm" } },
76
- { "delay": 30600, "type": "verification", "data": { "claim": "Rate limiting on auth endpoints", "result": "fail", "method": "llm" } },
77
- { "delay": 31000, "type": "verification", "data": { "claim": "CORS configured for frontend origin", "result": "pass", "method": "llm" } },
78
- { "delay": 31400, "type": "verification", "data": { "claim": "Prisma client instantiated once per module", "result": "pass", "method": "formal" } },
79
-
80
- { "delay": 31700, "type": "phase_change", "data": { "phase": "build_repairing" } },
81
- { "delay": 32000, "type": "task_add", "data": { "id": "task-9", "title": "Fix rate limiting on auth endpoints", "agent": "CodeGen", "status": "in_progress" } },
82
- { "delay": 32600, "type": "code_generated", "data": { "path": "src/middleware/rate-limiter.ts", "language": "typescript", "content": "import rateLimit from 'express-rate-limit';\n\nexport const authLimiter = rateLimit({\n windowMs: 15 * 60 * 1000,\n max: 5,\n standardHeaders: true,\n legacyHeaders: false,\n message: { error: 'Too many login attempts, please try again later' }\n});\n\nexport const apiLimiter = rateLimit({\n windowMs: 60 * 1000,\n max: 100,\n standardHeaders: true,\n legacyHeaders: false,\n message: { error: 'Rate limit exceeded' }\n});" } },
83
- { "delay": 33100, "type": "verification", "data": { "claim": "Rate limiting applied to auth endpoints", "result": "pass", "method": "formal" } },
84
- { "delay": 33400, "type": "task_update", "data": { "id": "task-9", "status": "completed" } },
85
-
86
- { "delay": 34000, "type": "phase_change", "data": { "phase": "cross_verifying" } },
87
- { "delay": 34400, "type": "verification", "data": { "claim": "Auth middleware applied to todo routes", "result": "pass", "method": "formal" } },
88
- { "delay": 34800, "type": "verification", "data": { "claim": "Foreign key constraint enforced in queries", "result": "pass", "method": "formal" } },
89
- { "delay": 35200, "type": "verification", "data": { "claim": "Login page redirects to todo list on success", "result": "pass", "method": "llm" } },
90
- { "delay": 35600, "type": "verification", "data": { "claim": "Logout clears JWT from client storage", "result": "pass", "method": "llm" } },
91
- { "delay": 36000, "type": "verification", "data": { "claim": "Error responses use consistent format across all endpoints", "result": "pass", "method": "llm" } },
92
-
93
- { "delay": 38000, "type": "phase_change", "data": { "phase": "finalizing" } },
94
- { "delay": 39000, "type": "agent_activate", "data": { "name": "CodeGen", "role": "code", "status": "idle", "trust": 0.93 } },
95
- { "delay": 39200, "type": "agent_activate", "data": { "name": "Reviewer", "role": "review", "status": "idle", "trust": 0.94 } },
96
- { "delay": 39400, "type": "agent_activate", "data": { "name": "Tester", "role": "test", "status": "idle", "trust": 0.91 } },
97
-
98
- { "delay": 40500, "type": "phase_change", "data": { "phase": "completed" } },
99
- { "delay": 40700, "type": "agent_activate", "data": { "name": "Coordinator", "role": "coordinator", "status": "idle", "trust": 0.96 } },
100
-
101
- { "delay": 43000, "type": "phase_change", "data": { "phase": "failed" } },
102
- { "delay": 45000, "type": "phase_change", "data": { "phase": "completed" } }
103
- ]
@@ -1,107 +0,0 @@
1
- // demo-mode.js — Canned event replay for offline demos
2
- // Loads pre-recorded events and replays them with timing
3
-
4
- const AppState = window.AppState;
5
-
6
- let events = null;
7
- let timers = [];
8
-
9
- function dispatchEvent(event) {
10
- const { type, data } = event;
11
-
12
- switch (type) {
13
- case 'phase_change':
14
- AppState.update({ phase: data.phase });
15
- break;
16
-
17
- case 'agent_activate': {
18
- const existing = AppState.get().agents.find(a => a.name === data.name);
19
- if (existing) {
20
- AppState.updateAgent(data.name, data);
21
- } else {
22
- AppState.addAgent(data);
23
- }
24
- break;
25
- }
26
-
27
- case 'task_add':
28
- AppState.addTask(data);
29
- AppState.update({ currentTask: { name: data.title || data.name, agent: data.agent, status: data.status } });
30
- break;
31
-
32
- case 'task_update':
33
- AppState.updateTask(data.id, data);
34
- break;
35
-
36
- case 'verification':
37
- AppState.addVerification(data);
38
- break;
39
-
40
- case 'code_generated':
41
- AppState.addCodeFile(data);
42
- break;
43
-
44
- case 'metric_update':
45
- AppState.update({ metrics: data });
46
- break;
47
- }
48
- }
49
-
50
- function clearTimers() {
51
- for (const id of timers) {
52
- clearTimeout(id);
53
- }
54
- timers = [];
55
- }
56
-
57
- export function initDemoMode() {
58
- return fetch('data/demo-events.json')
59
- .then(res => {
60
- if (!res.ok) throw new Error(`Failed to load demo events: ${res.status}`);
61
- return res.json();
62
- })
63
- .then(data => {
64
- events = data;
65
- })
66
- .catch(err => {
67
- console.error('[Demo] Failed to load events:', err);
68
- });
69
- }
70
-
71
- export function startDemo(prompt) {
72
- if (!events || events.length === 0) {
73
- console.error('[Demo] No events loaded. Call initDemoMode() first.');
74
- return;
75
- }
76
-
77
- // Reset state for fresh demo
78
- AppState.reset();
79
- clearTimers();
80
-
81
- // Disable input during demo
82
- const input = document.getElementById('prompt-input');
83
- const btn = document.getElementById('submit-btn');
84
- if (input) input.disabled = true;
85
- if (btn) btn.disabled = true;
86
-
87
- // Log the prompt
88
- AppState.addLog({ level: 'info', message: `Demo started: "${prompt}"` });
89
-
90
- // Schedule all events by their absolute delay
91
- const lastDelay = events[events.length - 1].delay;
92
-
93
- for (const event of events) {
94
- const id = setTimeout(() => {
95
- dispatchEvent(event);
96
- }, event.delay);
97
- timers.push(id);
98
- }
99
-
100
- // Re-enable input after all events complete
101
- const finishId = setTimeout(() => {
102
- if (input) input.disabled = false;
103
- if (btn) btn.disabled = false;
104
- timers = [];
105
- }, lastDelay + 500);
106
- timers.push(finishId);
107
- }