@nordsym/apiclaw 1.3.5 → 1.3.7

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 (50) hide show
  1. package/README.md +33 -0
  2. package/convex/_generated/api.d.ts +12 -0
  3. package/convex/billing.ts +651 -216
  4. package/convex/crons.ts +17 -0
  5. package/convex/email.ts +135 -82
  6. package/convex/feedback.ts +265 -0
  7. package/convex/http.ts +80 -4
  8. package/convex/logs.ts +287 -0
  9. package/convex/providerKeys.ts +209 -0
  10. package/convex/providers.ts +18 -0
  11. package/convex/schema.ts +115 -0
  12. package/convex/stripeActions.ts +512 -0
  13. package/convex/webhooks.ts +494 -0
  14. package/convex/workspaces.ts +74 -1
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +38 -7
  17. package/dist/cli.js.map +1 -1
  18. package/dist/index.js +178 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/metered.d.ts +62 -0
  21. package/dist/metered.d.ts.map +1 -0
  22. package/dist/metered.js +81 -0
  23. package/dist/metered.js.map +1 -0
  24. package/dist/stripe.d.ts +62 -0
  25. package/dist/stripe.d.ts.map +1 -1
  26. package/dist/stripe.js +212 -0
  27. package/dist/stripe.js.map +1 -1
  28. package/docs/PRD-final-polish.md +117 -0
  29. package/docs/PRD-mobile-responsive.md +56 -0
  30. package/docs/PRD-navigation-expansion.md +295 -0
  31. package/docs/PRD-stripe-billing.md +312 -0
  32. package/docs/PRD-workspace-cleanup.md +200 -0
  33. package/landing/src/app/api/billing/checkout/route.ts +109 -0
  34. package/landing/src/app/api/billing/payment-method/route.ts +118 -0
  35. package/landing/src/app/api/billing/portal/route.ts +64 -0
  36. package/landing/src/app/auth/verify/page.tsx +20 -5
  37. package/landing/src/app/earn/page.tsx +6 -6
  38. package/landing/src/app/login/page.tsx +1 -1
  39. package/landing/src/app/page.tsx +70 -70
  40. package/landing/src/app/providers/dashboard/page.tsx +1 -1
  41. package/landing/src/app/workspace/page.tsx +3497 -535
  42. package/landing/src/components/CheckoutButton.tsx +188 -0
  43. package/landing/src/components/Toast.tsx +84 -0
  44. package/landing/src/lib/stats.json +1 -1
  45. package/landing/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +1 -1
  47. package/src/cli.ts +57 -7
  48. package/src/index.ts +205 -0
  49. package/src/metered.ts +149 -0
  50. package/src/stripe.ts +253 -0
@@ -307,7 +307,7 @@ Website: https://apiclaw.nordsym.com`;
307
307
  href="#for-providers"
308
308
  className={`transition ${activeSection === "for-providers" ? "text-accent font-medium" : "hover:text-text-primary"}`}
309
309
  >
310
- For Providers
310
+ For API Providers
311
311
  </a>
312
312
  <a
313
313
  href="/docs"
@@ -341,7 +341,7 @@ Website: https://apiclaw.nordsym.com`;
341
341
  </a>
342
342
  ) : (
343
343
  <a
344
- href="/providers/register"
344
+ href="/workspace?tab=my-apis"
345
345
  className="text-sm text-text-muted hover:text-accent transition flex items-center gap-1"
346
346
  >
347
347
  <FileText className="w-4 h-4" />
@@ -408,14 +408,14 @@ Website: https://apiclaw.nordsym.com`;
408
408
  onClick={() => setMobileMenuOpen(false)}
409
409
  className="py-2 text-text-muted hover:text-text-primary transition"
410
410
  >
411
- For Providers
411
+ For API Providers
412
412
  </a>
413
413
  <a
414
- href="#get-started"
414
+ href="/docs"
415
415
  onClick={() => setMobileMenuOpen(false)}
416
416
  className="py-2 text-text-muted hover:text-text-primary transition"
417
417
  >
418
- Get Started
418
+ Docs
419
419
  </a>
420
420
  <a
421
421
  href="#faq"
@@ -426,12 +426,12 @@ Website: https://apiclaw.nordsym.com`;
426
426
  </a>
427
427
  <div className="border-t border-border pt-3 mt-1 flex flex-col space-y-3">
428
428
  <a
429
- href="/providers/dashboard"
429
+ href="/workspace"
430
430
  onClick={() => setMobileMenuOpen(false)}
431
431
  className="py-2 text-accent font-medium flex items-center gap-2"
432
432
  >
433
- <FileText className="w-4 h-4" />
434
- Add Your API
433
+ <Zap className="w-4 h-4" />
434
+ Workspace
435
435
  </a>
436
436
  <a
437
437
  href="https://github.com/nordsym/apiclaw"
@@ -456,7 +456,7 @@ Website: https://apiclaw.nordsym.com`;
456
456
  <div className="grid lg:grid-cols-2 gap-12 lg:gap-16 items-start">
457
457
  {/* Left: Copy */}
458
458
  <div className="text-center lg:text-left">
459
- <div className="flex flex-wrap items-center justify-center lg:justify-start gap-3 mb-6">
459
+ <div className="flex flex-wrap items-center justify-center lg:justify-start gap-2 sm:gap-3 mb-4 sm:mb-6">
460
460
  <div className="badge badge-live inline-flex">
461
461
  <span className="flex items-center gap-2"><span className="w-2 h-2 bg-green-500 rounded-full animate-pulse" />Live • {statsData.apiCount.toLocaleString()} APIs</span>
462
462
  </div>
@@ -468,13 +468,13 @@ Website: https://apiclaw.nordsym.com`;
468
468
  </button>
469
469
  </div>
470
470
 
471
- <h1 className="text-5xl md:text-6xl lg:text-7xl font-black mb-6 leading-[1.05] tracking-tighter">
471
+ <h1 className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-black mb-4 sm:mb-6 leading-[1.05] tracking-tighter">
472
472
  <span className="gradient-text">The API Layer</span>
473
473
  <br />
474
474
  <span className="text-text-primary">for AI Agents</span>
475
475
  </h1>
476
476
 
477
- <p className="text-xl md:text-2xl text-text-secondary mb-4 leading-relaxed max-w-xl mx-auto lg:mx-0">
477
+ <p className="text-lg sm:text-xl md:text-2xl text-text-secondary mb-3 sm:mb-4 leading-relaxed max-w-xl mx-auto lg:mx-0">
478
478
  Find, evaluate, and integrate APIs in milliseconds.
479
479
  </p>
480
480
 
@@ -486,20 +486,20 @@ Website: https://apiclaw.nordsym.com`;
486
486
  {/* Copy Context Button */}
487
487
  <button
488
488
  onClick={copyContextToClipboard}
489
- className="group relative inline-flex items-center gap-3 px-6 py-4 bg-gradient-to-r from-accent to-accent/80 hover:from-accent/90 hover:to-accent/70 text-white font-bold rounded-2xl shadow-lg shadow-accent/25 hover:shadow-xl hover:shadow-accent/30 transition-all duration-300 hover:scale-[1.02]"
489
+ className="group relative inline-flex items-center gap-2 sm:gap-3 px-4 sm:px-6 py-3 sm:py-4 bg-gradient-to-r from-accent to-accent/80 hover:from-accent/90 hover:to-accent/70 text-white font-bold rounded-xl sm:rounded-2xl shadow-lg shadow-accent/25 hover:shadow-xl hover:shadow-accent/30 transition-all duration-300 hover:scale-[1.02] w-full sm:w-auto justify-center"
490
490
  >
491
- <Sparkles className="w-6 h-6" />
491
+ <Sparkles className="w-5 h-5 sm:w-6 sm:h-6" />
492
492
  <span className="flex flex-col items-start">
493
- <span className="text-base">{showContextCopied ? "Copied!" : "Explain to your AI"}</span>
493
+ <span className="text-sm sm:text-base">{showContextCopied ? "Copied!" : "Explain to your AI"}</span>
494
494
  <span className="text-xs opacity-80 font-normal">Copy context for your agent</span>
495
495
  </span>
496
496
  {showContextCopied ? (
497
- <Check className="w-5 h-5" />
497
+ <Check className="w-4 h-4 sm:w-5 sm:h-5" />
498
498
  ) : (
499
- <Copy className="w-5 h-5 group-hover:scale-110 transition-transform" />
499
+ <Copy className="w-4 h-4 sm:w-5 sm:h-5 group-hover:scale-110 transition-transform" />
500
500
  )}
501
501
  {showContextCopied && (
502
- <span className="absolute -top-12 left-1/2 -translate-x-1/2 bg-black text-white text-sm px-4 py-2 rounded-lg whitespace-nowrap shadow-lg">
502
+ <span className="absolute -top-12 left-1/2 -translate-x-1/2 bg-black text-white text-xs sm:text-sm px-3 sm:px-4 py-2 rounded-lg whitespace-nowrap shadow-lg">
503
503
  ✓ Paste this to your AI agent!
504
504
  </span>
505
505
  )}
@@ -648,26 +648,26 @@ Website: https://apiclaw.nordsym.com`;
648
648
  </p>
649
649
 
650
650
  {/* Waitlist Form */}
651
- <div className="max-w-md mx-auto mt-6">
651
+ <div className="max-w-md mx-auto mt-6 px-4 sm:px-0">
652
652
  {waitlistStatus === "success" ? (
653
- <div className="flex items-center justify-center gap-2 text-green-500 bg-green-500/10 rounded-xl px-4 py-3">
654
- <Check className="w-5 h-5" />
653
+ <div className="flex items-center justify-center gap-2 text-green-500 bg-green-500/10 rounded-xl px-4 py-3 text-sm sm:text-base">
654
+ <Check className="w-5 h-5 flex-shrink-0" />
655
655
  <span>You're on the list! We'll reach out soon.</span>
656
656
  </div>
657
657
  ) : (
658
- <form onSubmit={submitWaitlist} className="flex gap-2">
658
+ <form onSubmit={submitWaitlist} className="flex flex-col sm:flex-row gap-2">
659
659
  <input
660
660
  type="email"
661
661
  placeholder="your@email.com"
662
662
  value={waitlistEmail}
663
663
  onChange={(e) => setWaitlistEmail(e.target.value)}
664
664
  required
665
- className="flex-1 px-4 py-3 rounded-xl bg-surface border border-border focus:border-accent focus:outline-none text-sm"
665
+ className="w-full sm:flex-1 px-4 py-3 rounded-xl bg-surface border border-border focus:border-accent focus:outline-none text-sm"
666
666
  />
667
667
  <button
668
668
  type="submit"
669
669
  disabled={waitlistStatus === "loading"}
670
- className="px-6 py-3 bg-accent hover:bg-accent/90 text-white font-medium rounded-xl transition-colors disabled:opacity-50"
670
+ className="w-full sm:w-auto px-6 py-3 bg-accent hover:bg-accent/90 text-white font-medium rounded-xl transition-colors disabled:opacity-50"
671
671
  >
672
672
  {waitlistStatus === "loading" ? "..." : "Join Waitlist"}
673
673
  </button>
@@ -681,17 +681,17 @@ Website: https://apiclaw.nordsym.com`;
681
681
  </section>
682
682
 
683
683
  {/* Quick Start */}
684
- <section className="py-16 px-6 bg-surface/50">
684
+ <section className="py-12 sm:py-16 px-4 sm:px-6 bg-surface/50">
685
685
  <div className="max-w-3xl mx-auto">
686
- <div className="text-center mb-8">
687
- <h2 className="text-2xl md:text-3xl font-bold flex items-center justify-center gap-3">
688
- <Zap className="w-6 h-6 text-accent" />
686
+ <div className="text-center mb-6 sm:mb-8">
687
+ <h2 className="text-xl sm:text-2xl md:text-3xl font-bold flex items-center justify-center gap-2 sm:gap-3">
688
+ <Zap className="w-5 h-5 sm:w-6 sm:h-6 text-accent" />
689
689
  Quick Start
690
690
  </h2>
691
- <p className="text-text-secondary mt-2">Get running in 30 seconds</p>
691
+ <p className="text-text-secondary mt-2 text-sm sm:text-base">Get running in 30 seconds</p>
692
692
  </div>
693
693
 
694
- <div className="grid md:grid-cols-2 gap-6">
694
+ <div className="grid md:grid-cols-2 gap-4 sm:gap-6">
695
695
  {/* Install */}
696
696
  <div className="code-preview">
697
697
  <div className="code-preview-header">
@@ -750,24 +750,24 @@ Website: https://apiclaw.nordsym.com`;
750
750
  </p>
751
751
  </div>
752
752
 
753
- <div className="grid md:grid-cols-3 gap-8">
753
+ <div className="grid md:grid-cols-3 gap-6 md:gap-8">
754
754
  {howItWorks.map((step, i) => (
755
755
  <div key={i} className="feature-card">
756
- <div className="flex items-center gap-4 mb-6">
756
+ <div className="flex items-center gap-3 sm:gap-4 mb-4 sm:mb-6">
757
757
  <div className="step-indicator">{step.step}</div>
758
758
  <div>
759
- <h3 className="font-bold text-xl">{step.title}</h3>
759
+ <h3 className="font-bold text-lg sm:text-xl">{step.title}</h3>
760
760
  </div>
761
761
  </div>
762
- <p className="text-text-secondary mb-6 leading-relaxed">
762
+ <p className="text-text-secondary mb-4 sm:mb-6 leading-relaxed text-sm sm:text-base">
763
763
  {step.description}
764
764
  </p>
765
765
  <div className="code-preview">
766
766
  <div className="code-preview-header">
767
767
  example.ts
768
768
  </div>
769
- <div className="code-preview-body">
770
- <pre className="text-sm whitespace-pre-wrap">{step.codeJsx}</pre>
769
+ <div className="code-preview-body overflow-x-auto">
770
+ <pre className="text-xs sm:text-sm whitespace-pre-wrap">{step.codeJsx}</pre>
771
771
  </div>
772
772
  </div>
773
773
  </div>
@@ -893,7 +893,7 @@ Website: https://apiclaw.nordsym.com`;
893
893
  <p className="text-text-muted text-sm">For all API providers</p>
894
894
  </div>
895
895
  <div className="flex gap-2">
896
- <a href="/providers/dashboard" className="btn-ghost !py-2.5 !px-4 text-sm">
896
+ <a href="/workspace?tab=my-apis" className="btn-ghost !py-2.5 !px-4 text-sm">
897
897
  Dashboard
898
898
  </a>
899
899
  <a href="/providers" className="btn-primary !py-2.5 !px-5 text-sm">
@@ -952,33 +952,33 @@ Website: https://apiclaw.nordsym.com`;
952
952
  </p>
953
953
  </div>
954
954
 
955
- <div className="grid md:grid-cols-2 gap-8">
955
+ <div className="grid md:grid-cols-2 gap-6 md:gap-8">
956
956
  {/* For Agents */}
957
- <div className="rounded-2xl bg-surface-elevated border-2 border-accent p-8 relative glow">
958
- <div className="absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 bg-accent text-white text-xs font-bold tracking-wide rounded-full uppercase">
957
+ <div className="rounded-2xl bg-surface-elevated border-2 border-accent p-6 sm:p-8 relative glow">
958
+ <div className="absolute -top-3 left-1/2 -translate-x-1/2 px-3 sm:px-4 py-1 bg-accent text-white text-xs font-bold tracking-wide rounded-full uppercase">
959
959
  Live Now
960
960
  </div>
961
- <h3 className="text-2xl font-bold mb-2">For Agents</h3>
962
- <p className="text-text-secondary mb-8">Discovery + Direct Call</p>
963
- <ul className="space-y-4 mb-8">
964
- <li className="flex items-center gap-3 text-text-secondary">
965
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
961
+ <h3 className="text-xl sm:text-2xl font-bold mb-2">For Agents</h3>
962
+ <p className="text-text-secondary mb-6 sm:mb-8">Discovery + Direct Call</p>
963
+ <ul className="space-y-3 sm:space-y-4 mb-6 sm:mb-8">
964
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
965
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
966
966
  Search {statsData.apiCount.toLocaleString()}+ APIs by capability
967
967
  </li>
968
- <li className="flex items-center gap-3 text-text-secondary">
969
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
968
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
969
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
970
970
  Direct Call: Use APIs without keys
971
971
  </li>
972
- <li className="flex items-center gap-3 text-text-secondary">
973
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
972
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
973
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
974
974
  10+ providers (AI Models, Scraping, Code, Search)
975
975
  </li>
976
- <li className="flex items-center gap-3 text-text-secondary">
977
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
976
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
977
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
978
978
  Structured JSON responses
979
979
  </li>
980
- <li className="flex items-center gap-3 text-text-secondary">
981
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
980
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
981
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
982
982
  MCP native
983
983
  </li>
984
984
  </ul>
@@ -988,35 +988,35 @@ Website: https://apiclaw.nordsym.com`;
988
988
  </div>
989
989
 
990
990
  {/* For Providers */}
991
- <div className="rounded-2xl bg-surface-elevated border-2 border-accent p-8 relative glow">
992
- <div className="absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 bg-accent text-white text-xs font-bold tracking-wide rounded-full uppercase">
991
+ <div className="rounded-2xl bg-surface-elevated border-2 border-accent p-6 sm:p-8 relative glow">
992
+ <div className="absolute -top-3 left-1/2 -translate-x-1/2 px-3 sm:px-4 py-1 bg-accent text-white text-xs font-bold tracking-wide rounded-full uppercase">
993
993
  Live Now
994
994
  </div>
995
- <h3 className="text-2xl font-bold mb-2">For Providers</h3>
996
- <p className="text-text-secondary mb-8">Get discovered by AI agents</p>
997
- <ul className="space-y-4 mb-8">
998
- <li className="flex items-center gap-3 text-text-secondary">
999
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
995
+ <h3 className="text-xl sm:text-2xl font-bold mb-2">For API Providers</h3>
996
+ <p className="text-text-secondary mb-6 sm:mb-8">Get discovered by AI agents</p>
997
+ <ul className="space-y-3 sm:space-y-4 mb-6 sm:mb-8">
998
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
999
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
1000
1000
  Get discovered by AI agents
1001
1001
  </li>
1002
- <li className="flex items-center gap-3 text-text-secondary">
1003
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
1002
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
1003
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
1004
1004
  Become a Direct Call partner
1005
1005
  </li>
1006
- <li className="flex items-center gap-3 text-text-secondary">
1007
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
1006
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
1007
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
1008
1008
  Self-service onboarding
1009
1009
  </li>
1010
- <li className="flex items-center gap-3 text-text-secondary">
1011
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
1010
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
1011
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
1012
1012
  Analytics & usage insights
1013
1013
  </li>
1014
- <li className="flex items-center gap-3 text-text-secondary">
1015
- <Check className="w-5 h-5 text-accent flex-shrink-0" />
1014
+ <li className="flex items-start gap-3 text-text-secondary text-sm sm:text-base">
1015
+ <Check className="w-5 h-5 text-accent flex-shrink-0 mt-0.5" />
1016
1016
  Zero integration work
1017
1017
  </li>
1018
1018
  </ul>
1019
- <a href="/providers/dashboard" className="btn-primary w-full justify-center">
1019
+ <a href="/workspace?tab=my-apis" className="btn-primary w-full justify-center">
1020
1020
  Add Your API
1021
1021
  </a>
1022
1022
  </div>
@@ -1129,8 +1129,8 @@ Website: https://apiclaw.nordsym.com`;
1129
1129
  <ul className="space-y-3 text-text-muted">
1130
1130
  <li><a href="#how-it-works" className="hover:text-text-primary transition">How It Works</a></li>
1131
1131
  <li><a href="#for-agents" className="hover:text-text-primary transition">For Agents</a></li>
1132
- <li><a href="#for-providers" className="hover:text-text-primary transition">For Providers</a></li>
1133
- <li><a href="/providers/dashboard" className="hover:text-text-primary transition">Provider Dashboard</a></li>
1132
+ <li><a href="#for-providers" className="hover:text-text-primary transition">For API Providers</a></li>
1133
+ <li><a href="/workspace" className="hover:text-text-primary transition">Workspace</a></li>
1134
1134
  <li><a href="#get-started" className="hover:text-text-primary transition">Get Started</a></li>
1135
1135
  <li><a href="#faq" className="hover:text-text-primary transition">FAQ</a></li>
1136
1136
  <li><a href="/docs" className="hover:text-text-primary transition">Documentation</a></li>
@@ -8,7 +8,7 @@ export default function ProviderDashboardRedirect() {
8
8
  const router = useRouter();
9
9
 
10
10
  useEffect(() => {
11
- router.replace("/workspace?tab=apis");
11
+ router.replace("/workspace?tab=my-apis");
12
12
  }, [router]);
13
13
 
14
14
  return (