2026-05-23 06:58:20 -07:00
<!DOCTYPE html>
< html lang = "en" >
< head >
2026-08-08 12:32:17 -07:00
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< title > Plan2Code — Spec-Driven Workflow for AI Coding Agents< / title >
< meta name = "description" content = "Send the plan — the build follows. You approve a plan, it becomes phase documents in your repo, and the agent builds to those documents one phase at a time." >
< link rel = "icon" href = "favicon.ico" sizes = "32x32" >
< link rel = "icon" type = "image/png" sizes = "32x32" href = "favicon.png" >
< link rel = "icon" href = "favicon.svg" type = "image/svg+xml" >
< link rel = "apple-touch-icon" href = "apple-touch-icon.png" >
< link rel = "preconnect" href = "https://fonts.googleapis.com" >
< link rel = "preconnect" href = "https://fonts.gstatic.com" crossorigin >
< link href = "https://fonts.googleapis.com/css2?family=Big+Shoulders+Display:wght@500;700;800&family=Karla:wght@300;400;500;600;700&family=Caveat:wght@500&display=swap" rel = "stylesheet" >
< style >
: root {
--air : #E4ECF6 ; --air-2 : #D3DEEE ; --paper : #FBFAF6 ;
--ink : #16233D ; --ink-soft : #5E6E8A ;
--red : #D33A38 ; --blue : #2455A4 ; --kraft : #E5D8BE ;
}
* { margin : 0 ; padding : 0 ; box-sizing : border-box }
body { background : var ( - - air ) ; color : var ( - - ink ) ; font : 400 16.5 px / 1.65 'Karla' , system-ui , sans-serif ; -webkit- font-smoothing : antialiased }
. bs { font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; letter-spacing : .005 em }
. hand { font-family : 'Caveat' , cursive }
. wrap { max-width : 1140 px ; margin : 0 auto ; padding : 0 34 px }
a { color : inherit }
: focus-visible { outline : 2 px solid var ( - - red ) ; outline-offset : 3 px }
/* ── SIGNATURE: airmail chevron border framing the page on all four sides ── */
: root { --fr : 11 px }
. frame-t , . frame-b , . frame-l , . frame-r {
position : fixed ; z-index : 60 ; pointer-events : none ;
background : repeating-linear-gradient ( -45 deg ,
var ( - - red ) 0 14 px , var ( - - paper ) 14 px 28 px ,
var ( - - blue ) 28 px 42 px , var ( - - paper ) 42 px 56 px ) ;
}
. frame-t , . frame-b { left : 0 ; right : 0 ; height : var ( - - fr ) }
. frame-t { top : 0 }
. frame-b { bottom : 0 }
. frame-l , . frame-r { top : 0 ; bottom : 0 ; width : var ( - - fr ) }
. frame-l { left : 0 }
. frame-r { right : 0 }
body { padding : var ( - - fr ) }
/* ── header (sticky, sits just under the top frame) ── */
. top {
background : var ( - - paper ) ; border-bottom : 2 px solid var ( - - ink ) ;
position : sticky ; top : var ( - - fr ) ; z-index : 40 ;
}
. top . wrap { display : flex ; align-items : center ; gap : 16 px ; padding-top : 13 px ; padding-bottom : 12 px }
. brand { font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; font-size : 26 px ; letter-spacing : .01 em ; text-transform : uppercase }
. brand i { font-style : normal ; color : var ( - - red ) }
. avion {
margin-left : auto ; border : 1.5 px solid var ( - - blue ) ; color : var ( - - blue ) ;
font-size : 10 px ; letter-spacing : .22 em ; text-transform : uppercase ; font-weight : 700 ; padding : 5 px 11 px ;
}
/* ── hero: the envelope ── */
. hero { padding : 56 px 0 70 px }
. env {
background : var ( - - paper ) ; border : 2 px solid var ( - - ink ) ; position : relative ;
box-shadow : 10 px 12 px 0 rgba ( 22 , 35 , 61 , .14 ) ; padding : 40 px 42 px 44 px ;
}
/* cancellation waves */
. cancel { position : absolute ; right : 34 px ; top : 34 px ; width : 210 px ; height : 110 px ; pointer-events : none }
. cancel . ring { fill : none ; stroke : var ( - - red ) ; stroke-width : 2.2 }
. cancel . wv { fill : none ; stroke : var ( - - red ) ; stroke-width : 2.2 ; opacity : .85 }
. cancel text { font-family : 'Karla' , sans-serif ; font-weight : 700 ; fill : var ( - - red ) ; letter-spacing : .06 em }
/* stamp */
. pstamp {
position : absolute ; right : 250 px ; top : 34 px ; width : 86 px ; height : 104 px ; background : var ( - - air -2 ) ;
border : 2 px solid var ( - - ink ) ; padding : 8 px ; text-align : center ;
}
. pstamp . in { border : 1 px solid rgba ( 22 , 35 , 61 , .35 ) ; height : 100 % ; display : flex ; flex-direction : column ; justify-content : center ; gap : 2 px }
. pstamp b { font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; font-size : 26 px ; line-height : 1 ; color : var ( - - blue ) }
. pstamp span { font-size : 8 px ; letter-spacing : .12 em ; text-transform : uppercase ; color : var ( - - ink - soft ) ; font-weight : 700 }
@ media ( max-width : 900px ) { . cancel , . pstamp { display : none } }
. kick { font-size : 10.5 px ; letter-spacing : .24 em ; text-transform : uppercase ; color : var ( - - blue ) ; font-weight : 700 }
h1 { font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; font-size : clamp ( 3 rem , 9 vw , 7 rem ) ; line-height : .86 ; text-transform : uppercase ; margin-top : 14 px ; max-width : 13 ch }
h1 em { font-style : normal ; color : var ( - - red ) }
. addr {
margin-top : 32 px ; padding-top : 26 px ; border-top : 1.5 px dashed rgba ( 22 , 35 , 61 , .3 ) ;
display : grid ; grid-template-columns : 1 fr 1 fr ; gap : 36 px ; align-items : end ;
}
. addr . to { font-size : 10 px ; letter-spacing : .2 em ; text-transform : uppercase ; color : var ( - - ink - soft ) ; font-weight : 700 }
. addr p { margin-top : 10 px ; color : var ( - - ink - soft ) ; max-width : 44 ch }
. acts { display : flex ; flex-wrap : wrap ; gap : 12 px }
. btn {
display : inline-block ; text-decoration : none ; background : var ( - - ink ) ; color : var ( - - paper ) ;
font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 700 ; font-size : 19 px ; letter-spacing : .1 em ;
text-transform : uppercase ; padding : 12 px 28 px ; transition : background .18 s , transform .18 s ;
}
. btn : hover { background : var ( - - red ) ; transform : translateY ( -2 px ) }
. btn . -o { background : transparent ; border : 2 px solid var ( - - ink ) ; color : var ( - - ink ) ; padding : 10 px 26 px }
. btn . -o : hover { background : var ( - - ink ) ; color : var ( - - paper ) }
/* ── postage meter strip ── */
. meter { background : var ( - - ink ) ; color : var ( - - paper ) }
. meter . wrap { display : grid ; grid-template-columns : repeat ( auto - fit , minmax ( 140 px , 1 fr ) ) ; gap : 0 }
. meter div { padding : 24 px 18 px ; border-left : 1 px dashed rgba ( 251 , 250 , 246 , .28 ) }
. meter div : first-child { border-left : none }
. meter b { display : block ; font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; font-size : 2.4 rem ; line-height : 1 ; color : #8FB6E8 }
. meter span { display : block ; margin-top : 3 px ; font-size : 9.5 px ; letter-spacing : .14 em ; text-transform : uppercase ; opacity : .66 ; font-weight : 700 }
/* ── dispatch (steps as airmail envelopes) ── */
. dispatch { padding : 80 px 0 40 px }
. sect { display : flex ; align-items : flex-end ; gap : 16 px ; border-bottom : 2 px solid var ( - - ink ) ; padding-bottom : 10 px }
. sect h2 { font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; font-size : clamp ( 2 rem , 5 vw , 3.4 rem ) ; text-transform : uppercase ; line-height : .95 }
. sect span { margin-left : auto ; font-size : 10.5 px ; letter-spacing : .16 em ; text-transform : uppercase ; color : var ( - - ink - soft ) ; font-weight : 700 ; padding-bottom : 5 px }
. letters { display : grid ; grid-template-columns : repeat ( auto - fit , minmax ( 400 px , 1 fr ) ) ; gap : 22 px ; margin-top : 30 px }
. ltr {
background : var ( - - paper ) ; border : 2 px solid var ( - - ink ) ; position : relative ;
padding : 26 px 26 px 28 px 40 px ; display : flex ; flex-direction : column ;
box-shadow : 6 px 7 px 0 rgba ( 22 , 35 , 61 , .12 ) ; transition : transform .2 s , box-shadow .2 s ;
}
. ltr : hover { transform : translate ( -3 px , -3 px ) ; box-shadow : 9 px 10 px 0 rgba ( 22 , 35 , 61 , .16 ) }
/* chevron spine */
. ltr :: before {
content : '' ; position : absolute ; left : 0 ; top : 0 ; bottom : 0 ; width : 14 px ;
background : repeating-linear-gradient ( -45 deg , var ( - - red ) 0 10 px , var ( - - paper ) 10 px 20 px , var ( - - blue ) 20 px 30 px , var ( - - paper ) 30 px 40 px ) ;
border-right : 1 px solid var ( - - ink ) ;
}
. ltr . mark {
position : absolute ; right : 20 px ; top : 18 px ; width : 56 px ; height : 56 px ; border : 2 px solid var ( - - red ) ; border-radius : 50 % ;
display : grid ; place-items : center ; text-align : center ; transform : rotate ( -11 deg ) ;
font-size : 8.5 px ; letter-spacing : .08 em ; text-transform : uppercase ; color : var ( - - red ) ; font-weight : 700 ; line-height : 1.25 ;
}
. ltr h3 { font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; font-size : 1.9 rem ; text-transform : uppercase ; line-height : 1 ; padding-right : 70 px }
. ltr . flag {
display : inline-block ; margin-left : 9 px ; vertical-align : 5 px ; font-family : 'Karla' , sans-serif ; font-weight : 700 ;
font-size : 9 px ; letter-spacing : .11 em ; text-transform : uppercase ; background : var ( - - blue ) ; color : #fff ; padding : 3 px 8 px ;
}
. ltr . flag . -r { background : var ( - - red ) }
. ltr code { display : block ; font-family : ui-monospace , Menlo , monospace ; font-size : 11.5 px ; color : var ( - - blue ) ; margin-top : 7 px ; font-weight : 600 }
. ltr p { margin-top : 12 px ; color : var ( - - ink - soft ) ; font-size : .94 rem }
. ltr . pen { font-family : 'Caveat' , cursive ; font-size : 1.2 rem ; color : var ( - - red ) ; margin-top : 10 px ; transform : rotate ( -.8 deg ) }
. ltr ul { list-style : none ; margin-top : auto ; padding-top : 16 px }
. ltr li { font-size : .85 rem ; padding : 6 px 0 6 px 18 px ; position : relative ; border-top : 1 px dotted rgba ( 22 , 35 , 61 , .24 ) }
. ltr li :: before { content : '✈' ; position : absolute ; left : 0 ; color : var ( - - blue ) ; font-size : 9 px ; top : 9 px }
/* ── two routes ── */
. routes { background : var ( - - paper ) ; border-top : 2 px solid var ( - - ink ) ; border-bottom : 2 px solid var ( - - ink ) ; padding : 76 px 0 ; margin-top : 56 px }
. rc { display : grid ; grid-template-columns : 1 fr 1 fr ; gap : 24 px ; margin-top : 28 px }
. rc div { border : 2 px solid var ( - - ink ) ; padding : 26 px 24 px }
. rc . -a { background : rgba ( 211 , 58 , 56 , .06 ) }
. rc . -b { background : rgba ( 36 , 85 , 164 , .06 ) }
. rc h4 { font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; font-size : 1.5 rem ; text-transform : uppercase }
. rc ul { list-style : none ; margin-top : 14 px }
. rc li { padding : 9 px 0 9 px 24 px ; position : relative ; font-size : .95 rem ; border-top : 1 px solid rgba ( 22 , 35 , 61 , .14 ) ; color : var ( - - ink - soft ) }
. rc li : first-child { border-top : none }
. rc . -a li :: before { content : '✕' ; position : absolute ; left : 0 ; color : var ( - - red ) ; font-weight : 700 }
. rc . -b li :: before { content : '✓' ; position : absolute ; left : 0 ; color : var ( - - blue ) ; font-weight : 700 }
/* ── regulations ── */
. regs { padding : 78 px 0 }
. rg { display : grid ; grid-template-columns : repeat ( auto - fit , minmax ( 230 px , 1 fr ) ) ; gap : 0 ; margin-top : 26 px ; border-top : 2 px solid var ( - - ink ) ; border-left : 2 px solid var ( - - ink ) }
. rg div { padding : 22 px 20 px ; border-right : 2 px solid var ( - - ink ) ; border-bottom : 2 px solid var ( - - ink ) ; background : var ( - - paper ) }
. rg b { font-size : 10 px ; letter-spacing : .15 em ; text-transform : uppercase ; color : var ( - - red ) ; font-weight : 700 }
. rg p { margin-top : 9 px ; font-size : .94 rem ; color : var ( - - ink - soft ) }
. rg p strong { color : var ( - - ink ) ; font-weight : 700 }
/* ── install ── */
. install { padding : 0 0 82 px }
. term { margin-top : 20 px ; background : var ( - - ink ) ; color : #D6E2F2 ; padding : 24 px ;
font-family : ui-monospace , Menlo , monospace ; font-size : 12.5 px ; line-height : 2.05 ; overflow-x : auto }
. term . c { color : #7488A6 } . term . k { color : #F0B06A } . term . p { color : #8FB6E8 }
/* ── close ── */
. close { background : var ( - - ink ) ; color : var ( - - paper ) ; text-align : center ; padding : 92 px 0 }
. close h2 { font-family : 'Big Shoulders Display' , sans-serif ; font-weight : 800 ; font-size : clamp ( 2.4 rem , 7 vw , 5.2 rem ) ; text-transform : uppercase ; line-height : .9 }
. close h2 em { font-style : normal ; color : #8FB6E8 }
. close . hand { display : block ; margin-top : 14 px ; font-size : 1.5 rem ; color : #8FB6E8 }
. close . btn { margin-top : 24 px ; background : var ( - - red ) }
. close . btn : hover { background : var ( - - paper ) ; color : var ( - - ink ) }
footer { background : var ( - - ink ) ; color : rgba ( 251 , 250 , 246 , .5 ) ; padding : 0 0 28 px ; font-size : 10 px ; letter-spacing : .15 em ; text-transform : uppercase ; font-weight : 700 }
footer . wrap { display : flex ; justify-content : space-between ; gap : 12 px ; flex-wrap : wrap ; border-top : 1 px dashed rgba ( 251 , 250 , 246 , .24 ) ; padding-top : 20 px }
@ media ( max-width : 700px ) { : root { --fr : 8 px } }
@ media ( max-width : 820px ) {
. wrap { padding : 0 20 px }
. env { padding : 26 px 22 px 28 px }
. addr { grid-template-columns : 1 fr ; gap : 22 px }
. rc { grid-template-columns : 1 fr }
. letters { grid-template-columns : 1 fr }
}
@ media ( prefers-reduced-motion : reduce ) { * { transition : none !important } }
< / style >
2026-05-23 06:58:20 -07:00
< / head >
< body >
2026-08-08 12:32:17 -07:00
< div class = "frame-t" aria-hidden = "true" > < / div >
< div class = "frame-b" aria-hidden = "true" > < / div >
< div class = "frame-l" aria-hidden = "true" > < / div >
< div class = "frame-r" aria-hidden = "true" > < / div >
< header class = "top" >
< div class = "wrap" >
< span class = "brand" > PLAN< i > 2< / i > CODE< / span >
< span class = "avion" > Par Avion · Via Air Mail< / span >
< / div >
< / header >
< section class = "hero" >
< div class = "wrap" >
< div class = "env" >
< div class = "pstamp" > < div class = "in" > < b > 2.0< / b > < span > Plan2Code< / span > < span > Postage< / span > < / div > < / div >
< svg class = "cancel" viewBox = "0 0 210 110" aria-hidden = "true" >
< circle class = "ring" cx = "52" cy = "55" r = "42" / >
< text x = "52" y = "46" text-anchor = "middle" font-size = "10" > SHIPPED< / text >
< text x = "52" y = "62" text-anchor = "middle" font-size = "13" font-weight = "700" > 2026< / text >
< text x = "52" y = "76" text-anchor = "middle" font-size = "8" > NO REWORK< / text >
< path class = "wv" d = "M98,36 C118,28 138,44 158,36 C178,28 194,40 208,34" / >
< path class = "wv" d = "M98,50 C118,42 138,58 158,50 C178,42 194,54 208,48" / >
< path class = "wv" d = "M98,64 C118,56 138,72 158,64 C178,56 194,68 208,62" / >
< path class = "wv" d = "M98,78 C118,70 138,86 158,78 C178,70 194,82 208,76" / >
< / svg >
< p class = "kick" > Spec-driven workflow for AI coding agents< / p >
< h1 > Send the plan.< br > The build < em > follows< / em > .< / h1 >
< div class = "addr" >
< div >
< p class = "to" > Addressed to< / p >
< p > Anyone who has watched an AI agent confidently build the wrong thing. You approve a plan, it becomes phase documents in your repo, and the agent works to those documents one phase at a time.< / p >
2026-05-23 06:58:20 -07:00
< / div >
2026-08-08 12:32:17 -07:00
< div class = "acts" >
< a class = "btn" href = "https://github.com/jparkerweb/plan2code" > Install Plan2Code< / a >
< a class = "btn -o" href = "#dispatch" > Read the letters< / a >
2026-05-23 06:58:20 -07:00
< / div >
2026-08-08 12:32:17 -07:00
< / div >
< / div >
< / div >
< / section >
< div class = "meter" >
< div class = "wrap" >
< div > < b > 90%< / b > < span > Confidence gate< / span > < / div >
< div > < b > 11< / b > < span > Review dimensions< / span > < / div >
< div > < b > 1< / b > < span > Chat per phase< / span > < / div >
< div > < b > 0< / b > < span > Context pollution< / span > < / div >
< / div >
< / div >
< section class = "dispatch wrap" id = "dispatch" >
< div class = "sect" > < h2 > Six written letters< / h2 > < span > Two optional< / span > < / div >
< div class = "letters" >
< article class = "ltr" >
< span class = "mark" > Opt< br > 00< / span >
< h3 > Pathfinder< span class = "flag" > New in 2.0< / span > < / h3 >
< code > /plan2code-0-pathfinder< / code >
< p > For an idea that arrives too foggy to plan. It charts the idea as a map of decision questions and clears exactly one per session until nothing is left to decide.< / p >
< p class = "pen" > it never answers its own questions — that's the point< / p >
< ul >
< li > One decision per file, one file per session< / li >
< li > Research questions fan out to parallel agents< / li >
< li > Clears at ≥18/25 on four confidence dimensions< / li >
< li > Hands a hot plan draft to Step 1< / li >
< / ul >
< / article >
< article class = "ltr" >
< span class = "mark" > Req< br > 01< / span >
< h3 > Plan< / h3 >
< code > /plan2code-1-plan< / code >
< p > A real back-and-forth about what gets built. Requirements pulled apart, your codebase actually read, the stack confirmed rather than assumed.< / p >
< ul >
< li > Functional and non-functional requirements< / li >
< li > Integration points read from real source< / li >
< li > Tech stack confirmed by explicit approval< / li >
< li > Will not finalize below 90% confidence< / li >
< / ul >
< / article >
< article class = "ltr" >
< span class = "mark" > Req< br > 02< / span >
< h3 > Document< / h3 >
< code > /plan2code-2-document< / code >
< p > The plan stops being a conversation and becomes files — an overview plus one self-contained phase document per phase, cut into one-story-point tasks.< / p >
< ul >
< li > overview.md and Phase 1…N.md land in your repo< / li >
< li > One-point tasks with real checkboxes< / li >
< li > Parallel groups marked for concurrent agents< / li >
< li > Each phase readable with no prior context< / li >
< / ul >
< / article >
< article class = "ltr" >
< span class = "mark" > Req< br > 03< / span >
< h3 > Implement< / h3 >
< code > /plan2code-3-implement< / code >
< p > Build to the drawing, one phase per conversation. Planning context bleeding into implementation is where most agent drift starts.< / p >
< p class = "pen" > reply “approved” — nothing advances on a guess< / p >
< ul >
< li > Fresh conversation for every phase< / li >
< li > Specs followed exactly as documented< / li >
< li > Self-review against the spec before close< / li >
< li > [/] claims prevent parallel-agent collisions< / li >
< / ul >
< / article >
< article class = "ltr" >
< span class = "mark" > Opt< br > ✳< / span >
< h3 > Review< span class = "flag -r" > Second opinion< / span > < / h3 >
< code > /plan2code-review< / code >
< p > An independent senior engineer with fresh eyes and no attachment to the code that just shipped. It reads every changed file completely and reports only what it can prove — file, line, and a concrete fix.< / p >
< ul >
< li > Scope adapts: files, branch diff, or subsystem< / li >
< li > All 11 dimensions reported, clean ones justified< / li >
< li > Ranked Critical / Warning / Suggestion< / li >
< li > Read-only until you reply H, A, or S 1,3,5< / li >
< / ul >
< / article >
< article class = "ltr" >
< span class = "mark" > Req< br > 04< / span >
< h3 > Finalize< / h3 >
< code > /plan2code-4-finalize< / code >
< p > Close it out. Every task audited against the spec it came from, a summary of what was built, docs checked for drift, and the folder filed away.< / p >
< ul >
< li > Audit for tasks quietly left open< / li >
< li > Summary of what was built and changed< / li >
< li > README and other docs reconciled< / li >
< li > Specs archived to specs--completed/< / li >
< / ul >
< / article >
< / div >
< / section >
< section class = "routes" >
< div class = "wrap" >
< div class = "sect" > < h2 > Two routes< / h2 > < span > Same destination< / span > < / div >
< div class = "rc" >
< div class = "-a" >
< h4 > Sent without an address< / h4 >
< ul >
< li > Coding starts, requirements arrive later< / li >
< li > Design problems surface mid-build< / li >
< li > Constant backtracking and rework< / li >
< li > Context bloated with abandoned attempts< / li >
< li > No way to prove requirements were met< / li >
< li > Tokens burned on trial and error< / li >
< / ul >
< / div >
< div class = "-b" >
< h4 > Sent with a plan attached< / h4 >
< ul >
< li > The plan is approved before any code< / li >
< li > Problems caught while they are still cheap< / li >
< li > Implementation follows the drawing< / li >
< li > Clean context, one phase at a time< / li >
< li > Checkboxes prove what is done< / li >
< li > Tokens spent building the agreed thing< / li >
< / ul >
< / div >
< / div >
< / div >
< / section >
< section class = "regs wrap" >
< div class = "sect" > < h2 > Postal regulations< / h2 > < span > Four · non-negotiable< / span > < / div >
< div class = "rg" >
< div > < b > Reg 01< / b > < p > A < strong > fresh conversation< / strong > for each step, and each implementation phase.< / p > < / div >
< div > < b > Reg 02< / b > < p > No code until the plan hits < strong > 90% confidence< / strong > . The gate does not negotiate.< / p > < / div >
< div > < b > Reg 03< / b > < p > < strong > Checkboxes are the state< / strong > , not the chat. Any session resumes cold.< / p > < / div >
< div > < b > Reg 04< / b > < p > Reply < strong > approved< / strong > to close a phase. Nothing advances on a guess.< / p > < / div >
< / div >
< / section >
< section class = "install wrap" >
2026-08-20 13:42:43 -07:00
< div class = "sect" > < h2 > Installation< / h2 > < span > Node 18+ · network required · re-run to update< / span > < / div >
2026-08-08 12:32:17 -07:00
< pre class = "term" > < span class = "p" > $< / span > npx < span class = "k" > --allow-git=all< / span > git+https://github.com/jparkerweb/plan2code.git< / pre >
< / section >
< section class = "close" >
< div class = "wrap" >
< h2 > Post it once.< br > < em > Then go outside.< / em > < / h2 >
< span class = "hand" > free, MIT, twenty seconds to install< / span >
< br > < a class = "btn" href = "https://github.com/jparkerweb/plan2code" > Get Plan2Code< / a >
< / div >
< / section >
< footer > < div class = "wrap" > < span > Plan2Code v2.0.0< / span > < span > MIT< / span > < span > plan2code.jparkerweb.com< / span > < / div > < / footer >
2026-05-23 06:58:20 -07:00
< / body >
< / html >