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.
Files changed (3) hide show
  1. package/bin/50c.js +226 -6
  2. package/lib/subagent.js +24 -2
  3. 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
- process.stdout.write(JSON.stringify(response) + '\n');
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', 'BatchMode=yes',
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.13",
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
+ }