@@ -1706,6 +1706,157 @@ mod echidna_tests {
17061706 }
17071707}
17081708
1709+ // ===========================================================================
1710+ // Protocol-Squisher CLI Bridge
1711+ // ===========================================================================
1712+
1713+ const DEFAULT_PROTOCOL_SQUISHER_BIN : & str = "protocol-squisher" ;
1714+
1715+ /// Resolve the protocol-squisher binary path from environment or default.
1716+ fn protocol_squisher_bin ( ) -> String {
1717+ std:: env:: var ( "PROTOCOL_SQUISHER_BIN" )
1718+ . unwrap_or_else ( |_| DEFAULT_PROTOCOL_SQUISHER_BIN . to_string ( ) )
1719+ }
1720+
1721+ /// Check whether the protocol-squisher CLI binary is available.
1722+ #[ tauri:: command]
1723+ fn protocol_squisher_check ( ) -> Result < String , String > {
1724+ let output = std:: process:: Command :: new ( protocol_squisher_bin ( ) )
1725+ . arg ( "--version" )
1726+ . output ( )
1727+ . map_err ( |e| format ! ( "CLI not found: {}" , e) ) ?;
1728+
1729+ if output. status . success ( ) {
1730+ let version = String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) ;
1731+ Ok ( format ! ( "{{\" available\" :true,\" version\" :\" {}\" }}" , version) )
1732+ } else {
1733+ Err ( "protocol-squisher CLI not available" . to_string ( ) )
1734+ }
1735+ }
1736+
1737+ /// Analyse a schema file using `protocol-squisher analyze`.
1738+ /// Returns JSON analysis result.
1739+ #[ tauri:: command]
1740+ fn protocol_squisher_analyze ( file_path : String ) -> Result < String , String > {
1741+ let output = std:: process:: Command :: new ( protocol_squisher_bin ( ) )
1742+ . args ( [ "analyze" , & file_path, "--format" , "json" ] )
1743+ . output ( )
1744+ . map_err ( |e| format ! ( "Analysis failed: {}" , e) ) ?;
1745+
1746+ if output. status . success ( ) {
1747+ Ok ( String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) )
1748+ } else {
1749+ let stderr = String :: from_utf8_lossy ( & output. stderr ) . to_string ( ) ;
1750+ Err ( format ! ( "Analysis error: {}" , stderr) )
1751+ }
1752+ }
1753+
1754+ /// Compare two schema files using `protocol-squisher compare`.
1755+ /// Returns JSON compatibility result.
1756+ #[ tauri:: command]
1757+ fn protocol_squisher_compare ( left_path : String , right_path : String ) -> Result < String , String > {
1758+ let output = std:: process:: Command :: new ( protocol_squisher_bin ( ) )
1759+ . args ( [ "compare" , & left_path, & right_path, "--format" , "json" ] )
1760+ . output ( )
1761+ . map_err ( |e| format ! ( "Comparison failed: {}" , e) ) ?;
1762+
1763+ if output. status . success ( ) {
1764+ Ok ( String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) )
1765+ } else {
1766+ let stderr = String :: from_utf8_lossy ( & output. stderr ) . to_string ( ) ;
1767+ Err ( format ! ( "Comparison error: {}" , stderr) )
1768+ }
1769+ }
1770+
1771+ // ===========================================================================
1772+ // My-Lang CLI Bridge
1773+ // ===========================================================================
1774+
1775+ const DEFAULT_MYLANG_BIN : & str = "my" ;
1776+
1777+ /// Resolve the my-lang binary path from environment or default.
1778+ fn mylang_bin ( ) -> String {
1779+ std:: env:: var ( "MYLANG_BIN" ) . unwrap_or_else ( |_| DEFAULT_MYLANG_BIN . to_string ( ) )
1780+ }
1781+
1782+ /// Check whether the my-lang CLI binary is available.
1783+ #[ tauri:: command]
1784+ fn mylang_check ( ) -> Result < String , String > {
1785+ let output = std:: process:: Command :: new ( mylang_bin ( ) )
1786+ . arg ( "--version" )
1787+ . output ( )
1788+ . map_err ( |e| format ! ( "CLI not found: {}" , e) ) ?;
1789+
1790+ if output. status . success ( ) {
1791+ let version = String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) ;
1792+ Ok ( format ! ( "{{\" available\" :true,\" version\" :\" {}\" }}" , version) )
1793+ } else {
1794+ Err ( "my-lang CLI not available" . to_string ( ) )
1795+ }
1796+ }
1797+
1798+ /// Compile source code in a given dialect.
1799+ /// Writes source to a temp file, runs `my compile`, returns JSON result.
1800+ #[ tauri:: command]
1801+ fn mylang_compile ( source : String , dialect : String ) -> Result < String , String > {
1802+ use std:: io:: Write ;
1803+
1804+ let ext = match dialect. to_lowercase ( ) . as_str ( ) {
1805+ "solo" => "solo" ,
1806+ "duet" => "duet" ,
1807+ "ensemble" => "ens" ,
1808+ "me" => "me" ,
1809+ _ => "solo" ,
1810+ } ;
1811+
1812+ let tmp_dir = std:: env:: temp_dir ( ) . join ( "panll-mylang" ) ;
1813+ std:: fs:: create_dir_all ( & tmp_dir)
1814+ . map_err ( |e| format ! ( "Failed to create temp dir: {}" , e) ) ?;
1815+
1816+ let tmp_file = tmp_dir. join ( format ! ( "input.{}" , ext) ) ;
1817+ let mut f = std:: fs:: File :: create ( & tmp_file)
1818+ . map_err ( |e| format ! ( "Failed to create temp file: {}" , e) ) ?;
1819+ f. write_all ( source. as_bytes ( ) )
1820+ . map_err ( |e| format ! ( "Failed to write source: {}" , e) ) ?;
1821+
1822+ let start = std:: time:: Instant :: now ( ) ;
1823+ let output = std:: process:: Command :: new ( mylang_bin ( ) )
1824+ . args ( [ "compile" , tmp_file. to_str ( ) . unwrap_or ( "input" ) , "--format" , "json" ] )
1825+ . output ( )
1826+ . map_err ( |e| format ! ( "Compilation failed: {}" , e) ) ?;
1827+ let elapsed_ms = start. elapsed ( ) . as_millis ( ) ;
1828+
1829+ let stdout = String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) ;
1830+ let stderr = String :: from_utf8_lossy ( & output. stderr ) . to_string ( ) ;
1831+
1832+ // Construct a JSON result
1833+ let success = output. status . success ( ) ;
1834+ Ok ( format ! (
1835+ "{{\" success\" :{},\" output\" :{},\" diagnostics\" :{},\" error_count\" :0,\" warning_count\" :0,\" compile_time_ms\" :{}}}" ,
1836+ success,
1837+ serde_json:: to_string( & stdout) . unwrap_or_else( |_| "\" \" " . to_string( ) ) ,
1838+ serde_json:: to_string( & stderr) . unwrap_or_else( |_| "\" \" " . to_string( ) ) ,
1839+ elapsed_ms
1840+ ) )
1841+ }
1842+
1843+ /// Evaluate a REPL input line.
1844+ /// Runs `my repl --eval` with the given input and dialect.
1845+ #[ tauri:: command]
1846+ fn mylang_repl ( input : String , dialect : String ) -> Result < String , String > {
1847+ let output = std:: process:: Command :: new ( mylang_bin ( ) )
1848+ . args ( [ "repl" , "--eval" , & input, "--dialect" , & dialect. to_lowercase ( ) ] )
1849+ . output ( )
1850+ . map_err ( |e| format ! ( "REPL eval failed: {}" , e) ) ?;
1851+
1852+ if output. status . success ( ) {
1853+ Ok ( String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) )
1854+ } else {
1855+ let stderr = String :: from_utf8_lossy ( & output. stderr ) . trim ( ) . to_string ( ) ;
1856+ Err ( if stderr. is_empty ( ) { "Evaluation error" . to_string ( ) } else { stderr } )
1857+ }
1858+ }
1859+
17091860fn main ( ) {
17101861 tauri:: Builder :: default ( )
17111862 . plugin ( tauri_plugin_shell:: init ( ) )
@@ -1851,6 +2002,14 @@ fn main() {
18512002 typell:: commands:: typell_compute,
18522003 typell:: commands:: typell_list_signatures,
18532004 typell:: commands:: typell_universes,
2005+ // Protocol-Squisher — 13-format schema analysis CLI bridge
2006+ protocol_squisher_check,
2007+ protocol_squisher_analyze,
2008+ protocol_squisher_compare,
2009+ // My-Lang — AI-native language CLI bridge
2010+ mylang_check,
2011+ mylang_compile,
2012+ mylang_repl,
18542013 ] )
18552014 . setup ( |_app| {
18562015 Ok ( ( ) )
0 commit comments