diff --git a/src/amduatd.c b/src/amduatd.c
index be61cd5..86639bb 100644
--- a/src/amduatd.c
+++ b/src/amduatd.c
@@ -224,14 +224,18 @@ static const char k_amduatd_ui_html[] =
" \n"
"
\n"
" \n"
- " \n"
+ " \n"
" \n"
"
\n"
- " \n"
+ " \n"
+ " \n"
+ " \n"
+ "
\n"
" \n"
" \n"
" \n"
@@ -289,12 +293,22 @@ static const char k_amduatd_ui_html[] =
" el('latestRef').value = j.latest_ref || '';\n"
" el('programRef').value = name;\n"
" if(!j.latest_ref){ el('editor').value=''; out(text); return; }\n"
+ " const mode = el('mode').value;\n"
" const infoResp = await fetch(`/v1/artifacts/${j.latest_ref}?format=info`);\n"
" if(infoResp.ok){ const info = JSON.parse(await infoResp.text()); el('typeTag').value = info.has_type_tag ? info.type_tag : ''; }\n"
+ " if(mode === 'pel_program'){\n"
+ " if(!el('editor').value.trim()){\n"
+ " el('editor').value = JSON.stringify({\n"
+ " nodes:[{id:1,op:{name:'pel.bytes.concat',version:1},inputs:[{external:{input_index:0}}],params_hex:''}],\n"
+ " roots:[{node_id:1,output_index:0}]\n"
+ " }, null, 2);\n"
+ " }\n"
+ " out(text);\n"
+ " return;\n"
+ " }\n"
" const aResp = await fetch(`/v1/artifacts/${j.latest_ref}`);\n"
" if(!aResp.ok){ out(await aResp.text()); return; }\n"
" const u8 = new Uint8Array(await aResp.arrayBuffer());\n"
- " const mode = el('mode').value;\n"
" if(mode==='hex') el('editor').value = toHex(u8);\n"
" else if(mode==='base64') el('editor').value = toB64(u8);\n"
" else el('editor').value = td.decode(u8);\n"
@@ -306,6 +320,19 @@ static const char k_amduatd_ui_html[] =
" if(!name){ out('missing concept name'); return; }\n"
" await ensureConcept(name);\n"
" const mode = el('mode').value;\n"
+ " if(mode === 'pel_program'){\n"
+ " const body = JSON.parse(el('editor').value || '{}');\n"
+ " const mkResp = await fetch('/v1/pel/programs',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});\n"
+ " const mkText = await mkResp.text();\n"
+ " if(!mkResp.ok){ out(mkText); return; }\n"
+ " const mk = JSON.parse(mkText);\n"
+ " const pref = mk.program_ref;\n"
+ " const pubResp = await fetch(`/v1/concepts/${encodeURIComponent(name)}/publish`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({ref:pref})});\n"
+ " const pubText = await pubResp.text();\n"
+ " out(pubText);\n"
+ " if(pubResp.ok){ el('typeTag').value = '0x00000101'; await loadConcept(); }\n"
+ " return;\n"
+ " }\n"
" let u8;\n"
" if(mode==='hex') u8 = fromHex(el('editor').value);\n"
" else if(mode==='base64') u8 = fromB64(el('editor').value);\n"
@@ -326,7 +353,21 @@ static const char k_amduatd_ui_html[] =
" el('btnConceptCreate').addEventListener('click', async () => { try{ await ensureConcept(el('conceptName').value.trim()); out('{\"ok\":true}\\n'); }catch(e){ out(String(e)); } });\n"
" el('btnLoad').addEventListener('click', () => loadConcept().catch(e => out(String(e))));\n"
" el('btnSave').addEventListener('click', () => saveConcept().catch(e => out(String(e))));\n"
- " el('mode').addEventListener('change', () => loadConcept().catch(() => {}));\n"
+ " el('mode').addEventListener('change', () => {\n"
+ " if(el('mode').value === 'pel_program'){\n"
+ " el('typeTag').value = '0x00000101';\n"
+ " }\n"
+ " loadConcept().catch(() => {});\n"
+ " });\n"
+ "\n"
+ " el('btnProgramTemplate').addEventListener('click', () => {\n"
+ " el('mode').value = 'pel_program';\n"
+ " el('typeTag').value = '0x00000101';\n"
+ " el('editor').value = JSON.stringify({\n"
+ " nodes:[{id:1,op:{name:'pel.bytes.concat',version:1},inputs:[{external:{input_index:0}}],params_hex:''}],\n"
+ " roots:[{node_id:1,output_index:0}]\n"
+ " }, null, 2);\n"
+ " });\n"
"\n"
" el('btnPublishRef').addEventListener('click', async () => {\n"
" try{\n"