Skip to content

Commit 35b2ece

Browse files
Fixes
1 parent fb18b06 commit 35b2ece

3 files changed

Lines changed: 85 additions & 6 deletions

File tree

website/eleventy.config.js

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export default function(eleventyConfig) {
5454
return content.replace(original, replacement);
5555
});
5656

57-
const blogHeroBanner = [
57+
const blogHeroDefault = [
5858
'<div class="blog-hero-banner">',
5959
' <div class="blog-hero-glow"></div>',
6060
' <img src="/assets/images/logo.png" alt="CommandTree logo" class="blog-hero-logo">',
@@ -66,6 +66,33 @@ export default function(eleventyConfig) {
6666
'</div>',
6767
].join("\n");
6868

69+
const blogHeroImages = {
70+
"/blog/ai-summaries-hover/": '/assets/images/ai-summary-banner.png',
71+
};
72+
73+
const makeBanner = (href) => {
74+
const img = blogHeroImages[href];
75+
if (!img) { return blogHeroDefault; }
76+
return '<div class="blog-hero-banner">\n'
77+
+ ` <img src="${img}" alt="Blog post banner" class="blog-hero-screenshot">\n`
78+
+ '</div>';
79+
};
80+
81+
const ARTICLE_TAG = '<article class="blog-post">';
82+
83+
const addBannersToCards = (content) => {
84+
const parts = content.split(ARTICLE_TAG);
85+
return parts.map((part, i) => {
86+
if (i === 0) { return part; }
87+
const hrefStart = part.indexOf('href="/blog/');
88+
const hrefEnd = hrefStart >= 0 ? part.indexOf('"', hrefStart + 6) : -1;
89+
const href = hrefStart >= 0 && hrefEnd >= 0
90+
? part.substring(hrefStart + 6, hrefEnd)
91+
: "";
92+
return ARTICLE_TAG + "\n" + makeBanner(href) + part;
93+
}).join("");
94+
};
95+
6996
eleventyConfig.addTransform("blogHero", function(content) {
7097
if (!this.page.outputPath?.endsWith(".html")) {
7198
return content;
@@ -74,14 +101,14 @@ export default function(eleventyConfig) {
74101
return content;
75102
}
76103
if (this.page.url === "/blog/") {
77-
return content.replaceAll(
78-
'<article class="blog-post">',
79-
'<article class="blog-post">\n' + blogHeroBanner
80-
);
104+
return addBannersToCards(content);
105+
}
106+
if (content.includes('blog-hero-banner')) {
107+
return content;
81108
}
82109
return content.replace(
83110
'<div class="blog-post-content">',
84-
'<div class="blog-post-content">\n' + blogHeroBanner
111+
'<div class="blog-post-content">\n' + makeBanner(this.page.url)
85112
);
86113
});
87114

website/src/assets/css/styles.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,15 @@ li::marker { color: var(--color-primary); }
704704
overflow: hidden;
705705
min-height: 220px;
706706
}
707+
.blog-hero-banner img.blog-hero-screenshot {
708+
width: 100%;
709+
height: 100%;
710+
object-fit: cover;
711+
position: absolute;
712+
top: 0;
713+
left: 0;
714+
border-radius: var(--radius-lg);
715+
}
707716
.blog-hero-glow {
708717
position: absolute;
709718
top: 50%;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
layout: layouts/blog.njk
3+
title: AI Summaries on Hover - Know What Every Command Does Before You Run It
4+
description: CommandTree now shows AI-generated summaries when you hover over any command. Powered by GitHub Copilot, every tooltip tells you exactly what a script does.
5+
date: 2026-02-08
6+
author: Christian Findlay
7+
tags: posts
8+
excerpt: Hover over any command in CommandTree and see a plain-language summary of what it does, powered by GitHub Copilot. Security warnings included.
9+
---
10+
11+
<div class="blog-hero-banner">
12+
<img src="/assets/images/ai-summary-banner.png" alt="CommandTree AI summary tooltip showing a plain-language description of a build command" class="blog-hero-screenshot">
13+
</div>
14+
15+
You found the script. But what does it actually *do*?
16+
17+
Shell scripts rarely explain themselves. Makefile targets are cryptic. Even npm scripts chain together enough flags and pipes that you have to read the source to know what happens when you hit run.
18+
19+
**CommandTree 0.5.0 fixes that.** Hover over any command and a tooltip tells you exactly what it does, in plain language.
20+
21+
## How It Works
22+
23+
When [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) is installed, CommandTree reads the content of every discovered command and asks Copilot for a one-to-two sentence summary. These summaries appear instantly when you hover:
24+
25+
> *Compiles the TypeScript extension, packages it as a .vsix file, and installs it into VS Code in one step.*
26+
27+
No reading source code. No guessing. Just hover and know.
28+
29+
## Security Warnings
30+
31+
Copilot also flags dangerous operations. If a script runs `rm -rf`, force-pushes to a remote, or handles credentials, the tooltip includes a security warning and the command label shows a warning indicator. You know the risk before you run.
32+
33+
## Stored Locally, Updated Automatically
34+
35+
Summaries are cached in a local SQLite database at `.commandtree/commandtree.sqlite3` in your workspace. They persist across sessions and only regenerate when the underlying script content changes, so there is no repeated API overhead.
36+
37+
## Works Without Copilot
38+
39+
Every core feature of CommandTree, including discovery, execution, tagging, and filtering, works without Copilot. AI summaries are a bonus layer. If Copilot is unavailable, the extension behaves exactly as before.
40+
41+
## Get Started
42+
43+
Update to CommandTree 0.5.0 from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=nimblesite.commandtree), make sure [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) is installed, and hover over any command in the tree. For full details, see the [AI Summaries documentation](/docs/ai-summaries/).

0 commit comments

Comments
 (0)