Add parse/route step types, wider modal, automated link troubleshooter

- Add 'parse' step type: reads KEY=VALUE lines from last command output into execution state
- Add 'route' step type: evaluates JS conditions list, auto-jumps to first match with no user input
- Support condition field on parse steps (skip when conditional execute was also skipped)
- Widen execution detail modal to min(1100px, 96vw) to eliminate horizontal scrolling
- Show last command output in prompt boxes so user has context before clicking
- Add formatLogEntry support for parse_complete and route_taken log actions
- Apply applyParams() substitution to prompt messages ({{server_name}}, {{iface}}, etc.)
- Fix prompt button onclick using data-opt attribute to avoid JSON double-quote breakage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-17 19:29:28 -04:00
parent 2290d52f8b
commit 0990e5b807
2 changed files with 97 additions and 5 deletions

View File

@@ -474,9 +474,9 @@
padding: 0;
border: 3px double var(--terminal-green);
border-radius: 0;
max-width: 600px;
width: 90%;
max-height: 85vh;
max-width: min(1100px, 96vw);
width: 96vw;
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 0 30px rgba(0, 255, 65, 0.3);
position: relative;
@@ -702,6 +702,28 @@
border-color: #330000;
}
/* parse_complete and route_taken log entries */
.log-parse-table {
display: grid;
grid-template-columns: max-content 1fr;
gap: 2px 12px;
font-size: 0.82em;
margin-top: 6px;
}
.log-parse-key { color: var(--terminal-amber); opacity: .8; }
.log-parse-val { color: var(--terminal-green); word-break: break-all; }
.log-route-label {
color: var(--terminal-cyan);
font-size: 0.9em;
margin-top: 4px;
}
.log-route-goto {
color: var(--terminal-amber);
font-size: 0.82em;
opacity: .75;
margin-top: 2px;
}
.log-entry code {
background: var(--bg-terminal);
padding: 2px 6px;
@@ -2136,6 +2158,31 @@
`;
}
if (log.action === 'parse_complete') {
const pairs = log.parsed || {};
const keys = Object.keys(pairs);
const tableRows = keys.map(k =>
`<div class="log-parse-key">${escapeHtml(k)}</div><div class="log-parse-val">${escapeHtml(pairs[k])}</div>`
).join('');
return `
<div class="log-entry" style="border-left-color: #444; opacity:.85;">
<div class="log-timestamp">[${timestamp}]</div>
<div class="log-title" style="color:#666;">⚙ Parsed ${keys.length} variable${keys.length !== 1 ? 's' : ''}</div>
${keys.length > 0 ? `<div class="log-details"><div class="log-parse-table">${tableRows}</div></div>` : ''}
</div>
`;
}
if (log.action === 'route_taken') {
return `
<div class="log-entry" style="border-left-color: var(--terminal-cyan); opacity:.9;">
<div class="log-timestamp">[${timestamp}]</div>
<div class="log-title" style="color: var(--terminal-cyan);">⇒ Auto-route: Step ${log.step}</div>
${log.label ? `<div class="log-details"><div class="log-route-label">${escapeHtml(log.label)}</div>${log.goto ? `<div class="log-route-goto">→ ${escapeHtml(log.goto)}</div>` : ''}</div>` : ''}
</div>
`;
}
if (log.action === 'no_workers') {
return `
<div class="log-entry failed">