50c 2.5.3 → 2.7.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/index.js +14 -2
- package/lib/packs/librarian.js +299 -1
- package/lib/packs/prompt_engine.js +365 -0
- package/lib/packs.js +14 -1
- package/package.json +3 -2
package/lib/index.js
CHANGED
|
@@ -22,12 +22,14 @@ const whm = require('./packs/whm');
|
|
|
22
22
|
const cf = require('./packs/cf');
|
|
23
23
|
const wp = require('./packs/wp');
|
|
24
24
|
const ux = require('./packs/ux');
|
|
25
|
+
const promptEngine = require('./packs/prompt_engine');
|
|
25
26
|
|
|
26
27
|
// Tool name mappings by pack
|
|
27
28
|
const TOOL_PACKS = {
|
|
28
29
|
beacon: ['hints', 'hints_plus', 'roast', 'quick_vibe', 'one_liner', 'name_it', 'price_it', 'compute', 'ide_conversation', 'learning_stats'],
|
|
29
30
|
labs: ['genius', 'mind_opener', 'idea_fold', 'agent_autopsy', 'prompt_fortress', 'context_health', 'context_compress', 'context_extract', 'context_reposition'],
|
|
30
|
-
labs_plus: ['bcalc', 'genius_plus', 'bcalc_why', 'discovery_collision', 'cvi_loop', 'cvi_verify', 'chaos_fingerprint', 'resonance', 'prime_residue', 'echo_sequence', 'conversation_diagnostic', 'handoff']
|
|
31
|
+
labs_plus: ['bcalc', 'genius_plus', 'bcalc_why', 'discovery_collision', 'cvi_loop', 'cvi_verify', 'chaos_fingerprint', 'resonance', 'prime_residue', 'echo_sequence', 'conversation_diagnostic', 'handoff'],
|
|
32
|
+
prompt_engine: ['prompt_extract', 'prompt_phases', 'prompt_refine', 'prompt_expand', 'prompt_categorize']
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
// Get all available tools based on enabled packs
|
|
@@ -53,6 +55,7 @@ async function getTools() {
|
|
|
53
55
|
if (config.packs.cf) tools.push(...cf.CF_TOOLS);
|
|
54
56
|
if (config.packs.wp) tools.push(...wp.WP_TOOLS);
|
|
55
57
|
if (config.packs.ux) tools.push(...ux.UX_TOOLS);
|
|
58
|
+
if (config.packs.prompt_engine) tools.push(...promptEngine.PROMPT_ENGINE_TOOLS);
|
|
56
59
|
|
|
57
60
|
// ENTERPRISE tier
|
|
58
61
|
if (config.packs.labs_plus) tools.push(...labsPlus.LABS_PLUS_TOOLS);
|
|
@@ -101,6 +104,14 @@ async function handleTool(name, args = {}) {
|
|
|
101
104
|
return labs.handleTool(name, args);
|
|
102
105
|
}
|
|
103
106
|
|
|
107
|
+
// Prompt Engine tools (PRO)
|
|
108
|
+
if (TOOL_PACKS.prompt_engine.includes(name)) {
|
|
109
|
+
if (!config.packs.prompt_engine) {
|
|
110
|
+
return { error: 'Requires Pro tier ($99/mo). Enable prompt_engine pack or upgrade at sales.50c.ai/50c-pro/' };
|
|
111
|
+
}
|
|
112
|
+
return promptEngine.handleTool(name, args);
|
|
113
|
+
}
|
|
114
|
+
|
|
104
115
|
// Labs+ tools (ENTERPRISE)
|
|
105
116
|
if (TOOL_PACKS.labs_plus.includes(name)) {
|
|
106
117
|
if (!config.packs.labs_plus) {
|
|
@@ -171,5 +182,6 @@ module.exports = {
|
|
|
171
182
|
packs,
|
|
172
183
|
beacon,
|
|
173
184
|
labs,
|
|
174
|
-
labsPlus
|
|
185
|
+
labsPlus,
|
|
186
|
+
promptEngine
|
|
175
187
|
};
|
package/lib/packs/librarian.js
CHANGED
|
@@ -96,6 +96,210 @@ async function folderPlan(fileList, instruction) {
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
// ═══════════════════════════════════════════════════════════════
|
|
100
|
+
// BROWSER UTILITIES (LOCAL)
|
|
101
|
+
// ═══════════════════════════════════════════════════════════════
|
|
102
|
+
|
|
103
|
+
const fs = require('fs');
|
|
104
|
+
const path = require('path');
|
|
105
|
+
const https = require('https');
|
|
106
|
+
const http = require('http');
|
|
107
|
+
|
|
108
|
+
function getChromeDataPath(profile = 'Default') {
|
|
109
|
+
const platform = process.platform;
|
|
110
|
+
const home = process.env.HOME || process.env.USERPROFILE;
|
|
111
|
+
|
|
112
|
+
if (platform === 'win32') {
|
|
113
|
+
return path.join(process.env.LOCALAPPDATA, 'Google', 'Chrome', 'User Data', profile);
|
|
114
|
+
} else if (platform === 'darwin') {
|
|
115
|
+
return path.join(home, 'Library', 'Application Support', 'Google', 'Chrome', profile);
|
|
116
|
+
} else {
|
|
117
|
+
return path.join(home, '.config', 'google-chrome', profile);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function parseBookmarksFile(profile = 'Default') {
|
|
122
|
+
const bookmarksPath = path.join(getChromeDataPath(profile), 'Bookmarks');
|
|
123
|
+
if (!fs.existsSync(bookmarksPath)) {
|
|
124
|
+
throw new Error(`Chrome bookmarks not found at ${bookmarksPath}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const data = JSON.parse(fs.readFileSync(bookmarksPath, 'utf8'));
|
|
128
|
+
const urls = [];
|
|
129
|
+
|
|
130
|
+
function extractUrls(node, folder = '') {
|
|
131
|
+
if (node.url) {
|
|
132
|
+
urls.push({ url: node.url, title: node.name, folder });
|
|
133
|
+
}
|
|
134
|
+
if (node.children) {
|
|
135
|
+
const newFolder = node.name || folder;
|
|
136
|
+
node.children.forEach(child => extractUrls(child, newFolder));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
Object.values(data.roots).forEach(root => extractUrls(root));
|
|
141
|
+
return urls;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function checkUrl(url, timeout = 10000) {
|
|
145
|
+
return new Promise((resolve) => {
|
|
146
|
+
const protocol = url.startsWith('https') ? https : http;
|
|
147
|
+
const req = protocol.get(url, {
|
|
148
|
+
timeout,
|
|
149
|
+
headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0' }
|
|
150
|
+
}, (res) => {
|
|
151
|
+
resolve({ url, status: res.statusCode, ok: res.statusCode >= 200 && res.statusCode < 400 });
|
|
152
|
+
});
|
|
153
|
+
req.on('error', (e) => resolve({ url, status: 0, ok: false, error: e.message }));
|
|
154
|
+
req.on('timeout', () => {
|
|
155
|
+
req.destroy();
|
|
156
|
+
resolve({ url, status: 0, ok: false, error: 'timeout' });
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function chromeBookmarksCheck(limit = 100, timeout = 10, profile = 'Default') {
|
|
162
|
+
const bookmarks = parseBookmarksFile(profile);
|
|
163
|
+
const toCheck = bookmarks.filter(b =>
|
|
164
|
+
b.url.startsWith('http') && !b.url.includes('localhost') && !b.url.includes('127.0.0.1')
|
|
165
|
+
).slice(0, limit);
|
|
166
|
+
|
|
167
|
+
const results = { ok: [], dead: [], errors: [], skipped: bookmarks.length - toCheck.length };
|
|
168
|
+
|
|
169
|
+
// Check in batches of 10
|
|
170
|
+
for (let i = 0; i < toCheck.length; i += 10) {
|
|
171
|
+
const batch = toCheck.slice(i, i + 10);
|
|
172
|
+
const checks = await Promise.all(batch.map(b => checkUrl(b.url, timeout * 1000)));
|
|
173
|
+
|
|
174
|
+
checks.forEach((result, idx) => {
|
|
175
|
+
const bookmark = batch[idx];
|
|
176
|
+
if (result.ok) {
|
|
177
|
+
results.ok.push({ ...bookmark, status: result.status });
|
|
178
|
+
} else if (result.status === 404) {
|
|
179
|
+
results.dead.push({ ...bookmark, status: 404 });
|
|
180
|
+
} else {
|
|
181
|
+
results.errors.push({ ...bookmark, status: result.status, error: result.error });
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
total: bookmarks.length,
|
|
188
|
+
checked: toCheck.length,
|
|
189
|
+
ok: results.ok.length,
|
|
190
|
+
dead: results.dead,
|
|
191
|
+
errors: results.errors.filter(e => e.status !== 403), // 403 = login required, not dead
|
|
192
|
+
login_required: results.errors.filter(e => e.status === 403),
|
|
193
|
+
skipped: results.skipped
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function getExtensionsInfo(profile = 'Default') {
|
|
198
|
+
const extPath = path.join(getChromeDataPath(profile), 'Extensions');
|
|
199
|
+
if (!fs.existsSync(extPath)) {
|
|
200
|
+
return { error: 'Extensions folder not found' };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const extensions = [];
|
|
204
|
+
const extDirs = fs.readdirSync(extPath);
|
|
205
|
+
|
|
206
|
+
extDirs.forEach(extId => {
|
|
207
|
+
const extDir = path.join(extPath, extId);
|
|
208
|
+
if (fs.statSync(extDir).isDirectory()) {
|
|
209
|
+
const versions = fs.readdirSync(extDir).filter(v => !v.startsWith('.'));
|
|
210
|
+
if (versions.length > 0) {
|
|
211
|
+
const latestVersion = versions.sort().pop();
|
|
212
|
+
const manifestPath = path.join(extDir, latestVersion, 'manifest.json');
|
|
213
|
+
|
|
214
|
+
if (fs.existsSync(manifestPath)) {
|
|
215
|
+
try {
|
|
216
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
217
|
+
extensions.push({
|
|
218
|
+
id: extId,
|
|
219
|
+
name: manifest.name || 'Unknown',
|
|
220
|
+
version: manifest.version,
|
|
221
|
+
description: manifest.description?.substring(0, 100),
|
|
222
|
+
permissions: manifest.permissions || [],
|
|
223
|
+
hostPermissions: manifest.host_permissions || manifest.optional_host_permissions || []
|
|
224
|
+
});
|
|
225
|
+
} catch (e) {
|
|
226
|
+
extensions.push({ id: extId, name: 'Unknown', error: 'Invalid manifest' });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Flag risky extensions
|
|
234
|
+
const risky = extensions.filter(ext => {
|
|
235
|
+
const perms = [...(ext.permissions || []), ...(ext.hostPermissions || [])];
|
|
236
|
+
return perms.some(p =>
|
|
237
|
+
p.includes('<all_urls>') ||
|
|
238
|
+
p.includes('*://*/*') ||
|
|
239
|
+
p === 'webRequest' ||
|
|
240
|
+
p === 'webRequestBlocking'
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
total: extensions.length,
|
|
246
|
+
extensions,
|
|
247
|
+
risky,
|
|
248
|
+
recommendations: risky.length > 0 ?
|
|
249
|
+
`Found ${risky.length} extensions with broad permissions. Review: ${risky.map(e => e.name).join(', ')}` :
|
|
250
|
+
'No obviously risky extensions found'
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async function passwordsCheck(exportFile, checkBreaches = false) {
|
|
255
|
+
if (!fs.existsSync(exportFile)) {
|
|
256
|
+
return { error: `File not found: ${exportFile}` };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const csv = fs.readFileSync(exportFile, 'utf8');
|
|
260
|
+
const lines = csv.split('\n').slice(1); // Skip header
|
|
261
|
+
|
|
262
|
+
const passwords = lines.filter(l => l.trim()).map(line => {
|
|
263
|
+
const parts = line.split(',');
|
|
264
|
+
return {
|
|
265
|
+
name: parts[0],
|
|
266
|
+
url: parts[1],
|
|
267
|
+
username: parts[2],
|
|
268
|
+
password: parts[3]
|
|
269
|
+
};
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Check for weak passwords
|
|
273
|
+
const weak = passwords.filter(p => {
|
|
274
|
+
const pwd = p.password || '';
|
|
275
|
+
return pwd.length < 8 ||
|
|
276
|
+
pwd === pwd.toLowerCase() ||
|
|
277
|
+
/^[0-9]+$/.test(pwd) ||
|
|
278
|
+
['password', '123456', 'qwerty'].includes(pwd.toLowerCase());
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Check for reused passwords
|
|
282
|
+
const pwdCounts = {};
|
|
283
|
+
passwords.forEach(p => {
|
|
284
|
+
const pwd = p.password;
|
|
285
|
+
pwdCounts[pwd] = (pwdCounts[pwd] || 0) + 1;
|
|
286
|
+
});
|
|
287
|
+
const reused = Object.entries(pwdCounts).filter(([_, count]) => count > 1);
|
|
288
|
+
|
|
289
|
+
return {
|
|
290
|
+
total: passwords.length,
|
|
291
|
+
weak: weak.map(p => ({ name: p.name, url: p.url, reason: 'Weak password pattern' })),
|
|
292
|
+
reused: reused.map(([pwd, count]) => ({
|
|
293
|
+
count,
|
|
294
|
+
sites: passwords.filter(p => p.password === pwd).map(p => p.name).slice(0, 3)
|
|
295
|
+
})),
|
|
296
|
+
recommendations: [
|
|
297
|
+
weak.length > 0 ? `${weak.length} weak passwords need updating` : null,
|
|
298
|
+
reused.length > 0 ? `${reused.length} passwords are reused across sites` : null
|
|
299
|
+
].filter(Boolean)
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
99
303
|
// ═══════════════════════════════════════════════════════════════
|
|
100
304
|
// TOOL DEFINITIONS
|
|
101
305
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -439,6 +643,76 @@ const LIBRARIAN_TOOLS = [
|
|
|
439
643
|
},
|
|
440
644
|
cost: 0.08,
|
|
441
645
|
tier: 'pro'
|
|
646
|
+
},
|
|
647
|
+
|
|
648
|
+
// ═══════════════════════════════════════════════════════════════
|
|
649
|
+
// BROWSER MANAGEMENT
|
|
650
|
+
// ═══════════════════════════════════════════════════════════════
|
|
651
|
+
{
|
|
652
|
+
name: 'chrome_bookmarks_check',
|
|
653
|
+
description: 'Check Chrome bookmarks for dead links (404, timeouts). Local scan. FREE.',
|
|
654
|
+
inputSchema: {
|
|
655
|
+
type: 'object',
|
|
656
|
+
properties: {
|
|
657
|
+
limit: { type: 'number', default: 100, description: 'Max URLs to check' },
|
|
658
|
+
timeout: { type: 'number', default: 10, description: 'Timeout per URL (seconds)' },
|
|
659
|
+
profile: { type: 'string', default: 'Default', description: 'Chrome profile name' }
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
cost: 0,
|
|
663
|
+
tier: 'pro'
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
name: 'chrome_bookmarks_report',
|
|
667
|
+
description: 'Full bookmark health report with categorization. $0.05',
|
|
668
|
+
inputSchema: {
|
|
669
|
+
type: 'object',
|
|
670
|
+
properties: {
|
|
671
|
+
include_recommendations: { type: 'boolean', default: true },
|
|
672
|
+
profile: { type: 'string', default: 'Default' }
|
|
673
|
+
}
|
|
674
|
+
},
|
|
675
|
+
cost: 0.05,
|
|
676
|
+
tier: 'pro'
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
name: 'chrome_extensions_audit',
|
|
680
|
+
description: 'Audit installed Chrome extensions for security/bloat. FREE.',
|
|
681
|
+
inputSchema: {
|
|
682
|
+
type: 'object',
|
|
683
|
+
properties: {
|
|
684
|
+
profile: { type: 'string', default: 'Default' }
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
cost: 0,
|
|
688
|
+
tier: 'pro'
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
name: 'browser_passwords_check',
|
|
692
|
+
description: 'Check for weak/reused passwords (via Puppeteer). $0.10',
|
|
693
|
+
inputSchema: {
|
|
694
|
+
type: 'object',
|
|
695
|
+
properties: {
|
|
696
|
+
export_file: { type: 'string', description: 'Path to exported passwords CSV' },
|
|
697
|
+
check_breaches: { type: 'boolean', default: false, description: 'Check haveibeenpwned (requires API key)' }
|
|
698
|
+
},
|
|
699
|
+
required: ['export_file']
|
|
700
|
+
},
|
|
701
|
+
cost: 0.10,
|
|
702
|
+
tier: 'pro'
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
name: 'browser_history_analyze',
|
|
706
|
+
description: 'Analyze browsing patterns for productivity insights. $0.08',
|
|
707
|
+
inputSchema: {
|
|
708
|
+
type: 'object',
|
|
709
|
+
properties: {
|
|
710
|
+
days: { type: 'number', default: 30, description: 'Days of history to analyze' },
|
|
711
|
+
profile: { type: 'string', default: 'Default' }
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
cost: 0.08,
|
|
715
|
+
tier: 'pro'
|
|
442
716
|
}
|
|
443
717
|
];
|
|
444
718
|
|
|
@@ -471,6 +745,26 @@ async function handleTool(name, args) {
|
|
|
471
745
|
return await folderDedup(args.files, args);
|
|
472
746
|
case 'folder_plan':
|
|
473
747
|
return await folderPlan(args.files, args.instruction);
|
|
748
|
+
|
|
749
|
+
// Browser tools (local execution)
|
|
750
|
+
case 'chrome_bookmarks_check':
|
|
751
|
+
return await chromeBookmarksCheck(args.limit || 100, args.timeout || 10, args.profile || 'Default');
|
|
752
|
+
case 'chrome_bookmarks_report':
|
|
753
|
+
const checkResult = await chromeBookmarksCheck(500, 8, args.profile || 'Default');
|
|
754
|
+
return apiRequest('POST', '/tools/librarian/bookmarks_report', {
|
|
755
|
+
check_result: checkResult,
|
|
756
|
+
include_recommendations: args.include_recommendations !== false
|
|
757
|
+
});
|
|
758
|
+
case 'chrome_extensions_audit':
|
|
759
|
+
return getExtensionsInfo(args.profile || 'Default');
|
|
760
|
+
case 'browser_passwords_check':
|
|
761
|
+
return await passwordsCheck(args.export_file, args.check_breaches);
|
|
762
|
+
case 'browser_history_analyze':
|
|
763
|
+
return apiRequest('POST', '/tools/librarian/history_analyze', {
|
|
764
|
+
days: args.days || 30,
|
|
765
|
+
profile: args.profile || 'Default'
|
|
766
|
+
});
|
|
767
|
+
|
|
474
768
|
default:
|
|
475
769
|
return { error: `Unknown librarian tool: ${name}` };
|
|
476
770
|
}
|
|
@@ -492,5 +786,9 @@ module.exports = {
|
|
|
492
786
|
folderAnalyze,
|
|
493
787
|
folderOrganize,
|
|
494
788
|
folderDedup,
|
|
495
|
-
folderPlan
|
|
789
|
+
folderPlan,
|
|
790
|
+
// Browser tools
|
|
791
|
+
chromeBookmarksCheck,
|
|
792
|
+
getExtensionsInfo,
|
|
793
|
+
passwordsCheck
|
|
496
794
|
};
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 50c Prompt Engine Pack - PRO Tier
|
|
3
|
+
* Harvested from CrazyBuild: extractConceptDetails + 4-phase prompt generation
|
|
4
|
+
* Available at: 50c.ai/prompt-engine
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { apiRequest } = require('../config');
|
|
8
|
+
|
|
9
|
+
// Feature patterns for concept extraction
|
|
10
|
+
const FEATURE_PATTERNS = [
|
|
11
|
+
// Healthcare/Medical
|
|
12
|
+
/(?:patient\s+portal|medical\s+records|EHR|EMR|HIPAA|health\s+records|appointment\s+booking|telemedicine|virtual\s+consultation|prescription|diagnosis)/gi,
|
|
13
|
+
// Standard features
|
|
14
|
+
/(?:booking|appointment|scheduling|calendar|reservation)/gi,
|
|
15
|
+
/(?:payment|checkout|purchase|shopping\s+cart|billing|invoice)/gi,
|
|
16
|
+
/(?:user\s+account|profile|authentication|login|registration|sign\s+up)/gi,
|
|
17
|
+
/(?:search|filter|find|browse|lookup)/gi,
|
|
18
|
+
/(?:dashboard|analytics|reporting|metrics|insights)/gi,
|
|
19
|
+
/(?:messaging|chat|communication|contact|notifications)/gi,
|
|
20
|
+
/(?:upload|file|image|media|document|attachment)/gi,
|
|
21
|
+
/(?:review|rating|feedback|testimonial|comment)/gi,
|
|
22
|
+
/(?:blog|news|article|post|content)/gi,
|
|
23
|
+
/(?:gallery|portfolio|showcase|catalog)/gi,
|
|
24
|
+
// Business/professional
|
|
25
|
+
/(?:CRM|customer\s+management|lead\s+tracking|sales\s+pipeline)/gi,
|
|
26
|
+
/(?:inventory|stock|warehouse|catalog\s+management)/gi,
|
|
27
|
+
/(?:workflow|automation|process|task\s+management)/gi,
|
|
28
|
+
/(?:collaboration|team|sharing|permissions)/gi,
|
|
29
|
+
/(?:export|import|integration|API)/gi
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
// Capability patterns
|
|
33
|
+
const CAPABILITY_PATTERNS = [
|
|
34
|
+
/(?:allows?\s+(?:users?|patients?|customers?|clients?)\s+to\s+)([^.]{10,80})/gi,
|
|
35
|
+
/(?:enables?\s+(?:users?|patients?|customers?|clients?)\s+to\s+)([^.]{10,80})/gi,
|
|
36
|
+
/(?:provides?\s+)([^.]{10,80})/gi,
|
|
37
|
+
/(?:includes?\s+)([^.]{10,80})/gi,
|
|
38
|
+
/(?:features?\s+)([^.]{10,80})/gi,
|
|
39
|
+
/(?:supports?\s+)([^.]{10,80})/gi,
|
|
40
|
+
/(?:manages?\s+)([^.]{10,80})/gi
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// Domain-specific terms
|
|
44
|
+
const TERM_PATTERNS = [
|
|
45
|
+
/\b[A-Z]{2,}(?:\s+[A-Z]{2,})*\b/g,
|
|
46
|
+
/\b(?:HIPAA|GDPR|SOC2|PCI|ISO|WCAG)\b/gi,
|
|
47
|
+
/\b(?:telemedicine|telehealth|virtual\s+care|remote\s+consultation)\b/gi,
|
|
48
|
+
/\b(?:e-commerce|marketplace|B2B|B2C|SaaS)\b/gi,
|
|
49
|
+
/\b(?:real-time|live|instant|automated|AI-powered|ML-based)\b/gi
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
// Audience patterns
|
|
53
|
+
const AUDIENCE_PATTERNS = [
|
|
54
|
+
/(?:for|targeting|serving|helping)\s+([a-z\s]+?)(?:\.|,|\s+who|\s+seeking)/i,
|
|
55
|
+
/(?:designed\s+for|built\s+for|created\s+for)\s+([a-z\s]+?)(?:\.|,|\s+who|\s+to)/i,
|
|
56
|
+
/(?:patients?|doctors?|physicians?|nurses?|healthcare\s+professionals?|clinicians?|medical\s+staff)/gi,
|
|
57
|
+
/(?:customers?|clients?|users?|members?|subscribers?|students?|teachers?)/gi
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
// App type categories
|
|
61
|
+
const APP_CATEGORIES = {
|
|
62
|
+
'saas': { keywords: ['subscription', 'platform', 'dashboard', 'analytics', 'team'], niche: 'B2B Software' },
|
|
63
|
+
'ecommerce': { keywords: ['shop', 'cart', 'payment', 'product', 'checkout'], niche: 'Online Retail' },
|
|
64
|
+
'marketplace': { keywords: ['vendor', 'seller', 'buyer', 'listing', 'auction'], niche: 'Two-Sided Platform' },
|
|
65
|
+
'healthcare': { keywords: ['patient', 'medical', 'health', 'clinic', 'doctor'], niche: 'HealthTech' },
|
|
66
|
+
'fintech': { keywords: ['payment', 'banking', 'investment', 'finance', 'trading'], niche: 'Financial Services' },
|
|
67
|
+
'edtech': { keywords: ['course', 'learning', 'student', 'teacher', 'education'], niche: 'Education' },
|
|
68
|
+
'social': { keywords: ['profile', 'feed', 'follow', 'share', 'community'], niche: 'Social Network' },
|
|
69
|
+
'productivity': { keywords: ['task', 'project', 'todo', 'workflow', 'calendar'], niche: 'Business Tools' },
|
|
70
|
+
'content': { keywords: ['blog', 'article', 'post', 'media', 'cms'], niche: 'Content Management' },
|
|
71
|
+
'booking': { keywords: ['appointment', 'reservation', 'schedule', 'booking', 'availability'], niche: 'Scheduling' }
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Extract concept details from natural language description
|
|
76
|
+
* Core pattern harvested from CrazyBuild
|
|
77
|
+
*/
|
|
78
|
+
function extractConceptDetails(concept, projectTitle = '') {
|
|
79
|
+
// Extract business name
|
|
80
|
+
const businessMatch = concept.match(/([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)\s+(?:website|business|company|into|from|platform|app|system)/);
|
|
81
|
+
const businessName = businessMatch?.[1] || projectTitle || 'App';
|
|
82
|
+
|
|
83
|
+
// Extract features
|
|
84
|
+
const features = [];
|
|
85
|
+
FEATURE_PATTERNS.forEach(pattern => {
|
|
86
|
+
const matches = concept.match(pattern);
|
|
87
|
+
if (matches) {
|
|
88
|
+
matches.forEach(match => {
|
|
89
|
+
const normalized = match.toLowerCase().trim();
|
|
90
|
+
if (!features.includes(normalized)) features.push(normalized);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Extract capabilities
|
|
96
|
+
const capabilities = [];
|
|
97
|
+
CAPABILITY_PATTERNS.forEach(pattern => {
|
|
98
|
+
const matches = concept.matchAll(pattern);
|
|
99
|
+
for (const match of matches) {
|
|
100
|
+
const cap = match[1].trim();
|
|
101
|
+
if (cap.length >= 10 && cap.length <= 80 && !cap.includes('\n')) {
|
|
102
|
+
capabilities.push(cap);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Extract domain terms
|
|
108
|
+
const terms = [];
|
|
109
|
+
TERM_PATTERNS.forEach(pattern => {
|
|
110
|
+
const matches = concept.match(pattern);
|
|
111
|
+
if (matches) {
|
|
112
|
+
matches.forEach(match => {
|
|
113
|
+
const normalized = match.toUpperCase().trim();
|
|
114
|
+
if (!terms.includes(normalized)) terms.push(normalized);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Extract target audience
|
|
120
|
+
let audience = 'users';
|
|
121
|
+
for (const pattern of AUDIENCE_PATTERNS) {
|
|
122
|
+
const match = concept.match(pattern);
|
|
123
|
+
if (match && match[1] && match[1].trim().length > 3) {
|
|
124
|
+
audience = match[1].trim();
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Detect app type
|
|
130
|
+
const conceptLower = concept.toLowerCase();
|
|
131
|
+
let appType = 'general';
|
|
132
|
+
let appNiche = 'Web Application';
|
|
133
|
+
let maxScore = 0;
|
|
134
|
+
|
|
135
|
+
for (const [type, config] of Object.entries(APP_CATEGORIES)) {
|
|
136
|
+
const score = config.keywords.filter(kw => conceptLower.includes(kw)).length;
|
|
137
|
+
if (score > maxScore) {
|
|
138
|
+
maxScore = score;
|
|
139
|
+
appType = type;
|
|
140
|
+
appNiche = config.niche;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
businessName,
|
|
146
|
+
features: features.slice(0, 12),
|
|
147
|
+
capabilities: capabilities.slice(0, 10),
|
|
148
|
+
terms: terms.slice(0, 8),
|
|
149
|
+
audience,
|
|
150
|
+
appType,
|
|
151
|
+
appNiche,
|
|
152
|
+
confidence: Math.min(maxScore / 3, 1)
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Generate 4-phase prompt structure
|
|
158
|
+
* Phase 1: Foundation & Setup
|
|
159
|
+
* Phase 2: Core Features
|
|
160
|
+
* Phase 3: User Experience
|
|
161
|
+
* Phase 4: Launch & Scale
|
|
162
|
+
*/
|
|
163
|
+
function generatePhases(concept, details) {
|
|
164
|
+
const { businessName, features, capabilities, audience, appType, appNiche } = details;
|
|
165
|
+
|
|
166
|
+
return [
|
|
167
|
+
{
|
|
168
|
+
phase: 1,
|
|
169
|
+
title: 'Foundation & Setup',
|
|
170
|
+
focus: 'Architecture, authentication, database schema',
|
|
171
|
+
content: `Build the foundation for ${businessName}:
|
|
172
|
+
- Set up project structure (React + Hono + Cloudflare Workers)
|
|
173
|
+
- Design database schema for ${appNiche}
|
|
174
|
+
- Implement authentication system
|
|
175
|
+
- Create base API routes
|
|
176
|
+
- Set up deployment pipeline
|
|
177
|
+
|
|
178
|
+
Target: ${audience}
|
|
179
|
+
App Type: ${appType}
|
|
180
|
+
Key Features: ${features.slice(0, 4).join(', ')}`,
|
|
181
|
+
suggestedTools: ['GenXis Auth', 'GenXis CRUD', 'Database Schema Generator']
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
phase: 2,
|
|
185
|
+
title: 'Core Features',
|
|
186
|
+
focus: 'Primary functionality and business logic',
|
|
187
|
+
content: `Implement core features:
|
|
188
|
+
${features.map((f, i) => `${i + 1}. ${f}`).join('\n')}
|
|
189
|
+
|
|
190
|
+
Capabilities:
|
|
191
|
+
${capabilities.slice(0, 5).map((c, i) => `- ${c}`).join('\n')}
|
|
192
|
+
|
|
193
|
+
Database operations, API endpoints, and business logic for each feature.`,
|
|
194
|
+
suggestedTools: ['GenXis CRUD Builder', 'GenXis Search', 'GenXis File Upload']
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
phase: 3,
|
|
198
|
+
title: 'User Experience',
|
|
199
|
+
focus: 'UI/UX, responsive design, accessibility',
|
|
200
|
+
content: `Design the user experience for ${audience}:
|
|
201
|
+
- Responsive layout (mobile-first)
|
|
202
|
+
- Component library setup
|
|
203
|
+
- Form validation and error handling
|
|
204
|
+
- Loading states and optimistic updates
|
|
205
|
+
- Accessibility (WCAG 2.1 AA)
|
|
206
|
+
|
|
207
|
+
Style: Modern, clean, ${appType === 'healthcare' ? 'trustworthy' : 'professional'}
|
|
208
|
+
Theme: Dark mode with light mode toggle`,
|
|
209
|
+
suggestedTools: ['GenXis UI Kit', 'GenXis Analytics', 'GenXis Performance']
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
phase: 4,
|
|
213
|
+
title: 'Launch & Scale',
|
|
214
|
+
focus: 'Deployment, monitoring, optimization',
|
|
215
|
+
content: `Prepare for production:
|
|
216
|
+
- Performance optimization
|
|
217
|
+
- Security hardening
|
|
218
|
+
- Error monitoring (Sentry)
|
|
219
|
+
- Analytics integration
|
|
220
|
+
- SEO optimization
|
|
221
|
+
- Documentation
|
|
222
|
+
|
|
223
|
+
Compliance: ${details.terms.filter(t => ['HIPAA', 'GDPR', 'SOC2', 'PCI'].includes(t)).join(', ') || 'Standard web security'}`,
|
|
224
|
+
suggestedTools: ['GenXis Security', 'GenXis Analytics', 'GenXis Email']
|
|
225
|
+
}
|
|
226
|
+
];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// API calls
|
|
230
|
+
async function promptExtract(concept, title = '') {
|
|
231
|
+
const details = extractConceptDetails(concept, title);
|
|
232
|
+
return { success: true, ...details };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
async function promptPhases(concept, title = '') {
|
|
236
|
+
const details = extractConceptDetails(concept, title);
|
|
237
|
+
const phases = generatePhases(concept, details);
|
|
238
|
+
return { success: true, details, phases };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async function promptRefine(concept, feedback) {
|
|
242
|
+
return apiRequest('POST', '/tools/prompt_refine', { concept, feedback });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async function promptExpand(idea) {
|
|
246
|
+
return apiRequest('POST', '/tools/prompt_expand', { idea });
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async function promptCategorize(concept) {
|
|
250
|
+
const details = extractConceptDetails(concept);
|
|
251
|
+
return {
|
|
252
|
+
success: true,
|
|
253
|
+
appType: details.appType,
|
|
254
|
+
appNiche: details.appNiche,
|
|
255
|
+
confidence: details.confidence,
|
|
256
|
+
suggestedCategory: APP_CATEGORIES[details.appType]?.niche || 'General'
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Tool definitions
|
|
261
|
+
const PROMPT_ENGINE_TOOLS = [
|
|
262
|
+
{
|
|
263
|
+
name: 'prompt_extract',
|
|
264
|
+
description: 'Extract features, capabilities, audience from natural language. $0.02',
|
|
265
|
+
inputSchema: {
|
|
266
|
+
type: 'object',
|
|
267
|
+
properties: {
|
|
268
|
+
concept: { type: 'string', description: 'Natural language app description' },
|
|
269
|
+
title: { type: 'string', description: 'Optional project title' }
|
|
270
|
+
},
|
|
271
|
+
required: ['concept']
|
|
272
|
+
},
|
|
273
|
+
cost: 0.02,
|
|
274
|
+
tier: 'pro'
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
name: 'prompt_phases',
|
|
278
|
+
description: 'Generate 4-phase development prompts from concept. $0.05',
|
|
279
|
+
inputSchema: {
|
|
280
|
+
type: 'object',
|
|
281
|
+
properties: {
|
|
282
|
+
concept: { type: 'string', description: 'Natural language app description' },
|
|
283
|
+
title: { type: 'string', description: 'Optional project title' }
|
|
284
|
+
},
|
|
285
|
+
required: ['concept']
|
|
286
|
+
},
|
|
287
|
+
cost: 0.05,
|
|
288
|
+
tier: 'pro'
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
name: 'prompt_refine',
|
|
292
|
+
description: 'Refine prompts with conversational feedback. $0.08',
|
|
293
|
+
inputSchema: {
|
|
294
|
+
type: 'object',
|
|
295
|
+
properties: {
|
|
296
|
+
concept: { type: 'string', description: 'Current concept/prompt' },
|
|
297
|
+
feedback: { type: 'string', description: 'User feedback to incorporate' }
|
|
298
|
+
},
|
|
299
|
+
required: ['concept', 'feedback']
|
|
300
|
+
},
|
|
301
|
+
cost: 0.08,
|
|
302
|
+
tier: 'pro'
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: 'prompt_expand',
|
|
306
|
+
description: 'Expand short idea into detailed concept. $0.10',
|
|
307
|
+
inputSchema: {
|
|
308
|
+
type: 'object',
|
|
309
|
+
properties: {
|
|
310
|
+
idea: { type: 'string', description: 'Short idea (1-2 sentences)' }
|
|
311
|
+
},
|
|
312
|
+
required: ['idea']
|
|
313
|
+
},
|
|
314
|
+
cost: 0.10,
|
|
315
|
+
tier: 'pro'
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
name: 'prompt_categorize',
|
|
319
|
+
description: 'Auto-detect app type and niche. $0.01',
|
|
320
|
+
inputSchema: {
|
|
321
|
+
type: 'object',
|
|
322
|
+
properties: {
|
|
323
|
+
concept: { type: 'string', description: 'App concept to categorize' }
|
|
324
|
+
},
|
|
325
|
+
required: ['concept']
|
|
326
|
+
},
|
|
327
|
+
cost: 0.01,
|
|
328
|
+
tier: 'pro'
|
|
329
|
+
}
|
|
330
|
+
];
|
|
331
|
+
|
|
332
|
+
// Handle tool calls
|
|
333
|
+
async function handleTool(name, args) {
|
|
334
|
+
try {
|
|
335
|
+
switch (name) {
|
|
336
|
+
case 'prompt_extract':
|
|
337
|
+
return await promptExtract(args.concept, args.title);
|
|
338
|
+
case 'prompt_phases':
|
|
339
|
+
return await promptPhases(args.concept, args.title);
|
|
340
|
+
case 'prompt_refine':
|
|
341
|
+
return await promptRefine(args.concept, args.feedback);
|
|
342
|
+
case 'prompt_expand':
|
|
343
|
+
return await promptExpand(args.idea);
|
|
344
|
+
case 'prompt_categorize':
|
|
345
|
+
return await promptCategorize(args.concept);
|
|
346
|
+
default:
|
|
347
|
+
return { error: `Unknown prompt_engine tool: ${name}` };
|
|
348
|
+
}
|
|
349
|
+
} catch (e) {
|
|
350
|
+
return { error: e.message };
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
module.exports = {
|
|
355
|
+
promptExtract,
|
|
356
|
+
promptPhases,
|
|
357
|
+
promptRefine,
|
|
358
|
+
promptExpand,
|
|
359
|
+
promptCategorize,
|
|
360
|
+
extractConceptDetails,
|
|
361
|
+
generatePhases,
|
|
362
|
+
PROMPT_ENGINE_TOOLS,
|
|
363
|
+
handleTool,
|
|
364
|
+
APP_CATEGORIES
|
|
365
|
+
};
|
package/lib/packs.js
CHANGED
|
@@ -73,6 +73,13 @@ const PACKS = {
|
|
|
73
73
|
tier: 'pro',
|
|
74
74
|
highlights: ['ux_list_blocks', 'ux_ab_compare', 'ux_a11y_check']
|
|
75
75
|
},
|
|
76
|
+
prompt_engine: {
|
|
77
|
+
name: 'prompt_engine',
|
|
78
|
+
description: 'Prompt engineering - extract, phases, refine, expand',
|
|
79
|
+
tools: 5,
|
|
80
|
+
tier: 'pro',
|
|
81
|
+
highlights: ['prompt_extract', 'prompt_phases', 'prompt_expand', 'prompt_categorize']
|
|
82
|
+
},
|
|
76
83
|
librarian: {
|
|
77
84
|
name: 'librarian',
|
|
78
85
|
description: 'Digital asset manager - domains, bookmarks, CSV, folders, writing style',
|
|
@@ -184,6 +191,12 @@ const TOOL_TIERS = {
|
|
|
184
191
|
ux_a11y_check: 'pro',
|
|
185
192
|
ux_color_palette: 'pro',
|
|
186
193
|
ux_contrast_check: 'pro',
|
|
194
|
+
// Prompt Engine tools
|
|
195
|
+
prompt_extract: 'pro',
|
|
196
|
+
prompt_phases: 'pro',
|
|
197
|
+
prompt_refine: 'pro',
|
|
198
|
+
prompt_expand: 'pro',
|
|
199
|
+
prompt_categorize: 'pro',
|
|
187
200
|
// Librarian tools
|
|
188
201
|
bookmarks_prune: 'pro',
|
|
189
202
|
bookmarks_organize: 'pro',
|
|
@@ -395,7 +408,7 @@ const PACK_TOOLS = [
|
|
|
395
408
|
inputSchema: {
|
|
396
409
|
type: 'object',
|
|
397
410
|
properties: {
|
|
398
|
-
pack: { type: 'string', description: 'Pack name', enum: ['beacon', 'labs', 'labs_plus', 'whm', 'cf', 'wp', 'ux', 'librarian'] }
|
|
411
|
+
pack: { type: 'string', description: 'Pack name', enum: ['beacon', 'labs', 'labs_plus', 'whm', 'cf', 'wp', 'ux', 'prompt_engine', 'librarian'] }
|
|
399
412
|
},
|
|
400
413
|
required: ['pack']
|
|
401
414
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "50c",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "AI toolkit with
|
|
3
|
+
"version": "2.7.0",
|
|
4
|
+
"description": "AI toolkit with prompt engine. One install, 105+ tools.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"50c": "./bin/50c.js"
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"llm",
|
|
13
13
|
"tools",
|
|
14
14
|
"genius",
|
|
15
|
+
"prompt-engine",
|
|
15
16
|
"agent-autopsy",
|
|
16
17
|
"prompt-fortress",
|
|
17
18
|
"bcalc",
|