50c 3.0.13 → 3.1.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 +226 -6
- package/lib/subagent.js +24 -2
- package/package.json +39 -39
package/bin/50c.js
CHANGED
|
@@ -600,8 +600,30 @@ function startMCPMode() {
|
|
|
600
600
|
const clean = line.trim();
|
|
601
601
|
if (!clean) return;
|
|
602
602
|
const request = JSON.parse(clean);
|
|
603
|
+
|
|
604
|
+
// Notifications (no id) don't get responses per JSON-RPC spec
|
|
605
|
+
if (request.method && request.method.startsWith('notifications/')) {
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Handle initialize locally
|
|
610
|
+
if (request.method === 'initialize') {
|
|
611
|
+
process.stdout.write(JSON.stringify({
|
|
612
|
+
jsonrpc: '2.0',
|
|
613
|
+
id: request.id,
|
|
614
|
+
result: {
|
|
615
|
+
protocolVersion: '2024-11-05',
|
|
616
|
+
serverInfo: { name: '50c', version: VERSION },
|
|
617
|
+
capabilities: { tools: {} }
|
|
618
|
+
}
|
|
619
|
+
}) + '\n');
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
|
|
603
623
|
const response = await handleMCPRequest(request);
|
|
604
|
-
|
|
624
|
+
if (response) {
|
|
625
|
+
process.stdout.write(JSON.stringify(response) + '\n');
|
|
626
|
+
}
|
|
605
627
|
} catch (e) {
|
|
606
628
|
process.stdout.write(JSON.stringify({
|
|
607
629
|
jsonrpc: '2.0',
|
|
@@ -648,8 +670,201 @@ const LOCAL_TOOLS = [
|
|
|
648
670
|
{ name: "team_ask", description: "50c Team: Ask the team to run any 50c tool. Uses your API key.", inputSchema: { type: "object", properties: { tool: { type: "string", description: "50c tool name (e.g., hints, roast, genius, bcalc)" }, args: { type: "object", description: "Tool arguments" } }, required: ["tool"] } },
|
|
649
671
|
{ name: "team_chain", description: "50c Team: Chain multiple tools together. Output flows via $prev placeholder.", inputSchema: { type: "object", properties: { steps: { type: "array", description: "Array of {tool, args} - use $prev for previous result", items: { type: "object" } }, input: { type: "string", description: "Initial input (optional)" } }, required: ["steps"] } },
|
|
650
672
|
{ name: "pre_publish", description: "Pre-publish verification. Thorough checks before npm/github/arxiv/medical publish. Profiles: npm, github, arxiv, medical, science, math. Uses AI tools (bCalc, genius+, web_search) for academic verification. FREE.", inputSchema: { type: "object", properties: { profile: { type: "string", description: "Verification profile: npm, github, arxiv, medical, science, math", enum: ["npm", "github", "arxiv", "medical", "science", "math"] }, cwd: { type: "string", description: "Directory to check (default: current)" }, save_receipt: { type: "boolean", description: "Save receipt as markdown file" } } } },
|
|
673
|
+
|
|
674
|
+
// ENTERPRISE PRESET - Auto-Invent pipeline
|
|
675
|
+
{ name: "auto_invent", description: "Enterprise: Full invention pipeline. Chains mind_opener → idea_fold → bcalc → genius_plus → compute → cvi_verify. Produces provable, verified solutions. $2.00", inputSchema: { type: "object", properties: { problem: { type: "string", description: "Problem or hypothesis to solve/prove" }, constraints: { type: "array", items: { type: "string" }, description: "Hard constraints the solution must satisfy" }, domain: { type: "string", description: "Domain hint: math, physics, engineering, business, code", enum: ["math", "physics", "engineering", "business", "code"] }, rigor: { type: "string", description: "Rigor level: standard (3 tools), deep (5 tools), exhaustive (all 6)", enum: ["standard", "deep", "exhaustive"], default: "deep" } }, required: ["problem"] } },
|
|
651
676
|
];
|
|
652
677
|
|
|
678
|
+
/**
|
|
679
|
+
* AUTO-INVENT: Enterprise invention pipeline
|
|
680
|
+
* Chains tools in order to produce provable, verified inventive solutions
|
|
681
|
+
*
|
|
682
|
+
* Pipeline (exhaustive):
|
|
683
|
+
* 1. mind_opener - 5 curious angles to explore the problem space
|
|
684
|
+
* 2. idea_fold - Test top angle through STEM lenses
|
|
685
|
+
* 3. bcalc - Mathematical discovery/verification
|
|
686
|
+
* 4. genius_plus - Self-improving code generation
|
|
687
|
+
* 5. compute - Execute and validate the solution
|
|
688
|
+
* 6. cvi_verify - Verify output against constraints
|
|
689
|
+
*
|
|
690
|
+
* Cost: ~$2.00 for exhaustive, ~$1.20 for deep, ~$0.60 for standard
|
|
691
|
+
*/
|
|
692
|
+
async function autoInvent(args) {
|
|
693
|
+
const { problem, constraints = [], domain = 'code', rigor = 'deep' } = args;
|
|
694
|
+
const startTime = Date.now();
|
|
695
|
+
|
|
696
|
+
// Define pipeline stages by rigor level
|
|
697
|
+
const PIPELINES = {
|
|
698
|
+
standard: ['mind_opener', 'genius_plus', 'cvi_verify'],
|
|
699
|
+
deep: ['mind_opener', 'idea_fold', 'bcalc', 'genius_plus', 'cvi_verify'],
|
|
700
|
+
exhaustive: ['mind_opener', 'idea_fold', 'bcalc', 'genius_plus', 'compute', 'cvi_verify']
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
const pipeline = PIPELINES[rigor] || PIPELINES.deep;
|
|
704
|
+
const results = {
|
|
705
|
+
ok: true,
|
|
706
|
+
problem,
|
|
707
|
+
domain,
|
|
708
|
+
rigor,
|
|
709
|
+
constraints,
|
|
710
|
+
stages: [],
|
|
711
|
+
invention: null,
|
|
712
|
+
verified: false,
|
|
713
|
+
proofs: [],
|
|
714
|
+
cost_estimate: rigor === 'exhaustive' ? '$2.00' : rigor === 'deep' ? '$1.20' : '$0.60'
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
let context = problem;
|
|
718
|
+
let bestAngle = null;
|
|
719
|
+
let mathProof = null;
|
|
720
|
+
let generatedCode = null;
|
|
721
|
+
|
|
722
|
+
for (const stage of pipeline) {
|
|
723
|
+
const stageStart = Date.now();
|
|
724
|
+
let stageResult = null;
|
|
725
|
+
|
|
726
|
+
try {
|
|
727
|
+
switch (stage) {
|
|
728
|
+
case 'mind_opener':
|
|
729
|
+
// Get 5 curious angles on the problem
|
|
730
|
+
stageResult = await call50cTool('mind_opener', { problem: context });
|
|
731
|
+
if (stageResult.angles && stageResult.angles.length > 0) {
|
|
732
|
+
bestAngle = stageResult.angles[0]; // Take the first/best angle
|
|
733
|
+
context = `${problem}\n\nApproach: ${bestAngle}`;
|
|
734
|
+
}
|
|
735
|
+
break;
|
|
736
|
+
|
|
737
|
+
case 'idea_fold':
|
|
738
|
+
// Test the chosen angle through STEM lenses
|
|
739
|
+
stageResult = await call50cTool('idea_fold', {
|
|
740
|
+
claim: bestAngle || problem,
|
|
741
|
+
context: `Domain: ${domain}. Problem: ${problem}`
|
|
742
|
+
});
|
|
743
|
+
if (stageResult.synthesis) {
|
|
744
|
+
context = `${context}\n\nSTEM Analysis: ${stageResult.synthesis}`;
|
|
745
|
+
}
|
|
746
|
+
break;
|
|
747
|
+
|
|
748
|
+
case 'bcalc':
|
|
749
|
+
// Mathematical discovery/verification
|
|
750
|
+
const mathQuery = domain === 'math' ? problem :
|
|
751
|
+
`Mathematical model for: ${bestAngle || problem}`;
|
|
752
|
+
stageResult = await call50cTool('bcalc', {
|
|
753
|
+
expression: mathQuery,
|
|
754
|
+
mode: 'explore'
|
|
755
|
+
});
|
|
756
|
+
if (stageResult.discovery || stageResult.result) {
|
|
757
|
+
mathProof = stageResult;
|
|
758
|
+
results.proofs.push({ type: 'mathematical', data: stageResult });
|
|
759
|
+
context = `${context}\n\nMath foundation: ${JSON.stringify(stageResult.discovery || stageResult.result)}`;
|
|
760
|
+
}
|
|
761
|
+
break;
|
|
762
|
+
|
|
763
|
+
case 'genius_plus':
|
|
764
|
+
// Self-improving code generation
|
|
765
|
+
const codePrompt = domain === 'code' ?
|
|
766
|
+
`${context}\n\nConstraints: ${constraints.join(', ')}` :
|
|
767
|
+
`Implement solution for: ${context}\n\nDomain: ${domain}\nConstraints: ${constraints.join(', ')}`;
|
|
768
|
+
stageResult = await call50cTool('genius_plus', { problem: codePrompt });
|
|
769
|
+
if (stageResult.code || stageResult.solution) {
|
|
770
|
+
generatedCode = stageResult.code || stageResult.solution;
|
|
771
|
+
results.invention = {
|
|
772
|
+
code: generatedCode,
|
|
773
|
+
explanation: stageResult.explanation || stageResult.reasoning,
|
|
774
|
+
iterations: stageResult.iterations || 1
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
break;
|
|
778
|
+
|
|
779
|
+
case 'compute':
|
|
780
|
+
// Execute and validate (only if we have code)
|
|
781
|
+
if (generatedCode) {
|
|
782
|
+
stageResult = await call50cTool('compute', { code: generatedCode });
|
|
783
|
+
results.proofs.push({ type: 'execution', data: stageResult });
|
|
784
|
+
if (stageResult.error) {
|
|
785
|
+
results.invention.execution_error = stageResult.error;
|
|
786
|
+
} else {
|
|
787
|
+
results.invention.execution_result = stageResult.result || stageResult.output;
|
|
788
|
+
}
|
|
789
|
+
} else {
|
|
790
|
+
stageResult = { skipped: true, reason: 'No code to execute' };
|
|
791
|
+
}
|
|
792
|
+
break;
|
|
793
|
+
|
|
794
|
+
case 'cvi_verify':
|
|
795
|
+
// Verify against constraints
|
|
796
|
+
if (constraints.length > 0 && results.invention) {
|
|
797
|
+
const output = typeof results.invention === 'string' ?
|
|
798
|
+
results.invention : JSON.stringify(results.invention);
|
|
799
|
+
stageResult = await call50cTool('cvi_verify', {
|
|
800
|
+
constraints,
|
|
801
|
+
output
|
|
802
|
+
});
|
|
803
|
+
results.verified = stageResult.passed || stageResult.all_passed || false;
|
|
804
|
+
results.proofs.push({ type: 'constraint_verification', data: stageResult });
|
|
805
|
+
} else {
|
|
806
|
+
stageResult = { skipped: true, reason: constraints.length === 0 ? 'No constraints specified' : 'No invention to verify' };
|
|
807
|
+
results.verified = constraints.length === 0; // Vacuously true if no constraints
|
|
808
|
+
}
|
|
809
|
+
break;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
results.stages.push({
|
|
813
|
+
name: stage,
|
|
814
|
+
success: true,
|
|
815
|
+
duration_ms: Date.now() - stageStart,
|
|
816
|
+
output_summary: summarizeStageOutput(stage, stageResult)
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
} catch (e) {
|
|
820
|
+
results.stages.push({
|
|
821
|
+
name: stage,
|
|
822
|
+
success: false,
|
|
823
|
+
error: e.message,
|
|
824
|
+
duration_ms: Date.now() - stageStart
|
|
825
|
+
});
|
|
826
|
+
// Continue pipeline even if a stage fails (graceful degradation)
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
results.total_duration_ms = Date.now() - startTime;
|
|
831
|
+
results.pipeline_completed = results.stages.filter(s => s.success).length;
|
|
832
|
+
results.pipeline_total = pipeline.length;
|
|
833
|
+
|
|
834
|
+
// Final verdict
|
|
835
|
+
if (results.invention && results.verified) {
|
|
836
|
+
results.verdict = 'INVENTION_VERIFIED';
|
|
837
|
+
} else if (results.invention) {
|
|
838
|
+
results.verdict = 'INVENTION_UNVERIFIED';
|
|
839
|
+
} else {
|
|
840
|
+
results.verdict = 'EXPLORATION_ONLY';
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
return results;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function summarizeStageOutput(stage, result) {
|
|
847
|
+
if (!result) return 'No output';
|
|
848
|
+
if (result.skipped) return `Skipped: ${result.reason}`;
|
|
849
|
+
|
|
850
|
+
switch (stage) {
|
|
851
|
+
case 'mind_opener':
|
|
852
|
+
return result.angles ? `${result.angles.length} angles found` : 'Angles generated';
|
|
853
|
+
case 'idea_fold':
|
|
854
|
+
return result.synthesis ? 'STEM synthesis complete' : 'Folded through lenses';
|
|
855
|
+
case 'bcalc':
|
|
856
|
+
return result.discovery ? 'Mathematical discovery made' : 'Math exploration done';
|
|
857
|
+
case 'genius_plus':
|
|
858
|
+
return result.code ? `Code generated (${result.iterations || 1} iterations)` : 'Solution generated';
|
|
859
|
+
case 'compute':
|
|
860
|
+
return result.error ? `Execution error: ${result.error}` : 'Execution successful';
|
|
861
|
+
case 'cvi_verify':
|
|
862
|
+
return result.passed || result.all_passed ? 'All constraints verified' : 'Verification incomplete';
|
|
863
|
+
default:
|
|
864
|
+
return 'Complete';
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
653
868
|
async function handleLocalTools(request) {
|
|
654
869
|
const { id, method, params } = request;
|
|
655
870
|
|
|
@@ -808,6 +1023,16 @@ async function handleLocalTools(request) {
|
|
|
808
1023
|
return mcpResult(id, { ok: false, error: e.message });
|
|
809
1024
|
}
|
|
810
1025
|
}
|
|
1026
|
+
|
|
1027
|
+
// AUTO-INVENT: Enterprise invention pipeline
|
|
1028
|
+
if (name === 'auto_invent') {
|
|
1029
|
+
try {
|
|
1030
|
+
const result = await autoInvent(args);
|
|
1031
|
+
return mcpResult(id, result);
|
|
1032
|
+
} catch (e) {
|
|
1033
|
+
return mcpResult(id, { ok: false, error: e.message, stage: 'auto_invent' });
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
811
1036
|
}
|
|
812
1037
|
|
|
813
1038
|
return null; // Not a local tool, forward to remote
|
|
@@ -973,10 +1198,6 @@ function installMCP() {
|
|
|
973
1198
|
'playwright': {
|
|
974
1199
|
command: 'npx',
|
|
975
1200
|
args: ['-y', '@playwright/mcp@latest']
|
|
976
|
-
},
|
|
977
|
-
'filesystem': {
|
|
978
|
-
command: 'npx',
|
|
979
|
-
args: ['-y', '@modelcontextprotocol/server-filesystem@latest', home]
|
|
980
1201
|
}
|
|
981
1202
|
};
|
|
982
1203
|
|
|
@@ -1024,7 +1245,6 @@ function installMCP() {
|
|
|
1024
1245
|
console.log('MCPs added:');
|
|
1025
1246
|
console.log(' 50c - AI dev tools ($0.01-$0.65)');
|
|
1026
1247
|
console.log(' playwright - Browser automation (free)');
|
|
1027
|
-
console.log(' filesystem - File system access (free)');
|
|
1028
1248
|
console.log('');
|
|
1029
1249
|
console.log('Optional: npx 50c-vault init # Secure credentials (Windows Hello/Touch ID)');
|
|
1030
1250
|
if (!API_KEY) {
|
package/lib/subagent.js
CHANGED
|
@@ -74,6 +74,7 @@ async function httpFetch(url, options = {}) {
|
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
76
|
* SSH execution via native ssh command (spawned, not shell)
|
|
77
|
+
* Fixed: Uses explicit identity file for Windows compatibility
|
|
77
78
|
*/
|
|
78
79
|
async function sshExec(server, command, options = {}) {
|
|
79
80
|
const serverConfig = typeof server === 'string' ? KNOWN_SERVERS[server] : server;
|
|
@@ -84,12 +85,32 @@ async function sshExec(server, command, options = {}) {
|
|
|
84
85
|
|
|
85
86
|
const { host, user = 'root', port = 22 } = serverConfig;
|
|
86
87
|
const timeout = options.timeout || 30000;
|
|
88
|
+
|
|
89
|
+
// Try to find SSH key - common locations
|
|
90
|
+
const os = require('os');
|
|
91
|
+
const homeDir = os.homedir();
|
|
92
|
+
const keyPaths = [
|
|
93
|
+
path.join(homeDir, '.ssh', 'id_rsa'),
|
|
94
|
+
path.join(homeDir, '.ssh', 'id_ed25519'),
|
|
95
|
+
options.keyFile
|
|
96
|
+
].filter(Boolean);
|
|
97
|
+
|
|
98
|
+
let identityArgs = [];
|
|
99
|
+
for (const keyPath of keyPaths) {
|
|
100
|
+
if (fs.existsSync(keyPath)) {
|
|
101
|
+
identityArgs = ['-i', keyPath];
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
87
105
|
|
|
88
106
|
return new Promise((resolve, reject) => {
|
|
89
107
|
const args = [
|
|
90
108
|
'-o', 'StrictHostKeyChecking=no',
|
|
109
|
+
'-o', 'UserKnownHostsFile=/dev/null',
|
|
91
110
|
'-o', 'ConnectTimeout=10',
|
|
92
|
-
'-o', '
|
|
111
|
+
'-o', 'ServerAliveInterval=5',
|
|
112
|
+
'-o', 'ServerAliveCountMax=2',
|
|
113
|
+
...identityArgs,
|
|
93
114
|
'-p', String(port),
|
|
94
115
|
`${user}@${host}`,
|
|
95
116
|
command
|
|
@@ -97,7 +118,8 @@ async function sshExec(server, command, options = {}) {
|
|
|
97
118
|
|
|
98
119
|
const proc = spawn('ssh', args, {
|
|
99
120
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
100
|
-
timeout
|
|
121
|
+
timeout,
|
|
122
|
+
windowsHide: true
|
|
101
123
|
});
|
|
102
124
|
|
|
103
125
|
let stdout = '';
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "50c",
|
|
3
|
-
"version": "3.0
|
|
4
|
-
"description": "AI developer tools via MCP. Pay-per-use from $0.01. No subscriptions.",
|
|
5
|
-
"bin": {
|
|
6
|
-
"50c": "./bin/50c.js"
|
|
7
|
-
},
|
|
8
|
-
"scripts": {
|
|
9
|
-
"postinstall": "node -e \"console.log('\\n50c Hub installed. Run: 50c install\\n')\""
|
|
10
|
-
},
|
|
11
|
-
"keywords": [
|
|
12
|
-
"mcp",
|
|
13
|
-
"ai",
|
|
14
|
-
"llm",
|
|
15
|
-
"cli",
|
|
16
|
-
"agent",
|
|
17
|
-
"50c",
|
|
18
|
-
"hints",
|
|
19
|
-
"genius",
|
|
20
|
-
"beacon",
|
|
21
|
-
"developer-tools",
|
|
22
|
-
"context",
|
|
23
|
-
"compression",
|
|
24
|
-
"caz",
|
|
25
|
-
"file-memory"
|
|
26
|
-
],
|
|
27
|
-
"author": "genxis",
|
|
28
|
-
"license": "SEE LICENSE IN LICENSE",
|
|
29
|
-
"homepage": "https://50c.ai",
|
|
30
|
-
"engines": {
|
|
31
|
-
"node": ">=18.0.0"
|
|
32
|
-
},
|
|
33
|
-
"files": [
|
|
34
|
-
"bin/",
|
|
35
|
-
"lib/",
|
|
36
|
-
"README.md",
|
|
37
|
-
"LICENSE"
|
|
38
|
-
]
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "50c",
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "AI developer tools via MCP. Pay-per-use from $0.01. No subscriptions.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"50c": "./bin/50c.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node -e \"console.log('\\n50c Hub installed. Run: 50c install\\n')\""
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"mcp",
|
|
13
|
+
"ai",
|
|
14
|
+
"llm",
|
|
15
|
+
"cli",
|
|
16
|
+
"agent",
|
|
17
|
+
"50c",
|
|
18
|
+
"hints",
|
|
19
|
+
"genius",
|
|
20
|
+
"beacon",
|
|
21
|
+
"developer-tools",
|
|
22
|
+
"context",
|
|
23
|
+
"compression",
|
|
24
|
+
"caz",
|
|
25
|
+
"file-memory"
|
|
26
|
+
],
|
|
27
|
+
"author": "genxis",
|
|
28
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
29
|
+
"homepage": "https://50c.ai",
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18.0.0"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"bin/",
|
|
35
|
+
"lib/",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
38
|
+
]
|
|
39
|
+
}
|