Brings the locked FlowPilot migration design onto the branch that will implement it. Includes the annotated target UI mockups (primary session view + three Script Generator integration states) and the superseded FLOWPILOT-AND-RESOLUTIONASSIST.md for historical reference. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1517 lines
49 KiB
HTML
1517 lines
49 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>FlowPilot — Script Generator integration</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Bricolage+Grotesque:wght@500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root {
|
||
--bg-0: #070b12;
|
||
--bg-1: #0d131c;
|
||
--bg-2: #121a25;
|
||
--bg-3: #1a2332;
|
||
--bg-4: #222d3f;
|
||
--bg-hover: #1f2a3a;
|
||
--border: rgba(148, 163, 184, 0.12);
|
||
--border-strong: rgba(148, 163, 184, 0.22);
|
||
--text-primary: #e2e8f0;
|
||
--text-secondary: #94a3b8;
|
||
--text-tertiary: #64748b;
|
||
--cyan-400: #22d3ee;
|
||
--cyan-500: #06b6d4;
|
||
--cyan-600: #0891b2;
|
||
--cyan-bg: rgba(34, 211, 238, 0.10);
|
||
--cyan-bg-strong: rgba(34, 211, 238, 0.18);
|
||
--cyan-border: rgba(34, 211, 238, 0.30);
|
||
--success: #34d399;
|
||
--success-bg: rgba(52, 211, 153, 0.12);
|
||
--success-border: rgba(52, 211, 153, 0.28);
|
||
--warning: #fbbf24;
|
||
--warning-bg: rgba(251, 191, 36, 0.10);
|
||
--warning-border: rgba(251, 191, 36, 0.25);
|
||
--danger: #f87171;
|
||
--danger-bg: rgba(248, 113, 113, 0.12);
|
||
--purple: #a78bfa;
|
||
--purple-bg: rgba(167, 139, 250, 0.12);
|
||
--purple-border: rgba(167, 139, 250, 0.30);
|
||
--purple-bg-strong: rgba(167, 139, 250, 0.18);
|
||
}
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
html, body {
|
||
background: var(--bg-0);
|
||
color: var(--text-primary);
|
||
font-family: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
body { min-height: 100vh; }
|
||
|
||
/* Each scene is a full-height viewport section */
|
||
.scene {
|
||
width: 100%;
|
||
min-height: 100vh;
|
||
padding: 48px 40px;
|
||
background: var(--bg-0);
|
||
border-bottom: 1px solid var(--border);
|
||
position: relative;
|
||
}
|
||
.scene:last-child { border-bottom: none; }
|
||
|
||
.scene-header {
|
||
max-width: 1400px;
|
||
margin: 0 auto 32px;
|
||
}
|
||
.scene-eyebrow {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
color: var(--cyan-400);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.1em;
|
||
background: var(--cyan-bg);
|
||
padding: 5px 12px;
|
||
border-radius: 20px;
|
||
border: 1px solid var(--cyan-border);
|
||
margin-bottom: 12px;
|
||
}
|
||
.scene-eyebrow .num {
|
||
width: 18px; height: 18px;
|
||
background: var(--cyan-500);
|
||
color: var(--bg-0);
|
||
border-radius: 50%;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
}
|
||
.scene-title {
|
||
font-family: 'Bricolage Grotesque', sans-serif;
|
||
font-size: 28px;
|
||
font-weight: 500;
|
||
letter-spacing: -0.02em;
|
||
margin-bottom: 6px;
|
||
}
|
||
.scene-subtitle {
|
||
font-size: 15px;
|
||
color: var(--text-secondary);
|
||
max-width: 720px;
|
||
line-height: 1.55;
|
||
}
|
||
|
||
/* Shared frame for all three scenes */
|
||
.frame {
|
||
max-width: 1400px;
|
||
margin: 0 auto;
|
||
background: var(--bg-1);
|
||
border: 1px solid var(--border-strong);
|
||
border-radius: 14px;
|
||
overflow: hidden;
|
||
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.4);
|
||
}
|
||
.frame-chrome {
|
||
padding: 10px 16px;
|
||
background: var(--bg-2);
|
||
border-bottom: 1px solid var(--border);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.chrome-dot { width: 10px; height: 10px; border-radius: 50%; }
|
||
.chrome-dot.r { background: #ff5f57; }
|
||
.chrome-dot.y { background: #febc2e; }
|
||
.chrome-dot.g { background: #28c840; }
|
||
.chrome-url {
|
||
margin-left: 14px;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 12px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
.chrome-url strong { color: var(--cyan-400); font-weight: 500; }
|
||
|
||
.mono {
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 12px;
|
||
background: var(--bg-3);
|
||
padding: 2px 7px;
|
||
border-radius: 4px;
|
||
color: var(--cyan-400);
|
||
}
|
||
|
||
/* ================ SCENE 1 — Template match ================ */
|
||
.scene1-layout {
|
||
display: grid;
|
||
grid-template-columns: 1fr 560px;
|
||
}
|
||
.session-context {
|
||
background: var(--bg-0);
|
||
padding: 24px 28px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
min-height: 680px;
|
||
}
|
||
.context-header {
|
||
padding-bottom: 16px;
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
.psa-chip-inline {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
background: var(--cyan-bg);
|
||
color: var(--cyan-400);
|
||
padding: 3px 10px;
|
||
border-radius: 4px;
|
||
font-size: 11px;
|
||
font-weight: 500;
|
||
letter-spacing: 0.02em;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
margin-bottom: 6px;
|
||
}
|
||
.psa-chip-inline::before {
|
||
content: '';
|
||
width: 5px; height: 5px;
|
||
background: var(--cyan-400);
|
||
border-radius: 50%;
|
||
}
|
||
.context-title {
|
||
font-family: 'Bricolage Grotesque', sans-serif;
|
||
font-size: 17px;
|
||
font-weight: 500;
|
||
margin-bottom: 4px;
|
||
}
|
||
.context-sub {
|
||
font-size: 12.5px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
.know-mini {
|
||
background: var(--bg-1);
|
||
border: 1px solid var(--border);
|
||
border-left: 3px solid var(--success);
|
||
border-radius: 7px;
|
||
padding: 12px 14px;
|
||
}
|
||
.know-mini-label {
|
||
font-size: 10px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
color: var(--success);
|
||
font-weight: 600;
|
||
margin-bottom: 8px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.know-mini-label svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||
.know-mini-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 5px;
|
||
font-size: 12.5px;
|
||
line-height: 1.5;
|
||
}
|
||
.know-mini-item {
|
||
display: flex;
|
||
gap: 8px;
|
||
align-items: flex-start;
|
||
color: var(--text-secondary);
|
||
}
|
||
.know-mini-item strong { color: var(--text-primary); font-weight: 500; }
|
||
.know-mini-item .mini-check {
|
||
color: var(--success);
|
||
font-weight: 700;
|
||
font-size: 11px;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
.suggested-fix-card {
|
||
background: var(--bg-1);
|
||
border: 1px solid var(--warning-border);
|
||
border-left: 3px solid var(--warning);
|
||
border-radius: 8px;
|
||
padding: 14px 16px;
|
||
cursor: pointer;
|
||
position: relative;
|
||
}
|
||
.suggested-fix-card::after {
|
||
content: '→';
|
||
position: absolute;
|
||
right: 16px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
font-size: 20px;
|
||
color: var(--warning);
|
||
}
|
||
.suggested-fix-label {
|
||
font-size: 10px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
color: var(--warning);
|
||
font-weight: 600;
|
||
margin-bottom: 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.suggested-fix-label svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||
.suggested-fix-title {
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
margin-bottom: 4px;
|
||
}
|
||
.suggested-fix-meta {
|
||
font-size: 11.5px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.5;
|
||
}
|
||
.match-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
background: var(--purple-bg);
|
||
color: var(--purple);
|
||
font-size: 10.5px;
|
||
font-weight: 500;
|
||
padding: 2px 8px;
|
||
border-radius: 10px;
|
||
border: 1px solid var(--purple-border);
|
||
margin-left: 6px;
|
||
}
|
||
|
||
.invoke-hint {
|
||
background: var(--bg-2);
|
||
border: 1px dashed var(--border-strong);
|
||
border-radius: 7px;
|
||
padding: 10px 12px;
|
||
font-size: 11.5px;
|
||
color: var(--text-tertiary);
|
||
line-height: 1.5;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.kbd {
|
||
display: inline-block;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 10px;
|
||
background: var(--bg-3);
|
||
border: 1px solid var(--border);
|
||
padding: 1px 6px;
|
||
border-radius: 3px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.arrow-to-generator {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 12px 0;
|
||
}
|
||
.arrow-to-generator svg {
|
||
width: 40px; height: 24px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
/* Script Generator panel */
|
||
.script-gen {
|
||
background: var(--bg-1);
|
||
border-left: 1px solid var(--border-strong);
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 680px;
|
||
}
|
||
.gen-header {
|
||
padding: 16px 20px;
|
||
border-bottom: 1px solid var(--border);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
.gen-title-wrap { flex: 1; min-width: 0; }
|
||
.gen-eyebrow {
|
||
font-size: 10px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
color: var(--purple);
|
||
font-weight: 600;
|
||
margin-bottom: 4px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.gen-eyebrow svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||
.gen-title {
|
||
font-family: 'Bricolage Grotesque', sans-serif;
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
}
|
||
.gen-close {
|
||
width: 28px; height: 28px;
|
||
background: transparent;
|
||
border: none;
|
||
color: var(--text-tertiary);
|
||
cursor: pointer;
|
||
border-radius: 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.gen-close:hover { background: var(--bg-3); color: var(--text-primary); }
|
||
.gen-close svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||
|
||
.template-badge {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
padding: 12px 20px;
|
||
background: var(--success-bg);
|
||
border-bottom: 1px solid var(--border);
|
||
font-size: 12.5px;
|
||
}
|
||
.template-badge-icon {
|
||
width: 24px; height: 24px;
|
||
background: var(--success-bg);
|
||
border: 1px solid var(--success-border);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
}
|
||
.template-badge-icon svg { width: 13px; height: 13px; stroke: var(--success); fill: none; stroke-width: 2.5; }
|
||
.template-badge-text {
|
||
color: var(--text-secondary);
|
||
}
|
||
.template-badge-text strong {
|
||
color: var(--success);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.gen-body {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: 18px 20px;
|
||
}
|
||
.prefilled-banner {
|
||
background: var(--cyan-bg);
|
||
border: 1px solid var(--cyan-border);
|
||
border-radius: 7px;
|
||
padding: 10px 12px;
|
||
margin-bottom: 18px;
|
||
font-size: 12px;
|
||
line-height: 1.5;
|
||
color: var(--text-secondary);
|
||
display: flex;
|
||
gap: 10px;
|
||
align-items: flex-start;
|
||
}
|
||
.prefilled-banner svg { width: 14px; height: 14px; stroke: var(--cyan-400); fill: none; stroke-width: 2; flex-shrink: 0; margin-top: 1px; }
|
||
.prefilled-banner strong { color: var(--cyan-400); font-weight: 500; }
|
||
|
||
.param-group-title {
|
||
font-size: 10px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
color: var(--text-tertiary);
|
||
font-weight: 600;
|
||
margin-bottom: 10px;
|
||
margin-top: 18px;
|
||
}
|
||
.param-group-title:first-child { margin-top: 0; }
|
||
|
||
.param-field {
|
||
margin-bottom: 14px;
|
||
}
|
||
.param-label {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
margin-bottom: 5px;
|
||
font-weight: 500;
|
||
}
|
||
.param-label .req { color: var(--danger); margin-left: 3px; }
|
||
.param-label .prefilled-tag {
|
||
font-size: 10px;
|
||
background: var(--cyan-bg);
|
||
color: var(--cyan-400);
|
||
padding: 1px 6px;
|
||
border-radius: 3px;
|
||
font-weight: 500;
|
||
letter-spacing: 0.02em;
|
||
border: 1px solid var(--cyan-border);
|
||
}
|
||
.param-input {
|
||
width: 100%;
|
||
background: var(--bg-2);
|
||
border: 1px solid var(--border-strong);
|
||
color: var(--text-primary);
|
||
padding: 8px 11px;
|
||
border-radius: 6px;
|
||
font-size: 13px;
|
||
font-family: inherit;
|
||
}
|
||
.param-input.prefilled {
|
||
border-color: var(--cyan-border);
|
||
background: rgba(34, 211, 238, 0.04);
|
||
}
|
||
.param-input.mono-font {
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 12px;
|
||
}
|
||
.param-input:focus {
|
||
outline: none;
|
||
border-color: var(--cyan-400);
|
||
box-shadow: 0 0 0 3px var(--cyan-bg);
|
||
}
|
||
.param-hint {
|
||
font-size: 11px;
|
||
color: var(--text-tertiary);
|
||
margin-top: 4px;
|
||
line-height: 1.45;
|
||
}
|
||
|
||
.gen-footer {
|
||
padding: 14px 20px;
|
||
border-top: 1px solid var(--border);
|
||
background: var(--bg-2);
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
.btn {
|
||
padding: 9px 14px;
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
background: var(--bg-2);
|
||
border: 1px solid var(--border);
|
||
color: var(--text-primary);
|
||
border-radius: 7px;
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 7px;
|
||
white-space: nowrap;
|
||
}
|
||
.btn:hover { background: var(--bg-hover); border-color: var(--border-strong); }
|
||
.btn-ghost { background: transparent; border-color: transparent; }
|
||
.btn-ghost:hover { background: var(--bg-3); }
|
||
.btn-primary {
|
||
background: var(--cyan-500);
|
||
color: var(--bg-0);
|
||
border-color: var(--cyan-500);
|
||
}
|
||
.btn-primary:hover { background: var(--cyan-400); }
|
||
.btn-success {
|
||
background: var(--success-bg);
|
||
color: var(--success);
|
||
border-color: var(--success-border);
|
||
}
|
||
.btn-success:hover { background: rgba(52, 211, 153, 0.20); border-color: var(--success); }
|
||
.btn-icon { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 1.75; }
|
||
|
||
/* ================ SCENE 2 — Three-option dialog ================ */
|
||
.scene2-layout {
|
||
display: grid;
|
||
grid-template-columns: 480px 1fr;
|
||
min-height: 720px;
|
||
}
|
||
.scene2-context {
|
||
background: var(--bg-0);
|
||
padding: 24px 28px;
|
||
border-right: 1px solid var(--border);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
}
|
||
.scene2-context-dim {
|
||
opacity: 0.45;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.three-option-panel {
|
||
padding: 32px 40px;
|
||
background: var(--bg-1);
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 100%;
|
||
}
|
||
.three-option-eyebrow {
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
color: var(--warning);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
margin-bottom: 8px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.three-option-eyebrow svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||
|
||
.three-option-title {
|
||
font-family: 'Bricolage Grotesque', sans-serif;
|
||
font-size: 22px;
|
||
font-weight: 500;
|
||
letter-spacing: -0.01em;
|
||
margin-bottom: 8px;
|
||
max-width: 620px;
|
||
}
|
||
.three-option-sub {
|
||
font-size: 14px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.55;
|
||
margin-bottom: 28px;
|
||
max-width: 620px;
|
||
}
|
||
|
||
.script-preview {
|
||
background: var(--bg-2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 10px;
|
||
padding: 14px 16px;
|
||
margin-bottom: 24px;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 12px;
|
||
line-height: 1.7;
|
||
color: var(--text-secondary);
|
||
}
|
||
.sp-comment { color: var(--text-tertiary); }
|
||
.sp-cmdlet { color: #8ab4f8; }
|
||
.sp-var { color: var(--cyan-400); }
|
||
.sp-str { color: #f0a879; }
|
||
.sp-param { color: var(--text-primary); }
|
||
.sp-hl {
|
||
background: var(--warning-bg);
|
||
border: 1px solid var(--warning-border);
|
||
border-radius: 3px;
|
||
padding: 1px 4px;
|
||
color: var(--warning);
|
||
font-weight: 500;
|
||
}
|
||
.script-preview-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
font-size: 11px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
color: var(--text-tertiary);
|
||
margin-bottom: 12px;
|
||
padding-bottom: 10px;
|
||
border-bottom: 1px solid var(--border);
|
||
font-weight: 600;
|
||
}
|
||
.script-preview-legend {
|
||
display: flex;
|
||
gap: 14px;
|
||
font-size: 11px;
|
||
color: var(--text-tertiary);
|
||
text-transform: none;
|
||
letter-spacing: normal;
|
||
font-weight: 400;
|
||
}
|
||
.legend-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
.legend-swatch {
|
||
width: 10px; height: 10px;
|
||
border-radius: 2px;
|
||
background: var(--warning-bg);
|
||
border: 1px solid var(--warning-border);
|
||
}
|
||
|
||
.options-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 14px;
|
||
}
|
||
.option-card {
|
||
background: var(--bg-2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 10px;
|
||
padding: 18px 18px 16px;
|
||
cursor: pointer;
|
||
position: relative;
|
||
transition: all 0.15s;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.option-card:hover {
|
||
border-color: var(--border-strong);
|
||
background: var(--bg-3);
|
||
}
|
||
.option-card.recommended {
|
||
border-color: var(--cyan-border);
|
||
background: linear-gradient(to bottom, rgba(34, 211, 238, 0.06), var(--bg-2) 50%);
|
||
box-shadow: 0 0 0 1px var(--cyan-border);
|
||
}
|
||
.option-card.recommended:hover {
|
||
border-color: var(--cyan-400);
|
||
box-shadow: 0 0 0 1px var(--cyan-400);
|
||
}
|
||
|
||
.option-badge {
|
||
position: absolute;
|
||
top: -1px;
|
||
right: 12px;
|
||
background: var(--cyan-500);
|
||
color: var(--bg-0);
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
padding: 3px 9px;
|
||
border-radius: 0 0 5px 5px;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.option-icon {
|
||
width: 36px; height: 36px;
|
||
border-radius: 9px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 12px;
|
||
}
|
||
.option-icon.oneoff { background: var(--bg-3); color: var(--text-secondary); }
|
||
.option-icon.draft { background: var(--cyan-bg-strong); color: var(--cyan-400); }
|
||
.option-icon.template { background: var(--purple-bg-strong); color: var(--purple); }
|
||
.option-icon svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.75; }
|
||
|
||
.option-title {
|
||
font-size: 14.5px;
|
||
font-weight: 500;
|
||
margin-bottom: 6px;
|
||
color: var(--text-primary);
|
||
}
|
||
.option-desc {
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.55;
|
||
margin-bottom: 14px;
|
||
flex: 1;
|
||
}
|
||
.option-tradeoffs {
|
||
border-top: 1px solid var(--border);
|
||
padding-top: 12px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 5px;
|
||
}
|
||
.tradeoff-row {
|
||
font-size: 11px;
|
||
line-height: 1.4;
|
||
display: flex;
|
||
gap: 6px;
|
||
align-items: flex-start;
|
||
color: var(--text-secondary);
|
||
}
|
||
.tradeoff-row svg { width: 11px; height: 11px; flex-shrink: 0; margin-top: 2px; stroke-width: 2.5; fill: none; stroke: currentColor; }
|
||
.tradeoff-row.good { color: var(--success); }
|
||
.tradeoff-row.neutral { color: var(--text-tertiary); }
|
||
.tradeoff-row.warn { color: var(--warning); }
|
||
|
||
.option-cta {
|
||
margin-top: 14px;
|
||
padding: 8px 12px;
|
||
font-size: 12.5px;
|
||
font-weight: 500;
|
||
border-radius: 6px;
|
||
text-align: center;
|
||
border: 1px solid;
|
||
font-family: inherit;
|
||
cursor: pointer;
|
||
width: 100%;
|
||
}
|
||
.option-cta.oneoff {
|
||
background: transparent;
|
||
color: var(--text-primary);
|
||
border-color: var(--border-strong);
|
||
}
|
||
.option-cta.draft {
|
||
background: var(--cyan-500);
|
||
color: var(--bg-0);
|
||
border-color: var(--cyan-500);
|
||
}
|
||
.option-cta.template {
|
||
background: transparent;
|
||
color: var(--purple);
|
||
border-color: var(--purple-border);
|
||
}
|
||
|
||
.option-footer {
|
||
margin-top: 28px;
|
||
padding-top: 20px;
|
||
border-top: 1px solid var(--border);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
font-size: 12px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
/* ================ SCENE 3 — Post-resolve prompt ================ */
|
||
.scene3-layout {
|
||
padding: 40px 48px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 24px;
|
||
min-height: 640px;
|
||
background: var(--bg-0);
|
||
}
|
||
|
||
.resolve-success-banner {
|
||
max-width: 880px;
|
||
width: 100%;
|
||
background: linear-gradient(135deg, rgba(52, 211, 153, 0.08), rgba(52, 211, 153, 0.02));
|
||
border: 1px solid var(--success-border);
|
||
border-radius: 12px;
|
||
padding: 20px 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16px;
|
||
}
|
||
.resolve-icon-wrap {
|
||
width: 44px; height: 44px;
|
||
background: var(--success-bg);
|
||
border: 1px solid var(--success-border);
|
||
border-radius: 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
}
|
||
.resolve-icon-wrap svg { width: 20px; height: 20px; stroke: var(--success); fill: none; stroke-width: 2.5; }
|
||
.resolve-info { flex: 1; min-width: 0; }
|
||
.resolve-title {
|
||
font-family: 'Bricolage Grotesque', sans-serif;
|
||
font-size: 17px;
|
||
font-weight: 500;
|
||
margin-bottom: 3px;
|
||
}
|
||
.resolve-meta {
|
||
font-size: 12.5px;
|
||
color: var(--text-secondary);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
.resolve-meta .mono-inline {
|
||
font-family: 'JetBrains Mono', monospace;
|
||
color: var(--cyan-400);
|
||
}
|
||
|
||
.templatize-card {
|
||
max-width: 880px;
|
||
width: 100%;
|
||
background: var(--bg-1);
|
||
border: 1px solid var(--border-strong);
|
||
border-radius: 14px;
|
||
overflow: hidden;
|
||
}
|
||
.templatize-header {
|
||
padding: 20px 24px 18px;
|
||
border-bottom: 1px solid var(--border);
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 16px;
|
||
}
|
||
.templatize-icon {
|
||
width: 40px; height: 40px;
|
||
background: var(--purple-bg-strong);
|
||
border-radius: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
}
|
||
.templatize-icon svg { width: 20px; height: 20px; stroke: var(--purple); fill: none; stroke-width: 1.75; }
|
||
.templatize-header-text { flex: 1; min-width: 0; }
|
||
.templatize-eyebrow {
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
color: var(--purple);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
margin-bottom: 5px;
|
||
}
|
||
.templatize-title {
|
||
font-family: 'Bricolage Grotesque', sans-serif;
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
margin-bottom: 4px;
|
||
}
|
||
.templatize-desc {
|
||
font-size: 13.5px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.55;
|
||
}
|
||
|
||
.templatize-body {
|
||
padding: 20px 24px;
|
||
display: grid;
|
||
grid-template-columns: 1.3fr 1fr;
|
||
gap: 24px;
|
||
}
|
||
.parameterize-preview {
|
||
background: var(--bg-2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 9px;
|
||
padding: 14px 16px;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 11.5px;
|
||
line-height: 1.75;
|
||
color: var(--text-secondary);
|
||
max-height: 340px;
|
||
overflow-y: auto;
|
||
}
|
||
.parameterize-header {
|
||
font-size: 10px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
color: var(--text-tertiary);
|
||
font-weight: 600;
|
||
margin-bottom: 10px;
|
||
padding-bottom: 8px;
|
||
border-bottom: 1px solid var(--border);
|
||
font-family: 'IBM Plex Sans', sans-serif;
|
||
}
|
||
|
||
.extracted-params {
|
||
background: var(--bg-2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 9px;
|
||
padding: 14px 16px;
|
||
}
|
||
.extracted-header {
|
||
font-size: 10px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
color: var(--text-tertiary);
|
||
font-weight: 600;
|
||
margin-bottom: 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
.extracted-count {
|
||
background: var(--purple-bg);
|
||
color: var(--purple);
|
||
font-size: 10px;
|
||
padding: 2px 7px;
|
||
border-radius: 10px;
|
||
border: 1px solid var(--purple-border);
|
||
}
|
||
.extracted-param {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 8px 10px;
|
||
background: var(--bg-1);
|
||
border: 1px solid var(--border);
|
||
border-radius: 6px;
|
||
margin-bottom: 6px;
|
||
font-size: 12px;
|
||
}
|
||
.extracted-param-name {
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 11px;
|
||
color: var(--warning);
|
||
background: var(--warning-bg);
|
||
padding: 2px 7px;
|
||
border-radius: 3px;
|
||
border: 1px solid var(--warning-border);
|
||
flex-shrink: 0;
|
||
}
|
||
.extracted-param-label {
|
||
color: var(--text-primary);
|
||
flex: 1;
|
||
}
|
||
.extracted-param-type {
|
||
font-size: 10.5px;
|
||
color: var(--text-tertiary);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
}
|
||
.extracted-param-remove {
|
||
background: transparent;
|
||
border: none;
|
||
color: var(--text-tertiary);
|
||
cursor: pointer;
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 4px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.extracted-param-remove:hover { background: var(--bg-3); color: var(--danger); }
|
||
.extracted-param-remove svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||
|
||
.templatize-provenance {
|
||
background: var(--bg-2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 7px;
|
||
padding: 10px 12px;
|
||
font-size: 11.5px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.5;
|
||
margin-top: 12px;
|
||
display: flex;
|
||
gap: 8px;
|
||
align-items: flex-start;
|
||
}
|
||
.templatize-provenance svg { width: 12px; height: 12px; stroke: var(--text-tertiary); fill: none; stroke-width: 2; flex-shrink: 0; margin-top: 2px; }
|
||
.templatize-provenance strong { color: var(--text-primary); font-weight: 500; }
|
||
|
||
.templatize-footer {
|
||
padding: 16px 24px;
|
||
border-top: 1px solid var(--border);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
background: var(--bg-2);
|
||
}
|
||
.templatize-footer-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
.settings-toggle {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 7px;
|
||
font-size: 11.5px;
|
||
color: var(--text-tertiary);
|
||
cursor: pointer;
|
||
}
|
||
.settings-toggle svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||
|
||
.templatize-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
/* Page intro/outro */
|
||
.intro {
|
||
max-width: 1400px;
|
||
margin: 0 auto 40px;
|
||
padding: 32px 40px 0;
|
||
}
|
||
.intro-title {
|
||
font-family: 'Bricolage Grotesque', sans-serif;
|
||
font-size: 32px;
|
||
font-weight: 500;
|
||
letter-spacing: -0.02em;
|
||
margin-bottom: 8px;
|
||
}
|
||
.intro-sub {
|
||
font-size: 16px;
|
||
color: var(--text-secondary);
|
||
max-width: 760px;
|
||
line-height: 1.55;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="intro">
|
||
<div class="intro-title">Script Generator · session integration</div>
|
||
<div class="intro-sub">
|
||
Three states showing how script creation flows from a FlowPilot session — matched template, custom script with three-option dialog, and the post-resolve templatization prompt.
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================================================================== -->
|
||
<!-- SCENE 1 — TEMPLATE MATCH FOUND -->
|
||
<!-- ==================================================================== -->
|
||
<section class="scene">
|
||
<div class="scene-header">
|
||
<div class="scene-eyebrow">
|
||
<div class="num">1</div>
|
||
Template match
|
||
</div>
|
||
<div class="scene-title">Suggested fix has a matching template</div>
|
||
<div class="scene-subtitle">
|
||
When FlowPilot's suggested fix maps to a template in the Script Library, clicking opens the generator with parameters pre-filled from What we know. The engineer confirms, generates, done.
|
||
</div>
|
||
</div>
|
||
|
||
<div class="frame">
|
||
<div class="frame-chrome">
|
||
<div class="chrome-dot r"></div>
|
||
<div class="chrome-dot y"></div>
|
||
<div class="chrome-dot g"></div>
|
||
<div class="chrome-url">resolutionflow.com/<strong>pilot/session/48291</strong></div>
|
||
</div>
|
||
|
||
<div class="scene1-layout">
|
||
<!-- Session context on left -->
|
||
<div class="session-context">
|
||
<div class="context-header">
|
||
<span class="psa-chip-inline">CW #48291</span>
|
||
<div class="context-title">Outlook not syncing after password reset</div>
|
||
<div class="context-sub">Acme Corp · jsmith@acme.com · P2 · Service board</div>
|
||
</div>
|
||
|
||
<div class="know-mini">
|
||
<div class="know-mini-label">
|
||
<svg viewBox="0 0 24 24"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/></svg>
|
||
What we know · 4 facts
|
||
</div>
|
||
<div class="know-mini-list">
|
||
<div class="know-mini-item"><span class="mini-check">✓</span><span>OWA working — <strong>rules out tenant/license</strong></span></div>
|
||
<div class="know-mini-item"><span class="mini-check">✓</span><span>Password reset via AD at <strong>14:02</strong></span></div>
|
||
<div class="know-mini-item"><span class="mini-check">✓</span><span>Isolated to <strong>jsmith</strong> — not tenant-wide</span></div>
|
||
<div class="know-mini-item"><span class="mini-check">✓</span><span>AD unlocked, EXO license <strong>active</strong></span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="suggested-fix-card">
|
||
<div class="suggested-fix-label">
|
||
<svg viewBox="0 0 24 24"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
||
Suggested fix · template found<span class="match-chip">94% match</span>
|
||
</div>
|
||
<div class="suggested-fix-title">Clear cached credentials + rebuild Outlook profile</div>
|
||
<div class="suggested-fix-meta">
|
||
From <strong style="color: var(--text-primary); font-weight: 500;">your team library</strong> · resolved 7 similar sessions · last used 3 days ago
|
||
</div>
|
||
</div>
|
||
|
||
<div class="invoke-hint">
|
||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
|
||
You can also invoke the script generator anytime with <span class="kbd">⌘K</span> → "script" or from the composer toolbar.
|
||
</div>
|
||
|
||
<div class="arrow-to-generator">
|
||
<svg viewBox="0 0 40 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||
<path d="M5 12h30M28 5l7 7-7 7"/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Script Generator panel -->
|
||
<div class="script-gen">
|
||
<div class="gen-header">
|
||
<div class="gen-title-wrap">
|
||
<div class="gen-eyebrow">
|
||
<svg viewBox="0 0 24 24"><path d="M4 17l6-6-6-6"/><path d="M12 19h8"/></svg>
|
||
Script Generator
|
||
</div>
|
||
<div class="gen-title">Clear cached credentials + rebuild profile</div>
|
||
</div>
|
||
<button class="gen-close">
|
||
<svg viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="template-badge">
|
||
<div class="template-badge-icon">
|
||
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
|
||
</div>
|
||
<div class="template-badge-text">
|
||
<strong>Verified template</strong> · v3 · ActiveDirectory module · runs as admin
|
||
</div>
|
||
</div>
|
||
|
||
<div class="gen-body">
|
||
<div class="prefilled-banner">
|
||
<svg viewBox="0 0 24 24"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
||
<div>
|
||
<strong>3 of 5 parameters pre-filled</strong> from session context. Review and adjust the highlighted fields, then generate.
|
||
</div>
|
||
</div>
|
||
|
||
<div class="param-group-title">Target user</div>
|
||
|
||
<div class="param-field">
|
||
<div class="param-label">
|
||
<span>SAM account name<span class="req">*</span></span>
|
||
<span class="prefilled-tag">from session</span>
|
||
</div>
|
||
<input class="param-input prefilled mono-font" value="jsmith" />
|
||
<div class="param-hint">Pulled from ticket subject + What we know.</div>
|
||
</div>
|
||
|
||
<div class="param-field">
|
||
<div class="param-label">
|
||
<span>Domain<span class="req">*</span></span>
|
||
<span class="prefilled-tag">from Acme config</span>
|
||
</div>
|
||
<input class="param-input prefilled mono-font" value="acmecorp.local" />
|
||
<div class="param-hint">Pulled from CW company config for Acme Corp.</div>
|
||
</div>
|
||
|
||
<div class="param-group-title">Cache targets</div>
|
||
|
||
<div class="param-field">
|
||
<div class="param-label">
|
||
<span>Clear Windows Credential Manager entries<span class="req">*</span></span>
|
||
</div>
|
||
<input class="param-input" value="MS.Outlook.*, *acmecorp.*" />
|
||
<div class="param-hint">Wildcard patterns. Default covers Outlook + ADAL cached tokens.</div>
|
||
</div>
|
||
|
||
<div class="param-field">
|
||
<div class="param-label">
|
||
<span>Clear Autodiscover cache</span>
|
||
</div>
|
||
<input class="param-input" value="true" style="color: var(--success);" />
|
||
</div>
|
||
|
||
<div class="param-group-title">Profile rebuild</div>
|
||
|
||
<div class="param-field">
|
||
<div class="param-label">
|
||
<span>Rebuild strategy</span>
|
||
</div>
|
||
<input class="param-input" value="Remove profile, let Outlook recreate on next launch" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="gen-footer">
|
||
<button class="btn btn-ghost">Reset to defaults</button>
|
||
<div style="flex: 1;"></div>
|
||
<button class="btn">
|
||
<svg class="btn-icon" viewBox="0 0 24 24"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
||
Preview
|
||
</button>
|
||
<button class="btn btn-primary">
|
||
<svg class="btn-icon" viewBox="0 0 24 24"><path d="M5 3l14 9-14 9V3z"/></svg>
|
||
Generate script
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ==================================================================== -->
|
||
<!-- SCENE 2 — THREE-OPTION DIALOG -->
|
||
<!-- ==================================================================== -->
|
||
<section class="scene">
|
||
<div class="scene-header">
|
||
<div class="scene-eyebrow">
|
||
<div class="num">2</div>
|
||
No template match
|
||
</div>
|
||
<div class="scene-title">AI generates a custom script — three paths</div>
|
||
<div class="scene-subtitle">
|
||
When no existing template matches, FlowPilot drafts a session-specific script and offers three paths. The middle option (one-off now, template later) is the default because it captures institutional knowledge without blocking the engineer mid-crisis.
|
||
</div>
|
||
</div>
|
||
|
||
<div class="frame">
|
||
<div class="frame-chrome">
|
||
<div class="chrome-dot r"></div>
|
||
<div class="chrome-dot y"></div>
|
||
<div class="chrome-dot g"></div>
|
||
<div class="chrome-url">resolutionflow.com/<strong>pilot/session/48307</strong></div>
|
||
</div>
|
||
|
||
<div class="scene2-layout">
|
||
<!-- Dimmed session context -->
|
||
<div class="scene2-context scene2-context-dim">
|
||
<div class="context-header">
|
||
<span class="psa-chip-inline">CW #48307</span>
|
||
<div class="context-title">VPN session torn down every 3–5 minutes</div>
|
||
<div class="context-sub">Duncan & Partners · GlobalProtect · P3</div>
|
||
</div>
|
||
|
||
<div class="know-mini">
|
||
<div class="know-mini-label">
|
||
<svg viewBox="0 0 24 24"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/></svg>
|
||
What we know · 3 facts
|
||
</div>
|
||
<div class="know-mini-list">
|
||
<div class="know-mini-item"><span class="mini-check">✓</span><span>Gateway logs show <strong>GPTunnel: session timeout</strong> every 3–5min</span></div>
|
||
<div class="know-mini-item"><span class="mini-check">✓</span><span>Happens on <strong>both wifi and LAN</strong> — not network-path</span></div>
|
||
<div class="know-mini-item"><span class="mini-check">✓</span><span>Gateway-side teardown confirmed via <strong>PAN XML API</strong></span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="suggested-fix-card">
|
||
<div class="suggested-fix-label">
|
||
<svg viewBox="0 0 24 24"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
||
Suggested fix · custom script
|
||
</div>
|
||
<div class="suggested-fix-title">Query & clear duplicate sessions from GP gateway</div>
|
||
<div class="suggested-fix-meta">
|
||
No template match in your library · AI drafted this from session context.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Three option dialog -->
|
||
<div class="three-option-panel">
|
||
<div class="three-option-eyebrow">
|
||
<svg viewBox="0 0 24 24"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
||
No template match — how would you like to proceed?
|
||
</div>
|
||
<div class="three-option-title">
|
||
FlowPilot has drafted a PowerShell script for this ticket
|
||
</div>
|
||
<div class="three-option-sub">
|
||
The script queries the GP gateway's active session table via the PAN XML API and clears duplicates. Pick how this gets saved — the choice affects whether your team benefits from it later.
|
||
</div>
|
||
|
||
<div class="script-preview">
|
||
<div class="script-preview-header">
|
||
<span>drafted script · PowerShell · 32 lines</span>
|
||
<div class="script-preview-legend">
|
||
<div class="legend-item">
|
||
<div class="legend-swatch"></div>
|
||
<span>proposed parameters</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="sp-comment"># Query & clear duplicate GP sessions — jsmith @ Duncan</span>
|
||
<span class="sp-var">$fw</span> = <span class="sp-hl">'fw01.duncan.law'</span>
|
||
<span class="sp-var">$key</span> = <span class="sp-hl">'LUFRPT1...ZG9u'</span>
|
||
<span class="sp-var">$user</span> = <span class="sp-hl">'dfield'</span>
|
||
|
||
<span class="sp-var">$xml</span> = <span class="sp-cmdlet">Invoke-RestMethod</span> <span class="sp-param">-Uri</span> <span class="sp-str">"https://</span><span class="sp-var">$fw</span><span class="sp-str">/api/?type=op&cmd=..."</span>
|
||
<span class="sp-var">$sessions</span> = <span class="sp-var">$xml</span>.response.result.entry | <span class="sp-cmdlet">Where-Object</span> { <span class="sp-var">$_</span>.username -eq <span class="sp-var">$user</span> }
|
||
<span class="sp-comment">... <span style="color: var(--text-tertiary);">(show full script)</span></span>
|
||
</div>
|
||
|
||
<div class="options-grid">
|
||
<!-- Option 1: One-off -->
|
||
<div class="option-card">
|
||
<div class="option-icon oneoff">
|
||
<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></svg>
|
||
</div>
|
||
<div class="option-title">Run as one-off</div>
|
||
<div class="option-desc">Generate the script for this ticket only. Captured in session documentation. Discarded after.</div>
|
||
<div class="option-tradeoffs">
|
||
<div class="tradeoff-row good">
|
||
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
|
||
Fastest — no follow-up
|
||
</div>
|
||
<div class="tradeoff-row warn">
|
||
<svg viewBox="0 0 24 24"><path d="M12 9v4M12 17h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg>
|
||
Team won't benefit next time
|
||
</div>
|
||
</div>
|
||
<button class="option-cta oneoff">Generate & run</button>
|
||
</div>
|
||
|
||
<!-- Option 2: Draft template (RECOMMENDED) -->
|
||
<div class="option-card recommended">
|
||
<div class="option-badge">Recommended</div>
|
||
<div class="option-icon draft">
|
||
<svg viewBox="0 0 24 24"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg>
|
||
</div>
|
||
<div class="option-title">Run now, templatize after resolve</div>
|
||
<div class="option-desc">Generate for this ticket. If it works, FlowPilot offers to turn it into a team template when you click Resolve.</div>
|
||
<div class="option-tradeoffs">
|
||
<div class="tradeoff-row good">
|
||
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
|
||
Zero cognitive overhead now
|
||
</div>
|
||
<div class="tradeoff-row good">
|
||
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
|
||
Only templatize what actually works
|
||
</div>
|
||
<div class="tradeoff-row neutral">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
|
||
~30 sec review after resolve
|
||
</div>
|
||
</div>
|
||
<button class="option-cta draft">Generate & run</button>
|
||
</div>
|
||
|
||
<!-- Option 3: Template now -->
|
||
<div class="option-card">
|
||
<div class="option-icon template">
|
||
<svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg>
|
||
</div>
|
||
<div class="option-title">Build as template now</div>
|
||
<div class="option-desc">Full parameterization up front. Takes 2–3 min but becomes a first-class team template immediately.</div>
|
||
<div class="option-tradeoffs">
|
||
<div class="tradeoff-row good">
|
||
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
|
||
Immediate team benefit
|
||
</div>
|
||
<div class="tradeoff-row warn">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
||
Adds time mid-ticket
|
||
</div>
|
||
</div>
|
||
<button class="option-cta template">Build template</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="option-footer">
|
||
<span>All options capture the script in session documentation with passwords redacted.</span>
|
||
<button class="btn btn-ghost">Cancel</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ==================================================================== -->
|
||
<!-- SCENE 3 — POST-RESOLVE TEMPLATIZATION -->
|
||
<!-- ==================================================================== -->
|
||
<section class="scene">
|
||
<div class="scene-header">
|
||
<div class="scene-eyebrow">
|
||
<div class="num">3</div>
|
||
Post-resolve prompt
|
||
</div>
|
||
<div class="scene-title">Turn what just worked into a reusable template</div>
|
||
<div class="scene-subtitle">
|
||
After Resolve posts the summary to CW, FlowPilot surfaces the templatization prompt for any custom script that ran successfully. The engineer reviews AI-proposed parameters, adjusts if needed, and ships — or skips.
|
||
</div>
|
||
</div>
|
||
|
||
<div class="frame">
|
||
<div class="frame-chrome">
|
||
<div class="chrome-dot r"></div>
|
||
<div class="chrome-dot y"></div>
|
||
<div class="chrome-dot g"></div>
|
||
<div class="chrome-url">resolutionflow.com/<strong>pilot/session/48307</strong> · resolved</div>
|
||
</div>
|
||
|
||
<div class="scene3-layout">
|
||
|
||
<!-- Success banner at top -->
|
||
<div class="resolve-success-banner">
|
||
<div class="resolve-icon-wrap">
|
||
<svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
|
||
</div>
|
||
<div class="resolve-info">
|
||
<div class="resolve-title">Session resolved — summary posted to CW #48307</div>
|
||
<div class="resolve-meta">
|
||
<span>Status set to <strong style="color: var(--success); font-weight: 500;">Resolved</strong></span>
|
||
<span>·</span>
|
||
<span>7 minutes total session time</span>
|
||
<span>·</span>
|
||
<span>Custom script ran successfully</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Templatize card -->
|
||
<div class="templatize-card">
|
||
<div class="templatize-header">
|
||
<div class="templatize-icon">
|
||
<svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg>
|
||
</div>
|
||
<div class="templatize-header-text">
|
||
<div class="templatize-eyebrow">One more thing</div>
|
||
<div class="templatize-title">Turn this into a team template?</div>
|
||
<div class="templatize-desc">
|
||
The script you just ran resolved the VPN session teardown for D. Field at Duncan & Partners. If a similar ticket comes in next week, your team can skip the analysis and run this in 10 seconds.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="templatize-body">
|
||
<div>
|
||
<div class="parameterize-header">Proposed template · parameters highlighted</div>
|
||
<div class="parameterize-preview">
|
||
<span class="sp-comment"># Query & clear duplicate GP sessions</span>
|
||
<span class="sp-comment"># Auto-generated from CW #48307 · D. Field · Duncan</span>
|
||
|
||
<span class="sp-var">$fw</span> = <span class="sp-hl">{{ gateway_host }}</span>
|
||
<span class="sp-var">$key</span> = <span class="sp-hl">{{ api_key }}</span>
|
||
<span class="sp-var">$user</span> = <span class="sp-hl">{{ sam_account_name }}</span>
|
||
|
||
<span class="sp-var">$xml</span> = <span class="sp-cmdlet">Invoke-RestMethod</span> <span class="sp-param">-Uri</span> <span class="sp-str">"https://</span><span class="sp-var">$fw</span><span class="sp-str">/api/?type=op&cmd=<show>..."</span>
|
||
<span class="sp-var">$sessions</span> = <span class="sp-var">$xml</span>.response.result.entry |
|
||
<span class="sp-cmdlet">Where-Object</span> { <span class="sp-var">$_</span>.username -eq <span class="sp-var">$user</span> }
|
||
|
||
<span class="sp-cmdlet">foreach</span> (<span class="sp-var">$s</span> <span class="sp-cmdlet">in</span> <span class="sp-var">$sessions</span>) {
|
||
<span class="sp-cmdlet">Invoke-RestMethod</span> <span class="sp-param">-Uri</span> <span class="sp-str">"https://</span><span class="sp-var">$fw</span><span class="sp-str">/api/?type=op&cmd=<clear>..."</span>
|
||
<span class="sp-cmdlet">Write-Host</span> <span class="sp-str">"Cleared session </span><span class="sp-var">$(</span><span class="sp-var">$s</span>.session-id<span class="sp-var">)</span><span class="sp-str">"</span>
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div class="extracted-params">
|
||
<div class="extracted-header">
|
||
<span>Extracted parameters</span>
|
||
<span class="extracted-count">3 proposed</span>
|
||
</div>
|
||
|
||
<div class="extracted-param">
|
||
<span class="extracted-param-name">gateway_host</span>
|
||
<span class="extracted-param-label">Firewall hostname</span>
|
||
<span class="extracted-param-type">text</span>
|
||
<button class="extracted-param-remove">
|
||
<svg viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="extracted-param">
|
||
<span class="extracted-param-name">api_key</span>
|
||
<span class="extracted-param-label">PAN API key</span>
|
||
<span class="extracted-param-type">password</span>
|
||
<button class="extracted-param-remove">
|
||
<svg viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="extracted-param">
|
||
<span class="extracted-param-name">sam_account_name</span>
|
||
<span class="extracted-param-label">Target username</span>
|
||
<span class="extracted-param-type">text</span>
|
||
<button class="extracted-param-remove">
|
||
<svg viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<button class="btn btn-ghost" style="width: 100%; justify-content: center; margin-top: 6px; border: 1px dashed var(--border-strong); font-size: 12px;">
|
||
<svg class="btn-icon" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></svg>
|
||
Add parameter
|
||
</button>
|
||
</div>
|
||
|
||
<div class="templatize-provenance">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
|
||
<div>
|
||
<strong>Provenance tracked</strong> · this template will show "generated from CW #48307 · resolved by M. Davis" in the library. Visible to your team only until promoted to Verified by an admin.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="templatize-footer">
|
||
<div class="templatize-footer-left">
|
||
<div class="settings-toggle">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 01-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
|
||
<span>Don't ask me again for this team</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="templatize-actions">
|
||
<button class="btn btn-ghost">Skip — keep as one-off</button>
|
||
<button class="btn">
|
||
<svg class="btn-icon" viewBox="0 0 24 24"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
|
||
Edit parameters
|
||
</button>
|
||
<button class="btn btn-success">
|
||
<svg class="btn-icon" viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
|
||
Save as team template
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</body>
|
||
</html>
|