@nordsym/apiclaw 1.7.7 → 1.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/capability-router.ts +1 -1
- package/src/cli.ts +1 -1
- package/src/hivr-whitelist.ts +1 -1
- package/src/index.ts +46 -14
- package/src/product-whitelist.ts +1 -1
- package/src/proxy.ts +1 -1
- package/src/telemetry.ts +1 -1
package/package.json
CHANGED
package/src/capability-router.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { executeAPICall } from './execute.js';
|
|
|
7
7
|
import { logAPICall } from './mcp-analytics.js';
|
|
8
8
|
|
|
9
9
|
// Convex HTTP API for capability queries
|
|
10
|
-
const CONVEX_URL = process.env.NEXT_PUBLIC_CONVEX_URL || 'https://
|
|
10
|
+
const CONVEX_URL = process.env.NEXT_PUBLIC_CONVEX_URL || 'https://brilliant-puffin-712.eu-west-1.convex.cloud';
|
|
11
11
|
|
|
12
12
|
interface ProviderMapping {
|
|
13
13
|
providerId: string;
|
package/src/cli.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { discoverAPIs, getAPIDetails, getCategories } from './discovery.js';
|
|
|
10
10
|
import { executeAPICall, getConnectedProviders } from './execute.js';
|
|
11
11
|
import { readSession, writeSession, clearSession, getMachineFingerprint } from './session.js';
|
|
12
12
|
|
|
13
|
-
const CONVEX_URL = process.env.CONVEX_URL || 'https://
|
|
13
|
+
const CONVEX_URL = process.env.CONVEX_URL || 'https://brilliant-puffin-712.eu-west-1.convex.cloud';
|
|
14
14
|
const convex = new ConvexHttpClient(CONVEX_URL);
|
|
15
15
|
|
|
16
16
|
// Colors for terminal
|
package/src/hivr-whitelist.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// Hivr PROD Convex deployment
|
|
8
|
-
const HIVR_CONVEX_URL = "https://
|
|
8
|
+
const HIVR_CONVEX_URL = "https://brilliant-puffin-712.eu-west-1.convex.cloud";
|
|
9
9
|
|
|
10
10
|
// Fallback static whitelist (in case Convex is down)
|
|
11
11
|
const STATIC_WHITELIST = [
|
package/src/index.ts
CHANGED
|
@@ -77,6 +77,7 @@ interface WorkspaceContext {
|
|
|
77
77
|
email: string;
|
|
78
78
|
tier: string;
|
|
79
79
|
usageRemaining: number;
|
|
80
|
+
usageCount: number;
|
|
80
81
|
status: string;
|
|
81
82
|
}
|
|
82
83
|
|
|
@@ -221,6 +222,7 @@ async function validateSession(): Promise<boolean> {
|
|
|
221
222
|
email: result.email ?? '',
|
|
222
223
|
tier: result.tier ?? 'free',
|
|
223
224
|
usageRemaining: result.usageRemaining ?? 0,
|
|
225
|
+
usageCount: result.usageCount ?? 0,
|
|
224
226
|
status: result.status ?? 'unknown',
|
|
225
227
|
};
|
|
226
228
|
|
|
@@ -274,6 +276,9 @@ interface RateLimitState {
|
|
|
274
276
|
|
|
275
277
|
const rateLimitStore = new Map<string, RateLimitState>();
|
|
276
278
|
|
|
279
|
+
// Unregistered (auto-provisioned, no email) users get this many calls before signup required
|
|
280
|
+
const UNREGISTERED_CALL_LIMIT = 5;
|
|
281
|
+
|
|
277
282
|
/**
|
|
278
283
|
* For proxy providers, allow anonymous usage with rate limiting
|
|
279
284
|
*/
|
|
@@ -308,12 +313,25 @@ function checkWorkspaceAccess(providerId?: string): { allowed: boolean; error?:
|
|
|
308
313
|
}
|
|
309
314
|
|
|
310
315
|
if (workspaceContext.status !== 'active') {
|
|
311
|
-
return {
|
|
312
|
-
allowed: false,
|
|
313
|
-
error: `Workspace status: ${workspaceContext.status}. Please verify your email.`
|
|
316
|
+
return {
|
|
317
|
+
allowed: false,
|
|
318
|
+
error: `Workspace status: ${workspaceContext.status}. Please verify your email.`
|
|
314
319
|
};
|
|
315
320
|
}
|
|
316
|
-
|
|
321
|
+
|
|
322
|
+
// Unregistered workspaces (auto-provisioned, no email) get limited calls then must register
|
|
323
|
+
if (!workspaceContext.email && workspaceContext.usageCount >= UNREGISTERED_CALL_LIMIT) {
|
|
324
|
+
return {
|
|
325
|
+
allowed: false,
|
|
326
|
+
error: JSON.stringify({
|
|
327
|
+
success: false,
|
|
328
|
+
error: `Register to continue. You've used ${UNREGISTERED_CALL_LIMIT} free calls.`,
|
|
329
|
+
hint: "Run register_owner with your email to unlock 50 calls/week.",
|
|
330
|
+
action: "register_owner"
|
|
331
|
+
}, null, 2)
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
317
335
|
if (workspaceContext.usageRemaining === 0) {
|
|
318
336
|
// Free tier hit weekly limit
|
|
319
337
|
if (workspaceContext.tier === 'free') {
|
|
@@ -1532,6 +1550,7 @@ Docs: https://apiclaw.nordsym.com
|
|
|
1532
1550
|
}) as { success: boolean; remaining?: number };
|
|
1533
1551
|
if (usageResult.success) {
|
|
1534
1552
|
workspaceContext.usageRemaining = usageResult.remaining ?? -1;
|
|
1553
|
+
workspaceContext.usageCount = (workspaceContext.usageCount || 0) + 1;
|
|
1535
1554
|
}
|
|
1536
1555
|
|
|
1537
1556
|
// Track earn progress (first direct call + unique APIs)
|
|
@@ -1541,18 +1560,29 @@ Docs: https://apiclaw.nordsym.com
|
|
|
1541
1560
|
}
|
|
1542
1561
|
}
|
|
1543
1562
|
|
|
1563
|
+
// Build response with signup nudge for unregistered users
|
|
1564
|
+
const responseData: Record<string, unknown> = {
|
|
1565
|
+
status: result.success ? 'success' : 'error',
|
|
1566
|
+
provider: result.provider,
|
|
1567
|
+
action: result.action,
|
|
1568
|
+
type: apiType,
|
|
1569
|
+
...(result.success ? { data: result.data } : { error: result.error }),
|
|
1570
|
+
...(result.cost !== undefined ? { cost_sek: result.cost } : {})
|
|
1571
|
+
};
|
|
1572
|
+
|
|
1573
|
+
// Nudge unregistered users
|
|
1574
|
+
if (result.success && workspaceContext && !workspaceContext.email) {
|
|
1575
|
+
const remaining = UNREGISTERED_CALL_LIMIT - (workspaceContext.usageCount || 0);
|
|
1576
|
+
if (remaining > 0 && remaining <= 3) {
|
|
1577
|
+
responseData._notice = `${remaining} free calls remaining. Run register_owner to unlock 50/week.`;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1544
1581
|
return {
|
|
1545
1582
|
content: [
|
|
1546
1583
|
{
|
|
1547
1584
|
type: 'text',
|
|
1548
|
-
text: JSON.stringify(
|
|
1549
|
-
status: result.success ? 'success' : 'error',
|
|
1550
|
-
provider: result.provider,
|
|
1551
|
-
action: result.action,
|
|
1552
|
-
type: apiType,
|
|
1553
|
-
...(result.success ? { data: result.data } : { error: result.error }),
|
|
1554
|
-
...(result.cost !== undefined ? { cost_sek: result.cost } : {})
|
|
1555
|
-
}, null, 2)
|
|
1585
|
+
text: JSON.stringify(responseData, null, 2)
|
|
1556
1586
|
}
|
|
1557
1587
|
],
|
|
1558
1588
|
isError: !result.success
|
|
@@ -1729,6 +1759,7 @@ Docs: https://apiclaw.nordsym.com
|
|
|
1729
1759
|
email,
|
|
1730
1760
|
tier: existing.tier,
|
|
1731
1761
|
usageRemaining: existing.usageLimit - existing.usageCount,
|
|
1762
|
+
usageCount: existing.usageCount,
|
|
1732
1763
|
status: existing.status,
|
|
1733
1764
|
};
|
|
1734
1765
|
|
|
@@ -1770,7 +1801,7 @@ Docs: https://apiclaw.nordsym.com
|
|
|
1770
1801
|
}) as { token: string; expiresAt: number };
|
|
1771
1802
|
|
|
1772
1803
|
// Send magic link via email
|
|
1773
|
-
const verifyUrl = `https://apiclaw.nordsym.com/verify?token=${magicLinkResult.token}`;
|
|
1804
|
+
const verifyUrl = `https://apiclaw.nordsym.com/auth/verify?token=${magicLinkResult.token}`;
|
|
1774
1805
|
|
|
1775
1806
|
const emailResponse = await fetch('https://api.resend.com/emails', {
|
|
1776
1807
|
method: 'POST',
|
|
@@ -1860,6 +1891,7 @@ Docs: https://apiclaw.nordsym.com
|
|
|
1860
1891
|
email: result.email ?? '',
|
|
1861
1892
|
tier: result.tier ?? 'free',
|
|
1862
1893
|
usageRemaining: result.usageRemaining ?? 0,
|
|
1894
|
+
usageCount: result.usageCount ?? 0,
|
|
1863
1895
|
status: result.status ?? 'unknown',
|
|
1864
1896
|
};
|
|
1865
1897
|
|
|
@@ -1940,7 +1972,7 @@ Docs: https://apiclaw.nordsym.com
|
|
|
1940
1972
|
}) as { token: string; expiresAt: number };
|
|
1941
1973
|
|
|
1942
1974
|
// TODO: Agent 2 will implement actual email sending
|
|
1943
|
-
const verifyUrl = `https://apiclaw.nordsym.com/verify?token=${magicLinkResult.token}`;
|
|
1975
|
+
const verifyUrl = `https://apiclaw.nordsym.com/auth/verify?token=${magicLinkResult.token}`;
|
|
1944
1976
|
|
|
1945
1977
|
return {
|
|
1946
1978
|
content: [{
|
package/src/product-whitelist.ts
CHANGED
|
@@ -18,7 +18,7 @@ interface ProductSource {
|
|
|
18
18
|
const PRODUCT_SOURCES: ProductSource[] = [
|
|
19
19
|
{
|
|
20
20
|
name: 'hivr',
|
|
21
|
-
convexUrl: 'https://
|
|
21
|
+
convexUrl: 'https://brilliant-puffin-712.eu-west-1.convex.cloud',
|
|
22
22
|
queryPath: 'agents:list',
|
|
23
23
|
agentIdField: 'handle', // ✅ Fixed: Hivr agents use 'handle', not 'agentId'
|
|
24
24
|
},
|
package/src/proxy.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { readSession, getMachineFingerprint } from './session.js';
|
|
6
6
|
|
|
7
|
-
const PROXY_BASE = "https://
|
|
7
|
+
const PROXY_BASE = "https://brilliant-puffin-712.eu-west-1.convex.site/proxy";
|
|
8
8
|
|
|
9
9
|
export async function callProxy(provider: string, params: any): Promise<any> {
|
|
10
10
|
const url = `${PROXY_BASE}/${provider}`;
|
package/src/telemetry.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Disable with APICLAW_TELEMETRY=false
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const TELEMETRY_ENDPOINT = 'https://
|
|
13
|
+
const TELEMETRY_ENDPOINT = 'https://brilliant-puffin-712.eu-west-1.convex.cloud/api/mutation';
|
|
14
14
|
|
|
15
15
|
interface TelemetryEvent {
|
|
16
16
|
type: 'startup' | 'search' | 'execute' | 'discovery';
|