Files
resolutionflow/docs/FlowAssist_Migration/mockups/02-04-script-integration.html
Michael Chihlas 46291f30b9 docs: add FlowPilot migration design doc and mockups
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>
2026-04-17 15:22:39 +00:00

1517 lines
49 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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 35 minutes</div>
<div class="context-sub">Duncan &amp; 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 35min</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 &amp; 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 &amp; 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&amp;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 &amp; 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 &amp; 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 23 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 &amp; 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 &amp; 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&amp;cmd=&lt;show&gt;..."</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&amp;cmd=&lt;clear&gt;..."</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>