50c 3.7.0 → 3.8.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/bin/50c.js +419 -1
- package/lib/team.js +12 -18
- package/lib/tools-registry.js +177 -0
- package/package.json +1 -1
package/bin/50c.js
CHANGED
|
@@ -126,6 +126,14 @@ const TOOL_COMMANDS = {
|
|
|
126
126
|
'invent': { tool: 'auto_invent', special: 'invent', cost: '$2.00' },
|
|
127
127
|
'invent-ui': { tool: 'auto_invent', special: 'invent-ui', cost: '$2.00' },
|
|
128
128
|
'tv': { tool: null, special: 'mcp-tv', cost: 'FREE' },
|
|
129
|
+
'adopt': { tool: 'adoption_calc', special: 'adopt', cost: 'FREE' },
|
|
130
|
+
'adopt-dx': { tool: 'adoption_diagnose', special: 'adopt-dx', cost: 'FREE' },
|
|
131
|
+
'adopt-sim': { tool: 'adoption_simulate', special: 'adopt-sim', cost: 'FREE' },
|
|
132
|
+
'team': { tool: null, special: 'team', cost: 'FREE' },
|
|
133
|
+
'team-create': { tool: null, special: 'team-create', cost: 'FREE' },
|
|
134
|
+
'team-mint': { tool: null, special: 'team-mint', cost: 'FREE' },
|
|
135
|
+
'team-recall': { tool: null, special: 'team-recall', cost: 'FREE' },
|
|
136
|
+
'team-analytics': { tool: null, special: 'team-analytics', cost: 'FREE' },
|
|
129
137
|
};
|
|
130
138
|
|
|
131
139
|
// Route command
|
|
@@ -249,6 +257,9 @@ function searchPacks(query) {
|
|
|
249
257
|
{ pack: 'beacon', tool: 'checkpoint', desc: 'Save state', cost: '$0.02' },
|
|
250
258
|
{ pack: 'router', tool: 'compare', desc: 'Multi-model compare', cost: '$0.05' },
|
|
251
259
|
{ pack: 'router', tool: 'battle', desc: 'Model battle', cost: '$0.10' },
|
|
260
|
+
{ pack: 'adoption', tool: 'adoption_calc', desc: 'P(adopt) calculator', cost: 'FREE' },
|
|
261
|
+
{ pack: 'adoption', tool: 'adoption_diagnose', desc: 'Bottleneck diagnosis', cost: 'FREE' },
|
|
262
|
+
{ pack: 'adoption', tool: 'adoption_simulate', desc: 'Time-series ODE sim', cost: 'FREE' },
|
|
252
263
|
];
|
|
253
264
|
|
|
254
265
|
return all.filter(t =>
|
|
@@ -266,7 +277,7 @@ async function cmdAdd(args) {
|
|
|
266
277
|
process.exit(1);
|
|
267
278
|
}
|
|
268
279
|
|
|
269
|
-
const valid = ['core', 'labs', 'beacon', 'router'];
|
|
280
|
+
const valid = ['core', 'labs', 'beacon', 'router', 'adoption'];
|
|
270
281
|
if (!valid.includes(pack)) {
|
|
271
282
|
console.error(`Unknown pack: ${pack}`);
|
|
272
283
|
console.error('Available: ' + valid.join(', '));
|
|
@@ -658,6 +669,188 @@ async function runToolCommand(cmd, args) {
|
|
|
658
669
|
return;
|
|
659
670
|
}
|
|
660
671
|
|
|
672
|
+
// ADOPTION EQUATION TOOLS (FREE, local compute)
|
|
673
|
+
if (spec.special === 'adopt') {
|
|
674
|
+
// 50c adopt 2.0 0.3 0.8 [churn] [lambda]
|
|
675
|
+
const R = parseFloat(args[0]);
|
|
676
|
+
const N = parseFloat(args[1]);
|
|
677
|
+
const W = parseFloat(args[2]);
|
|
678
|
+
const churn = parseFloat(args[3]) || 0;
|
|
679
|
+
const lambda = parseFloat(args[4]) || 1.0;
|
|
680
|
+
|
|
681
|
+
if (isNaN(R) || isNaN(N) || isNaN(W)) {
|
|
682
|
+
console.error('Usage: 50c adopt <reward> <network> <window> [churn] [lambda]');
|
|
683
|
+
console.error('Example: 50c adopt 2.0 0.3 0.8');
|
|
684
|
+
process.exit(1);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const result = adoptionCalc({ reward: R, network: N, window: W, churn, lambda });
|
|
688
|
+
console.log('\n=== ADOPTION PROBABILITY ===');
|
|
689
|
+
console.log(`P(adopt) = ${(result.probability * 100).toFixed(2)}%`);
|
|
690
|
+
console.log(`Equation: ${result.equation}`);
|
|
691
|
+
console.log(`\nTerms:`);
|
|
692
|
+
console.log(` Reward: ${(result.reward_term * 100).toFixed(1)}%`);
|
|
693
|
+
console.log(` Network: ${(result.network_effect * 100).toFixed(1)}%`);
|
|
694
|
+
console.log(` Window: ${(result.upheaval_window * 100).toFixed(1)}%`);
|
|
695
|
+
console.log(`\nDiagnosis: ${result.diagnosis}`);
|
|
696
|
+
console.log(`Bottleneck: ${result.bottleneck} (${(result.bottleneck_value * 100).toFixed(1)}%)`);
|
|
697
|
+
if (result.threshold_R_for_50pct !== 'impossible') {
|
|
698
|
+
console.log(`R needed for 50%: ${result.threshold_R_for_50pct}`);
|
|
699
|
+
}
|
|
700
|
+
console.log(`Past bifurcation (viral threshold): ${result.past_bifurcation ? 'YES' : 'NO'}`);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (spec.special === 'adopt-dx') {
|
|
705
|
+
// 50c adopt-dx 2.0 0.3 0.8
|
|
706
|
+
const R = parseFloat(args[0]);
|
|
707
|
+
const N = parseFloat(args[1]);
|
|
708
|
+
const W = parseFloat(args[2]);
|
|
709
|
+
|
|
710
|
+
if (isNaN(R) || isNaN(N) || isNaN(W)) {
|
|
711
|
+
console.error('Usage: 50c adopt-dx <reward> <network> <window>');
|
|
712
|
+
process.exit(1);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
const result = adoptionDiagnose({ reward: R, network: N, window: W });
|
|
716
|
+
console.log('\n=== ADOPTION DIAGNOSIS ===');
|
|
717
|
+
console.log(`P(adopt) = ${(result.probability * 100).toFixed(2)}%`);
|
|
718
|
+
console.log(`\nDiagnosis: ${result.diagnosis.toUpperCase()}`);
|
|
719
|
+
console.log(`Priority: ${result.prescription.priority}`);
|
|
720
|
+
console.log(`\nProblem: ${result.prescription.problem}`);
|
|
721
|
+
console.log(`Fix: ${result.prescription.fix}`);
|
|
722
|
+
if (result.kill_switches.length > 0) {
|
|
723
|
+
console.log('\n⚠️ KILL SWITCHES:');
|
|
724
|
+
result.kill_switches.forEach(k => console.log(` ${k}`));
|
|
725
|
+
}
|
|
726
|
+
console.log(`\nInsight: ${result.insight}`);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
if (spec.special === 'adopt-sim') {
|
|
731
|
+
// 50c adopt-sim 2.0 [steps]
|
|
732
|
+
const R = parseFloat(args[0]) || 2.0;
|
|
733
|
+
const steps = parseInt(args[1]) || 100;
|
|
734
|
+
|
|
735
|
+
const result = adoptionSimulate({ reward: R, steps });
|
|
736
|
+
console.log('\n=== ADOPTION SIMULATION ===');
|
|
737
|
+
console.log(`Initial: R=${R}, N0=0.1, W0=0.9, alpha=1.5, churn=0.05`);
|
|
738
|
+
console.log(`\nTrajectory:`);
|
|
739
|
+
result.series.forEach(p => {
|
|
740
|
+
const bar = '█'.repeat(Math.round(p.P * 40));
|
|
741
|
+
console.log(`t=${p.t.toFixed(1).padStart(4)}: ${(p.P * 100).toFixed(1).padStart(5)}% ${bar}`);
|
|
742
|
+
});
|
|
743
|
+
console.log(`\nFinal P: ${(result.summary.final_adoption * 100).toFixed(2)}%`);
|
|
744
|
+
console.log(`Peak P: ${(result.summary.peak_adoption * 100).toFixed(2)}% at t=${result.summary.peak_time}`);
|
|
745
|
+
console.log(`Tipped viral: ${result.summary.tipped_at !== 'never' ? 'YES at t=' + result.summary.tipped_at : 'NO'}`);
|
|
746
|
+
console.log(`Trajectory: ${result.summary.trajectory}`);
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// TEAM COMMANDS (FREE, uses API)
|
|
751
|
+
if (spec.special === 'team') {
|
|
752
|
+
const res = await fetch('https://api.50c.ai/v1/team/info', {
|
|
753
|
+
method: 'POST',
|
|
754
|
+
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
755
|
+
body: '{}'
|
|
756
|
+
});
|
|
757
|
+
const data = await res.json();
|
|
758
|
+
if (data.error === 'Not in a team') {
|
|
759
|
+
console.log('\n=== NO TEAM ===');
|
|
760
|
+
console.log('You are not in a team yet.');
|
|
761
|
+
console.log('Create one with: 50c team-create "My Team"');
|
|
762
|
+
} else if (data.team) {
|
|
763
|
+
console.log('\n=== TEAM INFO ===');
|
|
764
|
+
console.log(`Name: ${data.team.name}`);
|
|
765
|
+
console.log(`Plan: ${data.team.plan}`);
|
|
766
|
+
console.log(`Members: ${data.members.length}/${data.team.max_members}`);
|
|
767
|
+
console.log(`Your role: ${data.your_role}`);
|
|
768
|
+
console.log('\nMembers:');
|
|
769
|
+
data.members.forEach(m => console.log(` ${m.email || m.customer_id} (${m.role})`));
|
|
770
|
+
} else {
|
|
771
|
+
console.log(JSON.stringify(data, null, 2));
|
|
772
|
+
}
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
if (spec.special === 'team-create') {
|
|
777
|
+
const name = args.join(' ') || 'My Team';
|
|
778
|
+
const res = await fetch('https://api.50c.ai/v1/team/create', {
|
|
779
|
+
method: 'POST',
|
|
780
|
+
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
781
|
+
body: JSON.stringify({ name })
|
|
782
|
+
});
|
|
783
|
+
const data = await res.json();
|
|
784
|
+
console.log('\n=== TEAM CREATED ===');
|
|
785
|
+
console.log(`ID: ${data.team_id}`);
|
|
786
|
+
console.log(`Name: ${data.name}`);
|
|
787
|
+
console.log(`Plan: ${data.plan}`);
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
if (spec.special === 'team-mint') {
|
|
792
|
+
if (args.length < 2) {
|
|
793
|
+
console.error('Usage: 50c team-mint <key> <value> [scope]');
|
|
794
|
+
process.exit(1);
|
|
795
|
+
}
|
|
796
|
+
const key = args[0];
|
|
797
|
+
const value = args.slice(1, -1).join(' ') || args[1];
|
|
798
|
+
const scope = args.length > 2 ? args[args.length - 1] : 'general';
|
|
799
|
+
const res = await fetch('https://api.50c.ai/v1/team/mint', {
|
|
800
|
+
method: 'POST',
|
|
801
|
+
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
802
|
+
body: JSON.stringify({ key, value, scope })
|
|
803
|
+
});
|
|
804
|
+
const data = await res.json();
|
|
805
|
+
console.log('\n=== MEMORY SHARED ===');
|
|
806
|
+
console.log(`ID: ${data.id}`);
|
|
807
|
+
console.log(`Team: ${data.team_id}`);
|
|
808
|
+
console.log(`Shared: ${data.shared}`);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
if (spec.special === 'team-recall') {
|
|
813
|
+
const query = args.join(' ') || null;
|
|
814
|
+
const res = await fetch('https://api.50c.ai/v1/team/recall', {
|
|
815
|
+
method: 'POST',
|
|
816
|
+
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
817
|
+
body: JSON.stringify({ query, limit: 20 })
|
|
818
|
+
});
|
|
819
|
+
const data = await res.json();
|
|
820
|
+
console.log('\n=== TEAM MEMORIES ===');
|
|
821
|
+
console.log(`Team: ${data.team_id}`);
|
|
822
|
+
console.log(`Found: ${data.count} memories\n`);
|
|
823
|
+
data.memories.forEach(m => {
|
|
824
|
+
console.log(`[${m.scope}] ${m.key}`);
|
|
825
|
+
console.log(` ${m.value}`);
|
|
826
|
+
console.log('');
|
|
827
|
+
});
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
if (spec.special === 'team-analytics') {
|
|
832
|
+
const res = await fetch('https://api.50c.ai/v1/team/analytics', {
|
|
833
|
+
method: 'POST',
|
|
834
|
+
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
|
|
835
|
+
body: '{}'
|
|
836
|
+
});
|
|
837
|
+
const data = await res.json();
|
|
838
|
+
if (data.error) {
|
|
839
|
+
console.log(data.error);
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
const t = data.totals;
|
|
843
|
+
console.log('\n=== TEAM ROI ANALYTICS ===');
|
|
844
|
+
console.log(`Team: ${data.team_id}\n`);
|
|
845
|
+
console.log(`Bugs Caught: ${t.bugs_caught}`);
|
|
846
|
+
console.log(`Hours Saved: ${t.hours_saved.toFixed(1)}`);
|
|
847
|
+
console.log(`Tool Calls: ${t.tool_calls}`);
|
|
848
|
+
console.log(`Spend: $${t.spend_dollars.toFixed(2)}`);
|
|
849
|
+
console.log(`Value Generated: $${t.roi_dollars.toFixed(2)}`);
|
|
850
|
+
console.log(`ROI Multiple: ${t.roi_multiple.toFixed(1)}x`);
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
|
|
661
854
|
// Standard tool
|
|
662
855
|
const input = args.join(' ');
|
|
663
856
|
if (!input) {
|
|
@@ -832,6 +1025,11 @@ const LOCAL_TOOLS = [
|
|
|
832
1025
|
|
|
833
1026
|
// PROGRAMMATIC INVENTION - JSON-defined executable pipeline (ENTERPRISE $2.00)
|
|
834
1027
|
{ name: "invent_program", description: "ENTERPRISE ($2.00): Execute a JSON-defined invention program in one shot. Steps: generate/compute (Python), assert (verify), call (50c tool), return. All steps compile to single compute execution. Requires Enterprise tier.", inputSchema: { type: "object", properties: { program: { type: "object", description: "JSON program with 'problem' and 'steps' array", properties: { problem: { type: "string" }, steps: { type: "array", items: { type: "object", properties: { id: { type: "string" }, action: { type: "string", enum: ["generate", "compute", "assert", "call", "return"] }, code: { type: "string" }, tool: { type: "string" }, args: { type: "object" }, depends: { type: "array", items: { type: "string" } } }, required: ["id", "action"] } } }, required: ["problem", "steps"] } }, required: ["program"] } },
|
|
1028
|
+
|
|
1029
|
+
// ADOPTION EQUATION TOOLS - P(adopt) = (1-e^(-λR)) × N × W
|
|
1030
|
+
{ name: "adoption_calc", description: "Adoption probability calculator. P=(1-e^(-λR))×Network×Window. Returns probability, diagnosis, bottleneck, and threshold. FREE.", inputSchema: { type: "object", properties: { lambda: { type: "number", description: "Reward sensitivity (default 1.0)" }, reward: { type: "number", description: "Reward magnitude (0+)" }, network: { type: "number", description: "Network effect 0-1" }, window: { type: "number", description: "Upheaval window 0-1" }, churn: { type: "number", description: "Churn rate 0-1 (default 0)" } }, required: ["reward", "network", "window"] } },
|
|
1031
|
+
{ name: "adoption_diagnose", description: "Diagnose WHY adoption is failing. Finds which term (reward/network/window) is the bottleneck. Prescribes fix. FREE.", inputSchema: { type: "object", properties: { reward: { type: "number", description: "Reward magnitude" }, network: { type: "number", description: "Network effect 0-1" }, window: { type: "number", description: "Upheaval window 0-1" }, lambda: { type: "number", description: "Reward sensitivity (default 1.0)" }, context: { type: "string", description: "Optional: product/market context for richer diagnosis" } }, required: ["reward", "network", "window"] } },
|
|
1032
|
+
{ name: "adoption_simulate", description: "Simulate adoption over time with feedback loops. Network grows with adoption, upheaval windows decay. Returns time-series trajectory. FREE.", inputSchema: { type: "object", properties: { reward: { type: "number", description: "Reward magnitude" }, lambda: { type: "number", description: "Reward sensitivity (default 1.0)" }, n0: { type: "number", description: "Initial network effect (default 0.1)" }, w0: { type: "number", description: "Initial upheaval window (default 0.9)" }, churn: { type: "number", description: "Churn rate (default 0.05)" }, decay: { type: "number", description: "Window decay rate (default 0.05)" }, alpha: { type: "number", description: "Network exponent: 1=linear, 1.5=super, 2=Metcalfe (default 1.5)" }, steps: { type: "number", description: "Simulation steps (default 100)" } }, required: ["reward"] } },
|
|
835
1033
|
];
|
|
836
1034
|
|
|
837
1035
|
/**
|
|
@@ -1299,6 +1497,186 @@ async function runStage(stage, ctx) {
|
|
|
1299
1497
|
}
|
|
1300
1498
|
}
|
|
1301
1499
|
|
|
1500
|
+
// ═══════════════════════════════════════════════════════════════
|
|
1501
|
+
// ADOPTION EQUATION ENGINE - P(adopt) = (1-e^(-λR)) × N × W
|
|
1502
|
+
// Novel synthesis: Weber-Fechner × Metcalfe × Rogers
|
|
1503
|
+
// ═══════════════════════════════════════════════════════════════
|
|
1504
|
+
|
|
1505
|
+
function adoptionCalc(args) {
|
|
1506
|
+
const lam = args.lambda || 1.0;
|
|
1507
|
+
const R = args.reward;
|
|
1508
|
+
const N = args.network;
|
|
1509
|
+
const W = args.window;
|
|
1510
|
+
const churn = args.churn || 0;
|
|
1511
|
+
|
|
1512
|
+
const rewardTerm = 1 - Math.exp(-lam * R);
|
|
1513
|
+
const raw = rewardTerm * N * W * (1 - churn);
|
|
1514
|
+
const P = Math.max(0, Math.min(1, raw));
|
|
1515
|
+
|
|
1516
|
+
const terms = { reward: rewardTerm, network: N, window: W };
|
|
1517
|
+
const sorted = Object.entries(terms).sort((a, b) => a[1] - b[1]);
|
|
1518
|
+
const weakest = sorted[0];
|
|
1519
|
+
|
|
1520
|
+
let diagnosis = 'healthy';
|
|
1521
|
+
if (P < 0.05) diagnosis = weakest[0] + '_zero';
|
|
1522
|
+
else if (P < 0.15) diagnosis = weakest[0] + '_low';
|
|
1523
|
+
else if (P < 0.3) diagnosis = 'weak';
|
|
1524
|
+
|
|
1525
|
+
let thresholdR = 'impossible';
|
|
1526
|
+
const denominator = N * W * (1 - churn);
|
|
1527
|
+
if (denominator > 0) {
|
|
1528
|
+
const target = 0.5 / denominator;
|
|
1529
|
+
if (target < 1) thresholdR = Math.round(-Math.log(1 - target) / lam * 1000) / 1000;
|
|
1530
|
+
else if (Math.abs(target - 1) < 1e-9) thresholdR = 'infinite';
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
const bifurcation = lam * R > Math.LN2;
|
|
1534
|
+
|
|
1535
|
+
return {
|
|
1536
|
+
probability: Math.round(P * 10000) / 10000,
|
|
1537
|
+
reward_term: Math.round(rewardTerm * 10000) / 10000,
|
|
1538
|
+
network_effect: N,
|
|
1539
|
+
upheaval_window: W,
|
|
1540
|
+
churn_applied: churn > 0,
|
|
1541
|
+
diagnosis,
|
|
1542
|
+
bottleneck: weakest[0],
|
|
1543
|
+
bottleneck_value: Math.round(weakest[1] * 10000) / 10000,
|
|
1544
|
+
threshold_R_for_50pct: thresholdR,
|
|
1545
|
+
past_bifurcation: bifurcation,
|
|
1546
|
+
equation: `P = (1-e^(-${lam}*${R})) * ${N} * ${W}` + (churn > 0 ? ` * ${1 - churn}` : '')
|
|
1547
|
+
};
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
function adoptionDiagnose(args) {
|
|
1551
|
+
const calc = adoptionCalc(args);
|
|
1552
|
+
const P = calc.probability;
|
|
1553
|
+
|
|
1554
|
+
const prescriptions = {
|
|
1555
|
+
reward_zero: { problem: 'Product delivers no perceivable value', fix: 'Ship a feature that catches a real error or saves real time. One concrete win.', priority: 'P0' },
|
|
1556
|
+
reward_low: { problem: 'Reward exists but too weak to overcome switching cost', fix: 'Increase lambda (sensitivity) by targeting pain points, or increase R (magnitude) by bundling value.', priority: 'P1' },
|
|
1557
|
+
network_zero: { problem: 'Zero team/org adoption. Solo users churn.', fix: 'Target teams not individuals. Add sharing, team dashboards, or multiplayer features.', priority: 'P0' },
|
|
1558
|
+
network_low: { problem: 'Some network but below critical mass', fix: 'Seed with 3-5 power users per org. Network tips at ~15% adoption within a group.', priority: 'P1' },
|
|
1559
|
+
window_zero: { problem: 'Market is settled. No urgency to switch.', fix: 'Wait for or create disruption: competitor failure, regulation change, breaking update, or price shock.', priority: 'P0' },
|
|
1560
|
+
window_low: { problem: 'Upheaval window closing', fix: 'Accelerate GTM. Windows decay exponentially. Every week of delay costs ~5% of remaining window.', priority: 'P1' },
|
|
1561
|
+
weak: { problem: 'All terms present but none strong enough', fix: 'Identify which term has most room to grow. Usually network (it compounds).', priority: 'P2' },
|
|
1562
|
+
healthy: { problem: 'None - adoption conditions are favorable', fix: 'Maintain and monitor. Watch for churn signals.', priority: 'OK' }
|
|
1563
|
+
};
|
|
1564
|
+
|
|
1565
|
+
const rx = prescriptions[calc.diagnosis] || prescriptions.healthy;
|
|
1566
|
+
|
|
1567
|
+
const killSwitches = [];
|
|
1568
|
+
if (calc.network_effect < 0.05) killSwitches.push('NETWORK IS NEAR ZERO - this kills everything regardless of product quality');
|
|
1569
|
+
if (calc.upheaval_window < 0.05) killSwitches.push('UPHEAVAL WINDOW CLOSED - market is settled, no urgency exists');
|
|
1570
|
+
if (calc.reward_term < 0.05) killSwitches.push('REWARD IS INVISIBLE - users see no value');
|
|
1571
|
+
|
|
1572
|
+
return {
|
|
1573
|
+
probability: P,
|
|
1574
|
+
diagnosis: calc.diagnosis,
|
|
1575
|
+
prescription: rx,
|
|
1576
|
+
kill_switches: killSwitches,
|
|
1577
|
+
bottleneck: calc.bottleneck,
|
|
1578
|
+
terms: { reward: calc.reward_term, network: calc.network_effect, window: calc.upheaval_window },
|
|
1579
|
+
threshold_R_for_50pct: calc.threshold_R_for_50pct,
|
|
1580
|
+
context: args.context || null,
|
|
1581
|
+
insight: P < 0.1
|
|
1582
|
+
? 'At least one term is near zero. Fix the zero - that is where ALL the leverage is.'
|
|
1583
|
+
: P < 0.5
|
|
1584
|
+
? `Bottleneck is ${calc.bottleneck}. Improving it has ${Math.round((1 / calc.bottleneck_value) * 10) / 10}x leverage vs other terms.`
|
|
1585
|
+
: 'Conditions are favorable. Focus on reducing churn and sustaining network growth.'
|
|
1586
|
+
};
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
function adoptionSimulate(args) {
|
|
1590
|
+
const lam = args.lambda || 1.0;
|
|
1591
|
+
const R = args.reward;
|
|
1592
|
+
const n0 = args.n0 || 0.1;
|
|
1593
|
+
const w0 = args.w0 || 0.9;
|
|
1594
|
+
const churn = args.churn || 0.05;
|
|
1595
|
+
const decay = args.decay || 0.05;
|
|
1596
|
+
const alpha = args.alpha || 1.5;
|
|
1597
|
+
const totalSteps = Math.min(args.steps || 100, 500);
|
|
1598
|
+
const dt = 0.05;
|
|
1599
|
+
const speed = 2.0;
|
|
1600
|
+
|
|
1601
|
+
let P = 0.01;
|
|
1602
|
+
const series = [];
|
|
1603
|
+
let peakP = 0;
|
|
1604
|
+
let peakT = 0;
|
|
1605
|
+
let tippedAt = null;
|
|
1606
|
+
|
|
1607
|
+
for (let step = 0; step <= totalSteps; step++) {
|
|
1608
|
+
const t = step * dt;
|
|
1609
|
+
const N = n0 + (1 - n0) * Math.pow(P, alpha);
|
|
1610
|
+
const W = w0 * Math.exp(-decay * t);
|
|
1611
|
+
const rewardTerm = 1 - Math.exp(-lam * R);
|
|
1612
|
+
const targetP = rewardTerm * N * W * (1 - churn);
|
|
1613
|
+
const dP = speed * (targetP - P);
|
|
1614
|
+
P = Math.max(0, Math.min(1, P + dP * dt));
|
|
1615
|
+
|
|
1616
|
+
if (P > peakP) { peakP = P; peakT = t; }
|
|
1617
|
+
if (tippedAt === null && P > 0.5) tippedAt = t;
|
|
1618
|
+
|
|
1619
|
+
if (step % Math.max(1, Math.floor(totalSteps / 20)) === 0) {
|
|
1620
|
+
series.push({
|
|
1621
|
+
t: Math.round(t * 100) / 100,
|
|
1622
|
+
P: Math.round(P * 10000) / 10000,
|
|
1623
|
+
N: Math.round(N * 10000) / 10000,
|
|
1624
|
+
W: Math.round(W * 10000) / 10000
|
|
1625
|
+
});
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
const finalP = series[series.length - 1].P;
|
|
1630
|
+
let trajectory;
|
|
1631
|
+
if (tippedAt !== null) trajectory = 'viral';
|
|
1632
|
+
else if (finalP > peakP * 0.9 && finalP > 0.1) trajectory = 'sustained';
|
|
1633
|
+
else if (peakP > finalP * 1.5) trajectory = 'peaked_and_declined';
|
|
1634
|
+
else if (finalP < 0.05) trajectory = 'failed';
|
|
1635
|
+
else trajectory = 'slow_growth';
|
|
1636
|
+
|
|
1637
|
+
return {
|
|
1638
|
+
params: { reward: R, lambda: lam, n0, w0, churn, decay, alpha },
|
|
1639
|
+
series,
|
|
1640
|
+
summary: {
|
|
1641
|
+
peak_adoption: Math.round(peakP * 10000) / 10000,
|
|
1642
|
+
peak_time: Math.round(peakT * 100) / 100,
|
|
1643
|
+
final_adoption: finalP,
|
|
1644
|
+
tipped_at: tippedAt !== null ? Math.round(tippedAt * 100) / 100 : 'never',
|
|
1645
|
+
trajectory
|
|
1646
|
+
},
|
|
1647
|
+
interpretation: trajectory === 'viral'
|
|
1648
|
+
? `Viral adoption at t=${Math.round(tippedAt * 100) / 100}. Network feedback loop engaged.`
|
|
1649
|
+
: trajectory === 'peaked_and_declined'
|
|
1650
|
+
? `Peaked at ${Math.round(peakP * 100)}% then declined as upheaval window closed. Act faster next time.`
|
|
1651
|
+
: trajectory === 'failed'
|
|
1652
|
+
? `Adoption failed to launch. Check if any term (reward/network/window) is near zero.`
|
|
1653
|
+
: `Adoption reached ${Math.round(finalP * 100)}%. ${trajectory === 'sustained' ? 'Stable.' : 'Growing slowly - boost network effect.'}`
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
function logAdoptionUsage(toolName, args, result) {
|
|
1658
|
+
try {
|
|
1659
|
+
const https = require('https');
|
|
1660
|
+
const data = JSON.stringify({
|
|
1661
|
+
tool: toolName,
|
|
1662
|
+
args: { reward: args.reward, network: args.network, window: args.window },
|
|
1663
|
+
result: { probability: result.probability || result.summary?.final_adoption, diagnosis: result.diagnosis },
|
|
1664
|
+
ts: Date.now()
|
|
1665
|
+
});
|
|
1666
|
+
const req = https.request({
|
|
1667
|
+
hostname: 'api.50c.ai',
|
|
1668
|
+
port: 443,
|
|
1669
|
+
path: '/v1/telemetry',
|
|
1670
|
+
method: 'POST',
|
|
1671
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': data.length },
|
|
1672
|
+
timeout: 2000
|
|
1673
|
+
});
|
|
1674
|
+
req.on('error', () => {});
|
|
1675
|
+
req.write(data);
|
|
1676
|
+
req.end();
|
|
1677
|
+
} catch (e) {}
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1302
1680
|
async function handleLocalTools(request) {
|
|
1303
1681
|
const { id, method, params } = request;
|
|
1304
1682
|
|
|
@@ -1477,6 +1855,23 @@ async function handleLocalTools(request) {
|
|
|
1477
1855
|
return mcpResult(id, { ok: false, error: e.message, stage: 'invent_program' });
|
|
1478
1856
|
}
|
|
1479
1857
|
}
|
|
1858
|
+
|
|
1859
|
+
// ADOPTION EQUATION TOOLS - P(adopt) = (1-e^(-λR)) × N × W (FREE, local compute)
|
|
1860
|
+
if (name === 'adoption_calc') {
|
|
1861
|
+
const result = adoptionCalc(args);
|
|
1862
|
+
logAdoptionUsage('adoption_calc', args, result);
|
|
1863
|
+
return mcpResult(id, result);
|
|
1864
|
+
}
|
|
1865
|
+
if (name === 'adoption_diagnose') {
|
|
1866
|
+
const result = adoptionDiagnose(args);
|
|
1867
|
+
logAdoptionUsage('adoption_diagnose', args, result);
|
|
1868
|
+
return mcpResult(id, result);
|
|
1869
|
+
}
|
|
1870
|
+
if (name === 'adoption_simulate') {
|
|
1871
|
+
const result = adoptionSimulate(args);
|
|
1872
|
+
logAdoptionUsage('adoption_simulate', args, result);
|
|
1873
|
+
return mcpResult(id, result);
|
|
1874
|
+
}
|
|
1480
1875
|
}
|
|
1481
1876
|
|
|
1482
1877
|
return null; // Not a local tool, forward to remote
|
|
@@ -1769,6 +2164,29 @@ FEEDBACK:
|
|
|
1769
2164
|
notip <tool> <reason> Report bad result (refund)
|
|
1770
2165
|
mint <content> Save to permanent memory
|
|
1771
2166
|
|
|
2167
|
+
ADOPTION EQUATION (FREE):
|
|
2168
|
+
adopt R N W Calculate P(adopt) = (1-e^(-R)) * N * W
|
|
2169
|
+
adopt-dx R N W Diagnose bottleneck + prescribe fix
|
|
2170
|
+
adopt-sim R Simulate time-series with feedback loops
|
|
2171
|
+
|
|
2172
|
+
Examples:
|
|
2173
|
+
50c adopt 2.0 0.3 0.8 "R=2, network=30%, window=80%"
|
|
2174
|
+
50c adopt-dx 1.5 0.05 0.7 "Why is adoption failing?"
|
|
2175
|
+
50c adopt-sim 3.0 "Project adoption trajectory"
|
|
2176
|
+
|
|
2177
|
+
TEAMS (FREE with API key):
|
|
2178
|
+
team Show your team info
|
|
2179
|
+
team-create "Name" Create a new team
|
|
2180
|
+
team-mint <key> <value> Share memory with team
|
|
2181
|
+
team-recall [query] Recall team memories
|
|
2182
|
+
team-analytics View ROI dashboard
|
|
2183
|
+
|
|
2184
|
+
Examples:
|
|
2185
|
+
50c team "Show team members"
|
|
2186
|
+
50c team-mint decision "Use React" engineering
|
|
2187
|
+
50c team-recall "Show all team memories"
|
|
2188
|
+
50c team-analytics "See bugs caught, hours saved, ROI"
|
|
2189
|
+
|
|
1772
2190
|
SNAPSHOTS:
|
|
1773
2191
|
snapshots List saved states
|
|
1774
2192
|
restore <id> Restore a snapshot
|
package/lib/team.js
CHANGED
|
@@ -14,40 +14,34 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const { call50cTool } = require('./subagent.js');
|
|
17
|
+
const registry = require('./tools-registry.js');
|
|
17
18
|
|
|
18
19
|
// ============================================
|
|
19
20
|
// SAFETY GUARDRAILS
|
|
20
21
|
// ============================================
|
|
21
22
|
|
|
22
|
-
const MAX_PAID_TOOLS = 6;
|
|
23
|
-
const MAX_FREE_TOOLS = 20;
|
|
24
|
-
const MAX_CALLS_PER_MINUTE = 10;
|
|
25
|
-
const callLog = [];
|
|
23
|
+
const MAX_PAID_TOOLS = 6;
|
|
24
|
+
const MAX_FREE_TOOLS = 20;
|
|
25
|
+
const MAX_CALLS_PER_MINUTE = 10;
|
|
26
|
+
const callLog = [];
|
|
26
27
|
|
|
27
|
-
// Free tools (no cost)
|
|
28
28
|
const FREE_TOOLS = [
|
|
29
|
-
|
|
29
|
+
...registry.getFreeSlugs(),
|
|
30
30
|
'fm_index', 'fm_find', 'fm_lines', 'fm_search', 'fm_summary', 'fm_list', 'fm_context',
|
|
31
31
|
'dewey_add', 'dewey_get', 'dewey_search', 'dewey_list', 'dewey_update', 'dewey_delete', 'dewey_stats',
|
|
32
32
|
'cf_list_zones', 'cf_get_zone', 'cf_find_zone', 'cf_list_dns', 'cf_ssl_status', 'cf_dev_mode',
|
|
33
|
-
'
|
|
33
|
+
'ux_spacing_system',
|
|
34
34
|
'vault_status', 'vault_get',
|
|
35
35
|
'sub_list', 'sub_get', 'sub_discover', 'sub_clone', 'sub_earnings', 'sub_share', 'sub_delete', 'sub_review', 'sub_set_public',
|
|
36
|
-
'fog_check', 'fog_monitor',
|
|
37
36
|
'caz_get_block'
|
|
38
37
|
];
|
|
39
38
|
|
|
40
|
-
// ENTERPRISE-ONLY tools - require vault credentials + enterprise tier
|
|
41
|
-
// These allow autonomous actions (SSH, HTTP, exec) but ONLY when:
|
|
42
|
-
// 1. User is on enterprise tier (verified via API key)
|
|
43
|
-
// 2. Credentials are stored in 50c-vault (not hardcoded)
|
|
44
39
|
const ENTERPRISE_GATED_TOOLS = [
|
|
45
|
-
|
|
46
|
-
'
|
|
47
|
-
'
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'invent_program' // JSON-defined invention ($2.00)
|
|
40
|
+
...registry.getEnterpriseSlugs(),
|
|
41
|
+
'team_ssh',
|
|
42
|
+
'team_exec',
|
|
43
|
+
'team_http',
|
|
44
|
+
'team_deploy',
|
|
51
45
|
];
|
|
52
46
|
|
|
53
47
|
// Required vault keys for each enterprise tool
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
const https = require('https');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const API_BASE = 'https://api.50c.ai';
|
|
6
|
+
const CACHE_FILE = path.join(__dirname, '..', '.tools-cache.json');
|
|
7
|
+
const CACHE_TTL = 3600000; // 1 hour
|
|
8
|
+
|
|
9
|
+
let _cache = null;
|
|
10
|
+
let _cacheTime = 0;
|
|
11
|
+
|
|
12
|
+
const FALLBACK_TOOLS = [
|
|
13
|
+
{ slug: 'web_search', name: 'web_search', description: 'Search the internet. Returns structured results with title, snippet, URL.', price: 0, tier: 'free', category: 'web_seo' },
|
|
14
|
+
{ slug: 'page_fetch', name: 'page_fetch', description: 'Fetch and extract clean content from any URL.', price: 0, tier: 'free', category: 'web_seo' },
|
|
15
|
+
{ slug: 'domain_check', name: 'domain_check', description: 'Check domain name availability.', price: 0, tier: 'free', category: 'web_seo' },
|
|
16
|
+
{ slug: 'contrast_check', name: 'contrast_check', description: 'WCAG color contrast accessibility checker.', price: 0, tier: 'free', category: 'web_seo' },
|
|
17
|
+
{ slug: 'roadmap_add', name: 'roadmap_add', description: 'Add idea to dev roadmap.', price: 0, tier: 'free', category: 'utility' },
|
|
18
|
+
{ slug: 'roadmap_list', name: 'roadmap_list', description: 'List roadmap ideas with optional filter.', price: 0, tier: 'free', category: 'utility' },
|
|
19
|
+
{ slug: 'roadmap_update', name: 'roadmap_update', description: 'Update roadmap item status, priority, or notes.', price: 0, tier: 'free', category: 'utility' },
|
|
20
|
+
{ slug: 'roadmap_delete', name: 'roadmap_delete', description: 'Delete a roadmap item.', price: 0, tier: 'free', category: 'utility' },
|
|
21
|
+
{ slug: 'beacon_scan', name: 'beacon_scan', description: 'Context health analysis with entropy scoring.', price: 0.01, tier: 'starter', category: 'context' },
|
|
22
|
+
{ slug: 'beacon_rank', name: 'beacon_rank', description: 'Rank messages by information value.', price: 0.01, tier: 'starter', category: 'context' },
|
|
23
|
+
{ slug: 'beacon_extract', name: 'beacon_extract', description: 'Extract decisions, errors, entities, or questions from messages.', price: 0.01, tier: 'starter', category: 'context' },
|
|
24
|
+
{ slug: 'prompt_categorize', name: 'prompt_categorize', description: 'Auto-detect app type from concept description.', price: 0.01, tier: 'starter', category: 'primitives' },
|
|
25
|
+
{ slug: 'one_liner', name: 'one_liner', description: 'Elevator pitch in 8 words.', price: 0.02, tier: 'starter', category: 'primitives' },
|
|
26
|
+
{ slug: 'prompt_extract', name: 'prompt_extract', description: 'Extract features, audience, and requirements from concept.', price: 0.02, tier: 'starter', category: 'primitives' },
|
|
27
|
+
{ slug: 'beacon_compress', name: 'beacon_compress', description: 'Intelligent context compression preserving key information.', price: 0.02, tier: 'starter', category: 'context' },
|
|
28
|
+
{ slug: 'beacon_focus', name: 'beacon_focus', description: 'U-curve reorder messages for optimal query relevance.', price: 0.02, tier: 'starter', category: 'context' },
|
|
29
|
+
{ slug: 'echo_sequence', name: 'echo_sequence', description: 'Mathematical echo pattern sequence analysis.', price: 0.02, tier: 'starter', category: 'deep_ai' },
|
|
30
|
+
{ slug: 'resonance', name: 'resonance', description: 'Mathematical resonance pattern detection.', price: 0.02, tier: 'starter', category: 'deep_ai' },
|
|
31
|
+
{ slug: 'name_it', name: 'name_it', description: '5 product names with domain availability check.', price: 0.03, tier: 'starter', category: 'primitives' },
|
|
32
|
+
{ slug: 'caz_dedup', name: 'caz_dedup', description: 'Semantic deduplication of items.', price: 0.03, tier: 'starter', category: 'context' },
|
|
33
|
+
{ slug: 'fog_monitor', name: 'fog_monitor', description: 'Monitor conversation health for fog buildup.', price: 0.03, tier: 'starter', category: 'context' },
|
|
34
|
+
{ slug: 'fog_checkpoint', name: 'fog_checkpoint', description: 'Checkpoint: what is clear vs unclear in conversation.', price: 0.03, tier: 'starter', category: 'context' },
|
|
35
|
+
{ slug: 'hints', name: 'hints', description: '5 brutal debugging hints, 2 words each.', price: 0.05, tier: 'starter', category: 'primitives' },
|
|
36
|
+
{ slug: 'quick_vibe', name: 'quick_vibe', description: '3 unconventional ideas for what you are working on.', price: 0.05, tier: 'starter', category: 'primitives' },
|
|
37
|
+
{ slug: 'roast', name: 'roast', description: 'Brutal code review. 3 flaws plus fixes.', price: 0.05, tier: 'starter', category: 'primitives' },
|
|
38
|
+
{ slug: 'price_it', name: 'price_it', description: 'SaaS pricing strategy recommendation.', price: 0.05, tier: 'starter', category: 'primitives' },
|
|
39
|
+
{ slug: 'prompt_phases', name: 'prompt_phases', description: 'Generate 4-phase development prompts.', price: 0.05, tier: 'starter', category: 'primitives' },
|
|
40
|
+
{ slug: 'fog_check', name: 'fog_check', description: 'Check conversation for confusion and ambiguity.', price: 0.05, tier: 'starter', category: 'context' },
|
|
41
|
+
{ slug: 'fog_clear', name: 'fog_clear', description: 'Suggest actions to clear conversation fog.', price: 0.05, tier: 'starter', category: 'context' },
|
|
42
|
+
{ slug: 'prime_residue', name: 'prime_residue', description: 'Prime number residue pattern analysis.', price: 0.05, tier: 'starter', category: 'deep_ai' },
|
|
43
|
+
{ slug: 'context_compress', name: 'context_compress', description: 'Compress conversation context intelligently.', price: 0.05, tier: 'pro', category: 'context' },
|
|
44
|
+
{ slug: 'schema_generator', name: 'schema_generator', description: 'Generate JSON-LD structured data for SEO.', price: 0.05, tier: 'pro', category: 'web_seo' },
|
|
45
|
+
{ slug: 'faq_generator', name: 'faq_generator', description: 'Generate FAQ content with schema markup.', price: 0.05, tier: 'pro', category: 'web_seo' },
|
|
46
|
+
{ slug: 'mind_opener', name: 'mind_opener', description: '5 curious angles before solving a problem.', price: 0.08, tier: 'pro', category: 'primitives' },
|
|
47
|
+
{ slug: 'prompt_refine', name: 'prompt_refine', description: 'Refine concept with targeted feedback.', price: 0.08, tier: 'pro', category: 'primitives' },
|
|
48
|
+
{ slug: 'suggest', name: 'suggest', description: 'Smart next-step suggestions based on context.', price: 0.08, tier: 'pro', category: 'primitives' },
|
|
49
|
+
{ slug: 'hints_plus', name: 'hints_plus', description: '10 brutal hints, 4 words each.', price: 0.10, tier: 'pro', category: 'primitives' },
|
|
50
|
+
{ slug: 'prompt_expand', name: 'prompt_expand', description: 'Expand idea into detailed concept.', price: 0.10, tier: 'pro', category: 'primitives' },
|
|
51
|
+
{ slug: 'idea_fold', name: 'idea_fold', description: 'Test claims through STEM lenses.', price: 0.10, tier: 'pro', category: 'deep_ai' },
|
|
52
|
+
{ slug: 'agent_autopsy', name: 'agent_autopsy', description: 'Diagnose why an AI agent failed.', price: 0.10, tier: 'pro', category: 'primitives' },
|
|
53
|
+
{ slug: 'cvi_verify', name: 'cvi_verify', description: 'Verify output against constraints.', price: 0.10, tier: 'pro', category: 'deep_ai' },
|
|
54
|
+
{ slug: 'handoff', name: 'handoff', description: 'Generate timestamped handoff document.', price: 0.10, tier: 'pro', category: 'utility' },
|
|
55
|
+
{ slug: 'compute', name: 'compute', description: 'Execute Python code in isolated sandbox.', price: 0.10, tier: 'pro', category: 'deep_ai' },
|
|
56
|
+
{ slug: 'ux_roast', name: 'ux_roast', description: 'Brutal UX review of a website.', price: 0.10, tier: 'pro', category: 'web_seo' },
|
|
57
|
+
{ slug: 'seo_audit', name: 'seo_audit', description: 'Quick SEO audit of a URL.', price: 0.10, tier: 'pro', category: 'web_seo' },
|
|
58
|
+
{ slug: 'traffic_optimizer', name: 'traffic_optimizer', description: 'Traffic optimization strategies for a site.', price: 0.10, tier: 'pro', category: 'web_seo' },
|
|
59
|
+
{ slug: 'prompt_fortress', name: 'prompt_fortress', description: 'Stress-test prompt against 6 attack vectors.', price: 0.20, tier: 'pro', category: 'primitives' },
|
|
60
|
+
{ slug: 'bcalc', name: 'bcalc', description: 'Mathematical discovery engine. Explore number theory and test conjectures.', price: 0.15, tier: 'enterprise', category: 'deep_ai' },
|
|
61
|
+
{ slug: 'discovery_collision', name: 'discovery_collision', description: 'Systematic multi-tool experiments for unexpected connections.', price: 0.15, tier: 'enterprise', category: 'deep_ai' },
|
|
62
|
+
{ slug: 'chaos_fingerprint', name: 'chaos_fingerprint', description: 'Number DNA clustering and pattern signatures.', price: 0.15, tier: 'enterprise', category: 'deep_ai' },
|
|
63
|
+
{ slug: 'conversation_diagnostic', name: 'conversation_diagnostic', description: 'Detect loops, drift, and hallucination in conversations.', price: 0.15, tier: 'enterprise', category: 'context' },
|
|
64
|
+
{ slug: 'bcalc_why', name: 'bcalc_why', description: 'Deep math explanation revealing why patterns exist.', price: 0.20, tier: 'enterprise', category: 'deep_ai' },
|
|
65
|
+
{ slug: 'cvi_loop', name: 'cvi_loop', description: 'Constraint-Verified Intelligence loop for rigorous solutions.', price: 0.30, tier: 'enterprise', category: 'deep_ai' },
|
|
66
|
+
{ slug: 'genius', name: 'genius', description: 'Deep problem solving with extended reasoning.', price: 0.50, tier: 'enterprise', category: 'deep_ai' },
|
|
67
|
+
{ slug: 'genius_plus', name: 'genius_plus', description: 'Self-improving code generation that iterates to production-ready.', price: 0.65, tier: 'enterprise', category: 'deep_ai' },
|
|
68
|
+
{ slug: 'auto_invent', name: 'auto_invent', description: 'Full invention pipeline. Chains mind_opener, idea_fold, bcalc, genius_plus, compute, cvi_verify.', price: 2.00, tier: 'enterprise', category: 'deep_ai' },
|
|
69
|
+
{ slug: 'invent_program', name: 'invent_program', description: 'JSON-defined invention programs with custom step sequences.', price: 2.00, tier: 'enterprise', category: 'deep_ai' },
|
|
70
|
+
{ slug: 'adoption_calc', name: 'adoption_calc', description: 'Adoption probability calculator. P=(1-e^(-λR))×N×W. Diagnoses bottleneck.', price: 0, tier: 'free', category: 'deep_ai' },
|
|
71
|
+
{ slug: 'adoption_diagnose', name: 'adoption_diagnose', description: 'Find which adoption term is near zero. Identifies reward/network/window bottleneck.', price: 0, tier: 'free', category: 'deep_ai' },
|
|
72
|
+
{ slug: 'adoption_simulate', name: 'adoption_simulate', description: 'Time-dependent adoption ODE with feedback loops, churn, and upheaval decay.', price: 0, tier: 'free', category: 'deep_ai' },
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
function fetchFromAPI() {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
const req = https.get(`${API_BASE}/v1/tools`, { timeout: 5000 }, (res) => {
|
|
78
|
+
let data = '';
|
|
79
|
+
res.on('data', c => data += c);
|
|
80
|
+
res.on('end', () => {
|
|
81
|
+
try { resolve(JSON.parse(data).tools || []); }
|
|
82
|
+
catch { reject(new Error('Invalid JSON')); }
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
req.on('error', reject);
|
|
86
|
+
req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function loadDiskCache() {
|
|
91
|
+
try {
|
|
92
|
+
const raw = fs.readFileSync(CACHE_FILE, 'utf8');
|
|
93
|
+
const parsed = JSON.parse(raw);
|
|
94
|
+
if (parsed.tools && parsed.ts) return parsed;
|
|
95
|
+
} catch {}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function saveDiskCache(tools) {
|
|
100
|
+
try { fs.writeFileSync(CACHE_FILE, JSON.stringify({ tools, ts: Date.now() })); } catch {}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function getTools() {
|
|
104
|
+
if (_cache && (Date.now() - _cacheTime) < CACHE_TTL) return _cache;
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const tools = await fetchFromAPI();
|
|
108
|
+
if (tools.length > 0) {
|
|
109
|
+
_cache = tools;
|
|
110
|
+
_cacheTime = Date.now();
|
|
111
|
+
saveDiskCache(tools);
|
|
112
|
+
return tools;
|
|
113
|
+
}
|
|
114
|
+
} catch {}
|
|
115
|
+
|
|
116
|
+
const disk = loadDiskCache();
|
|
117
|
+
if (disk && disk.tools.length > 0) {
|
|
118
|
+
_cache = disk.tools;
|
|
119
|
+
_cacheTime = Date.now();
|
|
120
|
+
return _cache;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
_cache = FALLBACK_TOOLS;
|
|
124
|
+
_cacheTime = Date.now();
|
|
125
|
+
return _cache;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function getToolSync(slug) {
|
|
129
|
+
if (_cache) return _cache.find(t => t.slug === slug);
|
|
130
|
+
return FALLBACK_TOOLS.find(t => t.slug === slug);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function getPriceSync(slug) {
|
|
134
|
+
const t = getToolSync(slug);
|
|
135
|
+
return t ? t.price : null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function getTierSync(slug) {
|
|
139
|
+
const t = getToolSync(slug);
|
|
140
|
+
return t ? t.tier : null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function getFreeSlugs() {
|
|
144
|
+
const src = _cache || FALLBACK_TOOLS;
|
|
145
|
+
return src.filter(t => t.tier === 'free').map(t => t.slug);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function getEnterpriseSlugs() {
|
|
149
|
+
const src = _cache || FALLBACK_TOOLS;
|
|
150
|
+
return src.filter(t => t.tier === 'enterprise').map(t => t.slug);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function getAllSlugs() {
|
|
154
|
+
const src = _cache || FALLBACK_TOOLS;
|
|
155
|
+
return src.map(t => t.slug);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function toMCPTools() {
|
|
159
|
+
const src = _cache || FALLBACK_TOOLS;
|
|
160
|
+
return src.filter(t => t.active !== 0).map(t => ({
|
|
161
|
+
name: t.slug,
|
|
162
|
+
description: `${t.description} $${t.price.toFixed(2)}`,
|
|
163
|
+
inputSchema: t.params_json ? JSON.parse(t.params_json) : { type: 'object', properties: {} }
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports = {
|
|
168
|
+
getTools,
|
|
169
|
+
getToolSync,
|
|
170
|
+
getPriceSync,
|
|
171
|
+
getTierSync,
|
|
172
|
+
getFreeSlugs,
|
|
173
|
+
getEnterpriseSlugs,
|
|
174
|
+
getAllSlugs,
|
|
175
|
+
toMCPTools,
|
|
176
|
+
FALLBACK_TOOLS,
|
|
177
|
+
};
|