Release v0.9.163

Automated sync from private repository.
Built with obfuscation enabled.
This commit is contained in:
GitHub Actions Bot
2026-01-21 07:49:55 +00:00
parent 8017476d79
commit 181a83ec46
20 changed files with 72 additions and 28 deletions
+1 -1
View File
@@ -1 +1 @@
0.9.162
0.9.163
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{j as e,a2 as s,F as a,r as t,aP as l,a5 as c,aZ as n}from"./vendor-react-0D__tamq.js";import{c as i}from"./recharts-BovJNxPc.js";import{ab as o,ac as r,b as x,ad as d,r as m,L as u,aa as h,ae as p,af as j}from"./index-By5qf1JJ.js";import{u as g}from"./usePolling-CoS_cZMr.js";import{P as f,b as N,a as v,c as y,L as b}from"./PageLayout-lVaYU4M5.js";import"./vendor-core-WoOfkQwm.js";import"./deckgl-DTsmDcfs.js";const w=t.memo(function({log:s}){return e.jsx("div",{className:"p-3 rounded-2xl bg-white/[0.02] hover:bg-white/[0.04] transition-colors",children:e.jsxs("div",{className:"flex items-baseline gap-3",children:[e.jsx("span",{className:i("type-data-sm w-14 shrink-0",j(s.level)),children:s.level}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"type-data-sm text-text-primary break-words whitespace-pre-wrap",children:s.message}),e.jsx("p",{className:"type-data-xs text-text-muted mt-1",children:new Date(s.timestamp).toLocaleString()})]})]})})});function F(){const s=o(),[a,r]=t.useState("INFO"),[x,d]=t.useState(!1),[m,u]=t.useState(null);t.useEffect(()=>{if(s.length>0){const e=s.some(e=>"DEBUG"===e.level);r(e?"DEBUG":"INFO")}},[s]);const h=t.useCallback(async e=>{if(e!==a&&!x){d(!0),u(null);try{const s=await p(e);s.success&&s.data?(r(e),u(s.data.message),setTimeout(()=>u(null),5e3)):(u(s.error??"Failed to change log level"),setTimeout(()=>u(null),3e3))}catch{u("Failed to change log level"),setTimeout(()=>u(null),3e3)}finally{d(!1)}}},[a,x]),j="h-[32px] px-4 rounded-full type-data flex items-center gap-2 transition-colors",g=x&&"opacity-50 cursor-not-allowed";return e.jsxs("div",{className:"flex items-center gap-2",children:[m&&e.jsx("span",{className:"text-xs text-text-muted animate-pulse",children:m}),e.jsxs("div",{className:"flex bg-white/[0.02] rounded-full p-1",children:[e.jsxs("button",{onClick:()=>h("INFO"),disabled:x,className:i(j,"INFO"===a?"bg-accent-primary/20 text-accent-primary":"text-text-muted hover:text-text-secondary",g),children:[e.jsx(l,{className:"w-4 h-4"}),"Info"]}),e.jsxs("button",{onClick:()=>h("DEBUG"),disabled:x,className:i(j,"DEBUG"===a?"bg-accent-secondary/20 text-accent-secondary":"text-text-muted hover:text-text-secondary",g),children:[x?e.jsx(c,{className:"w-4 h-4 animate-spin"}):e.jsx(n,{className:"w-4 h-4"}),"Debug"]})]})]})}function L(){const t=o(),l=r(),c=x(),n=d(),p=m();return g(n,h.logs,c),e.jsxs(f,{children:[e.jsx(N,{title:"System Logs",icon:e.jsx(a,{}),controls:e.jsxs(e.Fragment,{children:[e.jsx(F,{}),c&&e.jsx(u,{showLabel:!0}),e.jsxs("button",{onClick:()=>p(!c),className:i("h-[32px] px-4 rounded-full type-data transition-colors","flex items-center gap-2",c?"bg-accent-success/20 text-accent-success":"bg-white/[0.02] text-text-muted hover:text-text-secondary"),children:[e.jsx(s,{className:i("w-4 h-4",c&&"animate-spin")}),e.jsx("span",{className:"hidden xs:inline",children:c?"Live":"Paused"})]})]})}),e.jsxs(v,{noPadding:!0,children:[e.jsx(y,{listHeader:!0,icon:e.jsx(a,{className:"icon-sm"}),title:"Log Entries"}),e.jsx("div",{className:"space-y-2 max-h-[calc(100vh-300px)] sm:max-h-[calc(100vh-250px)] overflow-y-auto p-4",children:l&&0===t.length?e.jsx(b,{count:10}):0===t.length?e.jsx("div",{className:"text-center py-12 text-text-muted",children:"No logs available"}):t.map((s,a)=>e.jsx(w,{log:s},`${s.timestamp}-${a}`))})]})]})}export{L as default};
import{j as e,a2 as s,F as a,r as t,aP as l,a5 as c,aZ as n}from"./vendor-react-0D__tamq.js";import{c as i}from"./recharts-BovJNxPc.js";import{ab as o,ac as r,b as x,ad as d,r as m,L as u,aa as h,ae as p,af as j}from"./index-NilB7JtJ.js";import{u as g}from"./usePolling-CoS_cZMr.js";import{P as f,b as N,a as v,c as y,L as b}from"./PageLayout-lVaYU4M5.js";import"./vendor-core-WoOfkQwm.js";import"./deckgl-DTsmDcfs.js";const w=t.memo(function({log:s}){return e.jsx("div",{className:"p-3 rounded-2xl bg-white/[0.02] hover:bg-white/[0.04] transition-colors",children:e.jsxs("div",{className:"flex items-baseline gap-3",children:[e.jsx("span",{className:i("type-data-sm w-14 shrink-0",j(s.level)),children:s.level}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"type-data-sm text-text-primary break-words whitespace-pre-wrap",children:s.message}),e.jsx("p",{className:"type-data-xs text-text-muted mt-1",children:new Date(s.timestamp).toLocaleString()})]})]})})});function F(){const s=o(),[a,r]=t.useState("INFO"),[x,d]=t.useState(!1),[m,u]=t.useState(null);t.useEffect(()=>{if(s.length>0){const e=s.some(e=>"DEBUG"===e.level);r(e?"DEBUG":"INFO")}},[s]);const h=t.useCallback(async e=>{if(e!==a&&!x){d(!0),u(null);try{const s=await p(e);s.success&&s.data?(r(e),u(s.data.message),setTimeout(()=>u(null),5e3)):(u(s.error??"Failed to change log level"),setTimeout(()=>u(null),3e3))}catch{u("Failed to change log level"),setTimeout(()=>u(null),3e3)}finally{d(!1)}}},[a,x]),j="h-[32px] px-4 rounded-full type-data flex items-center gap-2 transition-colors",g=x&&"opacity-50 cursor-not-allowed";return e.jsxs("div",{className:"flex items-center gap-2",children:[m&&e.jsx("span",{className:"text-xs text-text-muted animate-pulse",children:m}),e.jsxs("div",{className:"flex bg-white/[0.02] rounded-full p-1",children:[e.jsxs("button",{onClick:()=>h("INFO"),disabled:x,className:i(j,"INFO"===a?"bg-accent-primary/20 text-accent-primary":"text-text-muted hover:text-text-secondary",g),children:[e.jsx(l,{className:"w-4 h-4"}),"Info"]}),e.jsxs("button",{onClick:()=>h("DEBUG"),disabled:x,className:i(j,"DEBUG"===a?"bg-accent-secondary/20 text-accent-secondary":"text-text-muted hover:text-text-secondary",g),children:[x?e.jsx(c,{className:"w-4 h-4 animate-spin"}):e.jsx(n,{className:"w-4 h-4"}),"Debug"]})]})]})}function L(){const t=o(),l=r(),c=x(),n=d(),p=m();return g(n,h.logs,c),e.jsxs(f,{children:[e.jsx(N,{title:"System Logs",icon:e.jsx(a,{}),controls:e.jsxs(e.Fragment,{children:[e.jsx(F,{}),c&&e.jsx(u,{showLabel:!0}),e.jsxs("button",{onClick:()=>p(!c),className:i("h-[32px] px-4 rounded-full type-data transition-colors","flex items-center gap-2",c?"bg-accent-success/20 text-accent-success":"bg-white/[0.02] text-text-muted hover:text-text-secondary"),children:[e.jsx(s,{className:i("w-4 h-4",c&&"animate-spin")}),e.jsx("span",{className:"hidden xs:inline",children:c?"Live":"Paused"})]})]})}),e.jsxs(v,{noPadding:!0,children:[e.jsx(y,{listHeader:!0,icon:e.jsx(a,{className:"icon-sm"}),title:"Log Entries"}),e.jsx("div",{className:"space-y-2 max-h-[calc(100vh-300px)] sm:max-h-[calc(100vh-250px)] overflow-y-auto p-4",children:l&&0===t.length?e.jsx(b,{count:10}):0===t.length?e.jsx("div",{className:"text-center py-12 text-text-muted",children:"No logs available"}):t.map((s,a)=>e.jsx(w,{log:s},`${s.timestamp}-${a}`))})]})]})}export{L as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{d as t,as as e}from"./index-By5qf1JJ.js";function o(t){if(Array.isArray(t))return t;if("string"==typeof t&&t.startsWith("["))try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}return[]}function n(n,r,s){const a=new Map;for(const e of r){const o=t(e);a.has(o)||a.set(o,e)}const c=new Map,i=new Map;for(const t of n){const n=t.route??t.route_type;if(!e(n))continue;const r=o(t.original_path);if(0===r.length)continue;const f=r.map(t=>t.toUpperCase());if(!t.transmitted&&f.length>=2){const t=f[f.length-2];if(t){const e=a.get(t);e&&i.set(e,(i.get(e)??0)+1)}}if(f.includes(s))for(const t of f){if(t===s)continue;const e=a.get(t);e&&c.set(e,(c.get(e)??0)+1)}}let f=0,u=0;for(const t of r)f=Math.max(f,c.get(t)??0),u=Math.max(u,i.get(t)??0);const h=new Map;let d=0,g=0,l=0;for(const t of r){const e=c.get(t)??0,o=i.get(t)??0,n=f>0?Math.round(e/f*100):0,r=u>0?Math.round(o/u*100):0,s=n+r;h.set(t,{hash:t,listenerCount:e,loudCount:o,listenerScore:n,loudScore:r,blendedScore:s}),d=Math.max(d,n),g=Math.max(g,r),l=Math.max(l,s)}return{scores:h,maxListenerScore:d,maxLoudScore:g,maxBlendedScore:l}}const r={YELLOW:"#FBBF24",GREEN:"#719872",RED:"#E12672",GRAY:"#505050"};export{r as L,n as c};
import{d as t,as as e}from"./index-NilB7JtJ.js";function o(t){if(Array.isArray(t))return t;if("string"==typeof t&&t.startsWith("["))try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}return[]}function n(n,r,s){const a=new Map;for(const e of r){const o=t(e);a.has(o)||a.set(o,e)}const c=new Map,i=new Map;for(const t of n){const n=t.route??t.route_type;if(!e(n))continue;const r=o(t.original_path);if(0===r.length)continue;const f=r.map(t=>t.toUpperCase());if(!t.transmitted&&f.length>=2){const t=f[f.length-2];if(t){const e=a.get(t);e&&i.set(e,(i.get(e)??0)+1)}}if(f.includes(s))for(const t of f){if(t===s)continue;const e=a.get(t);e&&c.set(e,(c.get(e)??0)+1)}}let f=0,u=0;for(const t of r)f=Math.max(f,c.get(t)??0),u=Math.max(u,i.get(t)??0);const h=new Map;let d=0,g=0,l=0;for(const t of r){const e=c.get(t)??0,o=i.get(t)??0,n=f>0?Math.round(e/f*100):0,r=u>0?Math.round(o/u*100):0,s=n+r;h.set(t,{hash:t,listenerCount:e,loudCount:o,listenerScore:n,loudScore:r,blendedScore:s}),d=Math.max(d,n),g=Math.max(g,r),l=Math.max(l,s)}return{scores:h,maxListenerScore:d,maxLoudScore:g,maxBlendedScore:l}}const r={YELLOW:"#FBBF24",GREEN:"#719872",RED:"#E12672",GRAY:"#505050"};export{r as L,n as c};
@@ -1 +1 @@
import{al as t}from"./index-By5qf1JJ.js";async function e(e,r=10){return t("/api/ping_neighbor",{method:"POST",body:JSON.stringify({target_id:e,timeout:r})})}const r=["Chat Node","Repeater","Room Server","Hybrid Node","Unknown"];async function s(s,o=10){if(o<1||o>60)return{success:!1,error:"Timeout must be 1-60 seconds"};let n;const a=s.match(/^(0x)?([0-9a-fA-F]{1,2})$/);if(a)n=`0x${a[2].padStart(2,"0")}`;else{const e=await async function(e){const s=e.toLowerCase();for(const o of r)try{const e=await t(`/api/adverts_by_contact_type?contact_type=${encodeURIComponent(o)}&hours=168`),r=e.success&&e.data?e.data:e,n=(Array.isArray(r)?r:[]).find(t=>t.node_name&&t.node_name.toLowerCase()===s);if(n&&n.pubkey)return`0x${n.pubkey.substring(0,2)}`}catch{continue}return null}(s);if(!e)return{success:!1,error:`Node '${s}' not found`};n=e}const c=await e(n,o);if(!c.success||!c.data)return{success:!1,error:c.error||"Ping failed"};const i=(u=c.data).rtt_ms>500||u.rssi<-120?"Poor":u.rtt_ms>250||u.rssi<-100?"Fair":u.rtt_ms>100||u.rssi<-80?"Good":"Excellent";var u;return{success:!0,data:{...c.data,quality:i}}}export{s as a,e as p};
import{al as t}from"./index-NilB7JtJ.js";async function e(e,r=10){return t("/api/ping_neighbor",{method:"POST",body:JSON.stringify({target_id:e,timeout:r})})}const r=["Chat Node","Repeater","Room Server","Hybrid Node","Unknown"];async function s(s,o=10){if(o<1||o>60)return{success:!1,error:"Timeout must be 1-60 seconds"};let n;const a=s.match(/^(0x)?([0-9a-fA-F]{1,2})$/);if(a)n=`0x${a[2].padStart(2,"0")}`;else{const e=await async function(e){const s=e.toLowerCase();for(const o of r)try{const e=await t(`/api/adverts_by_contact_type?contact_type=${encodeURIComponent(o)}&hours=168`),r=e.success&&e.data?e.data:e,n=(Array.isArray(r)?r:[]).find(t=>t.node_name&&t.node_name.toLowerCase()===s);if(n&&n.pubkey)return`0x${n.pubkey.substring(0,2)}`}catch{continue}return null}(s);if(!e)return{success:!1,error:`Node '${s}' not found`};n=e}const c=await e(n,o);if(!c.success||!c.data)return{success:!1,error:c.error||"Ping failed"};const i=(u=c.data).rtt_ms>500||u.rssi<-120?"Poor":u.rtt_ms>250||u.rssi<-100?"Fair":u.rtt_ms>100||u.rssi<-80?"Good":"Excellent";var u;return{success:!0,data:{...c.data,quality:i}}}export{s as a,e as p};
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -39,7 +39,7 @@
--font-data: 'JetBrains Mono', 'SF Mono', Monaco, monospace;
}
</style>
<script type="module" crossorigin src="/assets/index-By5qf1JJ.js"></script>
<script type="module" crossorigin src="/assets/index-NilB7JtJ.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vendor-core-WoOfkQwm.js">
<link rel="modulepreload" crossorigin href="/assets/vendor-react-0D__tamq.js">
<link rel="stylesheet" crossorigin href="/assets/index-wp0elHoG.css">
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "pymc_console",
"version": "0.9.162",
"version": "0.9.163",
"description": "Vite + React Dashboard for pyMC_Repeater",
"private": true,
"type": "module",
+51 -7
View File
@@ -707,10 +707,38 @@ get_repeater_branch() {
fi
}
# Get pyMC Repeater version from installed pyproject.toml
# Get pyMC Repeater version from pip or pyproject.toml
# pyMC_Repeater uses setuptools_scm (dynamic versioning from git tags)
# so we need to check pip for the actual installed version
get_version() {
# First try pip (most accurate for installed package)
local version
version=$(pip3 show pymc-repeater 2>/dev/null | grep "^Version:" | awk '{print $2}')
if [ -n "$version" ]; then
echo "$version"
return
fi
# Try alternate package name
version=$(pip3 show pymc_repeater 2>/dev/null | grep "^Version:" | awk '{print $2}')
if [ -n "$version" ]; then
echo "$version"
return
fi
# Fallback: try static version in pyproject.toml (older format)
if [ -f "$REPEATER_DIR/pyproject.toml" ]; then
grep "^version" "$REPEATER_DIR/pyproject.toml" | cut -d'"' -f2 2>/dev/null || echo "unknown"
# Match 'version = "X.Y.Z"' but not 'version_scheme' or 'dynamic'
version=$(grep -E '^version\s*=\s*"' "$REPEATER_DIR/pyproject.toml" 2>/dev/null | cut -d'"' -f2 | head -1)
if [ -n "$version" ]; then
echo "$version"
return
fi
fi
# Check if directory exists but version unknown
if [ -d "$REPEATER_DIR" ]; then
echo "unknown"
else
echo "not installed"
fi
@@ -764,15 +792,26 @@ get_status_display() {
if ! is_installed; then
echo "Not Installed"
else
local version=$(get_version)
local status="Stopped"
backend_running && status="Running"
echo "v$version | Service: $status"
echo "Service: $status"
fi
}
# Get full version summary for display
# Returns multi-line string with all component versions
get_version_summary() {
local core_ver=$(get_core_version)
local repeater_ver=$(get_repeater_version)
local console_ver=$(get_console_version)
local core_branch=$(get_core_branch_from_toml "$CLONE_DIR")
local repeater_branch=$(get_repeater_branch)
echo "pyMC Core: v${core_ver} @${core_branch}"
echo "pyMC Repeater: v${repeater_ver} @${repeater_branch}"
echo "pyMC Console: ${console_ver}"
}
# ============================================================================
# Install Function
# ============================================================================
@@ -2624,8 +2663,13 @@ merge_config() {
show_main_menu() {
local status=$(get_status_display)
local core_ver=$(get_core_version)
local repeater_ver=$(get_repeater_version)
local console_ver=$(get_console_version)
local core_branch=$(get_core_branch_from_toml "$CLONE_DIR")
local repeater_branch=$(get_repeater_branch)
CHOICE=$($DIALOG --backtitle "pyMC Console Management" --title "pyMC Console" --menu "\nStatus: $status\n\nChoose an action:" 20 70 10 \
CHOICE=$($DIALOG --backtitle "pyMC Console Management" --title "pyMC Console" --menu "\n$status\n\nInstalled Versions:\n Core: v${core_ver} @${core_branch}\n Repeater: v${repeater_ver} @${repeater_branch}\n Console: ${console_ver}\n\nChoose an action:" 24 70 10 \
"install" "Install pyMC Console (fresh install)" \
"upgrade" "Upgrade existing installation" \
"settings" "Configure radio settings" \