@nordsym/apiclaw 2.1.0 → 2.2.1
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/README.md +15 -2
- package/dist/bin-http.js +0 -0
- package/dist/bin.bundled.js +79288 -0
- package/dist/funnel-client.d.ts +24 -0
- package/dist/funnel-client.d.ts.map +1 -0
- package/dist/funnel-client.js +131 -0
- package/dist/funnel-client.js.map +1 -0
- package/dist/funnel.test.d.ts +2 -0
- package/dist/funnel.test.d.ts.map +1 -0
- package/dist/funnel.test.js +145 -0
- package/dist/funnel.test.js.map +1 -0
- package/dist/gateway-client.d.ts.map +1 -1
- package/dist/gateway-client.js +24 -2
- package/dist/gateway-client.js.map +1 -1
- package/dist/index.bundled.js +61263 -0
- package/dist/index.js +161 -74
- package/dist/index.js.map +1 -1
- package/dist/postinstall.d.ts +0 -5
- package/dist/postinstall.d.ts.map +1 -1
- package/dist/postinstall.js +24 -3
- package/dist/postinstall.js.map +1 -1
- package/dist/registration-guard.d.ts +29 -0
- package/dist/registration-guard.d.ts.map +1 -0
- package/dist/registration-guard.js +87 -0
- package/dist/registration-guard.js.map +1 -0
- package/package.json +7 -2
- package/.claude/settings.local.json +0 -9
- package/.env.prod +0 -1
- package/apiclaw-README.md +0 -494
- package/convex/_generated/api.d.ts +0 -137
- package/convex/_generated/api.js +0 -23
- package/convex/_generated/dataModel.d.ts +0 -60
- package/convex/_generated/server.d.ts +0 -143
- package/convex/_generated/server.js +0 -93
- package/convex/adminActivate.ts +0 -53
- package/convex/adminStats.ts +0 -306
- package/convex/agents.ts +0 -939
- package/convex/analytics.ts +0 -187
- package/convex/apiKeys.ts +0 -220
- package/convex/backfillAnalytics.ts +0 -272
- package/convex/backfillSearchLogs.ts +0 -35
- package/convex/billing.ts +0 -834
- package/convex/capabilities.ts +0 -157
- package/convex/chains.ts +0 -1318
- package/convex/credits.ts +0 -211
- package/convex/crons.ts +0 -50
- package/convex/debugFilestackLogs.ts +0 -16
- package/convex/debugGetToken.ts +0 -18
- package/convex/directCall.ts +0 -713
- package/convex/earnProgress.ts +0 -753
- package/convex/email.ts +0 -329
- package/convex/feedback.ts +0 -265
- package/convex/http.ts +0 -3430
- package/convex/inbound.ts +0 -32
- package/convex/logs.ts +0 -701
- package/convex/migrateFilestack.ts +0 -81
- package/convex/migratePartnersProd.ts +0 -174
- package/convex/migratePratham.ts +0 -126
- package/convex/migrateProviderWorkspaces.ts +0 -175
- package/convex/mou.ts +0 -91
- package/convex/providerKeys.ts +0 -289
- package/convex/providers.ts +0 -1135
- package/convex/purchases.ts +0 -183
- package/convex/ratelimit.ts +0 -104
- package/convex/schema.ts +0 -869
- package/convex/searchLogs.ts +0 -265
- package/convex/seedAPILayerAPIs.ts +0 -191
- package/convex/seedDirectCallConfigs.ts +0 -336
- package/convex/seedPratham.ts +0 -149
- package/convex/spendAlerts.ts +0 -442
- package/convex/stripeActions.ts +0 -607
- package/convex/teams.ts +0 -243
- package/convex/telemetry.ts +0 -81
- package/convex/tsconfig.json +0 -25
- package/convex/updateAPIStatus.ts +0 -44
- package/convex/usage.ts +0 -260
- package/convex/usageReports.ts +0 -357
- package/convex/waitlist.ts +0 -55
- package/convex/webhooks.ts +0 -494
- package/convex/workspaceSettings.ts +0 -143
- package/convex/workspaces.ts +0 -1331
- package/convex.json +0 -3
- package/direct-test.mjs +0 -51
- package/email-templates/filestack-provider-outreach.html +0 -162
- package/email-templates/partnership-template.html +0 -116
- package/email-templates/pratham-draft-preview.txt +0 -57
- package/email-templates/pratham-partnership-draft.html +0 -141
- package/reports/APIClaw-Session-Report-2026-04-05.pdf +0 -0
- package/reports/pipeline/PIPELINE-REPORT.json +0 -153
- package/reports/pipeline/acquire_apisguru.json +0 -17
- package/reports/pipeline/capabilities.json +0 -38
- package/reports/pipeline/discover_azure_recursive.json +0 -1551
- package/reports/pipeline/discover_github.json +0 -25
- package/reports/pipeline/discover_github_repos.json +0 -49
- package/reports/pipeline/discover_swaggerhub.json +0 -24
- package/reports/pipeline/discover_well_known.json +0 -23
- package/reports/pipeline/fetch_specs.json +0 -19
- package/reports/pipeline/generate_providers.json +0 -14
- package/reports/pipeline/match_registry.json +0 -11
- package/reports/pipeline/parse_specs.json +0 -17
- package/reports/pipeline/promote_candidates.json +0 -34
- package/reports/pipeline/validate.json +0 -30
- package/reports/pipeline/validate_smoke_details.json +0 -3835
- package/reports/session-report-2026-04-05.html +0 -433
- package/seed-apis-direct.mjs +0 -106
- package/src/access-control.ts +0 -174
- package/src/adapters/base.ts +0 -364
- package/src/adapters/claude-desktop.ts +0 -41
- package/src/adapters/cline.ts +0 -88
- package/src/adapters/continue.ts +0 -91
- package/src/adapters/cursor.ts +0 -43
- package/src/adapters/custom.ts +0 -188
- package/src/adapters/detect.ts +0 -202
- package/src/adapters/index.ts +0 -47
- package/src/adapters/windsurf.ts +0 -44
- package/src/bin-http.ts +0 -45
- package/src/bin.ts +0 -34
- package/src/capability-router.ts +0 -331
- package/src/chainExecutor.ts +0 -730
- package/src/chainResolver.test.ts +0 -246
- package/src/chainResolver.ts +0 -658
- package/src/cli/commands/demo.ts +0 -109
- package/src/cli/commands/doctor.ts +0 -435
- package/src/cli/commands/index.ts +0 -9
- package/src/cli/commands/login.ts +0 -203
- package/src/cli/commands/mcp-install.ts +0 -373
- package/src/cli/commands/restore.ts +0 -333
- package/src/cli/commands/setup.ts +0 -297
- package/src/cli/commands/uninstall.ts +0 -240
- package/src/cli/index.ts +0 -148
- package/src/cli.ts +0 -370
- package/src/confirmation.ts +0 -296
- package/src/credentials.ts +0 -455
- package/src/credits.ts +0 -329
- package/src/crypto.ts +0 -75
- package/src/discovery.ts +0 -568
- package/src/enterprise/env.ts +0 -156
- package/src/enterprise/index.ts +0 -7
- package/src/enterprise/script-generator.ts +0 -481
- package/src/execute-dynamic.ts +0 -617
- package/src/execute.ts +0 -2386
- package/src/gateway-client.ts +0 -192
- package/src/hivr-whitelist.ts +0 -110
- package/src/http-api.ts +0 -286
- package/src/http-server-minimal.ts +0 -154
- package/src/index.ts +0 -2611
- package/src/intelligent-gateway.ts +0 -339
- package/src/mcp-analytics.ts +0 -156
- package/src/metered.ts +0 -149
- package/src/open-apis-generated.ts +0 -157
- package/src/open-apis.ts +0 -558
- package/src/postinstall.ts +0 -18
- package/src/product-whitelist.ts +0 -246
- package/src/proxy.ts +0 -36
- package/src/session.ts +0 -129
- package/src/stripe.ts +0 -497
- package/src/telemetry.ts +0 -71
- package/src/test.ts +0 -135
- package/src/types/convex-api.d.ts +0 -20
- package/src/types/convex-api.ts +0 -21
- package/src/types.ts +0 -109
- package/src/ui/colors.ts +0 -219
- package/src/ui/errors.ts +0 -394
- package/src/ui/index.ts +0 -17
- package/src/ui/prompts.ts +0 -390
- package/src/ui/spinner.ts +0 -325
- package/src/utils/backup.ts +0 -224
- package/src/utils/config.ts +0 -318
- package/src/utils/os.ts +0 -124
- package/src/utils/paths.ts +0 -203
- package/src/webhook.ts +0 -107
- package/test-10-working.cjs +0 -97
- package/test-14-final.cjs +0 -96
- package/test-actual-handlers.ts +0 -92
- package/test-apilayer-all-14.ts +0 -249
- package/test-apilayer-fixed.ts +0 -248
- package/test-direct-endpoints.ts +0 -174
- package/test-exact-endpoints.ts +0 -144
- package/test-final.ts +0 -83
- package/test-full-routing.ts +0 -100
- package/test-handlers-correct.ts +0 -217
- package/test-numverify-key.ts +0 -41
- package/test-via-handlers.ts +0 -92
- package/test-worldnews.mjs +0 -26
- package/tsconfig.json +0 -20
package/src/postinstall.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* APIClaw Postinstall Hook
|
|
4
|
-
* Prints a welcome message with links after install.
|
|
5
|
-
* No network calls. No side effects.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const CYAN = '\x1b[36m';
|
|
9
|
-
const RESET = '\x1b[0m';
|
|
10
|
-
const DIM = '\x1b[2m';
|
|
11
|
-
|
|
12
|
-
console.log('');
|
|
13
|
-
console.log(` 🦞 APIClaw installed successfully!`);
|
|
14
|
-
console.log('');
|
|
15
|
-
console.log(` → Sign in: ${CYAN}npx @nordsym/apiclaw login${RESET}`);
|
|
16
|
-
console.log(` → Full setup: ${CYAN}npx @nordsym/apiclaw setup${RESET} ${DIM}(auto-detects Claude, Cursor, Windsurf)${RESET}`);
|
|
17
|
-
console.log(` ⭐ Star us: ${CYAN}https://github.com/nordsym/apiclaw${RESET} ${DIM}(helps more devs find us)${RESET}`);
|
|
18
|
-
console.log('');
|
package/src/product-whitelist.ts
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Multi-Product Whitelist System
|
|
3
|
-
* Supports multiple products (Hivr, NordSym, partners) with namespaced agentIds
|
|
4
|
-
*
|
|
5
|
-
* Format: product:agentId
|
|
6
|
-
* Examples: hivr:bytebee, nordsym:mollebot, partner_x:agent1
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
interface ProductSource {
|
|
10
|
-
name: string;
|
|
11
|
-
convexUrl: string;
|
|
12
|
-
queryPath: string;
|
|
13
|
-
agentIdField: string;
|
|
14
|
-
authToken?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Product sources configuration
|
|
18
|
-
const PRODUCT_SOURCES: ProductSource[] = [
|
|
19
|
-
{
|
|
20
|
-
name: 'hivr',
|
|
21
|
-
convexUrl: 'https://brilliant-puffin-712.eu-west-1.convex.cloud',
|
|
22
|
-
queryPath: 'agents:list',
|
|
23
|
-
agentIdField: 'handle', // ✅ Fixed: Hivr agents use 'handle', not 'agentId'
|
|
24
|
-
},
|
|
25
|
-
// Add more products here as needed
|
|
26
|
-
// {
|
|
27
|
-
// name: 'nordsym',
|
|
28
|
-
// convexUrl: 'https://nordsym-deployment.convex.cloud',
|
|
29
|
-
// queryPath: 'team:listAgents',
|
|
30
|
-
// agentIdField: 'memberId',
|
|
31
|
-
// },
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
// Fallback static whitelist (emergency only)
|
|
35
|
-
const STATIC_WHITELIST = [
|
|
36
|
-
'hivr:bytebee',
|
|
37
|
-
'hivr:analyzerbee',
|
|
38
|
-
'hivr:buildbee',
|
|
39
|
-
'hivr:buzzwriter',
|
|
40
|
-
'hivr:hivemind',
|
|
41
|
-
'hivr:hivesage',
|
|
42
|
-
'hivr:symbot',
|
|
43
|
-
'hivr:hivrqueen',
|
|
44
|
-
'hivr:marketmaven',
|
|
45
|
-
'hivr:reconbee',
|
|
46
|
-
'hivr:sprintbee',
|
|
47
|
-
'hivr:quillbee',
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
// Cache per product (5 minutes TTL)
|
|
51
|
-
interface ProductCache {
|
|
52
|
-
agents: string[];
|
|
53
|
-
expiresAt: number;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const cache = new Map<string, ProductCache>();
|
|
57
|
-
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Fetch agents from a single product source
|
|
61
|
-
*/
|
|
62
|
-
async function fetchFromProduct(source: ProductSource): Promise<string[]> {
|
|
63
|
-
try {
|
|
64
|
-
const headers: Record<string, string> = {
|
|
65
|
-
'Content-Type': 'application/json',
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
if (source.authToken) {
|
|
69
|
-
headers['Authorization'] = `Bearer ${source.authToken}`;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const response = await fetch(`${source.convexUrl}/api/query`, {
|
|
73
|
-
method: 'POST',
|
|
74
|
-
headers,
|
|
75
|
-
body: JSON.stringify({
|
|
76
|
-
path: source.queryPath,
|
|
77
|
-
args: {},
|
|
78
|
-
}),
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
if (!response.ok) {
|
|
82
|
-
console.warn(`[Whitelist] ${source.name}: HTTP ${response.status}`);
|
|
83
|
-
return [];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const result = await response.json() as any;
|
|
87
|
-
|
|
88
|
-
// Convex HTTP API returns { status: "success", value: [...] }
|
|
89
|
-
const data = result.value || result;
|
|
90
|
-
|
|
91
|
-
if (!Array.isArray(data)) {
|
|
92
|
-
console.warn(`[Whitelist] ${source.name}: Invalid response format`, typeof data);
|
|
93
|
-
return [];
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Extract agentIds and add namespace
|
|
97
|
-
const agents = data
|
|
98
|
-
.map((item: any) => {
|
|
99
|
-
const agentId = item[source.agentIdField];
|
|
100
|
-
if (!agentId) return null;
|
|
101
|
-
return `${source.name}:${String(agentId).toLowerCase().trim()}`;
|
|
102
|
-
})
|
|
103
|
-
.filter((id): id is string => id !== null && id.length > 0);
|
|
104
|
-
|
|
105
|
-
console.log(`[Whitelist] ${source.name}: Fetched ${agents.length} agents`);
|
|
106
|
-
return agents;
|
|
107
|
-
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error(`[Whitelist] ${source.name}: Fetch failed`, error);
|
|
110
|
-
return [];
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Fetch and merge agents from all product sources
|
|
116
|
-
*/
|
|
117
|
-
async function fetchAllProducts(): Promise<string[]> {
|
|
118
|
-
const results = await Promise.allSettled(
|
|
119
|
-
PRODUCT_SOURCES.map(source => fetchFromProduct(source))
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
const allAgents: string[] = [];
|
|
123
|
-
|
|
124
|
-
for (const result of results) {
|
|
125
|
-
if (result.status === 'fulfilled') {
|
|
126
|
-
allAgents.push(...result.value);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// If no products returned data, use static fallback
|
|
131
|
-
if (allAgents.length === 0) {
|
|
132
|
-
console.warn('[Whitelist] All sources failed, using static fallback');
|
|
133
|
-
return STATIC_WHITELIST;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return allAgents;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Get current whitelist (cached or fresh)
|
|
141
|
-
*/
|
|
142
|
-
export async function getWhitelist(): Promise<string[]> {
|
|
143
|
-
const now = Date.now();
|
|
144
|
-
|
|
145
|
-
// Check if any cache entry is still valid
|
|
146
|
-
const validCaches: string[] = [];
|
|
147
|
-
for (const [product, cached] of cache.entries()) {
|
|
148
|
-
if (now < cached.expiresAt) {
|
|
149
|
-
validCaches.push(...cached.agents);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// If all caches valid, return merged
|
|
154
|
-
if (validCaches.length > 0 && cache.size === PRODUCT_SOURCES.length) {
|
|
155
|
-
return validCaches;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Fetch fresh data
|
|
159
|
-
const agents = await fetchAllProducts();
|
|
160
|
-
|
|
161
|
-
// Update cache per product
|
|
162
|
-
const agentsByProduct = new Map<string, string[]>();
|
|
163
|
-
for (const agent of agents) {
|
|
164
|
-
const [product] = agent.split(':');
|
|
165
|
-
if (!agentsByProduct.has(product)) {
|
|
166
|
-
agentsByProduct.set(product, []);
|
|
167
|
-
}
|
|
168
|
-
agentsByProduct.get(product)!.push(agent);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
for (const [product, productAgents] of agentsByProduct.entries()) {
|
|
172
|
-
cache.set(product, {
|
|
173
|
-
agents: productAgents,
|
|
174
|
-
expiresAt: now + CACHE_TTL,
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return agents;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Check if agentId is authorized
|
|
183
|
-
* Supports both namespaced (product:agent) and legacy (agent) formats
|
|
184
|
-
*/
|
|
185
|
-
export async function isAuthorized(agentId: string | undefined): Promise<boolean> {
|
|
186
|
-
if (!agentId) return false;
|
|
187
|
-
|
|
188
|
-
const normalized = agentId.toLowerCase().trim();
|
|
189
|
-
const whitelist = await getWhitelist();
|
|
190
|
-
|
|
191
|
-
// Check exact match (namespaced)
|
|
192
|
-
if (whitelist.includes(normalized)) {
|
|
193
|
-
return true;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Legacy support: check if agentId matches any product's agent (without namespace)
|
|
197
|
-
// e.g., "bytebee" matches "hivr:bytebee"
|
|
198
|
-
if (!normalized.includes(':')) {
|
|
199
|
-
const legacyMatch = whitelist.some(entry => {
|
|
200
|
-
const [, agent] = entry.split(':');
|
|
201
|
-
return agent === normalized;
|
|
202
|
-
});
|
|
203
|
-
if (legacyMatch) {
|
|
204
|
-
console.log(`[Whitelist] Legacy match for ${normalized}`);
|
|
205
|
-
return true;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Extract product name from agentId
|
|
214
|
-
*/
|
|
215
|
-
export function getProduct(agentId: string): string | null {
|
|
216
|
-
const [product] = agentId.split(':');
|
|
217
|
-
return product || null;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Force refresh whitelist (call after adding new agent)
|
|
222
|
-
*/
|
|
223
|
-
export function invalidateCache(product?: string): void {
|
|
224
|
-
if (product) {
|
|
225
|
-
cache.delete(product);
|
|
226
|
-
console.log(`[Whitelist] Cache invalidated for ${product}`);
|
|
227
|
-
} else {
|
|
228
|
-
cache.clear();
|
|
229
|
-
console.log('[Whitelist] All caches invalidated');
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Add new product source dynamically
|
|
235
|
-
*/
|
|
236
|
-
export function addProductSource(source: ProductSource): void {
|
|
237
|
-
const existing = PRODUCT_SOURCES.find(s => s.name === source.name);
|
|
238
|
-
if (existing) {
|
|
239
|
-
console.warn(`[Whitelist] Product ${source.name} already exists, updating`);
|
|
240
|
-
Object.assign(existing, source);
|
|
241
|
-
} else {
|
|
242
|
-
PRODUCT_SOURCES.push(source);
|
|
243
|
-
console.log(`[Whitelist] Added product source: ${source.name}`);
|
|
244
|
-
}
|
|
245
|
-
invalidateCache(source.name);
|
|
246
|
-
}
|
package/src/proxy.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* APIClaw Proxy - Fallback to hosted API when no local credentials
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { readSession, getMachineFingerprint } from './session.js';
|
|
6
|
-
|
|
7
|
-
const PROXY_BASE = "https://brilliant-puffin-712.eu-west-1.convex.site/proxy";
|
|
8
|
-
|
|
9
|
-
export async function callProxy(provider: string, params: any): Promise<any> {
|
|
10
|
-
const url = `${PROXY_BASE}/${provider}`;
|
|
11
|
-
|
|
12
|
-
// Get session and fingerprint for tracking
|
|
13
|
-
const session = readSession();
|
|
14
|
-
const fingerprint = getMachineFingerprint();
|
|
15
|
-
const identifier = session?.workspaceId || `anon:${fingerprint}`;
|
|
16
|
-
|
|
17
|
-
const response = await fetch(url, {
|
|
18
|
-
method: "POST",
|
|
19
|
-
headers: {
|
|
20
|
-
"Content-Type": "application/json",
|
|
21
|
-
"X-APIClaw-Identifier": identifier,
|
|
22
|
-
"X-APIClaw-Provider": provider,
|
|
23
|
-
"X-APIClaw-Action": params.action || "call",
|
|
24
|
-
},
|
|
25
|
-
body: JSON.stringify(params),
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
if (!response.ok) {
|
|
29
|
-
const errorData = await response.json().catch(() => ({ error: "Proxy request failed" })) as { error?: string };
|
|
30
|
-
throw new Error(errorData.error || `Proxy error: ${response.status}`);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return response.json();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const PROXY_PROVIDERS = ["openrouter", "brave_search", "resend", "elevenlabs", "46elks", "twilio", "replicate", "firecrawl", "e2b", "groq", "deepgram", "serper", "mistral", "cohere", "together", "stability", "assemblyai", "github", "apilayer"];
|
package/src/session.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session management for APIClaw MCP server
|
|
3
|
-
* Stores session token locally at ~/.apiclaw/session
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import * as fs from 'fs';
|
|
7
|
-
import * as path from 'path';
|
|
8
|
-
import * as os from 'os';
|
|
9
|
-
|
|
10
|
-
export interface SessionData {
|
|
11
|
-
sessionToken: string;
|
|
12
|
-
workspaceId: string;
|
|
13
|
-
email: string;
|
|
14
|
-
createdAt: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const SESSION_DIR = path.join(os.homedir(), '.apiclaw');
|
|
18
|
-
const SESSION_FILE = path.join(SESSION_DIR, 'session');
|
|
19
|
-
const SESSION_FILE_LEGACY = path.join(SESSION_DIR, 'session.json');
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Ensure the ~/.apiclaw directory exists
|
|
23
|
-
*/
|
|
24
|
-
function ensureSessionDir(): void {
|
|
25
|
-
if (!fs.existsSync(SESSION_DIR)) {
|
|
26
|
-
fs.mkdirSync(SESSION_DIR, { mode: 0o700 });
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Read session from ~/.apiclaw/session
|
|
32
|
-
* Returns null if no session file exists or if it's invalid
|
|
33
|
-
*/
|
|
34
|
-
export function readSession(): SessionData | null {
|
|
35
|
-
try {
|
|
36
|
-
// Try primary session file first
|
|
37
|
-
if (fs.existsSync(SESSION_FILE)) {
|
|
38
|
-
const content = fs.readFileSync(SESSION_FILE, 'utf8');
|
|
39
|
-
const data = JSON.parse(content) as SessionData;
|
|
40
|
-
if (data.sessionToken && data.workspaceId && data.email) {
|
|
41
|
-
return data;
|
|
42
|
-
}
|
|
43
|
-
// Invalid (e.g. empty email from anonymous write) — clear and fall through
|
|
44
|
-
console.error('[APIClaw] Invalid session file, checking legacy...');
|
|
45
|
-
fs.unlinkSync(SESSION_FILE);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Fall back to session.json (written by CLI login in older versions)
|
|
49
|
-
if (fs.existsSync(SESSION_FILE_LEGACY)) {
|
|
50
|
-
const content = fs.readFileSync(SESSION_FILE_LEGACY, 'utf8');
|
|
51
|
-
const data = JSON.parse(content) as SessionData;
|
|
52
|
-
if (data.sessionToken && data.workspaceId && data.email) {
|
|
53
|
-
console.error(`[APIClaw] Migrating session.json → session for ${data.email}`);
|
|
54
|
-
// Migrate to canonical location
|
|
55
|
-
fs.writeFileSync(SESSION_FILE, JSON.stringify({ ...data, createdAt: data.createdAt || Date.now() }, null, 2), { mode: 0o600 });
|
|
56
|
-
return data;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return null;
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.error('[APIClaw] Error reading session:', error);
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Write session to ~/.apiclaw/session
|
|
69
|
-
*/
|
|
70
|
-
export function writeSession(sessionToken: string, workspaceId: string, email: string): void {
|
|
71
|
-
try {
|
|
72
|
-
ensureSessionDir();
|
|
73
|
-
|
|
74
|
-
const data: SessionData = {
|
|
75
|
-
sessionToken,
|
|
76
|
-
workspaceId,
|
|
77
|
-
email,
|
|
78
|
-
createdAt: Date.now(),
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
fs.writeFileSync(SESSION_FILE, JSON.stringify(data, null, 2), {
|
|
82
|
-
mode: 0o600, // Read/write for owner only
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
console.error(`[APIClaw] Session saved for ${email}`);
|
|
86
|
-
} catch (error) {
|
|
87
|
-
console.error('[APIClaw] Error writing session:', error);
|
|
88
|
-
throw error;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Clear session file
|
|
94
|
-
*/
|
|
95
|
-
export function clearSession(): void {
|
|
96
|
-
try {
|
|
97
|
-
if (fs.existsSync(SESSION_FILE)) {
|
|
98
|
-
fs.unlinkSync(SESSION_FILE);
|
|
99
|
-
console.error('[APIClaw] Session cleared');
|
|
100
|
-
}
|
|
101
|
-
} catch (error) {
|
|
102
|
-
console.error('[APIClaw] Error clearing session:', error);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get machine fingerprint (for session binding)
|
|
108
|
-
* Uses hostname + username as a simple fingerprint
|
|
109
|
-
*/
|
|
110
|
-
export function getMachineFingerprint(): string {
|
|
111
|
-
const hostname = os.hostname();
|
|
112
|
-
const username = os.userInfo().username;
|
|
113
|
-
return `${hostname}:${username}`;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Detect which MCP client is running the server
|
|
118
|
-
* Priority: explicit env (set by mcp-install) → known env hints → fallback
|
|
119
|
-
*/
|
|
120
|
-
export function detectMCPClient(): string {
|
|
121
|
-
// 1. Explicit env (injected by mcp-install adapters)
|
|
122
|
-
if (process.env.APICLAW_MCP_CLIENT) return process.env.APICLAW_MCP_CLIENT;
|
|
123
|
-
// 2. Known environment variable hints
|
|
124
|
-
if (process.env.CURSOR_TRACE_DIR) return 'cursor';
|
|
125
|
-
if (process.env.CLAUDE_CODE) return 'claude-code';
|
|
126
|
-
if (process.env.WINDSURF_SESSION) return 'windsurf';
|
|
127
|
-
// 3. Fallback
|
|
128
|
-
return 'unknown';
|
|
129
|
-
}
|