11#!/usr/bin/env python3
22"""
3- HELIX-TTD-DBC-SUITCASE v0.3 - Unified CLI
3+ HELIX-TTD-DBC-SUITCASE v0.3.1 - Unified CLI
44The missing identity & custody primitive for sovereign AI agents.
55"""
66import argparse
@@ -51,7 +51,7 @@ class HelixCLI:
5151 """Main CLI orchestrator for HELIX-TTD-DBC-SUITCASE framework."""
5252
5353 def __init__ (self ):
54- self .version = "v0.3"
54+ self .version = "v0.3.1 "
5555 self .banner = f"""
5656╔══════════════════════════════════════════════════════════╗
5757║ HELIX-TTD-DBC-SUITCASE { self .version :<29} ║
@@ -134,16 +134,17 @@ def create_new_agent(self, custodian_id: str, agent_name: str, output_dir: str =
134134 "svg" : out / f"{ id_ } .svg" if glyph_data else None ,
135135 }
136136
137- with open (paths ["dbc" ], "w" ) as f :
137+ # WINDOWS FIX: Force utf-8 encoding on all file writes
138+ with open (paths ["dbc" ], "w" , encoding = "utf-8" ) as f :
138139 json .dump (dbc , f , indent = 2 )
139- with open (paths ["suitcase" ], "w" ) as f :
140+ with open (paths ["suitcase" ], "w" , encoding = "utf-8" ) as f :
140141 json .dump (suitcase , f , indent = 2 )
141142
142143 if glyph_data :
143- with open (paths ["glyph" ], "w" ) as f :
144+ with open (paths ["glyph" ], "w" , encoding = "utf-8" ) as f :
144145 json .dump (glyph_data , f , indent = 2 )
145146 if hasattr (gen , "generate_svg_template" ) and paths ["svg" ]:
146- with open (paths ["svg" ], "w" ) as f :
147+ with open (paths ["svg" ], "w" , encoding = "utf-8" ) as f :
147148 f .write (gen .generate_svg_template (glyph_data ))
148149
149150 print (f"\n 📁 Agent saved to: { out .resolve ()} " )
@@ -160,6 +161,7 @@ def verify_agent(self, dbc_file: str, suitcase_file: str) -> Optional[Dict]:
160161
161162 print ("\n 🔍 Verifying agent integrity..." )
162163 try :
164+ # WINDOWS FIX: Force utf-8 reading
163165 with open (dbc_file , "r" , encoding = "utf-8" ) as f :
164166 dbc = json .load (f )
165167 with open (suitcase_file , "r" , encoding = "utf-8" ) as f :
@@ -218,8 +220,9 @@ def update_agent_state(self, dbc_file: str, suitcase_file: str, new_state: str,
218220 sys .exit (1 )
219221
220222 try :
221- with open (dbc_file , "r" ) as f : dbc = json .load (f )
222- with open (suitcase_file , "r" ) as f : suitcase = json .load (f )
223+ # WINDOWS FIX: Force utf-8 reading/writing
224+ with open (dbc_file , "r" , encoding = "utf-8" ) as f : dbc = json .load (f )
225+ with open (suitcase_file , "r" , encoding = "utf-8" ) as f : suitcase = json .load (f )
223226
224227 last_hash = suitcase [- 1 ]["entry_hash" ] if suitcase else None
225228
@@ -231,7 +234,7 @@ def update_agent_state(self, dbc_file: str, suitcase_file: str, new_state: str,
231234 )
232235
233236 suitcase .append (new_entry )
234- with open (suitcase_file , "w" ) as f :
237+ with open (suitcase_file , "w" , encoding = "utf-8" ) as f :
235238 json .dump (suitcase , f , indent = 2 )
236239
237240 print (f"✓ State updated to { new_state } " )
@@ -248,9 +251,9 @@ def update_agent_state(self, dbc_file: str, suitcase_file: str, new_state: str,
248251 agent_name = dbc .get ("agent_name" ),
249252 )
250253 if paths ["glyph" ]:
251- with open (paths ["glyph" ], "w" ) as f : json .dump (updated , f , indent = 2 )
254+ with open (paths ["glyph" ], "w" , encoding = "utf-8" ) as f : json .dump (updated , f , indent = 2 )
252255 if paths ["svg" ]:
253- with open (paths ["svg" ], "w" ) as f : f .write (gen .generate_svg_template (updated ))
256+ with open (paths ["svg" ], "w" , encoding = "utf-8" ) as f : f .write (gen .generate_svg_template (updated ))
254257 print (f"✓ Visuals updated" )
255258 except Exception as e :
256259 print (f"⚠ Glyph update failed: { e } " )
@@ -270,6 +273,7 @@ def list_agents(self, directory: str = ".") -> None:
270273 return
271274 for dbc_file in dbc_files :
272275 try :
276+ # WINDOWS FIX: Force utf-8
273277 with open (dbc_file , "r" , encoding = "utf-8" ) as f :
274278 dbc = json .load (f )
275279 paths = derive_agent_paths (str (dbc_file ))
@@ -364,7 +368,7 @@ def show_agent_info(self, dbc_file: str) -> None:
364368
365369def main ():
366370 parser = argparse .ArgumentParser (
367- description = "HELIX-TTD-DBC-SUITCASE v0.3" ,
371+ description = "HELIX-TTD-DBC-SUITCASE v0.3.1 " ,
368372 epilog = "Example: helix new-agent --custodian alice --name AlphaBot" ,
369373 )
370374 subparsers = parser .add_subparsers (dest = "command" , help = "Command to execute" )
@@ -384,7 +388,8 @@ def main():
384388 update = subparsers .add_parser ("update-state" )
385389 update .add_argument ("--dbc" , required = True )
386390 update .add_argument ("--suitcase" , required = True )
387- update .add_argument ("--state" , "-s" , required = True )
391+ update .add_argument ("--state" , "-s" , required = True ,
392+ choices = ["ACTIVE" , "RESTRICTED" , "REVOKED" , "QUARANTINED" , "SUSPENDED" ])
388393 update .add_argument ("--reason" , "-r" , required = True )
389394
390395 # list
0 commit comments