50c 3.3.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/50c.js CHANGED
@@ -124,6 +124,8 @@ 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' },
127
129
  };
128
130
 
129
131
  // Route command
@@ -521,6 +523,62 @@ async function runToolCommand(cmd, args) {
521
523
  return;
522
524
  }
523
525
 
526
+ // INVENT-UI: Visual invention pipeline with browser UI
527
+ if (spec.special === 'invent-ui') {
528
+ let problem = '';
529
+ let rigor = 'deep';
530
+ let domain = 'code';
531
+
532
+ for (const arg of args) {
533
+ if (arg.startsWith('--rigor=')) rigor = arg.split('=')[1];
534
+ else if (arg.startsWith('--domain=')) domain = arg.split('=')[1];
535
+ else if (!arg.startsWith('--')) problem += (problem ? ' ' : '') + arg;
536
+ }
537
+
538
+ if (!problem) {
539
+ console.error('Usage: 50c invent-ui "problem" [--rigor=deep] [--domain=math]');
540
+ console.error('Opens a browser window with real-time swarm visualization.');
541
+ process.exit(1);
542
+ }
543
+
544
+ const { runInventWithUI } = require('../lib/invent-ui.js');
545
+ await runInventWithUI(problem, { domain, rigor });
546
+ return;
547
+ }
548
+
549
+ // MCP-TV: Universal MCP Visualization Platform (FREE)
550
+ if (spec.special === 'mcp-tv') {
551
+ let port = 50888;
552
+ let noOpen = false;
553
+
554
+ for (const arg of args) {
555
+ if (arg.startsWith('--port=')) port = parseInt(arg.split('=')[1]);
556
+ if (arg === '--no-open') noOpen = true;
557
+ }
558
+
559
+ const { createServer } = require('../lib/mcp-tv.js');
560
+ const { spawn } = require('child_process');
561
+
562
+ createServer(port);
563
+
564
+ if (!noOpen) {
565
+ setTimeout(() => {
566
+ const url = `http://localhost:${port}`;
567
+ const platform = process.platform;
568
+ if (platform === 'win32') {
569
+ spawn('cmd', ['/c', 'start', url], { detached: true, stdio: 'ignore' }).unref();
570
+ } else if (platform === 'darwin') {
571
+ spawn('open', [url], { detached: true, stdio: 'ignore' }).unref();
572
+ } else {
573
+ spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();
574
+ }
575
+ }, 500);
576
+ }
577
+
578
+ // Keep process alive
579
+ return new Promise(() => {});
580
+ }
581
+
524
582
  // INVENT: Enterprise invention pipeline
525
583
  if (spec.special === 'invent') {
526
584
  // Parse args: 50c invent "problem" --rigor=deep --domain=math --constraint="must be fast"
@@ -769,8 +827,11 @@ const LOCAL_TOOLS = [
769
827
  { 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"] } },
770
828
  { 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" } } } },
771
829
 
772
- // ENTERPRISE PRESET - Auto-Invent Swarm Pipeline
773
- { name: "auto_invent", description: "Enterprise: Full invention pipeline. Chains mind_opener → idea_fold → bcalc → genius_plus → compute → cvi_verify. Produces provable, verified solutions. $0.65-$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: fast ($0.65, genius_plus only), standard ($0.60, 3 tools), deep ($1.20, 5 tools parallel), exhaustive ($2.00, all 6)", enum: ["fast", "standard", "deep", "exhaustive"], default: "deep" } }, required: ["problem"] } },
830
+ // ENTERPRISE PRESET - Auto-Invent Swarm Pipeline ($2.00)
831
+ { name: "auto_invent", description: "ENTERPRISE ($2.00): Full invention pipeline. Chains mind_opener → idea_fold → bcalc → genius_plus → compute → cvi_verify. Produces provable, verified solutions. Requires Enterprise tier.", 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: fast, standard, deep, exhaustive (all $2.00)", enum: ["fast", "standard", "deep", "exhaustive"], default: "deep" } }, required: ["problem"] } },
832
+
833
+ // PROGRAMMATIC INVENTION - JSON-defined executable pipeline (ENTERPRISE $2.00)
834
+ { 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"] } },
774
835
  ];
775
836
 
776
837
  /**
@@ -794,6 +855,127 @@ const LOCAL_TOOLS = [
794
855
  *
795
856
  * Cost: $2.00 flat for full invention pipeline
796
857
  */
858
+
859
+ /**
860
+ * INVENT_PROGRAM: JSON-defined Executable Invention Pipeline
861
+ * Enterprise-only ($2.00/request) - programmatic multi-step invention
862
+ *
863
+ * Actions:
864
+ * - generate: Create data/variables (Python code in compute sandbox)
865
+ * - compute: Calculate/transform (Python code)
866
+ * - assert: Verify condition (must return truthy or throws)
867
+ * - call: Invoke a 50c tool (genius, bcalc, hints, etc.)
868
+ * - return: Final output
869
+ *
870
+ * GATED: Requires Enterprise tier + $2.00 balance
871
+ */
872
+ async function inventProgram(args) {
873
+ const { program } = args;
874
+ const startTime = Date.now();
875
+
876
+ if (!program || !program.problem || !program.steps) {
877
+ return { ok: false, error: 'Invalid program: must have "problem" and "steps" array' };
878
+ }
879
+
880
+ const results = {
881
+ ok: true,
882
+ problem: program.problem,
883
+ steps_completed: 0,
884
+ steps_total: program.steps.length,
885
+ outputs: {},
886
+ assertions: [],
887
+ tool_calls: [],
888
+ final_result: null,
889
+ cost: '$2.00',
890
+ tier_required: 'enterprise'
891
+ };
892
+
893
+ // Build execution context for Python code
894
+ let pythonContext = `
895
+ import json, math, re, itertools, functools, collections
896
+ from decimal import Decimal, getcontext
897
+ getcontext().prec = 100
898
+
899
+ # Shared context between steps
900
+ _ctx = {}
901
+ _results = {}
902
+
903
+ `;
904
+
905
+ // Execute steps sequentially
906
+ for (const step of program.steps) {
907
+ const stepStart = Date.now();
908
+
909
+ try {
910
+ if (step.action === 'generate' || step.action === 'compute') {
911
+ // Execute Python code in compute sandbox
912
+ pythonContext += `\n# Step: ${step.id}\n${step.code}\n_results['${step.id}'] = locals().get('result', None)\n`;
913
+
914
+ } else if (step.action === 'assert') {
915
+ // Add assertion check
916
+ pythonContext += `\n# Assert: ${step.id}\n_assert_${step.id} = ${step.code}\nif not _assert_${step.id}: raise AssertionError('${step.id} failed')\n_results['${step.id}'] = True\n`;
917
+ results.assertions.push({ id: step.id, code: step.code });
918
+
919
+ } else if (step.action === 'call') {
920
+ // Call a 50c tool
921
+ const toolResult = await call50cTool(step.tool, step.args || {});
922
+ results.tool_calls.push({ id: step.id, tool: step.tool, result: toolResult });
923
+ results.outputs[step.id] = toolResult;
924
+ // Inject result into Python context
925
+ pythonContext += `\n# Tool result: ${step.id}\n_results['${step.id}'] = ${JSON.stringify(toolResult)}\n`;
926
+
927
+ } else if (step.action === 'return') {
928
+ // Final return - will be evaluated after all code runs
929
+ pythonContext += `\n# Final output\n_final = ${step.code}\nprint('__FINAL__:' + json.dumps(_final))\n`;
930
+ }
931
+
932
+ results.steps_completed++;
933
+
934
+ } catch (err) {
935
+ results.ok = false;
936
+ results.error = `Step ${step.id} failed: ${err.message}`;
937
+ break;
938
+ }
939
+ }
940
+
941
+ // Execute all Python code in one compute call
942
+ if (results.ok) {
943
+ pythonContext += `\n# Output all results\nprint('__RESULTS__:' + json.dumps(_results))\n`;
944
+
945
+ try {
946
+ const computeResult = await call50cTool('compute', { code: pythonContext });
947
+
948
+ // Parse outputs
949
+ if (computeResult && typeof computeResult === 'string') {
950
+ const finalMatch = computeResult.match(/__FINAL__:(.+)/);
951
+ if (finalMatch) {
952
+ try {
953
+ results.final_result = JSON.parse(finalMatch[1]);
954
+ } catch (e) {
955
+ results.final_result = finalMatch[1];
956
+ }
957
+ }
958
+
959
+ const resultsMatch = computeResult.match(/__RESULTS__:(.+)/);
960
+ if (resultsMatch) {
961
+ try {
962
+ results.outputs = { ...results.outputs, ...JSON.parse(resultsMatch[1]) };
963
+ } catch (e) {}
964
+ }
965
+ }
966
+
967
+ results.compute_output = computeResult;
968
+
969
+ } catch (err) {
970
+ results.ok = false;
971
+ results.error = `Compute execution failed: ${err.message}`;
972
+ }
973
+ }
974
+
975
+ results.duration_ms = Date.now() - startTime;
976
+ return results;
977
+ }
978
+
797
979
  async function autoInvent(args) {
798
980
  const { problem, constraints = [], domain = 'code', rigor = 'deep' } = args;
799
981
  const startTime = Date.now();
@@ -1285,6 +1467,16 @@ async function handleLocalTools(request) {
1285
1467
  return mcpResult(id, { ok: false, error: e.message, stage: 'auto_invent' });
1286
1468
  }
1287
1469
  }
1470
+
1471
+ // ENTERPRISE: Programmatic invention pipeline ($2.00, gated)
1472
+ if (name === 'invent_program') {
1473
+ try {
1474
+ const result = await inventProgram(args);
1475
+ return mcpResult(id, result);
1476
+ } catch (e) {
1477
+ return mcpResult(id, { ok: false, error: e.message, stage: 'invent_program' });
1478
+ }
1479
+ }
1288
1480
  }
1289
1481
 
1290
1482
  return null; // Not a local tool, forward to remote
@@ -1554,6 +1746,16 @@ ENTERPRISE (auto_invent):
1554
1746
  --rigor=fast|standard|deep|exhaustive (default: deep)
1555
1747
  --domain=math|physics|code|business (default: code)
1556
1748
  --constraint="text" Add constraint (repeatable)
1749
+ invent-ui "problem" [opts] Same as invent, but opens browser UI
1750
+ Real-time swarm visualization (MCP TV!)
1751
+
1752
+ MCP-TV (FREE):
1753
+ tv Start MCP-TV server - universal MCP visualizer
1754
+ tv --port=3000 Custom port (default: 50888)
1755
+
1756
+ Any MCP can stream events to MCP-TV:
1757
+ POST http://localhost:50888/stream
1758
+ { "channel": "my-mcp", "event": "stage", "data": {...} }
1557
1759
 
1558
1760
  TOOLS (beacon pack):
1559
1761
  50c beacon.health Context health check (FREE)
@@ -1586,3 +1788,6 @@ MCP MODE:
1586
1788
 
1587
1789
  process.on('SIGINT', () => process.exit(130));
1588
1790
  process.on('SIGTERM', () => process.exit(143));
1791
+
1792
+ // Export enterprise functions for team.js integration
1793
+ module.exports = { autoInvent, inventProgram };