app
Codex
Public Made by Adomby adom
Codex in Adom Hydrogen: ecosystem setup, dock dashboard and live engineering demos.
← Commit history
0.1.24: Codex CLI kind (extension's copy vs a duplicate install) and sign-in pills on the dashboard
4 files changed
+29−4
adom_codex.py+26−1@@ -7,9 +7,34 @@ VERSION=json.loads((ROOT/'package.json').read_text())['version'] def version_tuple(value): m=re.fullmatch(r'(\d+)\.(\d+)\.(\d+)(?:[-+].*)?',str(value).strip()) return tuple(map(int,m.groups())) if m else (0,0,0)+def cli_state():+ """The Codex CLI on PATH, and whether it is the golden-image wrapper onto the extension's+ bundled binary (the no-duplicates rule) or a second install (npm, standalone)."""+ p=shutil.which('codex');kind='missing';target=None;version=None+ if p:+ try:head=open(p,'rb').read(2048).decode('utf8','replace')+ except Exception:head=''+ real=str(Path(p).resolve())+ if 'Adom golden image' in head or '/code-server/extensions/' in real:kind='wrapper';target='the extension\'s bundled binary'+ elif 'node' in head.split('\n',1)[0]:kind='npm';target=real+ else:kind='standalone';target=real+ try:+ import subprocess;version=subprocess.run([p,'--version'],capture_output=True,text=True,timeout=15).stdout.strip()[:60] or None+ except Exception:pass+ return {'path':p,'kind':kind,'target':target,'version':version,'duplicate':kind in('npm','standalone') and any(Path.home().glob('.local/share/code-server/extensions/openai.chatgpt-*/bin/linux-x86_64/codex'))}+def signin_state():+ """Read ~/.codex/auth.json (shared by the extension and the CLI); never a live call."""+ ch=Path(os.environ.get('CODEX_HOME',Path.home()/'.codex'));f=ch/'auth.json';email=None;ok=False+ try:+ d=json.loads(f.read_text());tok=d.get('tokens') or {};ok=bool(tok.get('access_token') or tok.get('refresh_token') or d.get('OPENAI_API_KEY'))+ idt=tok.get('id_token')+ if idt:+ import base64;seg=idt.split('.')[1];seg+='='*(-len(seg)%4);email=json.loads(base64.urlsafe_b64decode(seg)).get('email')+ except Exception:pass+ return {'signedIn':ok,'email':email,'file':str(f),'shared':'the extension and the CLI read this same file'} def context(): ch=Path(os.environ.get('CODEX_HOME',Path.home()/'.codex'))- return {'app':'adom/codex','version':VERSION,'container':{'system':platform.system(),'kernel':platform.release(),'hostname':platform.node(),'cwd':os.getcwd()},'tools':{n:shutil.which(n) for n in ['codex','adom-wiki','adom-cli','adom-bridge']},'instructionsInstalled':(ch/'skills/codex-adom/SKILL.md').exists(),'hostTarget':'Not inferred; select and verify through Adom Bridge','hydrogenControlConfigured':(Path.home()/'.adom/hydrogen-control-url').exists()}+ return {'app':'adom/codex','version':VERSION,'cli':cli_state(),'signin':signin_state(),'container':{'system':platform.system(),'kernel':platform.release(),'hostname':platform.node(),'cwd':os.getcwd()},'tools':{n:shutil.which(n) for n in ['codex','adom-wiki','adom-cli','adom-bridge']},'instructionsInstalled':(ch/'skills/codex-adom/SKILL.md').exists(),'hostTarget':'Not inferred; select and verify through Adom Bridge','hydrogenControlConfigured':(Path.home()/'.adom/hydrogen-control-url').exists()} class Handler(SimpleHTTPRequestHandler): def __init__(self,*a,**kw):super().__init__(*a,directory=str(ROOT),**kw) def log_message(self,*a):pass
dashboard/index.html+1−1@@ -13,6 +13,6 @@ const panel=AdomNewbiePanel.mount({mount:'#newbie',apiBase:'/codex',app:'codex', ]}); async function inspect(){try{const r=await fetch('/api/status');if(!r.ok)throw Error('Context unavailable');const s=await r.json();$('#context').textContent=JSON.stringify(s,null,2);$('#details').showModal()}catch(e){toast(e.message)}} $('#inspect').onclick=inspect;$('#settings').onclick=inspect;$('#close-details').onclick=()=>$('#details').close();$('#close-video').onclick=()=>$('#player').close();$('#player').addEventListener('close',()=>$('#video').pause());document.querySelectorAll('[data-demo]').forEach(b=>b.onclick=()=>play(b.dataset.demo));-function status(s){$('#machine').textContent=s.container.hostname;$('#status').replaceChildren(...['Entry point: '+(s.instructionsInstalled?'installed':'not installed'),'Bridge CLI: '+(s.tools['adom-bridge']?'available':'missing'),'Host target: select in Bridge'].map(t=>{let e=document.createElement('span');e.className='pill';e.textContent=t;return e}))}+function status(s){$('#machine').textContent=s.container.hostname;const c=s.cli||{},si=s.signin||{};const cliText='Codex CLI: '+(c.kind==='wrapper'?((c.version||'installed')+' · the extension\'s copy'):c.kind==='missing'?'missing':((c.version||c.kind)+' · '+c.kind+(c.duplicate?' install next to the extension\'s copy (duplicate)':'')));$('#status').replaceChildren(...['Entry point: '+(s.instructionsInstalled?'installed':'not installed'),cliText,'Sign-in: '+(si.signedIn?('signed in'+(si.email?' as '+si.email:'')+' · extension + CLI'):'not signed in'),'Bridge CLI: '+(s.tools['adom-bridge']?'available':'missing'),'Host target: select in Bridge'].map(t=>{let e=document.createElement('span');e.className='pill';if(t.includes('duplicate')||t.startsWith('Sign-in: not'))e.style.borderColor='#d29922';e.textContent=t;return e}))} fetch('/api/status').then(r=>r.json()).then(status).catch(e=>toast('Workspace status unavailable'));window.adomCodex={state:()=>fetch('/state').then(r=>r.json()),play,inspect,selfCheck:()=>AdomNewbiePanel.selfCheck()};window.__codexBootComplete=true;const events=new EventSource('/events');events.onmessage=e=>status(JSON.parse(e.data)); </script></html>
package.json+1−1@@ -4,7 +4,7 @@ "type": "app", "title": "Codex", "brief": "Codex in Adom Hydrogen: ecosystem setup, dock dashboard and live engineering demos.",- "version": "0.1.23",+ "version": "0.1.24", "description": "Codex in Adom Hydrogen with reusable CAD routing, electrical review, copper-ablation and narrated video skills, plus verified KiCad and Fusion demo progressions.", "org": "adom", "needs_sudo": false,
page.json+1−1@@ -4,7 +4,7 @@ "type": "app", "title": "Codex", "brief": "Codex in Adom Hydrogen: ecosystem setup, dock dashboard and live engineering demos.",- "version": "0.1.23",+ "version": "0.1.24", "hero": { "type": "image", "path": "screenshots/hero.png"