@nordsym/apiclaw 1.3.7 → 1.3.9

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 (203) hide show
  1. package/README.md +436 -200
  2. package/convex/_generated/api.d.ts +4 -0
  3. package/convex/agents.ts +403 -0
  4. package/convex/directCall.ts +80 -0
  5. package/convex/earnProgress.ts +753 -0
  6. package/convex/logs.ts +17 -0
  7. package/convex/providerKeys.ts +82 -2
  8. package/convex/schema.ts +71 -2
  9. package/convex/workspaces.ts +84 -2
  10. package/dist/adapters/base.d.ts +112 -0
  11. package/dist/adapters/base.d.ts.map +1 -0
  12. package/dist/adapters/base.js +247 -0
  13. package/dist/adapters/base.js.map +1 -0
  14. package/dist/adapters/claude-desktop.d.ts +12 -0
  15. package/dist/adapters/claude-desktop.d.ts.map +1 -0
  16. package/dist/adapters/claude-desktop.js +36 -0
  17. package/dist/adapters/claude-desktop.js.map +1 -0
  18. package/dist/adapters/cline.d.ts +20 -0
  19. package/dist/adapters/cline.d.ts.map +1 -0
  20. package/dist/adapters/cline.js +77 -0
  21. package/dist/adapters/cline.js.map +1 -0
  22. package/dist/adapters/continue.d.ts +26 -0
  23. package/dist/adapters/continue.d.ts.map +1 -0
  24. package/dist/adapters/continue.js +68 -0
  25. package/dist/adapters/continue.js.map +1 -0
  26. package/dist/adapters/cursor.d.ts +12 -0
  27. package/dist/adapters/cursor.d.ts.map +1 -0
  28. package/dist/adapters/cursor.js +38 -0
  29. package/dist/adapters/cursor.js.map +1 -0
  30. package/dist/adapters/custom.d.ts +47 -0
  31. package/dist/adapters/custom.d.ts.map +1 -0
  32. package/dist/adapters/custom.js +146 -0
  33. package/dist/adapters/custom.js.map +1 -0
  34. package/dist/adapters/detect.d.ts +69 -0
  35. package/dist/adapters/detect.d.ts.map +1 -0
  36. package/dist/adapters/detect.js +158 -0
  37. package/dist/adapters/detect.js.map +1 -0
  38. package/dist/adapters/index.d.ts +21 -0
  39. package/dist/adapters/index.d.ts.map +1 -0
  40. package/dist/adapters/index.js +23 -0
  41. package/dist/adapters/index.js.map +1 -0
  42. package/dist/adapters/windsurf.d.ts +12 -0
  43. package/dist/adapters/windsurf.d.ts.map +1 -0
  44. package/dist/adapters/windsurf.js +39 -0
  45. package/dist/adapters/windsurf.js.map +1 -0
  46. package/dist/bin.d.ts +9 -0
  47. package/dist/bin.d.ts.map +1 -0
  48. package/dist/bin.js +19 -0
  49. package/dist/bin.js.map +1 -0
  50. package/dist/cli/commands/doctor.d.ts +34 -0
  51. package/dist/cli/commands/doctor.d.ts.map +1 -0
  52. package/dist/cli/commands/doctor.js +312 -0
  53. package/dist/cli/commands/doctor.js.map +1 -0
  54. package/dist/cli/commands/index.d.ts +9 -0
  55. package/dist/cli/commands/index.d.ts.map +1 -0
  56. package/dist/cli/commands/index.js +9 -0
  57. package/dist/cli/commands/index.js.map +1 -0
  58. package/dist/cli/commands/mcp-install.d.ts +14 -0
  59. package/dist/cli/commands/mcp-install.d.ts.map +1 -0
  60. package/dist/cli/commands/mcp-install.js +246 -0
  61. package/dist/cli/commands/mcp-install.js.map +1 -0
  62. package/dist/cli/commands/restore.d.ts +50 -0
  63. package/dist/cli/commands/restore.d.ts.map +1 -0
  64. package/dist/cli/commands/restore.js +260 -0
  65. package/dist/cli/commands/restore.js.map +1 -0
  66. package/dist/cli/commands/setup.d.ts +19 -0
  67. package/dist/cli/commands/setup.d.ts.map +1 -0
  68. package/dist/cli/commands/setup.js +206 -0
  69. package/dist/cli/commands/setup.js.map +1 -0
  70. package/dist/cli/commands/uninstall.d.ts +37 -0
  71. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  72. package/dist/cli/commands/uninstall.js +189 -0
  73. package/dist/cli/commands/uninstall.js.map +1 -0
  74. package/dist/cli/index.d.ts +7 -0
  75. package/dist/cli/index.d.ts.map +1 -0
  76. package/dist/cli/index.js +105 -0
  77. package/dist/cli/index.js.map +1 -0
  78. package/dist/discovery.d.ts +6 -2
  79. package/dist/discovery.d.ts.map +1 -1
  80. package/dist/discovery.js +296 -2
  81. package/dist/discovery.js.map +1 -1
  82. package/dist/enterprise/env.d.ts +56 -0
  83. package/dist/enterprise/env.d.ts.map +1 -0
  84. package/dist/enterprise/env.js +124 -0
  85. package/dist/enterprise/env.js.map +1 -0
  86. package/dist/enterprise/index.d.ts +7 -0
  87. package/dist/enterprise/index.d.ts.map +1 -0
  88. package/dist/enterprise/index.js +7 -0
  89. package/dist/enterprise/index.js.map +1 -0
  90. package/dist/enterprise/script-generator.d.ts +32 -0
  91. package/dist/enterprise/script-generator.d.ts.map +1 -0
  92. package/dist/enterprise/script-generator.js +461 -0
  93. package/dist/enterprise/script-generator.js.map +1 -0
  94. package/dist/execute.d.ts +21 -0
  95. package/dist/execute.d.ts.map +1 -1
  96. package/dist/execute.js +231 -0
  97. package/dist/execute.js.map +1 -1
  98. package/dist/index.js +79 -7
  99. package/dist/index.js.map +1 -1
  100. package/dist/stripe.d.ts +1 -1
  101. package/dist/stripe.js +1 -1
  102. package/dist/stripe.js.map +1 -1
  103. package/dist/types.d.ts +29 -0
  104. package/dist/types.d.ts.map +1 -1
  105. package/dist/ui/colors.d.ts +111 -0
  106. package/dist/ui/colors.d.ts.map +1 -0
  107. package/dist/ui/colors.js +185 -0
  108. package/dist/ui/colors.js.map +1 -0
  109. package/dist/ui/errors.d.ts +69 -0
  110. package/dist/ui/errors.d.ts.map +1 -0
  111. package/dist/ui/errors.js +334 -0
  112. package/dist/ui/errors.js.map +1 -0
  113. package/dist/ui/index.d.ts +10 -0
  114. package/dist/ui/index.d.ts.map +1 -0
  115. package/dist/ui/index.js +14 -0
  116. package/dist/ui/index.js.map +1 -0
  117. package/dist/ui/prompts.d.ts +88 -0
  118. package/dist/ui/prompts.d.ts.map +1 -0
  119. package/dist/ui/prompts.js +295 -0
  120. package/dist/ui/prompts.js.map +1 -0
  121. package/dist/ui/spinner.d.ts +112 -0
  122. package/dist/ui/spinner.d.ts.map +1 -0
  123. package/dist/ui/spinner.js +229 -0
  124. package/dist/ui/spinner.js.map +1 -0
  125. package/dist/utils/backup.d.ts +48 -0
  126. package/dist/utils/backup.d.ts.map +1 -0
  127. package/dist/utils/backup.js +182 -0
  128. package/dist/utils/backup.js.map +1 -0
  129. package/dist/utils/config.d.ts +80 -0
  130. package/dist/utils/config.d.ts.map +1 -0
  131. package/dist/utils/config.js +221 -0
  132. package/dist/utils/config.js.map +1 -0
  133. package/dist/utils/os.d.ts +45 -0
  134. package/dist/utils/os.d.ts.map +1 -0
  135. package/dist/utils/os.js +106 -0
  136. package/dist/utils/os.js.map +1 -0
  137. package/dist/utils/paths.d.ts +38 -0
  138. package/dist/utils/paths.d.ts.map +1 -0
  139. package/dist/utils/paths.js +160 -0
  140. package/dist/utils/paths.js.map +1 -0
  141. package/docs/PRD-BILLING.md +226 -0
  142. package/docs/PRD-EARN-SYSTEM.md +261 -0
  143. package/docs/PRD-MCP-AUTO-SETUP.md +623 -0
  144. package/docs/enterprise-deployment.md +728 -0
  145. package/landing/next.config.mjs +14 -0
  146. package/landing/public/book/index.html +24 -5
  147. package/landing/public/demo-product.jpg +0 -0
  148. package/landing/public/stats.json +4 -2
  149. package/landing/scripts/generate-stats.js +13 -0
  150. package/landing/src/app/api/og/route.tsx +1 -3
  151. package/landing/src/app/api/workspace-auth/magic-link/route.ts +6 -3
  152. package/landing/src/app/auth/verify/page.tsx +11 -4
  153. package/landing/src/app/docs/page.tsx +1 -1
  154. package/landing/src/app/join/page.tsx +49 -0
  155. package/landing/src/app/layout.tsx +1 -1
  156. package/landing/src/app/login/page.tsx +7 -1
  157. package/landing/src/app/page.tsx +50 -38
  158. package/landing/src/app/providers/register/page.tsx +1 -1
  159. package/landing/src/app/workspace/page.tsx +484 -806
  160. package/landing/src/components/CheckoutButton.tsx +1 -1
  161. package/landing/src/components/EarnCreditsTab.tsx +842 -0
  162. package/landing/src/components/HeroTabs.tsx +2 -2
  163. package/landing/src/components/demo/PhoneDemo.tsx +423 -0
  164. package/landing/src/components/demo/index.ts +1 -0
  165. package/landing/src/lib/stats.json +3 -1
  166. package/landing/tailwind.config.ts +10 -0
  167. package/package.json +9 -2
  168. package/src/adapters/base.ts +363 -0
  169. package/src/adapters/claude-desktop.ts +41 -0
  170. package/src/adapters/cline.ts +88 -0
  171. package/src/adapters/continue.ts +91 -0
  172. package/src/adapters/cursor.ts +43 -0
  173. package/src/adapters/custom.ts +188 -0
  174. package/src/adapters/detect.ts +202 -0
  175. package/src/adapters/index.ts +47 -0
  176. package/src/adapters/windsurf.ts +44 -0
  177. package/src/bin.ts +19 -0
  178. package/src/cli/commands/doctor.ts +367 -0
  179. package/src/cli/commands/index.ts +9 -0
  180. package/src/cli/commands/mcp-install.ts +291 -0
  181. package/src/cli/commands/restore.ts +333 -0
  182. package/src/cli/commands/setup.ts +276 -0
  183. package/src/cli/commands/uninstall.ts +240 -0
  184. package/src/cli/index.ts +116 -0
  185. package/src/discovery.ts +328 -3
  186. package/src/enterprise/env.ts +156 -0
  187. package/src/enterprise/index.ts +7 -0
  188. package/src/enterprise/script-generator.ts +481 -0
  189. package/src/execute.ts +256 -0
  190. package/src/index.ts +85 -7
  191. package/src/stripe.ts +1 -1
  192. package/src/types.ts +32 -0
  193. package/src/ui/colors.ts +219 -0
  194. package/src/ui/errors.ts +394 -0
  195. package/src/ui/index.ts +17 -0
  196. package/src/ui/prompts.ts +390 -0
  197. package/src/ui/spinner.ts +325 -0
  198. package/src/utils/backup.ts +224 -0
  199. package/src/utils/config.ts +315 -0
  200. package/src/utils/os.ts +124 -0
  201. package/src/utils/paths.ts +203 -0
  202. package/STATUS.md +0 -160
  203. package/landing/tsconfig.tsbuildinfo +0 -1
@@ -31,7 +31,7 @@ export function HeroTabs() {
31
31
 
32
32
  const configSnippetJson = selectedClient === "chatgpt" ? chatGptInstructions : jsonConfig;
33
33
 
34
- const terminalCommand = "npx @nordsym/apiclaw";
34
+ const terminalCommand = "npx @nordsym/apiclaw mcp-install";
35
35
 
36
36
  const copyConfig = () => {
37
37
  navigator.clipboard.writeText(configSnippetJson);
@@ -126,7 +126,7 @@ export function HeroTabs() {
126
126
  <div className="code-preview-header">terminal</div>
127
127
  <div className="code-preview-body">
128
128
  <pre className="text-sm">
129
- <span className="text-green-400">$</span> <span className="text-blue-400">npx</span> @nordsym/apiclaw
129
+ <span className="text-green-400">$</span> <span className="text-blue-400">npx</span> @nordsym/apiclaw mcp-install
130
130
  </pre>
131
131
  </div>
132
132
  </div>
@@ -0,0 +1,423 @@
1
+ "use client";
2
+
3
+ import { useState, useEffect, useCallback } from "react";
4
+ import Image from "next/image";
5
+
6
+ interface WithMessage {
7
+ role: "user" | "assistant";
8
+ text: string;
9
+ meta?: string;
10
+ typing?: boolean;
11
+ image?: boolean;
12
+ currency?: boolean;
13
+ success?: boolean;
14
+ search?: boolean;
15
+ models?: { name: string; match: string }[];
16
+ results?: { name: string; match: string; cost: string }[];
17
+ }
18
+
19
+ interface WithoutMessage {
20
+ role: "step";
21
+ text: string;
22
+ }
23
+
24
+ type Message = WithMessage | WithoutMessage;
25
+
26
+ // Example 1: Direct Call - Replicate
27
+ const DirectCallExample: WithMessage[] = [
28
+ { role: "user", text: "Generate a product photo of a coffee mug" },
29
+ { role: "assistant", text: "Direct Call → Replicate", search: true },
30
+ {
31
+ role: "assistant",
32
+ text: "Selecting model...",
33
+ models: [
34
+ { name: "Flux Pro", match: "Best for products" },
35
+ { name: "SDXL", match: "Fast generation" },
36
+ { name: "Stable Diffusion 3", match: "Versatile" },
37
+ ]
38
+ },
39
+ { role: "assistant", text: "Using Flux Pro", meta: "via Replicate Direct Call" },
40
+ { role: "assistant", text: "Generating...", typing: true },
41
+ { role: "assistant", text: "Done", image: true, success: true },
42
+ ];
43
+
44
+ // Example 2: Open API - Currency
45
+ const OpenAPIExample: WithMessage[] = [
46
+ { role: "user", text: "What's the USD to SEK exchange rate?" },
47
+ { role: "assistant", text: "Open API → Frankfurter", search: true },
48
+ { role: "assistant", text: "No API key needed", meta: "Free, open access" },
49
+ { role: "assistant", text: "Fetching rate...", typing: true },
50
+ { role: "assistant", text: "Current rate", currency: true, success: true },
51
+ ];
52
+
53
+ // Example 3: Discovery - Search 22k APIs
54
+ const DiscoveryExample: WithMessage[] = [
55
+ { role: "user", text: "I need to transcribe meeting recordings" },
56
+ { role: "assistant", text: "Searching 22,000+ APIs...", search: true },
57
+ {
58
+ role: "assistant",
59
+ text: "Found 4 matches",
60
+ results: [
61
+ { name: "Deepgram", match: "96%", cost: "$0.0043/min" },
62
+ { name: "AssemblyAI", match: "94%", cost: "$0.0065/min" },
63
+ { name: "Rev.ai", match: "91%", cost: "$0.02/min" },
64
+ { name: "Google STT", match: "89%", cost: "$0.006/min" },
65
+ ]
66
+ },
67
+ { role: "assistant", text: "Deepgram recommended", meta: "Best accuracy + pricing", success: true },
68
+ ];
69
+
70
+ const WithoutAPIClaw: WithoutMessage[] = [
71
+ { role: "step", text: "Search for the right API" },
72
+ { role: "step", text: "Open 12 tabs, compare providers" },
73
+ { role: "step", text: "Read documentation for each" },
74
+ { role: "step", text: "Create account, verify email" },
75
+ { role: "step", text: "Set up billing, generate key" },
76
+ { role: "step", text: "Store key securely in .env" },
77
+ { role: "step", text: "Write API integration code" },
78
+ { role: "step", text: "Debug authentication errors" },
79
+ { role: "step", text: "Finally make first API call" },
80
+ ];
81
+
82
+ const examples = [
83
+ { id: "direct", label: "Direct Call", messages: DirectCallExample },
84
+ { id: "open", label: "Open API", messages: OpenAPIExample },
85
+ { id: "discovery", label: "Discovery", messages: DiscoveryExample },
86
+ ];
87
+
88
+ // OpenAI-style logo
89
+ function OpenAILogo({ className }: { className?: string }) {
90
+ return (
91
+ <svg className={className} viewBox="0 0 24 24" fill="currentColor">
92
+ <path d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855l-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023l-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135l-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08L8.704 5.46a.795.795 0 0 0-.393.681zm1.097-2.365l2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5z" />
93
+ </svg>
94
+ );
95
+ }
96
+
97
+ export function PhoneDemo() {
98
+ const [withClaw, setWithClaw] = useState(true);
99
+ const [exampleIndex, setExampleIndex] = useState(0);
100
+ const [visibleMessages, setVisibleMessages] = useState(0);
101
+ const [isPaused, setIsPaused] = useState(false);
102
+ const [completedSteps, setCompletedSteps] = useState<number[]>([]);
103
+
104
+ const currentExample = examples[exampleIndex];
105
+ const messages: Message[] = withClaw ? currentExample.messages : WithoutAPIClaw;
106
+
107
+ // Reset when switching modes or examples
108
+ useEffect(() => {
109
+ setVisibleMessages(0);
110
+ setCompletedSteps([]);
111
+ }, [exampleIndex, withClaw]);
112
+
113
+ // Animate messages appearing
114
+ useEffect(() => {
115
+ if (visibleMessages >= messages.length) return;
116
+
117
+ const delay = withClaw ? 800 : 700;
118
+ const timer = setTimeout(() => {
119
+ setVisibleMessages(v => v + 1);
120
+ // For "Without" mode, mark previous step as completed after a delay
121
+ if (!withClaw && visibleMessages > 0) {
122
+ setTimeout(() => {
123
+ setCompletedSteps(prev => [...prev, visibleMessages - 1]);
124
+ }, 300);
125
+ }
126
+ }, delay);
127
+
128
+ return () => clearTimeout(timer);
129
+ }, [visibleMessages, messages.length, withClaw]);
130
+
131
+ // Mark last step as completed when all visible
132
+ useEffect(() => {
133
+ if (!withClaw && visibleMessages === messages.length && visibleMessages > 0) {
134
+ const timer = setTimeout(() => {
135
+ setCompletedSteps(prev => [...prev, visibleMessages - 1]);
136
+ }, 500);
137
+ return () => clearTimeout(timer);
138
+ }
139
+ }, [visibleMessages, messages.length, withClaw]);
140
+
141
+ // Auto-rotate examples (only when withClaw is true)
142
+ useEffect(() => {
143
+ if (!withClaw || isPaused) return;
144
+ if (visibleMessages < messages.length) return;
145
+
146
+ const timer = setTimeout(() => {
147
+ setExampleIndex((i) => (i + 1) % examples.length);
148
+ }, 3500);
149
+
150
+ return () => clearTimeout(timer);
151
+ }, [visibleMessages, messages.length, withClaw, isPaused]);
152
+
153
+ const handleDotClick = useCallback((index: number) => {
154
+ setExampleIndex(index);
155
+ setIsPaused(true);
156
+ setTimeout(() => setIsPaused(false), 15000);
157
+ }, []);
158
+
159
+ return (
160
+ <div className="w-full max-w-sm mx-auto">
161
+ {/* Toggle */}
162
+ <div className="flex items-center justify-center gap-3 mb-6">
163
+ <button
164
+ onClick={() => setWithClaw(true)}
165
+ className={`px-5 py-2.5 rounded-full font-medium text-sm transition-all duration-200 ${
166
+ withClaw
167
+ ? "bg-zinc-900 text-white shadow-lg"
168
+ : "bg-zinc-100 text-zinc-600 hover:bg-zinc-200"
169
+ }`}
170
+ >
171
+ With APIClaw
172
+ </button>
173
+ <button
174
+ onClick={() => setWithClaw(false)}
175
+ className={`px-5 py-2.5 rounded-full font-medium text-sm transition-all duration-200 ${
176
+ !withClaw
177
+ ? "bg-zinc-900 text-white shadow-lg"
178
+ : "bg-zinc-100 text-zinc-600 hover:bg-zinc-200"
179
+ }`}
180
+ >
181
+ Without
182
+ </button>
183
+ </div>
184
+
185
+ {/* Example indicator (only show when withClaw) */}
186
+ {withClaw && (
187
+ <div className="flex items-center justify-center gap-2 mb-4">
188
+ {examples.map((ex, i) => (
189
+ <button
190
+ key={ex.id}
191
+ onClick={() => handleDotClick(i)}
192
+ className={`px-3 py-1.5 rounded-full text-xs font-medium transition-all duration-200 ${
193
+ i === exampleIndex
194
+ ? "bg-zinc-900 text-white"
195
+ : "bg-zinc-100 text-zinc-500 hover:bg-zinc-200"
196
+ }`}
197
+ >
198
+ {ex.label}
199
+ </button>
200
+ ))}
201
+ </div>
202
+ )}
203
+
204
+ {/* ChatGPT-style Phone Frame */}
205
+ <div className="relative mx-auto" style={{ maxWidth: "340px" }}>
206
+ <div className="relative bg-zinc-900 rounded-[2.5rem] p-2 shadow-2xl">
207
+ <div className="bg-white rounded-[2.2rem] overflow-hidden min-h-[480px] flex flex-col">
208
+ {/* Status bar */}
209
+ <div className="flex items-center justify-between px-6 py-2 text-xs text-zinc-900 font-medium">
210
+ <span>9:41</span>
211
+ <div className="flex items-center gap-1">
212
+ <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9-4.03-9-9-9zm0 16c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7z"/></svg>
213
+ <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M17 4h-3V2h-4v2H7v18h10V4zm-2 16H9V6h6v14z"/></svg>
214
+ </div>
215
+ </div>
216
+
217
+ {/* App Header */}
218
+ <div className="flex items-center justify-between px-4 py-3 border-b border-zinc-100">
219
+ <div className="flex items-center gap-3">
220
+ {withClaw ? (
221
+ <div className="w-8 h-8 rounded-full bg-zinc-900 flex items-center justify-center">
222
+ <OpenAILogo className="w-5 h-5 text-white" />
223
+ </div>
224
+ ) : (
225
+ <div className="w-8 h-8 rounded-full bg-orange-500 flex items-center justify-center">
226
+ <svg className="w-5 h-5 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
227
+ <path strokeLinecap="round" strokeLinejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
228
+ </svg>
229
+ </div>
230
+ )}
231
+ <div>
232
+ <div className="text-zinc-900 font-semibold text-sm">
233
+ {withClaw ? "Agent + APIClaw" : "Manual Workflow"}
234
+ </div>
235
+ </div>
236
+ </div>
237
+ </div>
238
+
239
+ {/* Messages area */}
240
+ <div className="flex-1 overflow-y-auto px-4 py-4 space-y-3 bg-white">
241
+ {messages.slice(0, visibleMessages).map((msg, i) => (
242
+ <div
243
+ key={`${withClaw}-${exampleIndex}-${i}`}
244
+ className="transition-all duration-500 ease-out"
245
+ style={{
246
+ opacity: 1,
247
+ transform: 'translateY(0)',
248
+ animation: 'slideUp 0.4s ease-out'
249
+ }}
250
+ >
251
+ {msg.role === "user" ? (
252
+ <div className="flex justify-end">
253
+ <div className="bg-zinc-100 text-zinc-900 px-4 py-2.5 rounded-2xl rounded-br-md max-w-[85%] text-sm">
254
+ {msg.text}
255
+ </div>
256
+ </div>
257
+ ) : msg.role === "step" ? (
258
+ <div className="flex items-center gap-3 transition-all duration-300">
259
+ <div className={`w-6 h-6 rounded-full flex items-center justify-center text-xs font-medium flex-shrink-0 transition-all duration-300 ${
260
+ completedSteps.includes(i)
261
+ ? "bg-green-500 text-white scale-100"
262
+ : "bg-zinc-100 text-zinc-500"
263
+ }`}>
264
+ {completedSteps.includes(i) ? (
265
+ <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
266
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
267
+ </svg>
268
+ ) : (
269
+ i + 1
270
+ )}
271
+ </div>
272
+ <span className={`text-sm transition-all duration-300 ${
273
+ completedSteps.includes(i) ? "text-zinc-400" : "text-zinc-700"
274
+ }`}>
275
+ {msg.text}
276
+ </span>
277
+ {!completedSteps.includes(i) && i === visibleMessages - 1 && (
278
+ <div className="flex gap-0.5 ml-1">
279
+ <span className="w-1 h-1 bg-zinc-400 rounded-full animate-pulse" />
280
+ <span className="w-1 h-1 bg-zinc-400 rounded-full animate-pulse" style={{ animationDelay: "0.15s" }} />
281
+ <span className="w-1 h-1 bg-zinc-400 rounded-full animate-pulse" style={{ animationDelay: "0.3s" }} />
282
+ </div>
283
+ )}
284
+ </div>
285
+ ) : (
286
+ <div className="flex gap-3">
287
+ <div className="w-7 h-7 rounded-full bg-zinc-900 flex items-center justify-center flex-shrink-0">
288
+ <OpenAILogo className="w-4 h-4 text-white" />
289
+ </div>
290
+
291
+ <div className="flex-1 min-w-0">
292
+ {msg.search && (
293
+ <div className="flex items-center gap-2 text-zinc-700 text-sm py-1 font-medium">
294
+ <svg className="w-4 h-4 text-zinc-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
295
+ <path strokeLinecap="round" strokeLinejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z" />
296
+ </svg>
297
+ {msg.text}
298
+ </div>
299
+ )}
300
+ {msg.models && (
301
+ <div className="space-y-2">
302
+ <div className="text-zinc-900 text-sm font-medium">{msg.text}</div>
303
+ <div className="space-y-1.5">
304
+ {msg.models.map((m, j) => (
305
+ <div key={j} className={`flex items-center justify-between text-xs px-3 py-2 rounded-lg transition-all duration-200 ${
306
+ j === 0 ? "bg-zinc-900 text-white" : "bg-zinc-50 text-zinc-600"
307
+ }`}>
308
+ <span className={j === 0 ? "font-medium" : ""}>{m.name}</span>
309
+ <span className={j === 0 ? "text-zinc-300" : "text-zinc-400"}>{m.match}</span>
310
+ </div>
311
+ ))}
312
+ </div>
313
+ </div>
314
+ )}
315
+ {msg.results && (
316
+ <div className="space-y-2">
317
+ <div className="text-zinc-900 text-sm font-medium">{msg.text}</div>
318
+ <div className="space-y-1.5">
319
+ {msg.results.map((r, j) => (
320
+ <div key={j} className={`flex items-center justify-between text-xs px-3 py-2 rounded-lg transition-all duration-200 ${
321
+ j === 0 ? "bg-zinc-900 text-white" : "bg-zinc-50 text-zinc-600"
322
+ }`}>
323
+ <span className={j === 0 ? "font-medium" : ""}>{r.name}</span>
324
+ <div className="flex items-center gap-2">
325
+ <span className={j === 0 ? "text-zinc-300" : "text-zinc-400"}>{r.match}</span>
326
+ <span className={j === 0 ? "text-zinc-500" : "text-zinc-300"}>·</span>
327
+ <span className={j === 0 ? "text-zinc-300" : "text-zinc-400"}>{r.cost}</span>
328
+ </div>
329
+ </div>
330
+ ))}
331
+ </div>
332
+ </div>
333
+ )}
334
+ {!msg.search && !msg.results && !msg.models && (
335
+ <div className="text-zinc-800 text-sm flex items-center gap-2 py-1">
336
+ {msg.success && (
337
+ <svg className="w-4 h-4 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
338
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
339
+ </svg>
340
+ )}
341
+ {msg.typing && (
342
+ <span className="flex gap-1">
343
+ <span className="w-1.5 h-1.5 bg-zinc-400 rounded-full animate-bounce" />
344
+ <span className="w-1.5 h-1.5 bg-zinc-400 rounded-full animate-bounce" style={{ animationDelay: "0.15s" }} />
345
+ <span className="w-1.5 h-1.5 bg-zinc-400 rounded-full animate-bounce" style={{ animationDelay: "0.3s" }} />
346
+ </span>
347
+ )}
348
+ {msg.text}
349
+ </div>
350
+ )}
351
+ {msg.meta && (
352
+ <div className="text-zinc-400 text-xs mt-0.5">{msg.meta}</div>
353
+ )}
354
+ {msg.image && (
355
+ <div className="mt-2 w-44 aspect-square rounded-xl overflow-hidden shadow-md">
356
+ <Image
357
+ src="/demo-product.jpg"
358
+ alt="Generated product image"
359
+ width={176}
360
+ height={176}
361
+ className="w-full h-full object-cover"
362
+ />
363
+ </div>
364
+ )}
365
+ {msg.currency && (
366
+ <div className="mt-2 bg-zinc-50 border border-zinc-200 rounded-xl p-3 inline-block">
367
+ <div className="flex items-center gap-3">
368
+ <div className="text-2xl font-bold text-zinc-900">10.82</div>
369
+ <div className="text-sm text-zinc-500">
370
+ <div className="font-medium">USD → SEK</div>
371
+ <div className="text-xs text-zinc-400">Live rate</div>
372
+ </div>
373
+ </div>
374
+ </div>
375
+ )}
376
+ </div>
377
+ </div>
378
+ )}
379
+ </div>
380
+ ))}
381
+ </div>
382
+
383
+ {/* Input area */}
384
+ <div className="p-3 border-t border-zinc-100">
385
+ <div className="flex items-center gap-2 bg-zinc-50 border border-zinc-200 rounded-2xl px-4 py-3">
386
+ <input
387
+ type="text"
388
+ placeholder="Message..."
389
+ className="flex-1 bg-transparent text-sm text-zinc-900 placeholder-zinc-400 outline-none"
390
+ readOnly
391
+ />
392
+ <button className="w-7 h-7 bg-zinc-900 rounded-full flex items-center justify-center">
393
+ <svg className="w-3.5 h-3.5 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
394
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5 10l7-7m0 0l7 7m-7-7v18" />
395
+ </svg>
396
+ </button>
397
+ </div>
398
+ </div>
399
+
400
+ {/* Home indicator */}
401
+ <div className="flex justify-center pb-2">
402
+ <div className="w-32 h-1 bg-zinc-900 rounded-full" />
403
+ </div>
404
+ </div>
405
+ </div>
406
+ </div>
407
+
408
+ {/* CSS for animations */}
409
+ <style jsx>{`
410
+ @keyframes slideUp {
411
+ from {
412
+ opacity: 0;
413
+ transform: translateY(10px);
414
+ }
415
+ to {
416
+ opacity: 1;
417
+ transform: translateY(0);
418
+ }
419
+ }
420
+ `}</style>
421
+ </div>
422
+ );
423
+ }
@@ -0,0 +1 @@
1
+ export { PhoneDemo } from './PhoneDemo';
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "apiCount": 22392,
3
+ "openApiCount": 1636,
4
+ "directCallCount": 18,
3
5
  "categoryCount": 13,
4
6
  "lastUpdated": "2026-02-27T09:10:41.344767",
5
- "generatedAt": "2026-02-28T16:05:37.143Z",
7
+ "generatedAt": "2026-03-01T16:05:56.209Z",
6
8
  "categoryBreakdown": {
7
9
  "Finance": 1179,
8
10
  "Auth & Security": 491,
@@ -28,8 +28,18 @@ const config: Config = {
28
28
  'tighter': '-0.03em',
29
29
  'widest': '0.15em',
30
30
  },
31
+ animation: {
32
+ 'fade-in': 'fadeIn 0.3s ease-out forwards',
33
+ },
34
+ keyframes: {
35
+ fadeIn: {
36
+ '0%': { opacity: '0', transform: 'translateY(8px)' },
37
+ '100%': { opacity: '1', transform: 'translateY(0)' },
38
+ },
39
+ },
31
40
  },
32
41
  },
33
42
  plugins: [],
34
43
  };
44
+
35
45
  export default config;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nordsym/apiclaw",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "description": "Agent-native API discovery and Direct Call execution via MCP",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,17 +28,24 @@
28
28
  "@hono/node-server": "^1.19.9",
29
29
  "@modelcontextprotocol/sdk": "^1.0.0",
30
30
  "@supabase/supabase-js": "^2.39.0",
31
+ "@types/inquirer": "^9.0.9",
32
+ "chalk": "^5.6.2",
33
+ "commander": "^14.0.3",
31
34
  "convex": "^1.32.0",
32
35
  "dotenv": "^17.3.1",
36
+ "fs-extra": "^11.3.3",
33
37
  "hono": "^4.0.0",
38
+ "inquirer": "^13.3.0",
39
+ "ora": "^9.3.0",
34
40
  "stripe": "^20.3.1"
35
41
  },
36
42
  "devDependencies": {
43
+ "@types/fs-extra": "^11.0.4",
37
44
  "@types/node": "^20.10.0",
38
45
  "tsx": "^4.7.0",
39
46
  "typescript": "^5.3.0"
40
47
  },
41
48
  "bin": {
42
- "apiclaw": "./dist/index.js"
49
+ "apiclaw": "./dist/bin.js"
43
50
  }
44
51
  }