Google koncom júna 2025 predstavil Gemini CLI, open-source AI agenta, ktorý prináša modelu Gemini 2.5 Pro priamo do terminálu. Tento nástroj je určený najmä pre programátorov a technických používateľov, ktorí preferujú prácu v príkazovom riadku pred grafickými rozhraniami.
Jedná sa o Node aplikáciu, ktorú si nainštalujete pomocou príkazu:
npm install -g @google/gemini-cli
Gemini CLI vyniká veľkorysými bezplatnými limitmi:
- Až 60 požiadaviek za minútu
- 1 000 požiadaviek denne
- 1 milión tokenov v kontextovom okne
V súčasnosti sa pravidelne stáva, že aplikácia prejde do nižšieho modelu Gemini 2.5 Flash, zrejme kvôli vysokému dopytu.
Gemini CLI umožňuje:
- Písať, vysvetľovať či opravovať kód priamo v termináli.
- Spúšťať príkazy, manipulovať so súbormi a integrovať sa do CI/CD skriptov.
- Vyhľadávať informácie cez Google Search a generovať texty, skripty či dokonca multimediálny obsah.
- Podporuje štandard Model Context Protocol (MCP) a umožňuje vlastné rozšírenia či úpravy workflowu.
Mať inteligentného agenta, ktorý vám dokáže na základe výziev priamo v projektovom adresári manipulovať s viacerými súbormi a vytvárať boilerplate kód, bolo ešte donedávna sci-fi. Dnes sa nad tým pomaly už ani nepozastavujeme.
Požiadal som Gemini CLI, aby mi vytvoril jednoduchú HTML stránku, ktorá by demoštrovala použitie novej CSS funkcie sibling-count, ktorá sa nedávno stala súčasťou Chrome enginu. Model vytvoril prepracovaný kód, ktorý však nefungoval. (Syntax bola zrejme vydedukovaná z niektorej z existujúcich funkcií.) Spravil som potom screenshot a požiadal ho o opravu. Na ďalší pokus model prepracoval príklad pomocou inej, existujúcej CSS syntaxe, ktorý robil, čo mal.
Potom som skopíroval tutoriál z https://css-tricks.com/almanac/functions/s/sibling-count/ a bez komentára vložil do riadku. Model pomocou tohoto textu vytvoril zaujímavú, funkčnú demoštráciu tejto CSS funkcie:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced CSS sibling-count() Demonstration</title>
<style>
:root {
--primary-color: #005a9c;
--secondary-color: #4caf50;
--bg-light: #f9f9f9;
--bg-white: #ffffff;
--text-dark: #333;
--border-color: #ddd;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
margin: 0;
padding: 2rem;
background-color: var(--bg-light);
color: var(--text-dark);
line-height: 1.6;
}
.main-container {
max-width: 900px;
margin: 0 auto;
padding: 2rem;
background-color: var(--bg-white);
border-radius: 8px;
box-shadow: 0 4px 16px rgba(0,0,0,0.08);
}
h1, h2 {
border-bottom: 2px solid var(--border-color);
padding-bottom: 10px;
color: var(--primary-color);
}
h1 { text-align: center; margin-bottom: 2rem; }
section {
margin-bottom: 3rem;
padding: 1.5rem;
border: 1px solid var(--border-color);
border-radius: 8px;
}
code {
background-color: #e0e0e0;
padding: 3px 6px;
border-radius: 4px;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
font-size: 0.95em;
}
.explanation {
margin-top: 1rem;
padding: 1rem;
background-color: #f0f7ff;
border-left: 4px solid var(--primary-color);
}
.warning {
background-color: #fffbe5;
border: 2px solid #ffc107;
border-left: 8px solid #ffc107;
padding: 1.5rem;
margin-bottom: 2rem;
border-radius: 8px;
}
.warning h2 { border: none; padding: 0; margin: 0 0 0.5rem 0; color: #e65100; }
/* --- Example 1: Dynamic Layout Sizing --- */
.bar-container {
display: flex;
flex-direction: column;
gap: 5px;
height: 200px;
background: #f1f8e9;
border: 2px dashed var(--secondary-color);
padding: 5px;
}
.bar {
background-color: var(--secondary-color);
/* Each bar's height is calculated based on its number of siblings */
height: calc(100% / sibling-count());
}
/* --- Example 2: Responsive Typography --- */
.tag-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
padding: 1rem;
border: 1px solid #ccc;
}
.tag {
background-color: #e1f5fe;
border: 1px solid #4fc3f7;
padding: 5px 10px;
border-radius: 15px;
/* Font size shrinks as more tags are added */
font-size: calc(3rem - (sibling-count() * 0.25rem));
}
/* --- Example 3: Shadow DOM --- */
.slotted-content-visualizer {
border: 2px dashed #673ab7;
padding: 1rem;
background: #f3e5f5;
}
</style>
</head>
<body>
<div class="main-container">
<h1>Advanced CSS <code>sibling-count()</code> Demonstration</h1>
<div class="warning">
<h2>Experimental Feature Ahead!</h2>
<p>The <code>sibling-count()</code> CSS function is highly experimental and <strong>will not work</strong> in most browsers by default.</p>
<p>To see these examples, you must:</p>
<ol>
<li>Use a recent Chromium-based browser (like Google Chrome, Microsoft Edge, or Brave).</li>
<li>Enable the "Experimental Web Platform features" flag. To do this, copy and paste this URL into your browser: <strong><code>chrome://flags/#enable-experimental-web-platform-features</code></strong></li>
<li>Enable the flag and restart your browser.</li>
</ol>
</div>
<section>
<h2>1. Dynamic Layout Sizing</h2>
<p>Instead of a fixed size, we can use <code>sibling-count()</code> to divide space evenly among elements. No matter how many bars we add, they will always perfectly fill the container's height.</p>
<h4>Container with 4 bars:</h4>
<div class="bar-container">
<div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div>
</div>
<h4>Container with 8 bars:</h4>
<div class="bar-container">
<div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div>
</div>
<div class="explanation">
<p>The magic is this one line of CSS applied to each bar. Each bar has 3 siblings in the first example and 7 in the second, but the calculation works for any number.</p>
<code>.bar { height: calc(100% / sibling-count()); }</code>
</div>
</section>
<section>
<h2>2. Responsive Typography</h2>
<p>We can dynamically adjust font size based on the number of elements. In this example, as you add more tags, the text becomes smaller to fit.</p>
<h4>Fewer Tags = Bigger Text</h4>
<div class="tag-container">
<div class="tag">HTML</div><div class="tag">CSS</div><div class="tag">JavaScript</div>
</div>
<h4>More Tags = Smaller Text</h4>
<div class="tag-container">
<div class="tag">React</div><div class="tag">Vue</div><div class="tag">Angular</div><div class="tag">Svelte</div><div class="tag">Solid</div><div class="tag">Qwik</div>
</div>
<div class="explanation">
<p>The font size is calculated relative to the number of sibling tags. This prevents text from overflowing when many tags are present.</p>
<code>.tag { font-size: calc(3rem - (sibling-count() * 0.25rem)); }</code>
</div>
</section>
<section>
<h2>3. Shadow DOM: DOM Tree vs. Flat Tree</h2>
<p>This is a crucial concept. <code>sibling-count()</code> operates on the <strong>DOM tree</strong> (the actual markup structure), not the "flat tree" (what you visually see rendered).</p>
<div class="slotted-content-visualizer">
<my-component>
<!-- These three divs are "slotted" into the component -->
<div>Slotted Content 1</div>
<div>Slotted Content 2</div>
<div>Slotted Content 3</div>
</my-component>
</div>
<div class="explanation">
<p>Visually, it looks like there are four elements inside the dashed border. However, the "Internal Div" reports a <code>sibling-count()</code> of <strong>1</strong>.</p>
<p>This is because, within the component's shadow DOM, there are only two children: the <code><slot></code> element and the "Internal Div". The three slotted divs are not "real" siblings of the internal div in the DOM tree, so they are not counted.</p>
<code>/* Inside the component, the structure is just <slot> and <div> */
width: calc(100% / sibling-count()); /* Becomes 100% / 1 = 100% */</code>
</div>
</section>
</div>
<script>
// Define the custom element for the Shadow DOM demonstration
class MyComponent extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const wrapper = document.createElement('div');
wrapper.setAttribute('class', 'wrapper');
// The <slot> element is where the user's content will be projected.
const slot = document.createElement('slot');
const internalDiv = document.createElement('div');
internalDiv.setAttribute('class', 'internal-div');
const style = document.createElement('style');
style.textContent = `
.wrapper {
border: 2px solid #c62828;
background: #ffebee;
padding: 1rem;
display: flex;
gap: 10px;
}
::slotted(div) {
border: 1px solid #aaa;
padding: 5px;
background: #fafafa;
}
.internal-div {
background: #ffcdd2;
border: 1px solid #c62828;
padding: 10px;
/* Here is the key part! */
/* The only sibling to this div is the <slot> element. */
/* So, sibling-count() will be 1. */
width: calc(400px / sibling-count()); /* 400px / 1 = 400px */
}
.internal-div::before {
font-weight: bold;
content: 'Internal Div';
}
.internal-div::after {
content: ' (sibling-count() = ' attr(data-sibling-count) ')';
font-family: monospace;
font-size: 0.9rem;
color: #c62828;
}
`;
shadow.appendChild(style);
shadow.appendChild(wrapper);
wrapper.appendChild(slot);
wrapper.appendChild(internalDiv);
// We can't use CSS attr() to show the result of sibling-count(),
// so we'll use a little JS inside the component to display it.
const count = window.getComputedStyle(internalDiv).getPropertyValue("width");
// A bit of a hack to show the logic. Since width is "400px", we know count was 1.
// A direct way to get the count isn't possible yet.
internalDiv.setAttribute('data-sibling-count', '1');
}
}
customElements.define('my-component', MyComponent);
</script>
</body>
</html>
Gemini CLI je zjavnou odpoveďou na populárny Claude Code, ktorý v posledných mesiacoch nastavil nový štandard v oblasti AI agentov pre príkazový riadok. Pri takomto rýchlom vývoji AI technológií môžeme dumať nad tým, čo všetko budú tieto nástroje schopné o dva či tri roky.