50c 3.5.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 +487 -1
- package/lib/invent-ui.js +717 -0
- package/lib/mcp-tv.js +1015 -0
- package/lib/team.js +12 -18
- package/lib/tools-registry.js +177 -0
- package/package.json +1 -1
package/bin/50c.js
CHANGED
|
@@ -124,6 +124,16 @@ const TOOL_COMMANDS = {
|
|
|
124
124
|
'chat': { tool: 'ide_conversation', special: 'chat' },
|
|
125
125
|
'refocus': { tool: 'llm_refocus', special: 'refocus' },
|
|
126
126
|
'invent': { tool: 'auto_invent', special: 'invent', cost: '$2.00' },
|
|
127
|
+
'invent-ui': { tool: 'auto_invent', special: 'invent-ui', cost: '$2.00' },
|
|
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' },
|
|
127
137
|
};
|
|
128
138
|
|
|
129
139
|
// Route command
|
|
@@ -247,6 +257,9 @@ function searchPacks(query) {
|
|
|
247
257
|
{ pack: 'beacon', tool: 'checkpoint', desc: 'Save state', cost: '$0.02' },
|
|
248
258
|
{ pack: 'router', tool: 'compare', desc: 'Multi-model compare', cost: '$0.05' },
|
|
249
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' },
|
|
250
263
|
];
|
|
251
264
|
|
|
252
265
|
return all.filter(t =>
|
|
@@ -264,7 +277,7 @@ async function cmdAdd(args) {
|
|
|
264
277
|
process.exit(1);
|
|
265
278
|
}
|
|
266
279
|
|
|
267
|
-
const valid = ['core', 'labs', 'beacon', 'router'];
|
|
280
|
+
const valid = ['core', 'labs', 'beacon', 'router', 'adoption'];
|
|
268
281
|
if (!valid.includes(pack)) {
|
|
269
282
|
console.error(`Unknown pack: ${pack}`);
|
|
270
283
|
console.error('Available: ' + valid.join(', '));
|
|
@@ -521,6 +534,62 @@ async function runToolCommand(cmd, args) {
|
|
|
521
534
|
return;
|
|
522
535
|
}
|
|
523
536
|
|
|
537
|
+
// INVENT-UI: Visual invention pipeline with browser UI
|
|
538
|
+
if (spec.special === 'invent-ui') {
|
|
539
|
+
let problem = '';
|
|
540
|
+
let rigor = 'deep';
|
|
541
|
+
let domain = 'code';
|
|
542
|
+
|
|
543
|
+
for (const arg of args) {
|
|
544
|
+
if (arg.startsWith('--rigor=')) rigor = arg.split('=')[1];
|
|
545
|
+
else if (arg.startsWith('--domain=')) domain = arg.split('=')[1];
|
|
546
|
+
else if (!arg.startsWith('--')) problem += (problem ? ' ' : '') + arg;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (!problem) {
|
|
550
|
+
console.error('Usage: 50c invent-ui "problem" [--rigor=deep] [--domain=math]');
|
|
551
|
+
console.error('Opens a browser window with real-time swarm visualization.');
|
|
552
|
+
process.exit(1);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
const { runInventWithUI } = require('../lib/invent-ui.js');
|
|
556
|
+
await runInventWithUI(problem, { domain, rigor });
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// MCP-TV: Universal MCP Visualization Platform (FREE)
|
|
561
|
+
if (spec.special === 'mcp-tv') {
|
|
562
|
+
let port = 50888;
|
|
563
|
+
let noOpen = false;
|
|
564
|
+
|
|
565
|
+
for (const arg of args) {
|
|
566
|
+
if (arg.startsWith('--port=')) port = parseInt(arg.split('=')[1]);
|
|
567
|
+
if (arg === '--no-open') noOpen = true;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
const { createServer } = require('../lib/mcp-tv.js');
|
|
571
|
+
const { spawn } = require('child_process');
|
|
572
|
+
|
|
573
|
+
createServer(port);
|
|
574
|
+
|
|
575
|
+
if (!noOpen) {
|
|
576
|
+
setTimeout(() => {
|
|
577
|
+
const url = `http://localhost:${port}`;
|
|
578
|
+
const platform = process.platform;
|
|
579
|
+
if (platform === 'win32') {
|
|
580
|
+
spawn('cmd', ['/c', 'start', url], { detached: true, stdio: 'ignore' }).unref();
|
|
581
|
+
} else if (platform === 'darwin') {
|
|
582
|
+
spawn('open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
583
|
+
} else {
|
|
584
|
+
spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
585
|
+
}
|
|
586
|
+
}, 500);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Keep process alive
|
|
590
|
+
return new Promise(() => {});
|
|
591
|
+
}
|
|
592
|
+
|
|
524
593
|
// INVENT: Enterprise invention pipeline
|
|
525
594
|
if (spec.special === 'invent') {
|
|
526
595
|
// Parse args: 50c invent "problem" --rigor=deep --domain=math --constraint="must be fast"
|
|
@@ -600,6 +669,188 @@ async function runToolCommand(cmd, args) {
|
|
|
600
669
|
return;
|
|
601
670
|
}
|
|
602
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
|
+
|
|
603
854
|
// Standard tool
|
|
604
855
|
const input = args.join(' ');
|
|
605
856
|
if (!input) {
|
|
@@ -774,6 +1025,11 @@ const LOCAL_TOOLS = [
|
|
|
774
1025
|
|
|
775
1026
|
// PROGRAMMATIC INVENTION - JSON-defined executable pipeline (ENTERPRISE $2.00)
|
|
776
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"] } },
|
|
777
1033
|
];
|
|
778
1034
|
|
|
779
1035
|
/**
|
|
@@ -1241,6 +1497,186 @@ async function runStage(stage, ctx) {
|
|
|
1241
1497
|
}
|
|
1242
1498
|
}
|
|
1243
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
|
+
|
|
1244
1680
|
async function handleLocalTools(request) {
|
|
1245
1681
|
const { id, method, params } = request;
|
|
1246
1682
|
|
|
@@ -1419,6 +1855,23 @@ async function handleLocalTools(request) {
|
|
|
1419
1855
|
return mcpResult(id, { ok: false, error: e.message, stage: 'invent_program' });
|
|
1420
1856
|
}
|
|
1421
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
|
+
}
|
|
1422
1875
|
}
|
|
1423
1876
|
|
|
1424
1877
|
return null; // Not a local tool, forward to remote
|
|
@@ -1688,6 +2141,16 @@ ENTERPRISE (auto_invent):
|
|
|
1688
2141
|
--rigor=fast|standard|deep|exhaustive (default: deep)
|
|
1689
2142
|
--domain=math|physics|code|business (default: code)
|
|
1690
2143
|
--constraint="text" Add constraint (repeatable)
|
|
2144
|
+
invent-ui "problem" [opts] Same as invent, but opens browser UI
|
|
2145
|
+
Real-time swarm visualization (MCP TV!)
|
|
2146
|
+
|
|
2147
|
+
MCP-TV (FREE):
|
|
2148
|
+
tv Start MCP-TV server - universal MCP visualizer
|
|
2149
|
+
tv --port=3000 Custom port (default: 50888)
|
|
2150
|
+
|
|
2151
|
+
Any MCP can stream events to MCP-TV:
|
|
2152
|
+
POST http://localhost:50888/stream
|
|
2153
|
+
{ "channel": "my-mcp", "event": "stage", "data": {...} }
|
|
1691
2154
|
|
|
1692
2155
|
TOOLS (beacon pack):
|
|
1693
2156
|
50c beacon.health Context health check (FREE)
|
|
@@ -1701,6 +2164,29 @@ FEEDBACK:
|
|
|
1701
2164
|
notip <tool> <reason> Report bad result (refund)
|
|
1702
2165
|
mint <content> Save to permanent memory
|
|
1703
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
|
+
|
|
1704
2190
|
SNAPSHOTS:
|
|
1705
2191
|
snapshots List saved states
|
|
1706
2192
|
restore <id> Restore a snapshot
|