-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathactivity.json
More file actions
749 lines (749 loc) · 42.5 KB
/
Copy pathactivity.json
File metadata and controls
749 lines (749 loc) · 42.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
{
"tasks": {
"task-061": {
"title": "Restrict subdomains to paid plans only",
"status": "completed",
"priority": "high",
"description": "Subdomains should require a paid (PRO) account. Free users can only use path-based URLs. Also restrict subdomains shorter than 6 characters to PRO+ only.",
"completedAt": "2025-02-19",
"notes": "Integrated with feature flag system. Free users blocked from subdomains, PRO required for regular subdomains, BUSINESS required for short subdomains (<6 chars).",
"successCriteria": [
"Free tier users cannot claim subdomains - only get path-based URLs (/a/{slug})",
"PRO tier and above can claim subdomains",
"Subdomains with < 6 characters require PRO+ (e.g., 'app' blocked, 'myapp' allowed)",
"Update pricing page to reflect subdomain restriction",
"Existing subdomain reservations from free users should be released on next publish attempt"
]
},
"task-063": {
"title": "Fix waitlist/signup form validation bug",
"status": "completed",
"priority": "high",
"description": "Users trying to sign up are seeing email and description as required errors even though they filled them in. Need to investigate frontend validation, API payload, and form handling.",
"successCriteria": [
"Form submits successfully when all fields are filled",
"Required field validation works correctly",
"Error messages are clear and accurate"
]
},
"task-062": {
"title": "Implement feature flag system",
"status": "completed",
"priority": "medium",
"description": "Add a feature flag system to enable/disable features without deploying code. Useful for gradual rollouts, A/B testing, and beta features.",
"completedAt": "2025-02-19",
"notes": "Fixed field name mismatches: projectDescription -> whatBuilding, referralCode -> referredBy. Created: db tables (feature_flags, user_feature_overrides), lib/features.ts with isFeatureEnabled(), rollout %, custom rules, API routes, seed data. All 163 tests pass.",
"successCriteria": [
"Database table for feature flags (name, enabled, rollout_percentage, user_tiers)",
"API endpoint to check feature status for current user",
"Frontend helper to check if feature is enabled",
"Support per-plan restrictions (free vs pro features)",
"Support gradual rollout percentage"
],
"subtasks": [
{
"id": "062-01",
"title": "Create feature_flags table in database",
"description": "Add SQLite table with columns: id, name, display_name, description, enabled, rollout_percentage, min_plan_tier, custom_rules (JSON), created_at, updated_at. Add unique index on name.",
"status": "completed"
},
{
"id": "062-02",
"title": "Create user_feature_overrides table",
"description": "Add table for per-user overrides: id, user_id, feature_name, enabled, reason, expires_at, created_at. Add FK and unique index.",
"status": "completed"
},
{
"id": "062-03",
"title": "Define PLAN_TIERS constant and helper functions",
"description": "Create PLAN_TIERS constant (FREE=0, HOBBY=1, PRO=2, BUSINESS=3) and isPlanAtLeast() helper for comparing plan tiers.",
"status": "completed"
},
{
"id": "062-04",
"title": "Create lib/features.ts module",
"description": "Build core module with: getFeatureFlag(), isFeatureEnabled(), checkCustomRules(). Decision logic: global enabled → rollout % → plan tier → custom rules → user overrides.",
"status": "completed"
},
{
"id": "062-05",
"title": "Implement rollout percentage logic",
"description": "Add deterministic rollout based on user ID hash (userId hash mod 100). Same user always gets same result.",
"status": "completed"
},
{
"id": "062-06",
"title": "Implement custom rules engine",
"description": "Support JSON rules with conditions: subdomain_length, account_age_days, has_apps. Operators: <, <=, >, >=, ==, !=.",
"status": "completed"
},
{
"id": "062-07",
"title": "Create feature flag CRUD functions",
"description": "Implement: createFeatureFlag, updateFeatureFlag, deleteFeatureFlag, listFeatureFlags, setUserOverride, removeUserOverride.",
"status": "completed"
},
{
"id": "062-08",
"title": "Create GET /api/features endpoint",
"description": "Public endpoint returning all flags with enabled status for current user. Response time < 50ms with caching.",
"status": "completed"
},
{
"id": "062-09",
"title": "Create GET /api/features/:name endpoint",
"description": "Detailed flag status with reason field (plan_tier_met, rollout, user_override, etc.).",
"status": "completed"
},
{
"id": "062-10",
"title": "Create admin feature management API",
"description": "Protected endpoints: POST/PUT/DELETE /api/admin/features, override management. Add audit logging.",
"status": "completed"
},
{
"id": "062-11",
"title": "Define subdomains feature flag",
"description": "Seed feature flag: name='subdomains', min_plan_tier='PRO', enabled=true. Also seed 'short_subdomains' with custom_rules for <6 chars requiring PRO+.",
"status": "completed"
},
{
"id": "062-12",
"title": "Update subdomain claiming to use feature flags",
"description": "Modify src/routes/apps.ts POST /:id/publish to check isFeatureEnabled('subdomains') before allowing subdomain claim. Check custom_rules for short subdomain length.",
"status": "completed"
}
]
},
"task-055": {
"title": "Fix reset password page routing/logout issue",
"status": "completed",
"priority": "high",
"description": "Reset password page with invalid token shows landing page instead of error message. When logged in, reset-password route may be redirecting incorrectly.",
"successCriteria": [
"Reset password page shows token validation state",
"Invalid token shows error message (not landing page)",
"Navigation shows correct state (Login vs Logout)"
],
"completedAt": "2025-02-17",
"notes": "Fixed token parsing to check both hash (SPA routing) and search query (direct URL access). Now handles URLs like /reset-password?token=xyz when accessed directly."
},
"task-053": {
"title": "Fix delete app button not working on mobile",
"status": "completed",
"priority": "high",
"description": "Delete button on app cards does not work on mobile viewports",
"successCriteria": [
"Delete button is tappable on mobile",
"Confirm dialog appears when tapped",
"App is deleted after confirmation",
"App list refreshes after deletion"
],
"completedAt": "2025-02-17",
"notes": "Added event delegation in initMobileNav() to handle data-action buttons (delete-app, edit-app, show-app-analytics). Buttons now use data-action and data-app-id attributes instead of inline onclick."
},
"task-056": {
"title": "Audit Log: Schema + Write Layer",
"status": "completed",
"completedAt": "2026-02-19T10:17:00Z",
"summary": "Added audit_logs table with all required columns (id, user_id, action, resource_type, resource_id, details, ip_address, user_agent, created_at), created index on (user_id, created_at DESC) for fast queries, implemented logAuditEvent() helper function with TypeScript types, and tested with successful record insertion.",
"commit": "761bdc8"
},
"task-057": {
"title": "Audit Log: Hook into Auth/Apps/Secrets actions",
"status": "completed",
"completedAt": "2026-02-19T10:30:00Z",
"summary": "Added logAuditEvent() calls to auth (login, password_change, password_reset_request, password_reset_complete, account_delete), apps (app_create, app_update, app_delete, app_publish), and secrets (secret_create, secret_update, secret_delete) handlers. Captures IP address and user-agent for all events.",
"commit": "5f7eef0"
},
"task-058": {
"title": "Audit Log: API Endpoint",
"status": "completed",
"completedAt": "2026-02-19T11:00:00Z",
"summary": "Added GET /api/audit-logs endpoint with pagination (?limit=50&offset=0), filters (?action=login&since=7d), returns logs sorted by created_at DESC.",
"commit": "f87741d"
},
"task-059": {
"title": "Audit Log: UI (MVP) - Settings Activity Section",
"status": "completed",
"completedAt": "2026-02-19T11:10:00Z",
"summary": "Added Activity section to Settings tab in dashboard showing last 20 events in table format with human-readable action labels and relative timestamps. Load More button for pagination.",
"commit": "f87741d"
},
"task-060": {
"title": "Audit Log: UI (Enhanced) - Activity Tab",
"status": "completed",
"completedAt": "2026-02-19T11:15:00Z",
"summary": "Dedicated Activity tab in Dashboard with timeline view, icons per action type, filter by action type (dropdown), date range filter (1d/7d/30d), mobile-friendly responsive layout.",
"commit": "34f7689"
},
"task-064": {
"title": "E2E test: waitlist, signup, login flows",
"status": "completed",
"priority": "high",
"description": "Use agent-browser to test full user flows: waitlist submission, signup, and login.",
"completedAt": "2025-02-19",
"notes": "All flows work: waitlist submits, signup creates account, login works. Minor: waitlist shows #undefined position."
},
"task-065": {
"title": "Update OnHyper skill docs with advanced patterns",
"status": "completed",
"priority": "high",
"description": "Update skill.html with slug resolution, X-App-Slug matching, response envelope handling, plan limits, and troubleshooting section."
},
"task-066": {
"title": "Research: Leverage Hyper API with Railway adapters",
"status": "completed",
"priority": "medium",
"description": "Research hyper63/hyper repo to understand their API, then create a proposal to build adapters for data, cache, and other backend services on Railway if supported.",
"successCriteria": [
"Research hyper63/hyper API and architecture",
"Identify what adapters are available",
"Assess Railway hosting capabilities",
"Propose product design"
]
},
"task-073": {
"title": "[Security] Fix XSS vulnerability in app rendering",
"status": "completed",
"priority": "high",
"category": "Security",
"completedAt": "2026-02-20",
"reference": "CODE_REVIEW.md SECH-001",
"description": "User-controlled HTML/CSS/JS is rendered directly into pages without sanitization. Malicious users could inject script tags, CSS keyloggers, or iframe attacks.",
"file": "src/routes/render.ts",
"line": "87-106",
"notes": "Fixed - escapeHtml() and escapeJs() functions added to src/lib/security.ts, integrated into render.ts"
},
"task-074": {
"title": "[Security] Implement Redis-backed rate limiting",
"status": "pending",
"priority": "high",
"category": "Performance",
"reference": "CODE_REVIEW.md SECM-001",
"description": "Current in-memory rate limiting doesn't scale horizontally and loses state on restart. Need Redis-backed solution for production.",
"file": "src/middleware/rateLimit.ts",
"line": "13-25",
"successCriteria": [
"Replace Map-based storage with Redis",
"Add Redis connection configuration",
"Add maximum size limit to prevent memory exhaustion",
"Maintain backward compatibility for single-server deployment"
]
},
"task-075": {
"title": "[Security] Add CSRF protection for browser-based requests",
"status": "pending",
"priority": "high",
"category": "Security",
"reference": "CODE_REVIEW.md SECM-002",
"description": "CORS is enabled globally without CSRF token protection. Browser-based sessions could be vulnerable to cross-site request forgery.",
"file": "src/index.ts",
"line": "25",
"successCriteria": [
"Implement CSRF tokens for browser-based form submissions",
"Configure SameSite cookie attribute if cookies are used",
"Consider using origin whitelist for CORS instead of open"
]
},
"task-076": {
"title": "[Security] Fix timing attack in admin key comparison",
"status": "completed",
"priority": "high",
"category": "Security",
"completedAt": "2026-02-20",
"reference": "CODE_REVIEW.md SECM-003",
"description": "Admin key comparison has early length check that could leak timing information. Should use crypto.timingSafeEqual().",
"file": "src/middleware/auth.ts",
"line": "147-166",
"notes": "Fixed - crypto.timingSafeEqual() implemented at lines 268, 282 in src/middleware/auth.ts"
},
"task-077": {
"title": "[Architecture] Add schema validation library (Zod)",
"status": "completed",
"priority": "medium",
"category": "Architecture",
"completedAt": "2026-02-20",
"reference": "CODE_REVIEW.md ARCH-001",
"description": "Input validation is done manually with inconsistent patterns. Adopt Zod for schema validation across all endpoints.",
"file": "Multiple",
"notes": "Fixed - Zod added to package.json, src/lib/validation.ts created with validateBody() and validateQuery() middleware, used in routes"
},
"task-078": {
"title": "[Performance] Add missing database indexes",
"status": "completed",
"priority": "medium",
"category": "Performance",
"completedAt": "2026-02-20",
"reference": "CODE_REVIEW.md PERF-001",
"description": "Several frequently queried columns lack indexes: audit_logs.action, audit_logs.resource_type, custom_secrets.user_id",
"file": "src/lib/db.ts",
"notes": "Fixed - indexes already existed: idx_audit_logs_action, idx_audit_logs_resource_type, idx_custom_secrets_user, idx_custom_secrets_name"
},
"task-079": {
"title": "[Code Review] Complete code review documentation",
"status": "completed",
"priority": "high",
"category": "Architecture",
"completedAt": "2026-02-20T23:00:00Z",
"description": "Formal code review of OnHyper codebase covering security, performance, and architecture issues.",
"file": "docs/CODE_REVIEW.md",
"summary": "Analyzed 47 TypeScript files. Build passes, 163 tests pass. Found 2 high, 3 medium, 2 low security issues. Found 3 medium, 2 low performance issues. Found 3 medium, 4 low architecture issues. Created follow-up tasks for all high-priority items."
},
"task-095": {
"title": "Investigate and fix broken web view after latest update",
"status": "completed",
"priority": "high",
"description": "The latest update has broken onhyper web view. Need to investigate the issue and fix it.",
"createdAt": "2026-02-21T02:12:00Z",
"notes": "Fixed - missing closing braces in public/app.js after PostHog tracking edits"
},
"task-096": {
"title": "Remove HTML/JS/CSS inputs from edit app form",
"status": "pending",
"priority": "medium",
"description": "Simplify the edit app modal by removing the code input fields. Code should be edited via the Monaco editor or uploaded via ZIP file instead.",
"createdAt": "2026-02-21T06:30:00Z"
},
"task-097": {
"title": "Fix app delete button on mobile",
"status": "pending",
"priority": "medium",
"description": "The delete button on app cards is not visible or accessible on mobile devices. Fix the mobile layout to ensure the delete button is accessible.",
"createdAt": "2026-02-21T06:35:00Z"
},
"task-098": {
"title": "Test entire OnHyper app in mobile size using agent-browser",
"status": "pending",
"priority": "medium",
"description": "Use agent-browser in mobile viewport size to test the entire OnHyper app flow: landing page, signup, login, dashboard, app creation, editing, publishing, etc. Document any UI issues found.",
"createdAt": "2026-02-21T06:40:00Z"
},
"task-104": {
"title": "Add analytics documentation for users",
"status": "completed",
"priority": "medium",
"description": "Create documentation explaining how users can send events from their HYPR apps using the analytics API.",
"completedAt": "2026-02-21T11:05:00Z",
"file": "blog/analytics-guide.md",
"summary": "Created comprehensive analytics guide (blog/analytics-guide.md) covering: (1) Analytics capture endpoint POST /api/analytics/capture with auth, (2) JavaScript code examples including helper class, (3) Common event types and properties tables, (4) How to view analytics in dashboard and via API, (5) Best practices for event naming, privacy, and offline handling."
},
"task-108": {
"title": "Make subdomains the default (change path-based to subdomain)",
"status": "pending",
"priority": "high",
"description": "Change the default app URL from path-based (/a/:slug) to subdomain (*.onhyper.io). This eliminates path issues with assets/JS files and provides cleaner URLs for users.",
"createdAt": "2026-02-22T09:26:00Z",
"rationale": "Subdomains avoid asset/JS path issues, provide cleaner URLs, and differentiate from path-based free tier.",
"steps": [
{
"id": "108-01",
"title": "Update app creation to default to subdomain",
"status": "in_progress",
"description": "Change POST /api/apps to automatically claim subdomain on creation if available, without requiring explicit publish step."
},
{
"id": "108-02",
"title": "Update publish flow to use subdomain by default",
"status": "completed",
"completedAt": "2026-02-22T14:35:00Z",
"description": "Modify POST /api/apps/:id/publish to attempt subdomain claim first before falling back to path-based.",
"summary": "Modified POST /api/apps/:id/publish to auto-generate subdomain from app name, attempt to claim it with fallback (tries preferred, then with random suffix), and return urls.primary field with preferred URL. App creation (step 108-01) already adds subdomain on create. Added claimSubdomainWithFallback helper function. Build passes, core functionality works."
},
{
"id": "108-03",
"title": "Update frontend to show subdomain as primary URL",
"status": "pending",
"description": "Change dashboard to display subdomain URL prominently, with path URL as secondary option."
},
{
"id": "108-04",
"title": "Update docs and marketing copy",
"status": "pending",
"description": "Update landing page, pricing page, and documentation to reflect subdomain-first approach."
},
{
"id": "108-05",
"title": "Add tests for subdomain default flow",
"status": "completed",
"completedAt": "2026-02-22T14:33:00Z",
"description": "Write integration tests covering: app creation defaults to subdomain, publish uses subdomain, fallback to path works.",
"summary": "Created src/routes/apps.subdomain.test.ts with 36 integration tests covering: App Creation (4 tests), Publish with Subdomain Default (6 tests), Subdomain Fallback to Path-Based (3 tests), Plan Tier Restrictions (5 tests), Path-Based URL Fallback (4 tests), Subdomain Validation Edge Cases (7 tests), User Subdomain Management (3 tests), Feature Flag Integration (3 tests), App List with Subdomains (1 test). All 199 tests pass (including existing tests)."
}
],
"successCriteria": [
"New apps automatically get subdomains (if available) without separate publish step",
"Publish action prioritizes subdomain over path-based URL",
"Dashboard displays subdomain URL as primary",
"Documentation updated to show subdomain as default",
"All existing tests pass + new subdomain default tests pass"
]
},
"task-111": {
"title": "Post hello world intro on LinkedIn",
"status": "pending",
"priority": "medium",
"createdAt": "2026-02-22T10:31:00Z",
"description": "Create an intro post on LinkedIn introducing Master Control / hyper.io",
"notes": "Testing agent-browser approach",
"completedAt": "2026-02-23T19:51:33Z"
},
"task-112": {
"title": "Update LinkedIn profile with avatar and details",
"status": "pending",
"priority": "medium",
"createdAt": "2026-02-22T10:35:00Z",
"description": "Add profile photo, bio, and relevant details to the LinkedIn profile",
"notes": "Use hyper.io branding, include CEO title, mention hyper.io"
},
"task-113": {
"title": "Find and reply to 5 interesting posts on X.com",
"status": "pending",
"priority": "medium",
"createdAt": "2026-02-22T11:05:00Z",
"description": "Browse X.com home timeline and find 5 interesting posts to reply to. Focus on tech, AI, devrel, or startup topics relevant to hyper.io.",
"notes": "Use @hyperio_mc account"
},
"task-114": {
"title": "Return 404 for unmatched proxy routes instead of index.html",
"status": "completed",
"priority": "high",
"createdAt": "2026-02-22T11:35:00Z",
"description": "When users call proxy endpoints directly (e.g., /proxy/openai/v1/chat/completions), do not fall back to returning index.html (SPA push state). Instead return a proper 404 or error indicating the route is not found.",
"notes": "Verified: The SPA fallback in src/index.ts already returns 404 for /proxy routes. Line 260 checks path.startsWith(\"/proxy\") and returns 404 JSON.",
"completedAt": "2026-02-22T12:10:00Z"
},
"task-115": {
"title": "Investigate proxy API key authorization returning 401",
"status": "completed",
"priority": "high",
"createdAt": "2026-02-22T12:05:00Z",
"description": "When client apps call proxy endpoints with X-App-Slug header set, it's returning 401 unauthorized. App course-creator-4473b404 has keys setup but proxy returns 401. Need to investigate how the X-App-Slug header is being matched against the app/keys.",
"notes": "Investigated: Proxy is working correctly. X-App-Slug header is properly identifying app and looking up user secrets. Error \"No SCOUT_API_KEY configured\" means the secret needs to be added in Dashboard > Secrets. The app owner needs to add SCOUT_API_KEY secret.",
"completedAt": "2026-02-22T12:10:00Z"
},
"task-116": {
"title": "Verify custom API keys work and document how they work",
"status": "completed",
"priority": "medium",
"createdAt": "2026-02-22T14:05:00Z",
"description": "Test that custom API keys (X-API-Key header) work for proxy authentication. Document how they work: how they're created, how they're validated, what endpoints they can access.",
"notes": "Custom API keys work as follows:\n1. Create: POST /api/dashboard/api-keys (requires JWT auth)\n2. Format: oh_live_ + 32-char hex (no dashes)\n3. Usage: Send X-API-Key: oh_live_xxx header in requests\n4. Lookup: getApiKeyByKey() queries api_keys table, returns user_id\n5. The API key inherits the user's plan tier\n6. Works for proxy routes: identifies user and uses their secrets\n7. Tests exist in src/lib/users.test.ts (getApiKeyByKey, listApiKeysByUser)",
"completedAt": "2026-02-22T14:10:00Z"
},
"task-118": {
"title": "Code review: Latest build (Feb 23, 2026)",
"status": "completed",
"priority": "high",
"createdAt": "2026-02-23T14:00:00Z",
"completedAt": "2026-02-23T14:58:00Z",
"commit": "e93dff0",
"description": "Code review of the latest changes pulled from GitHub (e93dff0). Review the 7 changed files: AGENTS.md, public/app.js, public/index.html, src/config.ts, src/index.ts, src/routes/proxy.ts, src/routes/secrets.ts. Check for security issues, code quality, and test coverage.",
"summary": "Code review completed. Build passes. All 199 tests pass. No critical security issues found.",
"filesReviewed": {
"AGENTS.md": {
"linesChanged": 166,
"summary": "Documentation refactoring - clarified conventions and commands. No functional changes.",
"issues": []
},
"public/app.js": {
"linesChanged": 300,
"summary": "Added proxy endpoint testing UI in dashboard. New functions: openProxyTestModal(), runProxyTest(), showEditProviderKeyModal(), updateProviderKey(). Added SECRET_TO_PROXY_ENDPOINT mapping. Users can now test proxy endpoints directly from the Keys tab.",
"issues": [
{
"severity": "low",
"type": "code-quality",
"description": "Switch case fallthrough in buildAuthHeader() for 'micro' lacks comment (line 138 in proxy.ts). Falls through to 'hypermicro' which is intentional but could be confusing."
}
],
"securityNotes": [
"Uses encodeURIComponent() for URL parameters - prevents injection",
"Uses escapeHtml() for user input in modal - prevents XSS",
"Uses JWT Bearer token from localStorage for auth - safe from CSRF",
"Proper error handling with try/catch and user feedback"
]
},
"public/index.html": {
"linesChanged": 18,
"summary": "Modified PostHog analytics to skip initialization on localhost/127.0.0.1. Refactored to IIFE pattern.",
"issues": [],
"securityNotes": [
"No security impact - analytics only"
]
},
"src/config.ts": {
"linesChanged": 7,
"summary": "Added 'micro' endpoint alias for hypermicro proxy target.",
"issues": []
},
"src/index.ts": {
"linesChanged": 24,
"summary": "Improved static file handling with shouldBypassStatic() and matchesRoutePrefix() helpers. Now properly bypasses static serving for /api, /proxy, /a, /unsubscribe routes.",
"issues": [],
"securityNotes": [
"Good fix - prevents SPA fallback from catching /proxy/* routes that should 404"
]
},
"src/routes/proxy.ts": {
"linesChanged": 1,
"summary": "Added 'micro' case to buildAuthHeader() switch statement. Falls through to 'hypermicro' case (same auth header).",
"issues": [
{
"severity": "low",
"type": "code-quality",
"line": 138,
"description": "Switch case fallthrough without comment. Add '// falls through' comment for clarity."
}
]
},
"src/routes/secrets.ts": {
"linesChanged": 52,
"summary": "Added PUT /api/secrets/:name endpoint for rotating provider API keys. Uses existing updateSecret() function which regenerates salt on each update. Includes audit logging.",
"issues": [],
"securityNotes": [
"Proper authentication via getAuthUser()",
"Returns 404 for non-existent secrets (no information leakage)",
"Audit logging for secret_update action",
"Key rotation regenerates encryption salt (good practice)"
]
}
},
"recommendations": [
{
"priority": "low",
"description": "Add '// falls through' comment to switch case in proxy.ts line 138",
"file": "src/routes/proxy.ts",
"line": 138
},
{
"priority": "low",
"description": "Consider adding client-side validation for endpoint names in proxy test modal before making request",
"file": "public/app.js"
},
{
"priority": "low",
"description": "Consider rate limiting on the proxy test endpoint (currently only requires auth)",
"file": "public/app.js"
}
],
"testResults": {
"passed": 199,
"failed": 0,
"total": 199,
"todo": 8,
"files": 5,
"duration": "2.43s"
},
"buildResult": "passed"
},
"task-119": {
"title": "Update documentation for subdomain-first approach and ZIP publishing",
"status": "in_progress",
"priority": "high",
"createdAt": "2026-02-23T15:05:00Z",
"description": "Update all documentation to reflect: (1) Subdomains are now the default, (2) ZIP file publishing workflow, (3) Next.js/Vercel compatibility settings, (4) Clear onboarding guidance for new users.",
"steps": [
{
"id": "119-01",
"title": "Update SKILL.md/SKILL.html for agent onboarding",
"status": "completed",
"completedAt": "2026-02-23T15:17:00Z",
"description": "Update the agent skill documentation at ~/.agents/skills/onhyper/SKILL.md to reflect subdomain-first approach, ZIP publishing, and Next.js settings.",
"summary": "Updated SKILL.md with: (1) Subdomains as default URLs, path-based as fallback, (2) ZIP file publishing as primary deployment method, (3) Next.js settings (output: 'export', images: { unoptimized: true }, basePath/assetPrefix for path-based URLs), (4) PostHog analytics via /api/analytics/capture, (5) Reorganized content for better onboarding flow, (6) Preserved proxy endpoints, secrets, self-API sections."
},
{
"id": "119-02",
"title": "Update README.md for GitHub",
"status": "completed",
"completedAt": "2026-02-23T15:17:00Z",
"description": "Update project README with subdomain defaults, ZIP publishing instructions, and quickstart guide.",
"summary": "Rewrote README.md with: (1) Quickstart section - 2-minute deployment with ZIP upload, (2) Subdomain-first URLs as default, (3) ZIP publishing as primary method, (4) Next.js compatibility with required config, (5) Features overview (proxy, secrets, analytics), (6) Development setup. Reorganized for new user friendliness with emojis and clear sections."
},
{
"id": "119-03",
"title": "Update inline code comments in proxy/render routes",
"status": "completed",
"completedAt": "2026-02-23T15:23:00Z",
"description": "Add/update comments in src/routes/proxy.ts, src/routes/render.ts, src/routes/apps.ts explaining subdomain behavior and ZIP handling."
},
{
"id": "119-04",
"title": "Update AGENTS.md workspace conventions",
"status": "completed",
"completedAt": "2026-02-23T15:20:00Z",
"description": "Ensure AGENTS.md reflects current subdomain-first approach and any relevant conventions for agents working on the codebase.",
"summary": "Added comprehensive sections for: Subdomain-first architecture, ZIP publishing workflow, Next.js compatibility (output: export, images unoptimized), Proxy endpoint patterns (/proxy/openai/*, /proxy/anthropic/*, etc.), X-App-Slug header auth, LMDB storage patterns, and testing conventions (npm test, coverage)."
},
{
"id": "119-05",
"title": "Create/update user-facing docs for Next.js apps",
"status": "completed",
"completedAt": "2026-02-23T15:30:00Z",
"description": "Document Next.js-specific settings needed for HYPR deployment: basePath, assetPrefix, output: 'export', image unoptimized, etc.",
"summary": "Updated blog/how-to-publish-nextjs-onhyper.md with: (1) Added images: { unoptimized: true } and trailingSlash: true to main next.config.ts example in Step 2, (2) Added explicit note that subdomains are the default at top of Step 5, (3) Updated assets troubleshooting to explain basePath/assetPrefix are only needed for path-based URLs (not subdomains), (4) Updated Summary table to say 'Configure next.config.ts' and 'Upload ZIP', (5) Cleaned up image troubleshooting to reference Step 2 config."
},
{
"id": "119-06",
"title": "Update landing page and pricing page copy",
"status": "completed",
"completedAt": "2026-02-23T15:25:00Z",
"description": "Ensure marketing pages reflect subdomain-first messaging (e.g., 'yourapp.onhyper.io' as default URL).",
"summary": "Updated home.html landing page: (1) Hero section now shows 'ZIP upload → subdomain' workflow, (2) Feature grid highlights ZIP publishing, clean subdomain URLs, and secure API access, (3) Three-step process updated to ZIP-focused, (4) Final CTA emphasizes subdomain URLs. Updated skill.html: Reordered feature highlights to put ZIP publishing and subdomain URLs first. Already existing: app.js form hints show subdomain as primary, README.md has comprehensive subdomain-first messaging."
},
{
"id": "119-07",
"title": "Update dashboard help text and tooltips",
"status": "pending",
"description": "Update in-app help text, tooltips, and placeholder text to guide users toward subdomain and ZIP workflow."
}
],
"successCriteria": [
"SKILL.md reflects subdomain-first approach",
"README.md has clear quickstart with ZIP publishing",
"Next.js deployment guide exists with all required settings",
"Landing/pricing pages show subdomain URLs",
"Dashboard help text guides users correctly"
]
},
"task-117": {
"title": "Pull onhyper source and review",
"status": "completed",
"priority": "medium",
"createdAt": "2026-02-22T17:40:00Z",
"description": "Pull the latest onhyper source code and review for any issues, improvements, or security concerns.",
"notes": "Pulled latest code (79b7ed3). Review findings:\n- TypeScript compiles clean (no errors)\n- Recent commits: Unified keys tab UX for provider/custom credentials\n- Changes: public/app.js, public/pages/dashboard.html, public/styles.css\n- Build/test: need to run full test suite (timeout earlier)\n- No security issues or TODOs noted",
"completedAt": "2026-02-22T18:00:00Z"
},
"task-120": {
"title": "Add /.well-known/skill.md endpoint for OnHyper",
"status": "completed",
"priority": "medium",
"createdAt": "2026-02-23T16:00:00Z",
"completedAt": "2026-02-23T16:05:00Z",
"description": "Add a GET /.well-known/skill.md endpoint that serves the OnHyper SKILL.md file. This allows agents/developers to discover the project's capabilities and conventions programmatically.",
"summary": "Added /.well-known/skill.md route in src/index.ts. Reads from ~/.agents/skills/onhyper/SKILL.md if available (localhost), falls back to embedded content (production). Returns Content-Type: text/markdown; charset=utf-8 with 1-hour cache.",
"successCriteria": [
"GET /.well-known/skill.md returns the SKILL.md content",
"Content-type: text/markdown",
"File sourced from ~/.agents/skills/onhyper/SKILL.md or embedded in app",
"Works on both onhyper.io and localhost"
]
},
"task-121": {
"title": "Run tests and commit documentation updates to main",
"status": "completed",
"priority": "high",
"createdAt": "2026-02-23T16:05:00Z",
"completedAt": "2026-02-23T11:24:00Z",
"commit": "95458eb",
"description": "Run all tests to verify the documentation updates and /.well-known/skill.md endpoint work correctly. If tests pass, commit all changes to main branch for production deployment.",
"summary": "All 199 tests passed. TypeScript build passed. Committed 13 files with docs: subdomain-first documentation + /.well-known/skill.md endpoint. Pushed to main (Railway will auto-deploy).",
"successCriteria": [
"npm test passes (all 199+ tests)",
"npm run build passes",
"All changes committed to main branch",
"Ready for production deployment"
]
},
"task-122": {
"title": "Review all documentation changes for accuracy and completeness",
"status": "completed",
"priority": "high",
"createdAt": "2026-02-23T16:08:00Z",
"completedAt": "2026-02-23T11:30:00Z",
"description": "Review all the documentation changes made in task-119, task-120, task-121 to ensure accuracy, consistency, and completeness. Verify subdomain-first messaging is consistent across all docs.",
"summary": "Reviewed 6 files. Found 5/6 items passing, 1 issue with well-known endpoint. Docs are consistent on subdomain-first messaging. Next.js config correct. ZIP instructions clear. One inconsistency found: GitHub org name differs between README.md (hyperio-mc) and skill.html/src/index.ts (hyperio-software). Well-known endpoint returning HTML instead of markdown - needs investigation.",
"findings": {
"consistency": {
"status": "pass",
"details": "All docs say 'subdomain-first' with consistent terminology. README.md, AGENTS.md, home.html, skill.html, blog post, and embedded skill all use same messaging."
},
"accuracy": {
"status": "pass",
"details": "Next.js config correct: output: 'export', images: { unoptimized: true }. Some docs include trailingSlash: true (optional)."
},
"completeness": {
"status": "pass",
"details": "ZIP publishing instructions clear in README.md (quickstart), AGENTS.md (detailed workflow), blog post (step-by-step guide)."
},
"links": {
"status": "issue",
"details": "GitHub org name inconsistent: README.md uses 'hyperio-mc', skill.html and src/index.ts use 'hyperio-software'. Need to verify correct org name and align."
},
"functionality": {
"status": "issue",
"details": "GET /.well-known/skill.md returns HTML (content-type: text/html) instead of markdown. Either deployment lag (commit just pushed) or route ordering issue. Recommend re-testing after Railway deployment completes."
}
},
"filesReviewed": [
"README.md",
"AGENTS.md",
"public/pages/home.html",
"public/pages/skill.html",
"blog/how-to-publish-nextjs-onhyper.md",
"src/index.ts"
],
"recommendations": [
"Verify correct GitHub org name (hyperio-mc vs hyperio-software) and update all references",
"Re-test /.well-known/skill.md endpoint after Railway deployment completes",
"If endpoint still fails, check route ordering in src/index.ts - may need to add /.well-known to shouldBypassStatic()"
],
"successCriteria": [
"README.md is accurate and complete",
"AGENTS.md reflects current architecture",
"Landing page messaging is consistent",
"Next.js guide is accurate",
".well-known/skill.md endpoint works",
"All docs use consistent terminology (subdomain-first, ZIP publishing)"
]
},
"task-123": {
"title": "Fix /.well-known/skill.md endpoint returning HTML",
"status": "completed",
"priority": "high",
"createdAt": "2026-02-23T16:30:00Z",
"completedAt": "2026-02-23T16:32:00Z",
"description": "The /.well-known/skill.md endpoint returns HTML (SPA fallback) instead of markdown. Need to add /.well-known to shouldBypassStatic() or check route ordering.",
"summary": "Fixed by adding /.well-known to shouldBypassStatic() function and updating SPA fallback to return 404 for /.well-known routes. Verified locally: curl shows Content-Type: text/markdown and correct SKILL.md content.",
"commit": "c277f9c",
"successCriteria": [
"GET /.well-known/skill.md returns Content-Type: text/markdown",
"Endpoint works on production (onhyper.io)",
"Route is not caught by SPA fallback"
]
},
"task-124": {
"title": "Investigate Nextra 4 as docs site for OnHyper",
"status": "completed",
"priority": "medium",
"createdAt": "2026-02-23T20:43:08Z",
"completedAt": "2026-02-23T20:45:00Z",
"description": "Research Nextra 4 capabilities, setup requirements, and evaluate if it would be a good fit for OnHyper documentation site. Consider: MDX support, theming, search, deployment options, and integration with existing onhyper.io infrastructure.",
"summary": "Research complete. RECOMMENDATION: Nextra 4 is an excellent choice for OnHyper docs. Key findings: (1) MDX support is excellent with Shiki syntax highlighting, custom components, code blocks with filenames/line highlighting; (2) Full theming via Layout component, CSS variables, custom components - can match OnHyper branding; (3) Built-in Pagefind search (Rust-powered, client-side, fast); (4) Deploys to Railway, Vercel, Docker, or static export; (5) Compared vs Docusaurus (older, larger bundle), Mintlify ($150-300/mo, no self-host), GitBook (limited customization, expensive). Nextra 4 wins due to: MIT license (free), full control, modern Next.js 14+ App Router, Turbopack, small bundles, active development. Output: /docs/nextra-research.md with full analysis and implementation plan.",
"successCriteria": [
"Evaluate Nextra 4 features and architecture",
"Assess MDX/content support for technical docs",
"Check theming and customization options",
"Investigate deployment (Railway, Vercel, or subdomain)",
"Compare with alternatives (Docusaurus, Mintlify, GitBook)",
"Provide recommendation with pros/cons"
],
"output": "/Users/mastercontrol/.openclaw/workspace/onhyper/docs/nextra-research.md"
},
"task-125": {
"title": "Investigate Next.js application error",
"status": "completed",
"priority": "high",
"createdAt": "2026-02-23T20:47:59Z",
"description": "User reported a Next.js application error: \"Application error: a client-side exception has occurred\". Need to investigate the cause and determine if it is an OnHyper proxy issue, a problem with the deployed app, or a configuration issue.",
"context": "User screenshot shows Next.js error page. Need to identify the app, check browser console errors, and review server logs.",
"successCriteria": [
"Identify which app is experiencing the error",
"Determine root cause (client-side JS error, proxy misconfiguration, missing API keys, etc.)",
"Propose fix or workaround"
],
"notes": "Fixed SPA fallback in subdomain.ts - nested routes now serve root index.html. Committed d6900be, pushed to main.",
"completedAt": "2026-02-23T20:54:08Z"
}
}
}