diff --git a/lmc_portfolio/analysis.html b/lmc_portfolio/analysis.html new file mode 100644 index 00000000..86546a14 --- /dev/null +++ b/lmc_portfolio/analysis.html @@ -0,0 +1,143 @@ + + + + + + Self-Assessment Analysis | Andrew Boyer + + + + + + + + +
+ Self-Assessment +

Analysis

+

+ Looking back at my Video Pitch goals and how the four learning outcomes (Rhetoric, Process, Modes & Media, and Design) played out + across the semester. +

+ +

Video Pitch

+

+ In my Video Pitch, my goals were to translate technical concepts into clear language, adapt my messaging and emphasis for different + audiences, and create a technical crisis infographic. I met those goals across the three major projects. I also met each of the four + learning outcomes for the course. +

+ +

Rhetoric

+

+ MP1 leaned hardest on considering the language for my audience and adapting my messaging and emphasis for different audience types. I + went through multiple revisions of my cover letter and thought carefully about the language I was using to describe my skills and + experience. +

+

I targeted a Software Engineer I role at Amazon. The cover letter opens by naming the role first, then pivots to my background:

+
+ "This position at Twitch as a Software Engineer I requires someone who will craft immersive experiences and scalable applications for + users. I believe my previous professional, project, and educational experiences make me a viable candidate for this job." +
+

+ I wanted the opening to prove I had read the job description. The body paragraph uses Amazon-specific vocabulary to signal cultural + fit: +

+
+ "This process acquainted me with Amazon's unique ecosystem of internal tools, like Brazil, Pipelines, and Cradle, as well as standard + software libraries like the AWS CDK." +
+

+ Brazil, Pipelines, and Cradle are internal Amazon tools. This would only resonate with someone who has worked at Amazon. I followed + this with a concrete impact metric: + "Adoption of the tool would reduce operational overhead by 99.8%, saving the company hundreds of thousands of dollars per + year." +

+

+ The resume follows this same structure, with an action paired with an actual outcome. + "Tool reduces operational overhead by 99.8%, saving $300,000 annually, built to scale with company-wide adoption." +

+

I've done this professionally as well, from writing documentation at Ashvin AI, to writing a presentation I gave at Amazon.

+ +

Process

+

+ For MP3, my team created training materials. The process involved discussion with teammates, getting everyone on the same page, + because we all had varying amounts of experience with Claude Code. +

+

+ We split the six parts up, drafted in Google Docs, and went through multiple revisions. The feedback that mattered most was + considering audience, because readers would have varying degrees of experience with the tool, as well as general technology concepts. + starting points with the tool. We added notes for readers who had never used an LLM, like the question that opens the memory section + of Part 1: +

+
+ "Have you ever tried asking Claude too many questions, and suddenly it forgets about the first question you asked? This has to do with + a concept called context." +
+

We also carried this through the remaining parts.

+

+ I've also had to go through iterations of feedback, implementation, and improvement during my internships. Code review at Amazon and + Ashvin AI followed a similar process. +

+ +

Modes and Media

+

MP2 combined a report and a graphic. Both sources had to reinforce the same argument without repeating each other.

+

+ The report is aimed at specialists, talking about company leadership, engineers, and regulators. It draws on Winsor's analysis of the + Challenger disaster and Grabill and Simmons' work on technocratic communication. It uses quotes straight from pilots. One captain + called the 737 Max manual "inadequate and almost criminally insufficient" and asked, + "I am left to wonder: what else don't I know?" Those quotes back up a specialist-facing argument: that excluding pilots from + MCAS documentation was a "technocratic" communication failure, where as Grabill and Simmons put it, + "risk communicators strive to educate/influence the public to think about risk the way experts do." +

+

+ The infographic packages the same research for a public reader. It opens with the death toll and uses a timeline, breaking the + failures into three causes. We added the pilot quotes too, packaged with colors so the casual reader gets them before any of the + statistics. Our + "Suppressed Internal Communication" label says: + "Communication requires shared interpretation, not just data," summarizing what we are trying to communicate. +

+

I've used different media in my internships, from documentation to presentations with graphics.

+ +

Design

+

+ For MP3, we went with a website design style appealing to the eye. This is so it's easy to follow along and read technical commands, + while also quickly understanding if something is part of the core guide or a tip. +

+

+ Code samples sit inside a card that gives a visual distinction to commands. The body font is Inter, while code is JetBrains Mono. + While this is subtle, it shows that font selection can be key to making an easy to follow technical guide. +

+

+ In the infographic from MP2, we had to fit a whole crisis onto one page adding too much clutter. We added a timeline at the top, + setting up how the crisis progressed before getting into any text. The "Lessons" section at the bottom uses four colored circles + around a central question, "How Future Disasters Can Be Prevented," to leave the reader with something actionable. +

+ +

Closing

+

+ The Video Pitch goals I set in January (clear translation, audience adaptation, a public infographic) all show up across MP1, MP2, and + MP3. I learned a lot throughout the revision processes and getting feedback from classmates. My content would change after a review + would flag something and my final submissions improved because of this. +

+
+ + + + diff --git a/lmc_portfolio/assets/img/at_desk.png b/lmc_portfolio/assets/img/at_desk.png new file mode 100644 index 00000000..a4836bc3 Binary files /dev/null and b/lmc_portfolio/assets/img/at_desk.png differ diff --git a/lmc_portfolio/assets/img/headshot.jpeg b/lmc_portfolio/assets/img/headshot.jpeg new file mode 100644 index 00000000..79ef2ca8 Binary files /dev/null and b/lmc_portfolio/assets/img/headshot.jpeg differ diff --git a/lmc_portfolio/assets/img/mp3-screenshot.png b/lmc_portfolio/assets/img/mp3-screenshot.png new file mode 100644 index 00000000..87eef2bf Binary files /dev/null and b/lmc_portfolio/assets/img/mp3-screenshot.png differ diff --git a/lmc_portfolio/assets/img/nba.png b/lmc_portfolio/assets/img/nba.png new file mode 100644 index 00000000..643dde21 Binary files /dev/null and b/lmc_portfolio/assets/img/nba.png differ diff --git a/lmc_portfolio/assets/img/spotify.png b/lmc_portfolio/assets/img/spotify.png new file mode 100644 index 00000000..4779b989 Binary files /dev/null and b/lmc_portfolio/assets/img/spotify.png differ diff --git a/lmc_portfolio/assets/pdf/mp1.pdf b/lmc_portfolio/assets/pdf/mp1.pdf new file mode 100644 index 00000000..bc722814 Binary files /dev/null and b/lmc_portfolio/assets/pdf/mp1.pdf differ diff --git a/lmc_portfolio/assets/pdf/mp2-infographic.pdf b/lmc_portfolio/assets/pdf/mp2-infographic.pdf new file mode 100644 index 00000000..793820aa Binary files /dev/null and b/lmc_portfolio/assets/pdf/mp2-infographic.pdf differ diff --git a/lmc_portfolio/assets/pdf/mp2-report.pdf b/lmc_portfolio/assets/pdf/mp2-report.pdf new file mode 100644 index 00000000..38bf4bef Binary files /dev/null and b/lmc_portfolio/assets/pdf/mp2-report.pdf differ diff --git a/lmc_portfolio/assets/pdf/mp2-rough-draft.pdf b/lmc_portfolio/assets/pdf/mp2-rough-draft.pdf new file mode 100644 index 00000000..eb27b519 Binary files /dev/null and b/lmc_portfolio/assets/pdf/mp2-rough-draft.pdf differ diff --git a/lmc_portfolio/assets/styles.css b/lmc_portfolio/assets/styles.css new file mode 100644 index 00000000..852913f1 --- /dev/null +++ b/lmc_portfolio/assets/styles.css @@ -0,0 +1,380 @@ +:root { + --bg: #fafafa; + --bg-elevated: #ffffff; + --bg-soft: #f4f4f5; + --bg-code: #f6f6f7; + --text: #18181b; + --text-muted: #52525b; + --text-faint: #a1a1aa; + --border: #e4e4e7; + --accent: #b3a369; + --accent-deep: #8a7a3a; + --gt-navy: #003057; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.04); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.06); + --radius: 8px; + --radius-lg: 12px; + --max-width: 820px; + --nav-height: 64px; +} + +* { box-sizing: border-box; margin: 0; padding: 0; } + +html { scroll-behavior: smooth; } + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + font-size: 16px; + line-height: 1.65; + color: var(--text); + background: var(--bg); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* nav */ +.nav { + position: sticky; + top: 0; + z-index: 100; + height: var(--nav-height); + background: rgba(255, 255, 255, 0.85); + backdrop-filter: saturate(180%) blur(10px); + -webkit-backdrop-filter: saturate(180%) blur(10px); + border-bottom: 1px solid var(--border); +} +.nav-inner { + max-width: 1100px; + margin: 0 auto; + padding: 0 24px; + height: var(--nav-height); + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; +} +.nav-brand { + font-weight: 700; + letter-spacing: -0.01em; + color: var(--text); + text-decoration: none; + font-size: 0.95rem; +} +.nav-brand .accent { color: var(--accent-deep); } +.nav-links { + display: flex; + align-items: center; + gap: 2px; + list-style: none; + overflow-x: auto; + scrollbar-width: none; +} +.nav-links::-webkit-scrollbar { display: none; } +.nav-links li { display: flex; align-items: center; } +.nav-links a { + display: inline-flex; + align-items: center; + height: 32px; + padding: 0 12px; + font-size: 0.875rem; + font-weight: 500; + color: var(--text-muted); + text-decoration: none; + border-radius: 6px; + white-space: nowrap; + transition: color 0.15s ease, background-color 0.15s ease; +} +.nav-links a:hover { color: var(--text); background: var(--bg-soft); } +.nav-links a.active { color: var(--accent-deep); background: var(--bg-soft); } + +/* layout */ +main { + max-width: var(--max-width); + margin: 0 auto; + padding: 56px 24px 120px; +} +main.wide { max-width: 1080px; } + +.part-label, .eyebrow { + display: inline-block; + font-size: 0.78rem; + font-weight: 600; + color: var(--accent-deep); + text-transform: uppercase; + letter-spacing: 0.1em; + margin-bottom: 14px; +} + +h1, h2, h3, h4 { + line-height: 1.2; + letter-spacing: -0.02em; + font-weight: 700; + color: var(--text); +} +h1 { font-size: 2.4rem; margin-bottom: 18px; letter-spacing: -0.03em; } +h2 { font-size: 1.55rem; margin-top: 56px; margin-bottom: 14px; } +h3 { font-size: 1.2rem; margin-top: 32px; margin-bottom: 10px; } + +.lead { + font-size: 1.125rem; + color: var(--text-muted); + margin-bottom: 28px; + line-height: 1.6; +} + +p { margin-bottom: 16px; color: var(--text); } + +a { color: var(--accent-deep); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color 0.15s ease; } +a:hover { border-bottom-color: var(--accent-deep); } + +strong { font-weight: 600; } +em { font-style: italic; } + +ul, ol { margin: 0 0 18px 22px; } +li { margin-bottom: 6px; } + +hr { border: none; border-top: 1px solid var(--border); margin: 56px 0; } + +/* landing hero */ +.hero { + display: grid; + grid-template-columns: 1.4fr 1fr; + gap: 48px; + align-items: center; + margin-top: 24px; + margin-bottom: 56px; +} +.hero-text h1 { font-size: 2.8rem; margin-bottom: 12px; } +.hero-text .subtitle { + font-size: 1.05rem; + color: var(--text-muted); + margin-bottom: 20px; +} +.hero-img { + width: 100%; + aspect-ratio: 1 / 1; + object-fit: cover; + border-radius: var(--radius-lg); + box-shadow: var(--shadow-md); + border: 1px solid var(--border); +} +@media (max-width: 720px) { + .hero { grid-template-columns: 1fr; gap: 28px; } + .hero-text h1 { font-size: 2.1rem; } +} + +/* card grid */ +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + gap: 18px; + margin-top: 8px; +} +.card { + display: block; + background: var(--bg-elevated); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 20px 22px; + text-decoration: none; + color: var(--text); + transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease; +} +.card:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-md); + border-color: var(--accent); + border-bottom: 1px solid var(--accent); +} +.card .tag { + display: inline-block; + font-size: 0.7rem; + font-weight: 600; + color: var(--accent-deep); + text-transform: uppercase; + letter-spacing: 0.08em; + margin-bottom: 8px; +} +.card h3 { margin: 0 0 6px; font-size: 1.1rem; } +.card p { margin: 0; font-size: 0.92rem; color: var(--text-muted); } + +/* project meta */ +.meta-row { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 18px 0 8px; +} +.chip { + display: inline-flex; + align-items: center; + height: 26px; + padding: 0 10px; + background: var(--bg-soft); + border: 1px solid var(--border); + border-radius: 999px; + font-size: 0.78rem; + color: var(--text-muted); + font-weight: 500; +} + +.intro-block { + background: var(--bg-elevated); + border: 1px solid var(--border); + border-left: 3px solid var(--accent); + border-radius: var(--radius); + padding: 18px 22px; + margin: 18px 0 28px; +} +.intro-block .label { + display: block; + font-size: 0.75rem; + font-weight: 700; + color: var(--accent-deep); + text-transform: uppercase; + letter-spacing: 0.1em; + margin-bottom: 6px; +} +.intro-block p:last-child { margin-bottom: 0; } + +/* PDF embed */ +.pdf-embed { + width: 100%; + height: 720px; + border: 1px solid var(--border); + border-radius: var(--radius-lg); + background: var(--bg-soft); + margin: 16px 0; + box-shadow: var(--shadow); +} +.pdf-embed.tall { height: 980px; } + +.iframe-embed { + width: 100%; + height: 720px; + border: 1px solid var(--border); + border-radius: var(--radius-lg); + background: var(--bg-soft); + margin: 16px 0; + box-shadow: var(--shadow); +} + +.btn-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0 12px; } +.btn { + display: inline-flex; + align-items: center; + gap: 6px; + height: 36px; + padding: 0 16px; + background: var(--text); + color: #fff; + border-radius: 6px; + font-size: 0.875rem; + font-weight: 500; + text-decoration: none; + border: 1px solid var(--text); + transition: opacity 0.15s ease; +} +.btn:hover { opacity: 0.85; border-bottom: 1px solid var(--text); } +.btn.outline { background: transparent; color: var(--text); } +.btn.outline:hover { background: var(--bg-soft); } + +figure { margin: 28px 0; } +figure img { + display: block; + width: 100%; + height: auto; + border-radius: var(--radius-lg); + border: 1px solid var(--border); + box-shadow: var(--shadow); +} +figure figcaption { + margin-top: 10px; + font-size: 0.875rem; + color: var(--text-muted); + text-align: center; + line-height: 1.5; +} + +blockquote { + border-left: 3px solid var(--accent); + padding: 6px 0 6px 18px; + margin: 24px 0; + color: var(--text-muted); + font-style: italic; +} + +.callout { + padding: 16px 20px; + margin: 22px 0; + background: var(--bg-elevated); + border: 1px solid var(--border); + border-left: 3px solid var(--accent); + border-radius: var(--radius); + color: var(--text-muted); + font-size: 0.96rem; +} + +.footer { + border-top: 1px solid var(--border); + padding: 36px 24px 60px; + margin-top: 48px; + text-align: center; + color: var(--text-faint); + font-size: 0.85rem; +} +.footer a { color: var(--text-muted); } + +.two-col { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 28px; +} +@media (max-width: 720px) { .two-col { grid-template-columns: 1fr; } } + +.before-after { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0; + border: 1px solid var(--border); + border-radius: var(--radius-lg); + overflow: hidden; + margin: 18px 0; +} +.before-after > div { padding: 18px 20px; } +.before-after .before { background: #fff7f1; border-right: 1px solid var(--border); } +.before-after .after { background: #f1fbf3; } +.before-after h4 { + font-size: 0.78rem; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--text-muted); + margin-bottom: 8px; +} +@media (max-width: 720px) { + .before-after { grid-template-columns: 1fr; } + .before-after .before { border-right: none; border-bottom: 1px solid var(--border); } +} + +.outcomes-list { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 14px; + margin: 14px 0 28px; +} +@media (max-width: 720px) { .outcomes-list { grid-template-columns: 1fr; } } +.outcomes-list .item { + background: var(--bg-elevated); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 14px 18px; +} +.outcomes-list .item strong { color: var(--accent-deep); } + +@media (max-width: 640px) { + h1 { font-size: 1.85rem; } + h2 { font-size: 1.25rem; } + main { padding: 36px 20px 80px; } + .nav-inner { padding: 0 16px; } + .pdf-embed { height: 540px; } +} diff --git a/lmc_portfolio/goatgrade.html b/lmc_portfolio/goatgrade.html new file mode 100644 index 00000000..fabb65d5 --- /dev/null +++ b/lmc_portfolio/goatgrade.html @@ -0,0 +1,73 @@ + + + + + + Goat Grade | Andrew Boyer + + + + + + + + +
+ Project outside of LMC 3403 +

Goat Grade

+

+ An NBA analytics web app that scrapes 70 years of statistics and ranks every player and team. Rankings are exposed via a custom API. +

+ +
+ Python + Flask + React + BeautifulSoup +
+ +
+ Goat Grade NBA rankings interface +
Uses official NBA data.
+
+ +
+ Project Introduction +

+ Goat Grade is a project I started in 2021 and have kept running since. It scrapes NBA statistics with Python and BeautifulSoup, + computes a custom ranking for every player and team going back to the 1956 season, and serves the data through a Flask backend. + The site has correctly identified the season MVP at an 80% rate, and predicted the 2024 NBA champion. The communication side of + the project came from explaining the ranking system, which I did in a + blog post. This is important because as users view the rankings and use + them to think about the NBA, its to be transparent how we use data to make these rankings. I am still adding to and improving the + site, and am planning on releasing more blog posts explaining new additions and features. A key part of this project is the users + viewing the rankings. +

+
+ +
+ Visit goatgrade.com + GitHub +
+ + +
+ + + + diff --git a/lmc_portfolio/index.html b/lmc_portfolio/index.html new file mode 100644 index 00000000..0c3cd7a4 --- /dev/null +++ b/lmc_portfolio/index.html @@ -0,0 +1,105 @@ + + + + + + Andrew Boyer | LMC 3403 Portfolio + + + + + + + + + +
+ Final Portfolio · Spring 2026 + +
+
+

Andrew Boyer

+

Hello world!

+ +
+ Headshot of Andrew Boyer +
+ +
+

About me

+

+ Hello world! I'm Andrew Boyer, a computer science student at Georgia Tech. My programming journey began sophomore year of high + school, where I had the "a-ha" moment of realizing computers do exactly what we tell them (and I mean exactly). This realization + led me to self-teach the basics of computer programming and computer building. I spent the remainder of high school teaching + others how to code and demystifying the field of computer science for younger students, through leading my school's computer + science club and teaching elementary age students at theCoderSchool. In parallel, I worked on side projects to further express my + creativity by using computer science to explore my other interests like basketball. This desire led me to Georgia Tech, where I + chose to specialize in Info-networks and Cybersecurity. I've also been fortunate to work with great companies and teams + professionally, from startup to enterprise level. These experiences furthered my interest in computing, leading me back to what + drew me to the field in the first place. I believe there is an unlimited room for creative solutions from developers who are + willing to learn, work hard, and think outside of the box, all for the love of the craft. These are values that I strive to embody + in not just my career, but beyond as well. This portfolio collects my work from LMC 3403 this semester, alongside a couple of + projects from outside this class. +

+
+ +
+

What's inside

+ +
+
+ + + + diff --git a/lmc_portfolio/mp1.html b/lmc_portfolio/mp1.html new file mode 100644 index 00000000..7afc8ec0 --- /dev/null +++ b/lmc_portfolio/mp1.html @@ -0,0 +1,66 @@ + + + + + + MP1: Career Materials | Andrew Boyer + + + + + + + + +
+ Major Project 1 +

Career Materials

+

Resume and cover letter.

+ +
+ Resumes + Cover Letters + Hiring / Job Application +
+ +
+ Project Introduction +

+ Major Project 1 was job application materials for an actual role we found online. I submitted a one-page resume and a tailored + cover letter. I picked a Software Engineer I role at Amazon, within the Twitch division. I had just finished a Software + Development internship at Amazon and could write about it specifically. My resume highlights my professional and project + experience using concrete numbers, like the 99.8% reduction in operational overhead from internal tool I built. My cover letter + names the role and identifies how I fit well. I did this by using Amazon vocabulary like Brazil, Pipelines, Cradle, AWS CDK. I + went through a couple revisions of the cover letter, focusing on the language I was using to describe my experience and how the + hiring team would actually read it. +

+
+ +
+ Open PDF + Download +
+ + + + +
+ + + + diff --git a/lmc_portfolio/mp2.html b/lmc_portfolio/mp2.html new file mode 100644 index 00000000..cbc7ac03 --- /dev/null +++ b/lmc_portfolio/mp2.html @@ -0,0 +1,84 @@ + + + + + + MP2: Crisis Report and Infographic | Andrew Boyer + + + + + + + + +
+ Major Project 2 +

Boeing 737 Max Crisis Report and Infographic

+

A report on the 737 Max crisis, paired with an infographic.

+ +
+ Technical Report + Infographic & Design + Presentation / Public speaking + Working with a partner +
+ +
+ Project Introduction +

+ In Major Project 2 we explored a technical communication crisis. The focus wasn't on actual technical failures or ethical issues, + but more on how the people involved communicated and how they failed. We investigated the Boeing 737 Max crashes, which killed 346 + people across two flights in 2018 and 2019. We focused on three particular failures failures: MCAS was left out of pilot training + and documentation, internal safety warnings from engineers were suppressed, and Boeing limited disclosure to FAA regulators. We + submitted incident report that went into depth of the failures and related them to academic papers. We also made an infographic + and presented this to the class. +

+
+ +

Final report

+
+ Open report PDF + Download +
+ + +

Public infographic

+

+ The infographic aims to present our research wider audience, in a more digestible way. We utilized graphics and colors to communicate + the information in an engaging way that is easy to follow. +

+
+ Open infographic PDF + Download +
+ + +

Revision process

+

+ Between our final and rough drafts, we made a lot of revisions. This included improving citations, connections we made between + findings and the Winsor and Grabill & Simmons frameworks. We also reworked our final recommendations so they read as advice to + other technical communicators rather than just a plain and simple recap of what went wrong. +

+ + +
+ + + + diff --git a/lmc_portfolio/mp3-site/.gitattributes b/lmc_portfolio/mp3-site/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/lmc_portfolio/mp3-site/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/lmc_portfolio/mp3-site/assets/ai-agent-diagram.png b/lmc_portfolio/mp3-site/assets/ai-agent-diagram.png new file mode 100644 index 00000000..3f496f38 Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/ai-agent-diagram.png differ diff --git a/lmc_portfolio/mp3-site/assets/drive-mcp-visal.png b/lmc_portfolio/mp3-site/assets/drive-mcp-visal.png new file mode 100644 index 00000000..40c9162a Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/drive-mcp-visal.png differ diff --git a/lmc_portfolio/mp3-site/assets/google-login.png b/lmc_portfolio/mp3-site/assets/google-login.png new file mode 100644 index 00000000..d5f933da Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/google-login.png differ diff --git a/lmc_portfolio/mp3-site/assets/img/homepage.png b/lmc_portfolio/mp3-site/assets/img/homepage.png new file mode 100644 index 00000000..a4a058e8 Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/img/homepage.png differ diff --git a/lmc_portfolio/mp3-site/assets/img/plan-options.png b/lmc_portfolio/mp3-site/assets/img/plan-options.png new file mode 100644 index 00000000..3b6181db Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/img/plan-options.png differ diff --git a/lmc_portfolio/mp3-site/assets/img/projectspagefinal.png b/lmc_portfolio/mp3-site/assets/img/projectspagefinal.png new file mode 100644 index 00000000..286988a4 Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/img/projectspagefinal.png differ diff --git a/lmc_portfolio/mp3-site/assets/img/s-sesh.png b/lmc_portfolio/mp3-site/assets/img/s-sesh.png new file mode 100644 index 00000000..15025e0e Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/img/s-sesh.png differ diff --git a/lmc_portfolio/mp3-site/assets/img/subagentfinalscreen.png b/lmc_portfolio/mp3-site/assets/img/subagentfinalscreen.png new file mode 100644 index 00000000..1f5ea39c Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/img/subagentfinalscreen.png differ diff --git a/lmc_portfolio/mp3-site/assets/img/website.png b/lmc_portfolio/mp3-site/assets/img/website.png new file mode 100644 index 00000000..1b121586 Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/img/website.png differ diff --git a/lmc_portfolio/mp3-site/assets/mcp-reconnect.png b/lmc_portfolio/mp3-site/assets/mcp-reconnect.png new file mode 100644 index 00000000..b4bcdb36 Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/mcp-reconnect.png differ diff --git a/lmc_portfolio/mp3-site/assets/running-mcp-command.png b/lmc_portfolio/mp3-site/assets/running-mcp-command.png new file mode 100644 index 00000000..4aec1c18 Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/running-mcp-command.png differ diff --git a/lmc_portfolio/mp3-site/assets/sample.svg b/lmc_portfolio/mp3-site/assets/sample.svg new file mode 100644 index 00000000..f8d06753 --- /dev/null +++ b/lmc_portfolio/mp3-site/assets/sample.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + Sample Image + Replace with your own + + diff --git a/lmc_portfolio/mp3-site/assets/styles.css b/lmc_portfolio/mp3-site/assets/styles.css new file mode 100644 index 00000000..a9ff5ba3 --- /dev/null +++ b/lmc_portfolio/mp3-site/assets/styles.css @@ -0,0 +1,341 @@ +:root { + --bg: #fafafa; + --bg-elevated: #ffffff; + --bg-code: #f6f6f7; + --bg-code-header: #efeff1; + --text: #18181b; + --text-muted: #71717a; + --text-faint: #a1a1aa; + --border: #e4e4e7; + --accent: #2563eb; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.03); + --radius: 8px; + --radius-lg: 12px; + --max-width: 780px; + --nav-height: 60px; + + --code-keyword: #9333ea; + --code-string: #059669; + --code-comment: #94a3b8; + --code-number: #d97706; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + font-size: 16px; + line-height: 1.65; + color: var(--text); + background: var(--bg); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.nav { + position: sticky; + top: 0; + z-index: 100; + height: var(--nav-height); + background: var(--bg-elevated); + border-bottom: 1px solid var(--border); + transition: background-color 0.2s ease, border-color 0.2s ease; +} + +.nav-inner { + max-width: 1100px; + margin: 0 auto; + padding: 0 24px; + height: var(--nav-height); + display: flex; + align-items: center; + justify-content: center; + gap: 16px; +} + +.nav-links { + display: flex; + align-items: center; + gap: 2px; + list-style: none; + overflow-x: auto; + scrollbar-width: none; +} + +.nav-links::-webkit-scrollbar { + display: none; +} + +.nav-links li { + display: flex; + align-items: center; + margin: 0; +} + +.nav-links a { + display: inline-flex; + align-items: center; + height: 32px; + padding: 0 12px; + font-size: 0.875rem; + font-weight: 500; + color: var(--text-muted); + text-decoration: none; + border: none; + border-radius: 6px; + white-space: nowrap; + line-height: 1; + transition: color 0.15s ease, background-color 0.15s ease; +} + +.nav-links a:hover { + color: var(--text); + background: var(--bg-code); + border-bottom: none; +} + +.nav-links a.active { + color: var(--accent); + background: var(--bg-code); +} + +main { + max-width: var(--max-width); + margin: 0 auto; + padding: 64px 24px 120px; +} + +.part-label { + display: inline-block; + font-size: 0.8rem; + font-weight: 500; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.08em; + margin-bottom: 12px; +} + +h1, h2, h3, h4 { + line-height: 1.25; + letter-spacing: -0.02em; + font-weight: 600; + color: var(--text); +} + +h1 { + font-size: 2.25rem; + margin-bottom: 20px; + letter-spacing: -0.03em; +} + +.lead { + font-size: 1.1rem; + color: var(--text-muted); + margin-bottom: 32px; + line-height: 1.6; +} + +h2 { + font-size: 1.5rem; + margin-top: 48px; + margin-bottom: 16px; +} + +h3 { + font-size: 1.2rem; + margin-top: 32px; + margin-bottom: 12px; +} + +p { + margin-bottom: 16px; + color: var(--text); +} + +a { + color: var(--accent); + text-decoration: none; + border-bottom: 1px solid transparent; + transition: border-color 0.15s ease; +} + +a:hover { + border-bottom-color: var(--accent); +} + +strong { + font-weight: 600; +} + +ul, ol { + margin: 0 0 16px 24px; +} + +li { + margin-bottom: 6px; +} + +hr { + border: none; + border-top: 1px solid var(--border); + margin: 48px 0; +} + +:not(pre) > code { + font-family: 'JetBrains Mono', 'Fira Code', Menlo, Monaco, Consolas, monospace; + font-size: 0.875em; + background: var(--bg-code); + color: var(--text); + padding: 2px 6px; + border-radius: 4px; + border: 1px solid var(--border); +} + +.code-block { + margin: 24px 0; + background: var(--bg-code); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + overflow: hidden; + box-shadow: var(--shadow); +} + +.code-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 14px; + background: var(--bg-code-header); + border-bottom: 1px solid var(--border); + font-family: 'JetBrains Mono', monospace; + font-size: 0.72rem; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.06em; +} + +.code-dots { + display: inline-flex; + gap: 6px; +} + +.code-dots span { + width: 10px; + height: 10px; + border-radius: 50%; + background: var(--text-faint); + opacity: 0.55; +} + +.code-block pre { + margin: 0; + padding: 16px 18px; + overflow-x: auto; + background: transparent; +} + +.code-block pre code { + font-family: 'JetBrains Mono', 'Fira Code', Menlo, Monaco, Consolas, monospace; + font-size: 0.875rem; + line-height: 1.65; + color: var(--text); + background: transparent; + padding: 0; + border: none; + display: block; +} + +.tok-k { color: var(--code-keyword); } +.tok-s { color: var(--code-string); } +.tok-c { color: var(--code-comment); font-style: italic; } +.tok-n { color: var(--code-number); } +.tok-f { color: var(--accent); } + +figure { + margin: 32px 0; +} + +figure img { + display: block; + width: 100%; + height: auto; + border-radius: var(--radius-lg); + border: 1px solid var(--border); +} + +figure figcaption { + margin-top: 10px; + font-size: 0.875rem; + color: var(--text-muted); + text-align: center; + line-height: 1.5; +} + +blockquote { + border-left: 3px solid var(--accent); + padding: 4px 0 4px 16px; + margin: 24px 0; + color: var(--text-muted); + font-style: italic; +} + +.next-link { + color: var(--text-muted); + font-size: 0.9rem; +} + +.placeholder { + padding: 48px 24px; + text-align: center; + color: var(--text-muted); + background: var(--bg-elevated); + border: 1px dashed var(--border); + border-radius: var(--radius-lg); + margin-top: 32px; +} + +.video-embed { + position: relative; + padding-bottom: 56.25%; + height: 0; + margin: 32px 0; + border-radius: var(--radius-lg); + border: 1px solid var(--border); + overflow: hidden; + background: #000; +} + +.video-embed iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} + +.callout { + padding: 14px 18px; + margin: 20px 0; + background: var(--bg-elevated); + border: 1px solid var(--border); + border-left: 3px solid var(--accent); + border-radius: var(--radius); + color: var(--text-muted); + font-size: 0.95rem; +} + +@media (max-width: 640px) { + h1 { font-size: 1.75rem; } + h2 { font-size: 1.3rem; } + main { padding: 40px 20px 80px; } + .nav-inner { padding: 0 16px; } +} diff --git a/lmc_portfolio/mp3-site/assets/website-with-resume.png b/lmc_portfolio/mp3-site/assets/website-with-resume.png new file mode 100644 index 00000000..87eef2bf Binary files /dev/null and b/lmc_portfolio/mp3-site/assets/website-with-resume.png differ diff --git a/lmc_portfolio/mp3-site/index.html b/lmc_portfolio/mp3-site/index.html new file mode 100644 index 00000000..aeefda04 --- /dev/null +++ b/lmc_portfolio/mp3-site/index.html @@ -0,0 +1,106 @@ + + + + + + Part 1 — Introduction + + + + + + + + + +
+ Part 1 +

Welcome to our Training Materials!

+

This tutorial will go over all the essentials you'll need to get started with Claude Code. + Specifically, we'll be working on building your own portfolio website. + You should start here for a conceptual overview on AI Agents & Claude Code, then proceed to part 2. +

+ +

What is an AI Agent?

+

By now, nearly all Computer Science students (including freshmen) are familiar with LLMs, or Large Language Models. As of recording writing this tutorial, there are 3 popular LLMs: ChatGPT by OpenAI, Claude by Anthropic, and Gemini by Google. These are effectively just gigantic machine learning models that can accept some natural language input, such as text, and generate a natural language output.

+ +

When these LLMs were first announced, all you could really do with them was have a conversation by typing into your keyboard and reading the output on your screen. However, if you've used any modern LLM recently, you might have noticed a few upgrades over the past couple of years:

+ + +

Let's call the new capability of these LLMs tools. Now, we can split up the functionality of services like Claude into 2 parts:

+ + +

An AI Agent is a specific combination of LLM, tools, and memory.

+ +

What do we mean by memory?

+

Have you ever tried asking Claude too many questions, and suddenly it forgets about the first question you asked? This has to do with a concept called context. Think of context like the specific set of information the agent can reference at any given point you try to use it.

+ +

For agents, we typically break up context into the following:

+ + +

Memory is effectively a storage unit that provides your agent with relevant context as it's performing a task. We break memory down into 2 types:

+ + +

Taking this information together, you can see that AI Agents can be super customizable:

+ + + We can see this visually: + +
+ Diagram showing the flow of an AI agent: memory and user input feed into the LLM context, which drives tool calls (actions), whose results combine with the prompt to produce a final output. +
+ The general flow of an AI agent. +
+
+ + From the diagram, we see that the memory adds to the information that you provide the LLM (such as a question, a prompt, etc). From there, the LLM uses all of the information in its context to call certain tools, which results in the LLM making "actions", and based on the actions and their results, combined with the user's prompt, the LLM will generate a result.

+ This can all get pretty complicated pretty fast! + +
+ +

Claude Code

+

For this project, we will be using Claude Code. Rather than chatting with an LLM in your browser, you gain the ability to chat with an LLM directly in a coding workspace through your terminal. In our specific case, this gives Claude the ability to read code, refactor files, and run commands to help you code faster. By doing this, we gain an assistant directly embedded into the context of our project that can understand large codebases, generate and edit files directly, debug errors, and run tests for us. This eliminates the need to copy several things to a chat window in your browser and automates several steps of coding with LLMs. Not all steps are the same though; there are several differences between generating code through a chat window and through Claude Code that require specific steps to produce better outputs.

+ +

There are several agentic coding tools—like GitHub Copilot and Cursor, with the closest one being OpenAI's Codex—but we will be using Claude for this tutorial as it has an array of features that can enhance your productivity. While tools like Copilot are designed for inline code generation and assistance, Claude Code is able to handle much larger codebases and tasks. It should be noted however that the landscape of coding agents is changing frequently, and the next best tool could arise at any time.

+ +

You should also have some IDE, like VSCode, set up already in this section (although companies are beginning to make IDE-free coding agents, we will still use an IDE to visualize code changes easier). You should also have Node setup (npm/npx) as we will need it to install some packages. Furthermore, you should have a terminal application to run Claude Code with, as it is a CLI-based application (the default terminal on your machine works fine).

+ +
+ + +
+ + diff --git a/lmc_portfolio/mp3-site/part2.html b/lmc_portfolio/mp3-site/part2.html new file mode 100644 index 00000000..68b012d7 --- /dev/null +++ b/lmc_portfolio/mp3-site/part2.html @@ -0,0 +1,258 @@ + + + + + + Part 2: Setting up the Project + + + + + + + + +
+ Part 2 +

Setting up the Project

+

+ Install Claude Code, build a memory system, and create two + skills that will drive "sessions." +

+ +

Prereqs

+

+ A terminal (and be comfortable with basic terminal commands), an + IDE (VSCode works), and Node so you have + npm / npx. From there you can install + Claude Code: +

+ +
+
+ + terminal +
+
curl -fsSL https://claude.ai/install.sh | bash
+
+ +

+ Docs + here + (stop after step 2). Also install the + GitHub CLI + and log in. Claude uses it later to push branches and open PRs. +

+ +

+ Then cd into your project folder and run + claude. +

+ +

Walkthrough

+

+ In this video we build the memory system from scratch. We + draft the init prompt in regular Claude, paste it into Claude + Code, and end up with a working .memory/ folder. +

+ +
+ +
+ + + +
+ The memory system we're setting up has one job. It makes sure + every new session knows (1) what we're building, (2) the + current state of the build, and (3) decisions we've already + made. Without it, we'd be re-explaining the project every time + the context window resets. +
+ +
+ A note about leading dots (.memory, + .CLAUDE.md): on Mac and Linux, files or folders + starting with . are hidden by default. + ls and Finder skip them unless you ask. That's why + configs live in .memory/, .claude/, + .git/. Run ls -a to see them. +
+ +

The Init Prompt

+

+ Skip writing your own. Paste + INIT.md + into Claude Code and it builds the memory system for you. The + prompt does three things. It creates the .memory/ + folder with a specific set of tracking files, fills + STATUS.md with your stack (HTML/CSS, GitHub Pages, + no build step), and stops there. It's essentially a setup + script written in English. You'll end up with: +

+ + + +

Skip Permission Prompts

+

+ To make the bypass flag from the video (4:27) stick, alias it: +

+ +
+
+ + terminal (zsh) +
+
echo "\nalias claude='claude --allow-dangerously-skip-permissions'" >> ~/.zshrc && source ~/.zshrc
+
+ +
+ The flag is called "dangerously" because Claude can run any + shell command without asking, including deleting files, + installing packages, or pushing to git. It's fine for this + tutorial because you're working inside a fresh project folder + and there's no production system to break. Anything Claude does + locally can be undone with git. Don't alias this flag in a + directory you care about (your home folder, a repo with + uncommitted work, anything touching real credentials). +
+ +

Skills

+

+ Skills are reusable prompts you trigger with a slash command. + Rather than typing out a long prompt, you can alias it to a + skill, so when you run that skill Claude reads that entire + prompt. This is how we can start to build out complex workflows + in Claude Code that we can run quickly. The actual text for + skills live in + .claude/skills/<name>/SKILL.md. Set up two: +

+ + + +

+ s-sesh gets you and Claude on the same page. + c-sesh hands off to the next session. +

+ +

CLAUDE.md

+

+ CLAUDE.md is a meta-prompt appended to + every message in the project, so keep it short. Its job + is to remind Claude of the project, the goal, and the memory + layout. Drop + this one + at the project root. It describes the project, structure, rules + / constraints we have, how we work with Claude, how we manage + memory files, and any conventions we want Claude to abide by. +

+ +
+ + +
+ + diff --git a/lmc_portfolio/mp3-site/part3.html b/lmc_portfolio/mp3-site/part3.html new file mode 100644 index 00000000..081f38e1 --- /dev/null +++ b/lmc_portfolio/mp3-site/part3.html @@ -0,0 +1,342 @@ + + + + + + Part 3: Website Scaffolding + + + + + + + + +
+ Part 3 +

Website Scaffolding

+

+ Run your first real session. Draft a plan, let Claude scaffold + the site, and add two skills that automate the end of every + phase after this one. +

+ +

+ While we hinted at it in the setup, the project for this + tutorial is a personal website with a home page, a resume page, + and a projects page. Plain HTML and CSS, hosted on GitHub Pages, + no JavaScript or frameworks. Phase 0, the one you're doing now, + is the + scaffolding. That means the folder structure, the + shared stylesheet, and the HTML boilerplate that every page will + use. Think of it like pouring the foundation before framing a + house. Get it right now and every later phase is easy, since the + focus is on content instead of underlying architecture. +

+ +

Start the Session

+

From your project folder:

+ +
+
+ + claude code +
+
/new
+/rename init
+/s-sesh phase 0, scaffolding phase
+
+ + + +
+ Terminal output from running /s-sesh phase 0, scaffolding phase. Claude writes a session file, then prints a Session Briefing with the phase goal, parallel sessions, last session, done-when criteria, and scope reminder. +
+ Figure 1. /s-sesh reads your memory files and + prints a briefing so Claude starts the session already + knowing the phase, the goal, and what "done" looks like. +
+
+ +

Plan Mode

+

+ Enter plan mode with /plan. In this mode Claude + writes a plan but won't touch files yet. Describe what you want + the site to look and feel like. The more specific you are, the + less revision you'll do later. Useful things to include: +

+ + + +

For example:

+ +
+
+ + example prompt +
+
lets plan out phase 0. the overall style im going for here is clean
+and minimal. think developer, monospace font, gruvbox theme. we
+should support light mode and dark mode. styling should be clearly
+labeled and reusable. boilerplate should be set up so that phases
+1, 2, 3 can all be worked on in parallel. separate pages for all
+of those. index.html is just scaffolding.
+
+ +

+ Claude writes a plan. + Read the whole thing. Plans get long but this + is the single most important step. If you and Claude don't agree + on what's being built, it builds the wrong thing. You have four + options when it's ready: +

+ +
    +
  1. Approve and bypass permissions
  2. +
  3. Approve with manual review on each edit
  4. +
  5. + Refine with Ultraplan (a bigger planning pass on the web) +
  6. +
  7. Tell Claude what to change
  8. +
+
+ The four approval options Claude shows after writing a plan: 1. Yes, and bypass permissions. 2. Yes, manually approve edits. 3. No, refine with Ultraplan on Claude Code on the web. 4. Tell Claude what to change. A shift+tab hint lets you approve with feedback. +
+ Figure 2. The four options Claude offers once the plan is + ready. +
+
+ +

+ Use option 4 liberally. It's always going to be easier to + iterate on the plan than to undo bad code that is already + written. +

+ +
+ Ironically, this is the step where you do the least typing. Once + the plan is right, Claude writes the scaffold while you watch. + But because you paid close attention to the plan, you know + exactly what it is doing and why. +
+ +
+ Pro tip: use dictation to speak your plan instead of typing it. + Either Claude Code's built-in /voice command or a + tool like + Wispr Flow + works. Getting the vision out of your head is faster out loud, + and revisions feel more like a conversation. +
+ +

Smoke-Test Skill

+

+ A smoke test is a quick sanity check, not a + full test suite. But sanity checks are important, and while AI + is phenomenal at writing code, quality assurance is still best + to be done by humans. You run it after a change to catch obvious + breakage, like checking if a file went missing, is the HTML + valid, did a stylesheet fail to load. The name comes from + hardware engineering. Hardware engineers would plug in the + circuit, see if smoke comes out. +

+ +

+ Before closing the session, build a reusable smoke-test skill + using the built-in skill-creator: +

+ +
+
+ + claude code +
+
/skill-creator:skill-creator create a smoke test skill where i can
+run at the end of every phase where there is significant changes
+and you can give me actionable steps to ensure everything functions
+properly and things run smoothly
+
+ +

+ It writes a checklist skill scoped to your project. The skill + checks that files exist, HTML is valid, CSS tokens are defined, + and no links are broken. Runs as /smoke-test. Flags + potential issues as FAIL, WARN, or PASS. +

+ +

PR Skill

+

+ The logic is the same for committing. One command that stages, + commits, pushes a branch, and opens a PR with a written + description: +

+ +
+
+ + claude code +
+
/skill-creator:skill-creator create a skill called pr that
+conventionally commits all changes from this session in a new
+branch, pushes to that branch, and prs with a detailed description
+of these changes. create a positional argument for auto merge or
+not. normal pr just prs, anything with "merge / auto / auto merge"
+should auto merge and switch to master
+
+ +

+ Have the pr skill run c-sesh before + any git work. That way your session-close edits + (STATUS.md, LAST_SESSION.md, + DECISIONS.md) in the same PR instead of lagging + behind as a second commit. +

+ +
+ This is where things can start to ramp up: skills can call other + skills. A skill that closes the session, runs the smoke test, + commits, pushes, and opens a PR is one command (/pr auto) that replaces ten. +
+ +

Close Out

+

If you built the combined skill above, just run:

+ +
+
+ + claude code +
+
/pr auto
+
+ +

If not, run them by hand:

+ +
+
+ + claude code +
+
/smoke-test
+/c-sesh
+/pr
+
+ +

+ Either way, you end with Phase 0 scaffolded, smoke-tested, + committed, PR'd, and the session logged. Everything Phases 1, 2, + and 3 need is now in place, and they can be built in parallel. +

+ +
+ The scaffolded site at the end of Phase 0. A dark gruvbox theme shows the brand 'george p. burdell' top-left, home/resume/projects nav top-right, a large 'George P. Burdell' hero with the tagline 'student · tinkerer · ramblin' wreck', and an open DevTools inspector confirming no console errors. +
+ Figure 3. Phase 0 output. Scaffold, nav, hero, theming, and + a clean DevTools console. +
+
+ +

You're Writing a Language

+

+ Step back and look at what we've set up. /s-sesh, + /c-sesh, /smoke-test, + /pr, /pr auto, CLAUDE.md, + the .memory/ files. None of that is Claude Code out + of the box; these are all things that we've set up so far. +

+ +

+ That's the point. You're not just telling an AI what to do, + you're building a command set that drives it. + /s-sesh phase 0 is a function call and + /pr auto is a pipeline. CLAUDE.md is a + contract. Skills calling skills is composition. +

+ +

+ From here on out every phase gets easier because the language + you've written automates redundancy. +

+ +
+ + +
+ + diff --git a/lmc_portfolio/mp3-site/part4.html b/lmc_portfolio/mp3-site/part4.html new file mode 100644 index 00000000..e05b863e --- /dev/null +++ b/lmc_portfolio/mp3-site/part4.html @@ -0,0 +1,131 @@ + + + + + + Part 4 — Training + + + + + + + + + +
+ Part 4 +

Building out the Homepage

+

+ Build out the homepage for our website, and learn how to test frontend attributes with the Claude Code Playwright plugin. +

+ +

+ We can now build out the basic homepage using the same structure that we previously utilized: +

+ + + + + +

+ After following the steps in the video above, we should have a homepage that looks something like the below (yours will likely vary as Claude does not generate deterministic outputs). + Feel free to give Claude some specific instructions to change the homepage to your liking with different colors, fonts, etc. + This can be achieved by being specific about how you want the homepage to look and feel, or you could even be broad with your instructions, only specifying overall themes or styles, and let Claude take the reins (but this will have higher variability). + You can also edit the biography section to your liking yourself or via Claude as well. +

+ +
+ Homepage example image from Claude's output of the session +
+ Figure 1. Homepage example image from Claude's output of the session after it implemented the plan we created. +
+
+ +

+ In the video, Claude told us to open index.html in a browser ourselves to confirm that everything works and our contact form works. + To test our form, we could in theory do this manually, but this process can be automated with Claude Code. + This is where plugins come into play. Plugins are similar to VSCode extensions, written by the community that empower Claude to have more abilities. + There are plugins to scan for common vulnerabilities in your codebase, review your code and simplify complex functions, and find relevant and current documentation. + For our purposes, since we just made a “Contact Me” form, we will use Playwright, a software originally created by Microsoft which was turned into a plugin for Claude Code. +

+

+ Note: since we don't have a backend setup, the form will throw a 501 error when we try to press the submit button. + This is normal because we don't have a backend to actually process the data, but in a real application, the frontend data would be sent to the backend and there would be no error. + But here, this error is expected and fully fine. +

+ +

+ Installing the Playwright Plugin +

+

+ To install the Playwright plugin, we need to run these commands: +

+
+
+ + Terminal +
+
npm install -g @playwright/cli
+
npx playwright install chromium
+
playwright-cli install --skills
+
+

+ There are several ways to install plugins; this is just one such way. The third command will install a Claude skill that we talked about previously. +

+

+ Now we can test our form using Playwright: +

+ + + +

+ Congrats! You've created a homepage by following proper practice using Claude Code, and learned about plugins and used one yourself to test your form. + Now that we've tested everything to make sure it works, you can commit and submit a PR! +

+ + +
+ + diff --git a/lmc_portfolio/mp3-site/part5.html b/lmc_portfolio/mp3-site/part5.html new file mode 100644 index 00000000..566b35d8 --- /dev/null +++ b/lmc_portfolio/mp3-site/part5.html @@ -0,0 +1,226 @@ + + + + + + Part 5 — Training + + + + + + + + + +
+ Part 5 +

Adding in a Resume

+

To expand on our portfolio website, we're going to be adding in our resume. However, rather than simply embed a PDF onto the website, we're going to learn how to use Claude Code to extract the contents of our resume and have Claude add in the contents of our resume for us.

+ +

Model Context Protocol (MCP)

+

Instead of copying and pasting a text-based version of our resume, we're going to simply provide Claude with a shareable Google Drive link to our resume. Claude will then do the following:

+
    +
  1. Use the link to access the file in Google Drive.
  2. +
  3. Read the contents of the file by automatically downloading it.
  4. +
  5. Extract the relevant contents from the resume that we specify.
  6. +
  7. Use the contents of the resume to build the resume portion of the website.
  8. +
+ +

At this point, you might be wondering: how can we give Claude access to Google Drive? + And why even bother doing all this work with a resume? The answer lies in understanding the super powerful Model Context Protocol.

+ +

As software continues to expand, we want to give these agents access to this software so that we can perform actions. In other words, we want to give our agent access to many tools.

+ +

However, there's a problem that arises: for each software we wish to integrate into Claude to use as a tool, we need to ensure that Claude communicates with this software correctly. Since every software is different, there might be multiple ways to communicate with other software. Model Context Protocol unifies this communication into a single standard.

+ +

You can think of MCP like giving Claude access to an intercom system. Instead of talking directly to Google Drive, we talked to a specialized worker that exists outside of Claude that can access Google Drive for us. So, to get access to our resume, we have the following flow:

+
    +
  1. You ask Claude to read your resume from Google Drive.
  2. +
  3. Claude cannot directly see into your private Google Drive. So, it uses the language defined in the Model Context Protocol to tell our Google Drive "worker" to find our resume file and provide Claude with the contents.
  4. +
  5. The worker goes into our Drive, finds the file, and provides it to Claude to temporarily download it to allow Claude to grab the contents.
  6. +
+ +

While this may not seem like a big deal at the moment (after all, we could have just downloaded the resume and copy-pasted the contents into Claude), MCP provides agents like Claude Code to access multiple pieces of software, all while only needing to know 1 language: MCP.

+ +
+ AI Agent accessing the tools from the Google Drive MCP server. +
+ AI Agent accessing tools from the Google Drive MCP Server. +
+
+ +
+ Also: for now, think about MCP Servers as giving Claude access to other software through a specialized set of tools. However, instead of needing to know how to build those tools and how the tools interact with something like Google Drive, Claude just needs to know how to correctly call those tools. +
+ +

Setting up a Google Drive MCP Server

+

To actually provide Claude with the tools to search your Google Drive, you need to use an MCP Server. This provides Claude Code with access to the set of tools needed to access your Google Drive.

+ +

You can think of it like a specific program that lives between Claude Code and Google Drive, containing the "worker" that goes into our Google Drive on behalf of Claude Code.

+ +

To set up Claude Code with a Google Drive MCP Server, which contains the tools we need to give Claude Code the ability to search + read files in your Google Drive, we need credentials.

+ +

Specifically, we need to use Google Cloud to provide us with a file that we can download that we then provide to Claude Code to make authenticated requests to our Google Drive.

+ +

To obtain the credentials, the steps are as follows:

+
    +
  1. Go to console.cloud.google.com
  2. +
  3. Click on the projects icon at the top, and then create a new project. +
      +
    • Feel free to call the project whatever you'd like. It does not matter for our purposes.
    • +
    +
  4. +
  5. Once the new project is created, click on the search bar at the top and search for "Google Drive API".
  6. +
  7. Once you find the Google Drive API, click on the option, then click "Enable".
  8. +
  9. Click on the left sidebar to make it appear, then click on the "OAuth consent screen" option under the APIs and Services menu.
  10. +
  11. Once you reach the landing page, click "Get Started", and fill in your information. You can set the name to whatever you'd like, but be sure to use the email associated with your Google Drive account.
  12. +
  13. Once you're done, head over to the left sidebar, and find the option for "Credentials" under the APIs and Services menu. Open the Credentials page.
  14. +
  15. At the top, click "Create Credentials", and select "OAuth Client ID". +
      +
    • Application Type: Desktop App
    • +
    • Name: Whatever you'd like.
    • +
    • At the end: be sure to click download JSON to download the credentials.
    • +
    +
  16. +
  17. Click on the set of credentials you just made, then on the navigation bar on the left, select the "Audience" tab.
  18. +
  19. Under this tab, you will see an area called "Test users". Add your email in to ensure you are added as a test user.
  20. +
+ +

You may also refer to the following video for getting a credentials file from Google Cloud:

+ +
+ +
+ +

Once you have your credentials file downloaded, go ahead and get the file path of the JSON file.

+ + +

Once you have the file path, you need to run 1 command to install the Google Drive MCP server:

+ +
+
+
+ Terminal +
+
claude mcp add gdrive -e GOOGLE_DRIVE_OAUTH_CREDENTIALS="[FILE_PATH]" -- npx -y @piotr-agier/google-drive-mcp
+
+ +
+ Be sure to replace the [FILE_PATH] portion with the file path that you just copied. +
+ +

Here is a video demonstrating this command being run, along with the expected output:

+ +
+ +
+ +

After the MCP Server has been installed, you can type in claude to open up Claude Code. Immediately, you should be prompted to log in with Google, and you should also see a screen like this:

+ +
+ Google OAuth login screen for an unpublished app, showing a warning that the app has not been verified by Google. +
+ +
+ Don't worry, we're not installing a virus or anything. This is simply just an unpublished project. Feel free to hit continue (which is NOT highlighted in blue). +
+ +

After that, with Claude Code open, type in the command /mcp. You should see something similar to this:

+ +
+ Terminal output after running the /mcp command in Claude Code, showing gdrive listed under Local MCPs with a connected status. +
+ +

Notice under the "Local MCPs" option, we see gdrive. This is our Google Drive MCP server. You can also see that it's still "connecting". Let's click enter to see the status:

+ +
+ Claude Code /mcp status screen showing the Reconnect option and 104 available Google Drive tools. +
+ +

Notice here that we have the option to "Reconnect". You should select this, then re-run the /mcp command to see the image above. Notice: we have nearly 104 tools, all for Google Drive related functionality!

+ +

With the Google Drive MCP server setup, we can finally use Claude Code to get the contents of our resume. Here are the general set of steps that we'll take:

+
    +
  1. Start a new session for "phase 2". This is the resume insertion phase, and will provide Claude Code with all the necessary information related to other phases and tasks completed previously.
  2. +
  3. Enter plan mode and have Claude Code create a plan. This includes fetching the contents of your resume.
  4. +
  5. Execute the plan with Claude Code.
  6. +
  7. Preview the website and its changes.
  8. +
  9. Commit the code to GitHub.
  10. +
  11. Close the session, allowing Claude Code to log its progress.
  12. +
+ +
+ Note: after you close the session, you should also commit the files that Claude Code has updated. Or, you can simply close the session before committing to GitHub. +
+ +

Here is a video going over this process (note: there is no audio as we're simply prompting Claude and + confirming it's outputs - feel free to skip ahead throughout the video!):

+ +
+ +
+ +

Here's the final result:

+ +
+ Portfolio website with the resume section added by Claude Code. +
+ + Well done! You've successfully learned all about MCP and have added your resume to your + personal portfolio! + +
+ + +
+ + diff --git a/lmc_portfolio/mp3-site/part6.html b/lmc_portfolio/mp3-site/part6.html new file mode 100644 index 00000000..cb6dd4d9 --- /dev/null +++ b/lmc_portfolio/mp3-site/part6.html @@ -0,0 +1,181 @@ + + + + + + Part 6 — Training + + + + + + + + + +
+ Part 6 +

Adding in Projects

+

+ Now that we have our homepage and resume section, let’s add a projects section. Since we don’t have real projects to display yet, we can delegate a subagent to generate realistic sample projects from scratch. +

+ +

Subagents

+

+ Subagents are specialized workers with their own isolated context window. They do the “messy” work like searching hundreds of files and return only a clean summary to your main chat to prevent context bloat. You can create them via the UI or by manually creating a file. +

+ + +

Creating a Tech Lead Subagent

+

+ Walkthrough Video +

+
+ +
+ + + +

+ To create a Tech Lead Subagent, first open your terminal. +

+ +
+
+ + claude code +
+
/agents
+
+ +

+ Using your arrow keys, switch to the Library tab, select Create new agent, then choose either Project or Personal. Selecting Project will confine the availability of this subagent to the current project and Personal will allow you to use this agent across all of your projects. For this particular tutorial, selecting Project will suffice. +

+ +

+ Afterwards, select Generate with Claude. When prompted, describe the subagent. An example prompt for our tech lead subagent is: +

+ +
+
+ + example prompt +
+
Act as a tech lead. Your task is to design a portfolio of 3 different
+technical engineering projects and then build the UI to display them.
+First, brainstorm 3 advanced projects across different specialties. Write a
+2-sentence technical architecture description, a project name, and a tech
+stack for each. Secondly, act as a frontend developer to implement these
+into projects.html using a responsive CSS grid and clean HTML.
+
+ +

+ Claude will generate the identifier, description, and system prompt for you. +

+ +

+ On the Select tools page, press Continue since the default is “All tools”. This will give the subagent permission to read, edit, and execute your code on your behalf. +

+ +

+ On the Select models page, we suggest selecting Sonnet for the best all around performance, which should suffice for our use case. +

+ +

+ On the Choose background color page, choose whichever color you desire for your agent. +

+ +

+ For Configure agent memory, select Project scope. This will apply to the current project and give the subagent persistent memory across different sessions. +

+ +

+ The final screen should look like this: +

+ +
+ The final configuration screen for the subagent. +
Figure 1. The final configuration screen for the subagent.
+
+ +

+ Remember the name of the subagent. This will be important so that we can reference it later to delegate our task to it. +

+ +

Using the Subagent

+ +

+ Within your project folder, open claude. Then: +

+ +
+
+ + claude code +
+
/new 
+/s-sesh phase 3, projects phase
+
+ +

+ When prompted with Do you want to create blah.md, select Yes, allow all edits during this session. +

+ +
+
+ + claude code +
+
/plan
+
+ +

+ Then run the following prompt: +

+ +
+
+ + example prompt +
+
I want to delegate the tech lead portfolio-builder subagent to create
+and populate sample project cards in the projects section of the website.
+
+ +
+ It’s important to mention the subagent you want to delegate the task to. This can either be done by simply referencing the name or explicitly mentioning it with @agent-name. +
+ +

+ Read the plan and approve as needed. Claude should generate the code and inform you when it is complete. The projects section should look similar to this: +

+ +
+ The finalized projects section with generated sample cards. +
Figure 2. Complete projects page generated by the tech lead subagent.
+
+
+ + diff --git a/lmc_portfolio/mp3.html b/lmc_portfolio/mp3.html new file mode 100644 index 00000000..692093c2 --- /dev/null +++ b/lmc_portfolio/mp3.html @@ -0,0 +1,75 @@ + + + + + + MP3: Community Training Materials | Andrew Boyer + + + + + + + + +
+ Major Project 3 +

Claude Code Training Website

+

+ A training site that teaches students how to build a portfolio with Claude Code, utilizing concepts from agents to MCP servers. +

+ +
+ Tutorial + Custom website + HTML / CSS + Group project +
+ +
+ Project Introduction +

+ In Major Project 3 we designed training materials for a specific community. Our team wrote a tutorial that walks a student + (ideally freshman studying CS) through building their own portfolio site using Claude Code. Claude Code is Anthropic's AI coding + agent, a tool that our team believed will be crucial in the future of software development. Our guide has six parts, starting with + a conceptual overview of AI agents and context windows, moving through installation and first commands, and finishing with + connecting MCP servers, and generating a static site. We built the site from scratch in HTML and CSS, which gave us full control + over how our content is ingested. The tutorial uses code blocks for commands and separate callouts for tips. We aimed consistent + formatting across the whole guide. +

+
+ +

Live tutorial

+

The full website is embedded below.

+
+ Open in new tab +
+ + +

Process and teamwork

+

+ A key part of this, that is unique when compared to other projects, is that we had to delegate the work between 4 team members. We + split the work up and drafted all of our parts before porting them into the actual website. +

+ + +
+ + + + diff --git a/lmc_portfolio/spotify.html b/lmc_portfolio/spotify.html new file mode 100644 index 00000000..37f9d75a --- /dev/null +++ b/lmc_portfolio/spotify.html @@ -0,0 +1,91 @@ + + + + + + Spotify Wrapped Android App | Andrew Boyer + + + + + + + + +
+ Project outside of LMC 3403 +

Spotify Wrapped Android App

+

+ An Android app built for CS2340. Led the group and contributed backend work utilizing Firebase, Spotify API, and local storage. +

+ +
+ Java + Firebase + Spotify API + XML + Gson + Android +
+ +
+ Spotify Wrapped Android app +
App generates personalized listening summaries using Spotify data.
+
+ +
+ Project Introduction +

+ This was an Android app I built with a team in CS2340 during spring 2024. I was the "Scrum Master," which meant I helped delegate + work and distribute tasks. I also designed and built most of the backend, including the Firebase integration, the Spotify API + authentication flow, the local storage layer, and the QA pass before each release. The app generates personalized "wraps" from a + user's Spotify listening history over a chosen time range and lets users share their wraps publicly through a feed. What I'm + including here are the team's public landing page, our GitHub repository, and the demo video. Coordinating six people on the same + codebase was the part of the project that taught me the most about how to communicate technical decisions across a team. As scrum + master, I utilized a task board where teammates could easily update the status of their tasks. I also had to frequently check in + with members to ensure goals were being met. +

+
+ +
+ Project landing page + GitHub + Demo video +
+ +

What I built

+

+ I implemented the Spotify OAuth flow so users could log in with their Spotify accounts and pull their listening data. I integrated + Firebase as the cloud database for user profiles and saved wraps, and wrote the local storage layer so the app would still feel + responsive offline. Once this data flow was working, I tested the features the rest of the team built, filed bugs, and pushed fixes + before the demo. +

+ +

Communication

+

+ The Scrum Master work wasn't about writing code, but was focused on keeping the sprint board moving, as well as making sure no one was + blocked. We also put together a public landing page (linked above) to explain the app to people who weren't in the class. This project + is on my resume and I would reference it in interviews. +

+ + +
+ + + +