50c 1.5.0 → 2.0.0

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/lib/packs.js ADDED
@@ -0,0 +1,406 @@
1
+ /**
2
+ * 50c Pack System - Tiered Access
3
+ * FREE / PRO / ENTERPRISE privilege levels
4
+ */
5
+
6
+ const { loadConfig, saveConfig } = require('./config');
7
+
8
+ // Tier definitions
9
+ const TIERS = {
10
+ free: { name: 'Free', price: '$0', credits: 0 },
11
+ starter: { name: 'Starter', price: '$29/mo', credits: 1000 },
12
+ pro: { name: 'Pro', price: '$99/mo', credits: 10000 },
13
+ enterprise: { name: 'Enterprise', price: '$499/mo', credits: 100000 }
14
+ };
15
+
16
+ // Pack definitions with tier access
17
+ const PACKS = {
18
+ // === FREE TIER (Always available) ===
19
+ core: {
20
+ name: 'core',
21
+ description: 'Search, fetch, domain check, balance',
22
+ tools: 4,
23
+ tier: 'free',
24
+ always_on: true,
25
+ highlights: ['web_search', 'page_fetch', 'domain_check', 'check_balance']
26
+ },
27
+ vault: {
28
+ name: 'vault',
29
+ description: 'Secure credential storage',
30
+ tools: 9,
31
+ tier: 'free',
32
+ always_on: true,
33
+ highlights: ['vault_add', 'vault_get', 'vault_yolo']
34
+ },
35
+
36
+ // === STARTER TIER ($29/mo) ===
37
+ beacon: {
38
+ name: 'beacon',
39
+ description: 'Consumer tools - hints, roast, naming, pricing',
40
+ tools: 10,
41
+ tier: 'starter',
42
+ highlights: ['hints', 'roast', 'quick_vibe', 'name_it', 'compute']
43
+ },
44
+
45
+ // === PRO TIER ($99/mo) ===
46
+ labs: {
47
+ name: 'labs',
48
+ description: 'Deep thinking - genius, bcalc, context management',
49
+ tools: 8,
50
+ tier: 'pro',
51
+ highlights: ['genius', 'mind_opener', 'bcalc', 'context_health']
52
+ },
53
+ cf: {
54
+ name: 'cf',
55
+ description: 'Cloudflare - Edge to origin',
56
+ tools: 34,
57
+ tier: 'pro',
58
+ highlights: ['cf_list_zones', 'cf_purge_cache', 'cf_point_to_server'],
59
+ requires: ['CF_API_TOKEN']
60
+ },
61
+ wp: {
62
+ name: 'wp',
63
+ description: 'WordPress - Full site management',
64
+ tools: 14,
65
+ tier: 'pro',
66
+ highlights: ['wp_list_pages', 'wp_create_page', 'wp_list_plugins'],
67
+ requires: ['WP_URL', 'WP_USER', 'WP_APP_PASSWORD']
68
+ },
69
+ ux: {
70
+ name: 'ux',
71
+ description: 'UI/UX - Design, A/B, accessibility',
72
+ tools: 17,
73
+ tier: 'pro',
74
+ highlights: ['ux_list_blocks', 'ux_ab_compare', 'ux_a11y_check']
75
+ },
76
+
77
+ // === ENTERPRISE TIER ($499/mo) ===
78
+ labs_plus: {
79
+ name: 'labs_plus',
80
+ description: 'Advanced - genius_plus, CVI, discovery collision',
81
+ tools: 11,
82
+ tier: 'enterprise',
83
+ highlights: ['genius_plus', 'cvi_loop', 'discovery_collision', 'bcalc_why']
84
+ },
85
+ whm: {
86
+ name: 'whm',
87
+ description: 'WHM/cPanel/SSH - Own your hosting',
88
+ tools: 39,
89
+ tier: 'enterprise',
90
+ highlights: ['whm_list_accounts', 'whm_create_account', 'ssh_exec'],
91
+ requires: ['WHM_HOST', 'WHM_TOKEN']
92
+ }
93
+ };
94
+
95
+ // Tool-to-tier mapping for fine-grained access
96
+ const TOOL_TIERS = {
97
+ // FREE - always available
98
+ web_search: 'free',
99
+ page_fetch: 'free',
100
+ domain_check: 'free',
101
+ check_balance: 'free',
102
+ learning_stats: 'free',
103
+ // Vault (free)
104
+ vault_status: 'free',
105
+ vault_init: 'free',
106
+ vault_unlock: 'free',
107
+ vault_lock: 'free',
108
+ vault_yolo: 'free',
109
+ vault_add: 'free',
110
+ vault_get: 'free',
111
+ vault_list: 'free',
112
+ vault_delete: 'free',
113
+
114
+ // STARTER ($29/mo)
115
+ hints: 'starter',
116
+ hints_plus: 'starter',
117
+ roast: 'starter',
118
+ quick_vibe: 'starter',
119
+ one_liner: 'starter',
120
+ name_it: 'starter',
121
+ price_it: 'starter',
122
+ compute: 'starter',
123
+ ide_conversation: 'starter',
124
+
125
+ // PRO ($99/mo)
126
+ genius: 'pro',
127
+ mind_opener: 'pro',
128
+ idea_fold: 'pro',
129
+ bcalc: 'pro',
130
+ context_health: 'pro',
131
+ context_compress: 'pro',
132
+ context_extract: 'pro',
133
+ context_reposition: 'pro',
134
+ // CF tools
135
+ cf_list_zones: 'pro',
136
+ cf_get_zone: 'pro',
137
+ cf_create_zone: 'pro',
138
+ cf_find_zone: 'pro',
139
+ cf_list_dns: 'pro',
140
+ cf_create_dns: 'pro',
141
+ cf_update_dns: 'pro',
142
+ cf_delete_dns: 'pro',
143
+ cf_ssl_status: 'pro',
144
+ cf_ssl_mode: 'pro',
145
+ cf_purge_cache: 'pro',
146
+ cf_dev_mode: 'pro',
147
+ cf_under_attack: 'pro',
148
+ cf_block_ip: 'pro',
149
+ cf_point_to_server: 'pro',
150
+ cf_setup_email: 'pro',
151
+ // WP tools
152
+ wp_list_pages: 'pro',
153
+ wp_create_page: 'pro',
154
+ wp_update_page: 'pro',
155
+ wp_delete_page: 'pro',
156
+ wp_list_posts: 'pro',
157
+ wp_create_post: 'pro',
158
+ wp_list_plugins: 'pro',
159
+ wp_activate_plugin: 'pro',
160
+ wp_list_themes: 'pro',
161
+ wp_activate_theme: 'pro',
162
+ // UX tools
163
+ ux_list_blocks: 'pro',
164
+ ux_get_block: 'pro',
165
+ ux_ab_compare: 'pro',
166
+ ux_a11y_check: 'pro',
167
+ ux_color_palette: 'pro',
168
+ ux_contrast_check: 'pro',
169
+
170
+ // ENTERPRISE ($499/mo)
171
+ genius_plus: 'enterprise',
172
+ bcalc_why: 'enterprise',
173
+ discovery_collision: 'enterprise',
174
+ cvi_loop: 'enterprise',
175
+ cvi_verify: 'enterprise',
176
+ chaos_fingerprint: 'enterprise',
177
+ resonance: 'enterprise',
178
+ prime_residue: 'enterprise',
179
+ echo_sequence: 'enterprise',
180
+ // WHM tools
181
+ whm_list_accounts: 'enterprise',
182
+ whm_create_account: 'enterprise',
183
+ whm_suspend_account: 'enterprise',
184
+ whm_unsuspend_account: 'enterprise',
185
+ whm_terminate_account: 'enterprise',
186
+ whm_change_password: 'enterprise',
187
+ whm_change_package: 'enterprise',
188
+ whm_list_packages: 'enterprise',
189
+ whm_server_info: 'enterprise',
190
+ whm_backup_account: 'enterprise',
191
+ ssh_exec: 'enterprise',
192
+ ssh_upload: 'enterprise',
193
+ ssh_download: 'enterprise',
194
+ cp_list_domains: 'enterprise',
195
+ cp_create_email: 'enterprise',
196
+ cp_list_databases: 'enterprise',
197
+ cp_create_database: 'enterprise'
198
+ };
199
+
200
+ // Tier hierarchy for access checks
201
+ const TIER_LEVEL = { free: 0, starter: 1, pro: 2, enterprise: 3 };
202
+
203
+ // Check if user tier can access tool
204
+ function canAccess(userTier, toolTier) {
205
+ return TIER_LEVEL[userTier] >= TIER_LEVEL[toolTier];
206
+ }
207
+
208
+ // Get required tier for a tool
209
+ function getToolTier(toolName) {
210
+ return TOOL_TIERS[toolName] || 'pro';
211
+ }
212
+
213
+ // Discovery - shows packs by tier
214
+ async function discover() {
215
+ const config = await loadConfig();
216
+ const userTier = config.tier || 'free';
217
+
218
+ const byTier = {
219
+ free: { accessible: true, packs: [] },
220
+ starter: { accessible: canAccess(userTier, 'starter'), packs: [] },
221
+ pro: { accessible: canAccess(userTier, 'pro'), packs: [] },
222
+ enterprise: { accessible: canAccess(userTier, 'enterprise'), packs: [] }
223
+ };
224
+
225
+ for (const [key, pack] of Object.entries(PACKS)) {
226
+ const packInfo = {
227
+ name: pack.name,
228
+ description: pack.description,
229
+ tools: pack.tools,
230
+ highlights: pack.highlights,
231
+ enabled: config.packs[key] || pack.always_on || false
232
+ };
233
+ byTier[pack.tier].packs.push(packInfo);
234
+ }
235
+
236
+ return {
237
+ your_tier: userTier,
238
+ tiers: TIERS,
239
+ packs_by_tier: byTier,
240
+ tip: 'Upgrade at sales.50c.ai to unlock more packs'
241
+ };
242
+ }
243
+
244
+ // Enable a pack (with tier check)
245
+ async function enablePack(packName) {
246
+ const pack = PACKS[packName];
247
+ if (!pack) {
248
+ return { error: `Unknown pack: ${packName}. Available: ${Object.keys(PACKS).join(', ')}` };
249
+ }
250
+
251
+ if (pack.always_on) {
252
+ return { message: `${packName} is always enabled`, tools: pack.tools };
253
+ }
254
+
255
+ const config = await loadConfig();
256
+ const userTier = config.tier || 'free';
257
+
258
+ if (!canAccess(userTier, pack.tier)) {
259
+ return {
260
+ error: `${packName} requires ${pack.tier} tier. You have ${userTier}.`,
261
+ upgrade: `Upgrade at sales.50c.ai/50c-${pack.tier}/`
262
+ };
263
+ }
264
+
265
+ config.packs[packName] = true;
266
+ await saveConfig(config);
267
+
268
+ return {
269
+ enabled: packName,
270
+ tools_added: pack.tools,
271
+ highlights: pack.highlights,
272
+ message: `${pack.description} - ${pack.tools} tools now available`,
273
+ requires: pack.requires || [],
274
+ next: pack.requires?.length
275
+ ? `Add credentials with: vault_add ${packName}/default "your-token"`
276
+ : 'Ready to use!'
277
+ };
278
+ }
279
+
280
+ // Disable a pack
281
+ async function disablePack(packName) {
282
+ const pack = PACKS[packName];
283
+ if (!pack) {
284
+ return { error: `Unknown pack: ${packName}` };
285
+ }
286
+
287
+ if (pack.always_on) {
288
+ return { error: `${packName} cannot be disabled` };
289
+ }
290
+
291
+ const config = await loadConfig();
292
+ config.packs[packName] = false;
293
+ await saveConfig(config);
294
+
295
+ return {
296
+ disabled: packName,
297
+ tools_removed: pack.tools,
298
+ message: `${packName} pack disabled`
299
+ };
300
+ }
301
+
302
+ // List packs with tier info
303
+ async function listPacks() {
304
+ const config = await loadConfig();
305
+ const userTier = config.tier || 'free';
306
+
307
+ const result = {
308
+ your_tier: userTier,
309
+ enabled: [],
310
+ available: [],
311
+ locked: []
312
+ };
313
+
314
+ for (const [key, pack] of Object.entries(PACKS)) {
315
+ const info = { name: key, tier: pack.tier, tools: pack.tools };
316
+
317
+ if (config.packs[key] || pack.always_on) {
318
+ result.enabled.push(info);
319
+ } else if (canAccess(userTier, pack.tier)) {
320
+ result.available.push(info);
321
+ } else {
322
+ result.locked.push({ ...info, requires: pack.tier });
323
+ }
324
+ }
325
+
326
+ return result;
327
+ }
328
+
329
+ // Check if pack is enabled
330
+ async function isPackEnabled(packName) {
331
+ const config = await loadConfig();
332
+ const pack = PACKS[packName];
333
+ return pack?.always_on || config.packs[packName] || false;
334
+ }
335
+
336
+ // Tool definitions
337
+ const PACK_TOOLS = [
338
+ {
339
+ name: '50c_discover',
340
+ description: 'Discover available packs by tier. FREE.',
341
+ inputSchema: { type: 'object', properties: {} }
342
+ },
343
+ {
344
+ name: '50c_enable_pack',
345
+ description: 'Enable a pack (if your tier allows). FREE.',
346
+ inputSchema: {
347
+ type: 'object',
348
+ properties: {
349
+ pack: { type: 'string', description: 'Pack name', enum: ['beacon', 'labs', 'labs_plus', 'whm', 'cf', 'wp', 'ux'] }
350
+ },
351
+ required: ['pack']
352
+ }
353
+ },
354
+ {
355
+ name: '50c_disable_pack',
356
+ description: 'Disable a pack. FREE.',
357
+ inputSchema: {
358
+ type: 'object',
359
+ properties: {
360
+ pack: { type: 'string', description: 'Pack name to disable' }
361
+ },
362
+ required: ['pack']
363
+ }
364
+ },
365
+ {
366
+ name: '50c_packs',
367
+ description: 'List packs - enabled, available, locked. FREE.',
368
+ inputSchema: { type: 'object', properties: {} }
369
+ }
370
+ ];
371
+
372
+ // Handle pack tool calls
373
+ async function handleTool(name, args) {
374
+ try {
375
+ switch (name) {
376
+ case '50c_discover':
377
+ return await discover();
378
+ case '50c_enable_pack':
379
+ return await enablePack(args.pack);
380
+ case '50c_disable_pack':
381
+ return await disablePack(args.pack);
382
+ case '50c_packs':
383
+ return await listPacks();
384
+ default:
385
+ return { error: `Unknown pack tool: ${name}` };
386
+ }
387
+ } catch (e) {
388
+ return { error: e.message };
389
+ }
390
+ }
391
+
392
+ module.exports = {
393
+ TIERS,
394
+ PACKS,
395
+ TOOL_TIERS,
396
+ TIER_LEVEL,
397
+ PACK_TOOLS,
398
+ handleTool,
399
+ discover,
400
+ enablePack,
401
+ disablePack,
402
+ listPacks,
403
+ isPackEnabled,
404
+ canAccess,
405
+ getToolTier
406
+ };