Guest User

Untitled

a guest
Jul 6th, 2025
28
0
27 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 240.61 KB | Software | 0 0
  1. # Tutorial: gemini-cli
  2.  
  3. The **gemini-cli** is an *interactive command-line interface* that provides AI-powered coding assistance. It combines **terminal UI components** with **Gemini AI capabilities** to help developers edit files, run commands, and get coding suggestions. Key features include:
  4. - *Sandboxed execution* for security
  5. - *Context-aware* suggestions based on project files
  6. - *Tool integration* for common development tasks
  7. - *Themable interface* with markdown support
  8.  
  9.  
  10. **Source Repository:** [None](None)
  11.  
  12. ```mermaid
  13. flowchart TD
  14. A0["Configuration System
  15. "]
  16. A1["Context Management
  17. "]
  18. A2["Sandbox System
  19. "]
  20. A3["Authentication Flow
  21. "]
  22. A4["Telemetry System
  23. "]
  24. A5["Content Generation
  25. "]
  26. A6["Tool Registry
  27. "]
  28. A7["Tool Scheduler
  29. "]
  30. A8["Editor Integration
  31. "]
  32. A9["Terminal UI Components
  33. "]
  34. A10["Message Display System
  35. "]
  36. A11["Theme Management System
  37. "]
  38. A12["Theme System
  39. "]
  40. A13["Tool System
  41. "]
  42. A14["Error Handling Framework
  43. "]
  44. A15["File System Operations
  45. "]
  46. A16["Interactive Shell Utilities
  47. "]
  48. A17["Interactive UI Framework
  49. "]
  50. A18["Utility Functions
  51. "]
  52. A19["Validation Framework
  53. "]
  54. A20["Build Pipeline
  55. "]
  56. A21["Custom Hooks
  57. "]
  58. A22["Input Handling
  59. "]
  60. A23["Layout Management
  61. "]
  62. A24["Markdown Rendering Engine
  63. "]
  64. A25["Package Management
  65. "]
  66. A26["Privacy Notices
  67. "]
  68. A27["Session Statistics
  69. "]
  70. A28["Shared UI Components
  71. "]
  72. A29["Telemetry Service
  73. "]
  74. A30["Tool Execution System
  75. "]
  76. A31["Tool Framework
  77. "]
  78. A32["CLI Application Core
  79. "]
  80. A33["Configuration Management
  81. "]
  82. A34["Error Handling System
  83. "]
  84. A35["Event Logging
  85. "]
  86. A36["File Operations
  87. "]
  88. A37["File Processing Pipeline
  89. "]
  90. A38["Release Process
  91. "]
  92. A39["Sandboxing System
  93. "]
  94. A40["User Context Management
  95. "]
  96. A41["API Server Interface
  97. "]
  98. A42["Command Processing
  99. "]
  100. A43["Config Management
  101. "]
  102. A44["Content Correction System
  103. "]
  104. A45["Content Diffing
  105. "]
  106. A46["Conversation Management
  107. "]
  108. A47["File Reference Processor
  109. "]
  110. A48["File System Utilities
  111. "]
  112. A49["History Management
  113. "]
  114. A50["Memory Management
  115. "]
  116. A51["Non-Interactive Mode
  117. "]
  118. A52["Request/Response Formatting
  119. "]
  120. A53["Schema Validation
  121. "]
  122. A54["Tool Execution
  123. "]
  124. A55["Activity Logger
  125. "]
  126. A56["Authentication System
  127. "]
  128. A57["Chat Session
  129. "]
  130. A58["Content Correction
  131. "]
  132. A59["Conversation Turn
  133. "]
  134. A60["Cross-Package Import Rules
  135. "]
  136. A61["Error Reporting
  137. "]
  138. A62["Extension System
  139. "]
  140. A63["File Discovery
  141. "]
  142. A64["File Discovery Service
  143. "]
  144. A65["Gemini Client
  145. "]
  146. A66["Gemini Stream Processing
  147. "]
  148. A67["Git Integration
  149. "]
  150. A68["MCP Tools
  151. "]
  152. A69["Shell Command Execution
  153. "]
  154. A70["Shell Execution
  155. "]
  156. A71["System Prompts
  157. "]
  158. A32 -- "Orchestrates" --> A0
  159. A32 -- "Manages" --> A3
  160. A32 -- "Controls" --> A17
  161. A17 -- "Renders" --> A9
  162. A17 -- "Displays" --> A10
  163. A5 -- "Uses" --> A65
  164. A6 -- "Manages" --> A13
  165. A7 -- "Coordinates" --> A30
  166. A11 -- "Controls" --> A12
  167. A14 -- "Extends" --> A34
  168. A15 -- "Wraps" --> A36
  169. A16 -- "Provides" --> A22
  170. A18 -- "Supports" --> A15
  171. A19 -- "Uses" --> A53
  172. A20 -- "Feeds" --> A38
  173. A21 -- "Extends" --> A17
  174. A23 -- "Arranges" --> A10
  175. A24 -- "Formats" --> A10
  176. A25 -- "Manages" --> A20
  177. A26 -- "Shows" --> A3
  178. A27 -- "Reports" --> A4
  179. A28 -- "Provides" --> A9
  180. A29 -- "Implements" --> A4
  181. A31 -- "Supports" --> A54
  182. A33 -- "Manages" --> A43
  183. A35 -- "Feeds" --> A55
  184. A37 -- "Processes" --> A47
  185. A39 -- "Implements" --> A2
  186. A40 -- "Provides" --> A1
  187. A41 -- "Connects" --> A5
  188. A42 -- "Triggers" --> A69
  189. A44 -- "Performs" --> A58
  190. A45 -- "Supports" --> A50
  191. A46 -- "Controls" --> A57
  192. A48 -- "Assists" --> A63
  193. A49 -- "Tracks" --> A59
  194. A51 -- "Bypasses" --> A8
  195. A52 -- "Formats" --> A66
  196. A56 -- "Implements" --> A3
  197. A60 -- "Governs" --> A25
  198. A61 -- "Feeds" --> A14
  199. A62 -- "Loads" --> A68
  200. A64 -- "Supports" --> A47
  201. A67 -- "Enhances" --> A15
  202. A70 -- "Secures" --> A69
  203. A71 -- "Guides" --> A5
  204. ```
  205.  
  206. ## Chapters
  207.  
  208. 1. [CLI Application Core
  209. ](01_cli_application_core_.md)
  210. 2. [Interactive UI Framework
  211. ](02_interactive_ui_framework_.md)
  212. 3. [Terminal UI Components
  213. ](03_terminal_ui_components_.md)
  214. 4. [Message Display System
  215. ](04_message_display_system_.md)
  216. 5. [Content Generation
  217. ](05_content_generation_.md)
  218. 6. [Gemini Client
  219. ](06_gemini_client_.md)
  220. 7. [Authentication Flow
  221. ](07_authentication_flow_.md)
  222. 8. [Authentication System
  223. ](08_authentication_system_.md)
  224. 9. [Sandbox System
  225. ](09_sandbox_system_.md)
  226. 10. [Sandboxing System
  227. ](10_sandboxing_system_.md)
  228. 11. [Tool Registry
  229. ](11_tool_registry_.md)
  230. 12. [Tool System
  231. ](12_tool_system_.md)
  232. 13. [Tool Execution System
  233. ](13_tool_execution_system_.md)
  234. 14. [Tool Execution
  235. ](14_tool_execution_.md)
  236. 15. [File System Operations
  237. ](15_file_system_operations_.md)
  238. 16. [File Operations
  239. ](16_file_operations_.md)
  240. 17. [File Discovery
  241. ](17_file_discovery_.md)
  242. 18. [File Reference Processor
  243. ](18_file_reference_processor_.md)
  244. 19. [Configuration System
  245. ](19_configuration_system_.md)
  246. 20. [Configuration Management
  247. ](20_configuration_management_.md)
  248. 21. [Config Management
  249. ](21_config_management_.md)
  250. 22. [Theme Management System
  251. ](22_theme_management_system_.md)
  252. 23. [Theme System
  253. ](23_theme_system_.md)
  254. 24. [Markdown Rendering Engine
  255. ](24_markdown_rendering_engine_.md)
  256. 25. [Error Handling Framework
  257. ](25_error_handling_framework_.md)
  258. 26. [Error Handling System
  259. ](26_error_handling_system_.md)
  260. 27. [Error Reporting
  261. ](27_error_reporting_.md)
  262. 28. [Telemetry System
  263. ](28_telemetry_system_.md)
  264. 29. [Telemetry Service
  265. ](29_telemetry_service_.md)
  266. 30. [Session Statistics
  267. ](30_session_statistics_.md)
  268. 31. [Conversation Management
  269. ](31_conversation_management_.md)
  270. 32. [Chat Session
  271. ](32_chat_session_.md)
  272. 33. [Conversation Turn
  273. ](33_conversation_turn_.md)
  274. 34. [System Prompts
  275. ](34_system_prompts_.md)
  276. 35. [Input Handling
  277. ](35_input_handling_.md)
  278. 36. [Interactive Shell Utilities
  279. ](36_interactive_shell_utilities_.md)
  280. 37. [Shell Command Execution
  281. ](37_shell_command_execution_.md)
  282. 38. [Shell Execution
  283. ](38_shell_execution_.md)
  284. 39. [Tool Scheduler
  285. ](39_tool_scheduler_.md)
  286. 40. [Tool Framework
  287. ](40_tool_framework_.md)
  288. 41. [Custom Hooks
  289. ](41_custom_hooks_.md)
  290. 42. [Layout Management
  291. ](42_layout_management_.md)
  292. 43. [Shared UI Components
  293. ](43_shared_ui_components_.md)
  294. 44. [Editor Integration
  295. ](44_editor_integration_.md)
  296. 45. [Non-Interactive Mode
  297. ](45_non_interactive_mode_.md)
  298. 46. [Utility Functions
  299. ](46_utility_functions_.md)
  300. 47. [Validation Framework
  301. ](47_validation_framework_.md)
  302. 48. [Schema Validation
  303. ](48_schema_validation_.md)
  304. 49. [Build Pipeline
  305. ](49_build_pipeline_.md)
  306. 50. [Package Management
  307. ](50_package_management_.md)
  308. 51. [Cross-Package Import Rules
  309. ](51_cross_package_import_rules_.md)
  310. 52. [Release Process
  311. ](52_release_process_.md)
  312. 53. [Privacy Notices
  313. ](53_privacy_notices_.md)
  314. 54. [Context Management
  315. ](54_context_management_.md)
  316. 55. [User Context Management
  317. ](55_user_context_management_.md)
  318. 56. [Event Logging
  319. ](56_event_logging_.md)
  320. 57. [Activity Logger
  321. ](57_activity_logger_.md)
  322. 58. [File Processing Pipeline
  323. ](58_file_processing_pipeline_.md)
  324. 59. [API Server Interface
  325. ](59_api_server_interface_.md)
  326. 60. [Command Processing
  327. ](60_command_processing_.md)
  328. 61. [Content Correction System
  329. ](61_content_correction_system_.md)
  330. 62. [Content Correction
  331. ](62_content_correction_.md)
  332. 63. [Content Diffing
  333. ](63_content_diffing_.md)
  334. 64. [File System Utilities
  335. ](64_file_system_utilities_.md)
  336. 65. [History Management
  337. ](65_history_management_.md)
  338. 66. [Memory Management
  339. ](66_memory_management_.md)
  340. 67. [Request/Response Formatting
  341. ](67_request_response_formatting_.md)
  342. 68. [Gemini Stream Processing
  343. ](68_gemini_stream_processing_.md)
  344. 69. [Extension System
  345. ](69_extension_system_.md)
  346. 70. [MCP Tools
  347. ](70_mcp_tools_.md)
  348. 71. [File Discovery Service
  349. ](71_file_discovery_service_.md)
  350. 72. [Git Integration
  351. ](72_git_integration_.md)
  352. ---
  353.  
  354. # Chapter 1: CLI Application Core
  355.  
  356. Welcome to your first step in building CLI applications! In this chapter, we'll explore the heart of any command-line tool - the **CLI Application Core**. Think of this as the "brain" that coordinates everything your app does.
  357.  
  358. ## Why Do We Need a Core?
  359.  
  360. Imagine you're building a simple weather CLI app. When someone types `weather --city Paris`, your app needs to:
  361. 1. Understand the command (`weather`)
  362. 2. Read the option (`--city Paris`)
  363. 3. Fetch weather data
  364. 4. Display it nicely
  365. 5. Handle any errors
  366.  
  367. The CLI Application Core handles all this coordination behind the scenes, like a restaurant manager making sure all staff work together smoothly.
  368.  
  369. ## Key Responsibilities
  370.  
  371. Our core has three main jobs:
  372.  
  373. 1. **Startup**: Setting up everything when the app launches
  374. 2. **Orchestration**: Managing all components (like [Configuration System](19_configuration_system_.md) and [Authentication Flow](07_authentication_flow_.md))
  375. 3. **Shutdown**: Cleaning up when the app closes
  376.  
  377. ## A Simple Example
  378.  
  379. Here's what a minimal core might look like:
  380.  
  381. ```typescript
  382. // The main entry point
  383. async function main() {
  384. // 1. Startup
  385. const config = loadConfig(); // [Configuration System](19_configuration_system_.md)
  386.  
  387. // 2. Orchestration
  388. const command = process.argv[2]; // Get user input
  389. if (command === 'weather') {
  390. const weather = await fetchWeather(config);
  391. displayWeather(weather); // [Message Display System](04_message_display_system_.md)
  392. }
  393.  
  394. // 3. Shutdown
  395. cleanup();
  396. }
  397. ```
  398.  
  399. This shows the core's basic flow: setup → do work → clean up.
  400.  
  401. ## Under the Hood
  402.  
  403. Let's visualize how this works using a simple sequence:
  404.  
  405. ```mermaid
  406. sequenceDiagram
  407. participant User as User
  408. participant Core as CLI Core
  409. participant Config as Configuration
  410. participant Service as Weather Service
  411.  
  412. User->>Core: Runs "weather --city Paris"
  413. Core->>Config: Load settings
  414. Config-->>Core: Returns config
  415. Core->>Service: Fetch Paris weather
  416. Service-->>Core: Returns data
  417. Core->>User: Displays forecast
  418. ```
  419.  
  420. ## Real-World Implementation
  421.  
  422. In our actual code (found in `packages/cli/src/gemini.tsx`), the core handles more complex scenarios:
  423.  
  424. ```typescript
  425. async function main() {
  426. // Load configuration
  427. const config = await loadCliConfig();
  428.  
  429. // Check if we need more memory
  430. const memoryArgs = getNodeMemoryArgs(config);
  431. if (memoryArgs.length > 0) {
  432. await relaunchWithAdditionalArgs(memoryArgs);
  433. }
  434.  
  435. // Handle user input
  436. if (hasInputFromUser) {
  437. await handleUserInput(config);
  438. } else {
  439. showInteractiveUI(config); // [Interactive UI Framework](02_interactive_ui_framework_.md)
  440. }
  441. }
  442. ```
  443.  
  444. Key things to notice:
  445. 1. It first loads configuration
  446. 2. Checks system resources
  447. 3. Decides whether to show an interactive UI or process direct input
  448.  
  449. ## Common Patterns
  450.  
  451. The core typically uses these patterns:
  452. - **Singleton**: Only one core instance exists
  453. - **Facade**: Provides simple interfaces to complex subsystems
  454. - **Lifecycle Hooks**: Methods like `startup()` and `shutdown()`
  455.  
  456. ## Error Handling
  457.  
  458. A good core also manages errors gracefully:
  459.  
  460. ```typescript
  461. main().catch((error) => {
  462. console.error('Oops! Something went wrong:');
  463. console.error(error);
  464. process.exit(1); // Exit with error code
  465. });
  466. ```
  467.  
  468. ## What's Next?
  469.  
  470. Now that you understand the CLI Application Core, you're ready to explore how it interacts with other parts! In [Chapter 2: Interactive UI Framework](02_interactive_ui_framework_.md), we'll see how the core manages user interfaces.
  471.  
  472. ---
  473.  
  474. # Chapter 2: Interactive UI Framework
  475.  
  476. Welcome back! In [Chapter 1: CLI Application Core](01_cli_application_core_.md), we learned how CLI apps work behind the scenes. Now, let's explore something exciting - how to make your terminal apps interactive like web apps!
  477.  
  478. ## Why Interactive UI?
  479.  
  480. Imagine typing `weather` and seeing a friendly menu where you can:
  481. - Use arrow keys to select cities
  482. - See live weather updates
  483. - Get colorful forecasts
  484.  
  485. This is what our Interactive UI Framework makes possible! It brings web-like experiences to your terminal.
  486.  
  487. ## Key Concepts
  488.  
  489. Our framework has three main parts:
  490.  
  491. 1. **Components**: Building blocks like buttons or menus
  492. 2. **State**: Remembering what's selected/changed
  493. 3. **Events**: Handling keyboard/mouse actions
  494.  
  495. Think of it like LEGO:
  496. - Components = LEGO pieces
  497. - State = What you're building
  498. - Events = Your hands moving pieces
  499.  
  500. ## A Simple Example
  501.  
  502. Here's how to create a basic menu:
  503.  
  504. ```typescript
  505. import { Menu } from 'gemini-cli';
  506.  
  507. function WeatherMenu() {
  508. return (
  509. <Menu
  510. items={["Paris", "London", "Tokyo"]}
  511. onSelect={(city) => fetchWeather(city)}
  512. />
  513. );
  514. }
  515. ```
  516.  
  517. This creates a menu that:
  518. 1. Shows 3 cities
  519. 2. Calls `fetchWeather` when you pick one
  520.  
  521. ## How It Works Inside
  522.  
  523. When you run this, here's what happens:
  524.  
  525. ```mermaid
  526. sequenceDiagram
  527. participant User as User
  528. participant UI as UI Framework
  529. participant App as Your App
  530.  
  531. User->>UI: Presses down arrow
  532. UI->>UI: Updates selected item
  533. UI->>App: Highlights "London"
  534. User->>UI: Presses Enter
  535. UI->>App: Calls onSelect("London")
  536. App->>App: Fetches weather data
  537. ```
  538.  
  539. ## Real-World Usage
  540.  
  541. In our actual code (like `packages/cli/src/ui/App.tsx`), we use hooks to manage state:
  542.  
  543. ```typescript
  544. function App() {
  545. const [city, setCity] = useState("Paris");
  546.  
  547. return (
  548. <Box>
  549. <Text>Selected: {city}</Text>
  550. <Menu items={cities} onSelect={setCity} />
  551. </Box>
  552. );
  553. }
  554. ```
  555.  
  556. Key things to notice:
  557. 1. `useState` remembers the selected city
  558. 2. `setCity` updates it when menu changes
  559. 3. The display automatically updates!
  560.  
  561. ## Common Patterns
  562.  
  563. You'll often see:
  564. - **State Hooks**: `useState`, `useEffect`
  565. - **Layout Components**: `Box`, `Text`
  566. - **Input Handlers**: `useInput` for keyboard events
  567.  
  568. ## What's Next?
  569.  
  570. Now you've seen how we build interactive terminal UIs! Next, we'll explore the [Terminal UI Components](03_terminal_ui_components_.md) that make this possible.
  571.  
  572. > Pro Tip: Try adding `<Button>` components to your menu for extra interactivity!
  573.  
  574. ---
  575.  
  576. # Chapter 3: Terminal UI Components
  577.  
  578. Welcome back! In [Chapter 2: Interactive UI Framework](02_interactive_ui_framework_.md), we learned how to make terminal apps interactive. Now, let's meet the building blocks that make this possible - Terminal UI Components!
  579.  
  580. ## Why Do We Need Components?
  581.  
  582. Imagine building a house. You wouldn't craft every brick from scratch - you'd use pre-made bricks, windows, and doors. Similarly, Terminal UI Components are pre-made pieces for building terminal interfaces:
  583.  
  584. - Boxes to organize content
  585. - Text with colors and styles
  586. - Borders for visual separation
  587. - Input fields for user interaction
  588.  
  589. ## Meet the Basic Components
  590.  
  591. Here are the most common components you'll use:
  592.  
  593. 1. **Text** - Displays words in the terminal
  594. 2. **Box** - Creates containers with borders
  595. 3. **Input** - Gets user keyboard input
  596. 4. **Menu** - Shows selectable options
  597.  
  598. ## A Simple Example
  599.  
  600. Let's create a basic message box:
  601.  
  602. ```typescript
  603. import { Box, Text } from 'gemini-cli';
  604.  
  605. function WelcomeMessage() {
  606. return (
  607. <Box borderStyle="round">
  608. <Text color="green">Welcome to Gemini CLI!</Text>
  609. </Box>
  610. );
  611. }
  612. ```
  613.  
  614. This creates:
  615. - A rounded border box
  616. - Green text inside saying "Welcome to Gemini CLI!"
  617.  
  618. ## How Components Work Together
  619.  
  620. When you use components, here's what happens behind the scenes:
  621.  
  622. ```mermaid
  623. sequenceDiagram
  624. participant App as Your App
  625. participant Ink as Ink Library
  626. participant Term as Terminal
  627.  
  628. App->>Ink: Render <Box> with <Text>
  629. Ink->>Term: Draw borders and text
  630. Term-->>User: Shows the boxed message
  631. ```
  632.  
  633. ## Real-World Component Usage
  634.  
  635. Let's look at a more complete example from our codebase (`packages/cli/src/ui/components/AboutBox.tsx`):
  636.  
  637. ```typescript
  638. function InfoBox() {
  639. return (
  640. <Box borderStyle="round" borderColor="gray">
  641. <Text bold>System Info</Text>
  642. <Text>Version: 1.0.0</Text>
  643. <Text>OS: MacOS</Text>
  644. </Box>
  645. );
  646. }
  647. ```
  648.  
  649. Key features:
  650. - `borderStyle` makes the rounded box
  651. - `borderColor` sets the border color
  652. - Nested `Text` components display information
  653.  
  654. ## Styling Your Components
  655.  
  656. You can customize components with props:
  657.  
  658. ```typescript
  659. <Text
  660. color="blue"
  661. bold
  662. underline
  663. >
  664. Important Message
  665. </Text>
  666. ```
  667.  
  668. Common styling props:
  669. - `color`: Text color (red, green, blue, etc.)
  670. - `bold`: Makes text bold
  671. - `underline`: Underlines text
  672. - `backgroundColor`: Sets background color
  673.  
  674. ## What's Next?
  675.  
  676. Now you understand the building blocks of terminal interfaces! In [Chapter 4: Message Display System](04_message_display_system_.md), we'll learn how to show messages and responses to users.
  677.  
  678. > Pro Tip: Try combining multiple Box components to create complex layouts!
  679.  
  680. ---
  681.  
  682. # Chapter 4: Message Display System
  683.  
  684. Welcome back! In [Chapter 3: Terminal UI Components](03_terminal_ui_components_.md), we learned about building blocks for terminal interfaces. Now, let's learn how to show different types of messages in your CLI app - like chat bubbles in a messaging app!
  685.  
  686. ## Why Do We Need Message Display?
  687.  
  688. Imagine you're building a chatbot. You need to show:
  689. - User messages (what people type)
  690. - AI responses
  691. - Error messages
  692. - System notifications
  693.  
  694. Each type should look different so users can tell them apart easily. That's what our Message Display System does!
  695.  
  696. ## Meet the Message Types
  697.  
  698. Here are the main message types we'll work with:
  699.  
  700. 1. **User Messages**: What the user types (shown in gray bubbles)
  701. 2. **AI Messages**: Responses from Gemini (purple prefix)
  702. 3. **Error Messages**: When something goes wrong (red text)
  703. 4. **Tool Messages**: When tools run commands (with status icons)
  704.  
  705. ## A Simple Example
  706.  
  707. Let's create a basic user message:
  708.  
  709. ```typescript
  710. import { UserMessage } from 'gemini-cli';
  711.  
  712. function ShowMessage() {
  713. return <UserMessage text="Hello Gemini!" />;
  714. }
  715. ```
  716.  
  717. This will display:
  718. ```
  719. > Hello Gemini!
  720. ```
  721. (In a gray rounded box)
  722.  
  723. ## How Messages Work Together
  724.  
  725. When messages are displayed, here's what happens:
  726.  
  727. ```mermaid
  728. sequenceDiagram
  729. participant App as Your App
  730. participant Message as Message System
  731. participant Term as Terminal
  732.  
  733. App->>Message: Show <UserMessage>
  734. Message->>Term: Draw gray bubble with text
  735. Term-->>User: Shows the message
  736. ```
  737.  
  738. ## Real-World Message Components
  739.  
  740. Let's look at how we show an AI response (from `packages/cli/src/ui/components/messages/GeminiMessage.tsx`):
  741.  
  742. ```typescript
  743. function GeminiResponse() {
  744. return (
  745. <Box flexDirection="row">
  746. <Text color="purple">✦ </Text>
  747. <Text>Here's your answer!</Text>
  748. </Box>
  749. );
  750. }
  751. ```
  752.  
  753. Key parts:
  754. - Purple `✦` prefix marks AI messages
  755. - Text appears next to it
  756. - Simple row layout
  757.  
  758. ## Styling Different Messages
  759.  
  760. Each message type has its own style:
  761.  
  762. ```typescript
  763. // Error message (red)
  764. <ErrorMessage text="File not found" />
  765.  
  766. // Info message (yellow)
  767. <InfoMessage text="Connected to server" />
  768.  
  769. // Tool message (with status icon)
  770. <ToolMessage name="search" status="success" />
  771. ```
  772.  
  773. Common styles:
  774. - Colors match message purpose (red for errors, etc.)
  775. - Icons show message type
  776. - Consistent spacing
  777.  
  778. ## What's Next?
  779.  
  780. Now you know how to display different message types! In [Chapter 5: Content Generation](05_content_generation_.md), we'll learn how Gemini creates the responses you show with this system.
  781.  
  782. > Pro Tip: Try combining message types to build a complete chat interface!
  783.  
  784. ---
  785.  
  786. # Chapter 5: Content Generation
  787.  
  788. Welcome back! In [Chapter 4: Message Display System](04_message_display_system_.md), we learned how to show messages in your CLI app. Now, let's explore how Gemini actually creates those responses - the magic of Content Generation!
  789.  
  790. ## Why Do We Need Content Generation?
  791.  
  792. Imagine asking your CLI app: "Translate 'hello' to French". The app needs to:
  793. 1. Understand your request
  794. 2. Generate the correct response ("bonjour")
  795. 3. Handle errors if something goes wrong
  796. 4. Show the result nicely
  797.  
  798. Content Generation is like a helpful translator that does all this work behind the scenes!
  799.  
  800. ## How Content Generation Works
  801.  
  802. Let's break it down into simple parts:
  803.  
  804. 1. **Input**: Your question ("Translate 'hello' to French")
  805. 2. **Processing**: Gemini understands and generates a response
  806. 3. **Output**: The translated word ("bonjour")
  807.  
  808. Here's a simple example:
  809.  
  810. ```typescript
  811. import { generateContent } from 'gemini-cli';
  812.  
  813. async function translate() {
  814. const response = await generateContent({
  815. prompt: "Translate 'hello' to French"
  816. });
  817. console.log(response); // "bonjour"
  818. }
  819. ```
  820.  
  821. This shows the basic flow: you ask, Gemini answers.
  822.  
  823. ## Behind the Scenes
  824.  
  825. When you make a request, here's what happens:
  826.  
  827. ```mermaid
  828. sequenceDiagram
  829. participant You as You
  830. participant CLI as Your CLI App
  831. participant Gemini as Gemini Service
  832.  
  833. You->>CLI: Ask to translate "hello"
  834. CLI->>Gemini: Sends request
  835. Gemini->>Gemini: Processes translation
  836. Gemini-->>CLI: Returns "bonjour"
  837. CLI->>You: Shows translation
  838. ```
  839.  
  840. ## Handling Different Cases
  841.  
  842. The Content Generation system is smart enough to handle different situations:
  843.  
  844. 1. **Success**: Gets the correct answer
  845. 2. **Errors**: If Gemini is busy, it tries again
  846. 3. **Fallback**: If the main model fails, it uses a simpler one
  847.  
  848. Here's how we handle errors:
  849.  
  850. ```typescript
  851. try {
  852. const response = await generateContent({ prompt: "Translate..." });
  853. console.log(response);
  854. } catch (error) {
  855. console.log("Oops! Let me try again...");
  856. // Automatically retries with a simpler model
  857. }
  858. ```
  859.  
  860. ## Real-World Example
  861.  
  862. In our actual code (like `packages/core/src/core/contentGenerator.ts`), we configure the generator:
  863.  
  864. ```typescript
  865. const config = {
  866. model: "gemini-pro", // Which AI model to use
  867. authType: "api-key" // How to authenticate
  868. };
  869.  
  870. const generator = createContentGenerator(config);
  871. ```
  872.  
  873. Key parts:
  874. - `model`: Which Gemini version to use
  875. - `authType`: How to log in (API key or Google account)
  876.  
  877. ## What's Next?
  878.  
  879. Now you understand how Gemini generates responses! In [Chapter 6: Gemini Client](06_gemini_client_.md), we'll explore how your app actually talks to Gemini's servers.
  880.  
  881. > Pro Tip: Try changing the `model` in the config to see how responses vary!
  882.  
  883. ---
  884.  
  885. # Chapter 6: Gemini Client
  886.  
  887. Welcome back! In [Chapter 5: Content Generation](05_content_generation_.md), we learned how Gemini creates responses. Now, let's meet the helpful "telephone operator" that connects your app to Gemini - the **Gemini Client**!
  888.  
  889. ## Your App's Personal Assistant
  890.  
  891. Imagine you're at a fancy hotel. When you need anything - room service, directions, or restaurant recommendations - you call the front desk. The Gemini Client works just like that helpful front desk operator:
  892.  
  893. 1. You make a request ("What's the weather?")
  894. 2. The client talks to Gemini's servers
  895. 3. It brings back the answer ("Sunny and 75°F")
  896.  
  897. ## A Simple Example
  898.  
  899. Here's how easy it is to use the Gemini Client:
  900.  
  901. ```typescript
  902. import { GeminiClient } from 'gemini-cli';
  903.  
  904. // Set up your client
  905. const client = new GeminiClient(config);
  906.  
  907. // Ask a question
  908. const response = await client.sendMessage("Hello Gemini!");
  909. console.log(response); // "Hello! How can I help you today?"
  910. ```
  911.  
  912. This shows the basic flow: create client → send message → get response.
  913.  
  914. ## What Can the Client Do?
  915.  
  916. The Gemini Client handles four main jobs:
  917.  
  918. 1. **Chat Sessions**: Keeps track of your conversation
  919. 2. **Content Generation**: Gets answers from Gemini
  920. 3. **Embeddings**: Turns words into numbers (for advanced features)
  921. 4. **Model Management**: Chooses the right Gemini version
  922.  
  923. ## Behind the Scenes
  924.  
  925. When you send a message, here's what happens:
  926.  
  927. ```mermaid
  928. sequenceDiagram
  929. participant You as You
  930. participant Client as Gemini Client
  931. participant Gemini as Gemini Servers
  932.  
  933. You->>Client: "What's 2+2?"
  934. Client->>Gemini: Sends question
  935. Gemini->>Gemini: Calculates answer
  936. Gemini-->>Client: Returns "4"
  937. Client->>You: Shows answer
  938. ```
  939.  
  940. ## Real-World Usage
  941.  
  942. In our actual code (like `packages/core/src/core/client.ts`), the client does much more:
  943.  
  944. ```typescript
  945. class GeminiClient {
  946. private chat; // Remembers conversation history
  947.  
  948. async sendMessage(message: string) {
  949. // 1. Add message to history
  950. this.chat.addMessage(message);
  951.  
  952. // 2. Get response from Gemini
  953. const response = await this.getGeminiResponse();
  954.  
  955. // 3. Return formatted answer
  956. return this.formatResponse(response);
  957. }
  958. }
  959. ```
  960.  
  961. Key parts:
  962. - `chat`: Keeps track of your conversation
  963. - `getGeminiResponse`: Talks to Gemini's servers
  964. - `formatResponse`: Makes answers look nice
  965.  
  966. ## Handling Different Requests
  967.  
  968. The client is smart enough to handle different types of requests:
  969.  
  970. ```typescript
  971. // Regular chat
  972. client.sendMessage("Hello!");
  973.  
  974. // Get embeddings (for search features)
  975. client.generateEmbedding(["cat", "dog"]);
  976.  
  977. // Generate JSON (for structured data)
  978. client.generateJson({schema: {name: "string"}});
  979. ```
  980.  
  981. ## What's Next?
  982.  
  983. Now you understand how your app talks to Gemini! In [Chapter 7: Authentication Flow](07_authentication_flow_.md), we'll learn how the client securely logs in to Gemini's services.
  984.  
  985. > Pro Tip: Try adding multiple messages to see how the client remembers your conversation history!
  986.  
  987. ---
  988.  
  989. # Chapter 7: Authentication Flow
  990.  
  991. Welcome back! In [Chapter 6: Gemini Client](06_gemini_client_.md), we learned how your app talks to Gemini. Now, let's explore how it securely logs in - just like when you sign into your favorite apps!
  992.  
  993. ## Why Do We Need Authentication?
  994.  
  995. Imagine going to a members-only club. Before entering, you need to:
  996. 1. Show your membership card (prove who you are)
  997. 2. Get checked by security (verify your access)
  998. 3. Receive a wristband (get temporary access)
  999.  
  1000. The Authentication Flow works similarly for your CLI app:
  1001. 1. You choose how to log in (Google account or API key)
  1002. 2. The system verifies your credentials
  1003. 3. You get temporary access to use Gemini
  1004.  
  1005. ## A Simple Example
  1006.  
  1007. Here's how easy authentication can be:
  1008.  
  1009. ```typescript
  1010. import { authenticate } from 'gemini-cli';
  1011.  
  1012. // Start authentication
  1013. await authenticate();
  1014. ```
  1015.  
  1016. When you run this, you'll see:
  1017. 1. A menu asking how you want to log in
  1018. 2. Instructions based on your choice
  1019. 3. Confirmation when successful
  1020.  
  1021. ## The Three-Step Flow
  1022.  
  1023. Authentication happens in three simple steps:
  1024.  
  1025. 1. **Selection**: Choose your login method
  1026. 2. **Verification**: Prove your identity
  1027. 3. **Confirmation**: Get access to Gemini
  1028.  
  1029. Here's how it looks in code:
  1030.  
  1031. ```typescript
  1032. // 1. Show login options
  1033. const method = await showAuthMenu();
  1034.  
  1035. // 2. Verify credentials
  1036. const isValid = await verifyCredentials(method);
  1037.  
  1038. // 3. Grant access
  1039. if (isValid) {
  1040. startGeminiSession();
  1041. }
  1042. ```
  1043.  
  1044. ## Behind the Scenes
  1045.  
  1046. When you authenticate, here's what happens:
  1047.  
  1048. ```mermaid
  1049. sequenceDiagram
  1050. participant You as You
  1051. participant CLI as Your CLI App
  1052. participant Google as Google Servers
  1053.  
  1054. You->>CLI: Runs "gemini auth"
  1055. CLI->>You: Shows login options
  1056. You->>CLI: Chooses "Google Login"
  1057. CLI->>Google: Opens browser for login
  1058. Google-->>CLI: Returns verification token
  1059. CLI->>You: "Login successful!"
  1060. ```
  1061.  
  1062. ## Real-World Implementation
  1063.  
  1064. In our actual code (like `packages/cli/src/ui/components/AuthDialog.tsx`), we handle different login methods:
  1065.  
  1066. ```typescript
  1067. function AuthDialog() {
  1068. return (
  1069. <Menu items={[
  1070. "Login with Google",
  1071. "Use API Key",
  1072. "Vertex AI"
  1073. ]} />
  1074. );
  1075. }
  1076. ```
  1077.  
  1078. Key parts:
  1079. - Shows three login options
  1080. - Handles each choice differently
  1081. - Manages timeouts if login takes too long
  1082.  
  1083. ## Handling Errors
  1084.  
  1085. The system also manages problems gracefully:
  1086.  
  1087. ```typescript
  1088. try {
  1089. await authenticate();
  1090. } catch (error) {
  1091. console.log("Oops! Let's try again...");
  1092. // Automatically retries
  1093. }
  1094. ```
  1095.  
  1096. Common issues it handles:
  1097. - Wrong passwords
  1098. - Expired API keys
  1099. - Network problems
  1100.  
  1101. ## What's Next?
  1102.  
  1103. Now you understand how authentication works! In [Chapter 8: Authentication System](08_authentication_system_.md), we'll explore how your login stays secure while using Gemini.
  1104.  
  1105. > Pro Tip: Try different login methods to see how the experience changes!
  1106.  
  1107. ---
  1108.  
  1109. # Chapter 8: Authentication System
  1110.  
  1111. Welcome back! In [Chapter 7: Authentication Flow](07_authentication_flow_.md), we learned how users log in to your CLI app. Now, let's explore how the app keeps them securely logged in - like a bouncer checking IDs at a club!
  1112.  
  1113. ## Why Do We Need an Authentication System?
  1114.  
  1115. Imagine you're running a VIP club. You need to:
  1116. 1. Check IDs at the door (verify who's allowed in)
  1117. 2. Give wristbands to approved guests (temporary access)
  1118. 3. Watch for expired wristbands (check ongoing access)
  1119.  
  1120. Our Authentication System does exactly this for your CLI app:
  1121. - Verifies login methods (API keys, Google accounts)
  1122. - Manages active sessions
  1123. - Handles expired or invalid credentials
  1124.  
  1125. ## Meet the Authentication Methods
  1126.  
  1127. The system supports three main ways to log in:
  1128.  
  1129. 1. **Google Login**: Like showing your ID card
  1130. 2. **API Key**: Like a secret password
  1131. 3. **Vertex AI**: For advanced Google Cloud users
  1132.  
  1133. Here's how simple it is to check credentials:
  1134.  
  1135. ```typescript
  1136. import { validateAuth } from 'gemini-cli';
  1137.  
  1138. // Check if login is valid
  1139. const isValid = await validateAuth('google-login');
  1140. console.log(isValid); // true or false
  1141. ```
  1142.  
  1143. ## How Authentication Works
  1144.  
  1145. When someone uses your app, here's what happens:
  1146.  
  1147. ```mermaid
  1148. sequenceDiagram
  1149. participant User as User
  1150. participant Auth as Auth System
  1151. participant Google as Google Servers
  1152.  
  1153. User->>Auth: Tries to use Gemini
  1154. Auth->>Auth: Checks saved credentials
  1155. Auth->>Google: Verifies with Google (if needed)
  1156. Google-->>Auth: Returns verification
  1157. Auth->>User: Grants or denies access
  1158. ```
  1159.  
  1160. ## Real-World Implementation
  1161.  
  1162. Let's look at how we validate different login methods (from `packages/cli/src/config/auth.ts`):
  1163.  
  1164. ```typescript
  1165. function validateAuthMethod(method) {
  1166. if (method === 'google-login') {
  1167. return true; // Google handles verification
  1168. }
  1169.  
  1170. if (method === 'api-key') {
  1171. return checkApiKeyExists(); // Looks for API key
  1172. }
  1173. }
  1174. ```
  1175.  
  1176. Key parts:
  1177. - Different checks for each login type
  1178. - Simple true/false responses
  1179. - Handles missing credentials
  1180.  
  1181. ## Keeping Sessions Secure
  1182.  
  1183. The system also manages ongoing access:
  1184.  
  1185. ```typescript
  1186. // Check if session is still valid
  1187. function checkSession() {
  1188. if (session.expired) {
  1189. logoutUser(); // Automatic logout
  1190. }
  1191. }
  1192. ```
  1193.  
  1194. Common security features:
  1195. - Automatic logout after timeout
  1196. - Token refreshing
  1197. - Error handling for invalid sessions
  1198.  
  1199. ## What's Next?
  1200.  
  1201. Now you understand how authentication keeps your app secure! In [Chapter 9: Sandbox System](09_sandbox_system_.md), we'll explore how Gemini runs code safely.
  1202.  
  1203. > Pro Tip: Try adding console logs to see when authentication checks happen!
  1204.  
  1205. ---
  1206.  
  1207. # Chapter 9: Sandbox System
  1208.  
  1209. Welcome back! In [Chapter 8: Authentication System](08_authentication_system_.md), we learned how to keep your CLI app secure. Now, let's explore another safety feature - the **Sandbox System** - which acts like a protective bubble around risky operations.
  1210.  
  1211. ## Why Do We Need a Sandbox?
  1212.  
  1213. Imagine you're teaching a child to cook. You wouldn't let them use sharp knives right away - you'd give them safe plastic tools first. The Sandbox System works similarly for your CLI app:
  1214.  
  1215. - It creates a safe space to run potentially dangerous code
  1216. - If something goes wrong, it won't affect your main system
  1217. - You can test new features without worrying about breaking things
  1218.  
  1219. ## How the Sandbox Works
  1220.  
  1221. Think of the sandbox like a playground with safety rules:
  1222. 1. **Isolation**: Code runs in a separate environment
  1223. 2. **Protection**: Can't accidentally delete your files
  1224. 3. **Control**: You decide what's allowed
  1225.  
  1226. Here's a simple example of running code in a sandbox:
  1227.  
  1228. ```typescript
  1229. import { runInSandbox } from 'gemini-cli';
  1230.  
  1231. // This runs safely in the sandbox
  1232. const result = await runInSandbox(() => {
  1233. return "Hello from the sandbox!";
  1234. });
  1235.  
  1236. console.log(result); // "Hello from the sandbox!"
  1237. ```
  1238.  
  1239. ## Behind the Scenes
  1240.  
  1241. When you use the sandbox, here's what happens:
  1242.  
  1243. ```mermaid
  1244. sequenceDiagram
  1245. participant You as Your Code
  1246. participant Sandbox as Sandbox System
  1247. participant Host as Your Computer
  1248.  
  1249. You->>Sandbox: Runs code
  1250. Sandbox->>Sandbox: Creates safe environment
  1251. Sandbox->>Host: Only allows approved actions
  1252. Sandbox-->>You: Returns result
  1253. Sandbox->>Sandbox: Cleans up safely
  1254. ```
  1255.  
  1256. ## Real-World Usage
  1257.  
  1258. In our actual code (like `packages/cli/src/utils/sandbox.ts`), the sandbox can do more advanced things:
  1259.  
  1260. ```typescript
  1261. // Run a command safely
  1262. await sandbox.executeCommand('ls', {
  1263. allowFileAccess: true,
  1264. timeout: 5000 // 5 second limit
  1265. });
  1266. ```
  1267.  
  1268. Key safety features:
  1269. - Time limits to prevent infinite loops
  1270. - File access controls
  1271. - Network restrictions
  1272.  
  1273. ## Common Sandbox Patterns
  1274.  
  1275. You'll often see these sandbox uses:
  1276. 1. **Testing New Code**: Try features safely
  1277. 2. **Running User Scripts**: Execute untrusted code
  1278. 3. **File Operations**: Prevent accidental deletions
  1279.  
  1280. ## What's Next?
  1281.  
  1282. Now you understand how the Sandbox System keeps your CLI app safe! In [Chapter 10: Sandboxing System](10_sandboxing_system_.md), we'll explore more advanced sandboxing techniques.
  1283.  
  1284. > Pro Tip: Try adding `console.log` inside a sandbox to see how it isolates your code!
  1285.  
  1286. ---
  1287.  
  1288. # Chapter 10: Sandboxing System
  1289.  
  1290. Welcome back! In [Chapter 9: Sandbox System](09_sandbox_system_.md), we learned how to run code safely in a protected environment. Now, let's explore the **Sandboxing System** - like putting your code in a protective bubble that keeps your computer safe!
  1291.  
  1292. ## Why Do We Need Sandboxing?
  1293.  
  1294. Imagine you're letting a friend use your computer. You wouldn't give them full access - you'd create a special guest account with limited permissions. That's exactly what sandboxing does for untrusted code:
  1295.  
  1296. - Runs code in an isolated space
  1297. - Prevents access to your important files
  1298. - Stops harmful network requests
  1299. - Still lets the code do its job safely
  1300.  
  1301. ## Meet the Sandbox Types
  1302.  
  1303. Our system offers two main ways to sandbox code:
  1304.  
  1305. 1. **macOS Seatbelt**: Like a strict parent watching over a child (only works on Mac)
  1306. 2. **Container-Based**: Like putting the code in a sealed box (works everywhere)
  1307.  
  1308. Here's how simple it is to use:
  1309.  
  1310. ```typescript
  1311. import { runSandboxed } from 'gemini-cli';
  1312.  
  1313. // Run code safely in a sandbox
  1314. const result = await runSandboxed(() => {
  1315. return "I'm safe inside the sandbox!";
  1316. });
  1317. console.log(result); // "I'm safe inside the sandbox!"
  1318. ```
  1319.  
  1320. ## How Sandboxing Works
  1321.  
  1322. When you run sandboxed code, here's what happens:
  1323.  
  1324. ```mermaid
  1325. sequenceDiagram
  1326. participant You as Your Code
  1327. participant Sandbox as Sandbox System
  1328. participant Computer as Your Computer
  1329.  
  1330. You->>Sandbox: Runs code
  1331. Sandbox->>Sandbox: Creates protective bubble
  1332. Sandbox->>Computer: Only allows safe actions
  1333. Sandbox-->>You: Returns result
  1334. Sandbox->>Sandbox: Cleans up safely
  1335. ```
  1336.  
  1337. ## Real-World Sandboxing
  1338.  
  1339. Let's look at how we actually set up a sandbox (from `packages/cli/src/utils/sandbox.ts`):
  1340.  
  1341. ```typescript
  1342. // Simple file access sandbox
  1343. const safeFileAccess = {
  1344. read: ['/safe-folder'], // Can only read here
  1345. write: ['/temp-folder'] // Can only write here
  1346. };
  1347.  
  1348. await runSandboxed(() => {
  1349. // This would fail outside the allowed folders
  1350. fs.readFile('/safe-folder/notes.txt');
  1351. }, { restrictions: safeFileAccess });
  1352. ```
  1353.  
  1354. Key safety features:
  1355. - Explicit file access rules
  1356. - Network restrictions
  1357. - Time limits on execution
  1358.  
  1359. ## Common Sandboxing Uses
  1360.  
  1361. You'll often use sandboxing for:
  1362. 1. **User Plugins**: Let users add features safely
  1363. 2. **Code Evaluation**: Run dynamic code safely
  1364. 3. **File Operations**: Prevent accidental deletions
  1365.  
  1366. ## What's Next?
  1367.  
  1368. Now you understand how sandboxing keeps your CLI app secure! In [Chapter 11: Tool Registry](11_tool_registry_.md), we'll learn how to manage all the tools your app can use.
  1369.  
  1370. > Pro Tip: Try sandboxing a simple file read operation to see the protection in action!
  1371.  
  1372. ---
  1373.  
  1374. # Chapter 11: Tool Registry
  1375.  
  1376. Welcome back! In [Chapter 10: Sandboxing System](10_sandboxing_system_.md), we learned how to run code safely. Now, let's meet the **Tool Registry** - your CLI app's very own tool organizer, like a handy toolbelt that keeps all your tools neatly arranged and ready to use!
  1377.  
  1378. ## Why Do We Need a Tool Registry?
  1379.  
  1380. Imagine you're a carpenter with dozens of tools. Without organization, you'd waste time searching for the right hammer or screwdriver. The Tool Registry solves this problem by:
  1381.  
  1382. 1. Keeping track of all available tools
  1383. 2. Making tools easy to find when needed
  1384. 3. Providing instructions for each tool
  1385.  
  1386. For example, when you type `gemini search "best pizza places"`, the Tool Registry helps find the "web search" tool to get your results!
  1387.  
  1388. ## Meet the Tool Organizer
  1389.  
  1390. The Tool Registry has three main jobs:
  1391.  
  1392. 1. **Registration**: Adding new tools to the collection
  1393. 2. **Discovery**: Finding tools automatically (even remote ones!)
  1394. 3. **Access**: Providing tool details when needed
  1395.  
  1396. Here's how simple it is to register a tool:
  1397.  
  1398. ```typescript
  1399. import { ToolRegistry } from 'gemini-cli';
  1400.  
  1401. // Create a registry
  1402. const registry = new ToolRegistry();
  1403.  
  1404. // Register a simple tool
  1405. registry.registerTool({
  1406. name: "greet",
  1407. description: "Says hello",
  1408. execute: () => "Hello there!"
  1409. });
  1410. ```
  1411.  
  1412. This adds a new "greet" tool to your registry that says hello when called.
  1413.  
  1414. ## How Tools Get Discovered
  1415.  
  1416. The Tool Registry can also find tools automatically:
  1417.  
  1418. ```typescript
  1419. // Discover tools from your project
  1420. await registry.discoverTools();
  1421. ```
  1422.  
  1423. This looks for special tool configuration files in your project and adds any tools it finds!
  1424.  
  1425. ## Behind the Scenes
  1426.  
  1427. When you use a tool, here's what happens:
  1428.  
  1429. ```mermaid
  1430. sequenceDiagram
  1431. participant You as You
  1432. participant Registry as Tool Registry
  1433. participant Tool as The Tool
  1434.  
  1435. You->>Registry: "Use the search tool"
  1436. Registry->>Tool: Finds and activates
  1437. Tool->>Registry: Returns results
  1438. Registry->>You: Shows pizza places
  1439. ```
  1440.  
  1441. ## Real-World Implementation
  1442.  
  1443. In our actual code (like `packages/core/src/tools/tool-registry.ts`), the registry does more advanced things:
  1444.  
  1445. ```typescript
  1446. class ToolRegistry {
  1447. private tools = new Map(); // Stores all tools
  1448.  
  1449. registerTool(tool) {
  1450. this.tools.set(tool.name, tool); // Add to storage
  1451. }
  1452.  
  1453. getTool(name) {
  1454. return this.tools.get(name); // Find by name
  1455. }
  1456. }
  1457. ```
  1458.  
  1459. Key parts:
  1460. - Uses a `Map` to store tools efficiently
  1461. - Simple methods to add and find tools
  1462. - Handles duplicate tools gracefully
  1463.  
  1464. ## Working with Remote Tools
  1465.  
  1466. The registry can even manage tools from remote servers (called MCP tools):
  1467.  
  1468. ```typescript
  1469. // Connect to remote tool server
  1470. await discoverMcpTools(serverConfig, registry);
  1471. ```
  1472.  
  1473. This lets your CLI use powerful tools hosted elsewhere while keeping everything organized in one place!
  1474.  
  1475. ## What's Next?
  1476.  
  1477. Now you understand how the Tool Registry keeps your CLI's tools organized! In [Chapter 12: Tool System](12_tool_system_.md), we'll explore how these tools actually work when you use them.
  1478.  
  1479. > Pro Tip: Try registering a simple tool that returns the current time to see the registry in action!
  1480.  
  1481. ---
  1482.  
  1483. # Chapter 12: Tool System
  1484.  
  1485. Welcome back! In [Chapter 11: Tool Registry](11_tool_registry_.md), we learned how to organize all the tools in your CLI app. Now, let's explore the **Tool System** - the magic that makes these tools actually work, like the engine in a Swiss Army knife that powers all its different functions!
  1486.  
  1487. ## Why Do We Need Tools?
  1488.  
  1489. Imagine you're building a robot helper. You want it to:
  1490. - Search the web when you ask questions
  1491. - Edit files when you need changes
  1492. - List folders when you explore
  1493.  
  1494. Each of these is a different "tool" your robot can use. The Tool System is what lets your CLI app switch between these different functions easily.
  1495.  
  1496. ## Meet the Basic Tools
  1497.  
  1498. Here are some simple tools you might use:
  1499.  
  1500. 1. **File Editor**: Changes text in files
  1501. 2. **Directory Lister**: Shows folder contents
  1502. 3. **Web Searcher**: Finds information online
  1503.  
  1504. Each tool follows the same simple pattern:
  1505.  
  1506. ```typescript
  1507. interface Tool {
  1508. name: string;
  1509. description: string;
  1510. execute(params): Promise<Result>;
  1511. }
  1512. ```
  1513.  
  1514. This means every tool has:
  1515. - A name (like "web_search")
  1516. - A description (what it does)
  1517. - An execute method (how to run it)
  1518.  
  1519. ## A Simple Example
  1520.  
  1521. Let's create a basic "greet" tool:
  1522.  
  1523. ```typescript
  1524. const greetTool = {
  1525. name: "greet",
  1526. description: "Says hello to someone",
  1527. execute: ({name}) => `Hello ${name}!`
  1528. };
  1529.  
  1530. // Using the tool:
  1531. const result = await greetTool.execute({name: "Alice"});
  1532. console.log(result); // "Hello Alice!"
  1533. ```
  1534.  
  1535. This shows how simple tools can be - just a name, description, and action!
  1536.  
  1537. ## How Tools Work Together
  1538.  
  1539. When you use a tool, here's what happens:
  1540.  
  1541. ```mermaid
  1542. sequenceDiagram
  1543. participant You as You
  1544. participant System as Tool System
  1545. participant Tool as The Tool
  1546.  
  1547. You->>System: "Use the search tool"
  1548. System->>Tool: Finds and runs
  1549. Tool->>System: Returns results
  1550. System->>You: Shows information
  1551. ```
  1552.  
  1553. ## Real-World Tools
  1554.  
  1555. Let's look at part of our actual file editor tool (from `packages/core/src/tools/edit.ts`):
  1556.  
  1557. ```typescript
  1558. class EditTool {
  1559. name = "edit_file";
  1560. description = "Edits text in files";
  1561.  
  1562. execute({filePath, oldText, newText}) {
  1563. // 1. Read the file
  1564. const content = fs.readFile(filePath);
  1565. // 2. Make changes
  1566. const newContent = content.replace(oldText, newText);
  1567. // 3. Save changes
  1568. fs.writeFile(filePath, newContent);
  1569. return "File updated!";
  1570. }
  1571. }
  1572. ```
  1573.  
  1574. Key parts:
  1575. 1. It reads the original file
  1576. 2. Makes the requested changes
  1577. 3. Saves the updated file
  1578.  
  1579. ## Common Tool Patterns
  1580.  
  1581. You'll often see tools that:
  1582. 1. **Read Files**: Like our directory lister
  1583. 2. **Modify Content**: Like the file editor
  1584. 3. **Fetch Data**: Like the web searcher
  1585.  
  1586. Each follows the same basic interface but does different work inside!
  1587.  
  1588. ## What's Next?
  1589.  
  1590. Now you understand how the Tool System powers all your CLI's functions! In [Chapter 13: Tool Execution System](13_tool_execution_system_.md), we'll learn how tools actually get run when you need them.
  1591.  
  1592. > Pro Tip: Try creating a simple tool that returns the current time to see the system in action!
  1593.  
  1594. ---
  1595.  
  1596. # Chapter 13: Tool Execution System
  1597.  
  1598. Welcome back! In [Chapter 12: Tool System](12_tool_system_.md), we learned how tools work in your CLI app. Now, let's meet the **Tool Execution System** - your app's personal assistant that carefully manages every tool operation from start to finish!
  1599.  
  1600. ## Why Do We Need Tool Execution?
  1601.  
  1602. Imagine you're baking cookies with a friend. You wouldn't just throw ingredients together randomly - you'd follow steps:
  1603. 1. Check you have everything (confirmation)
  1604. 2. Mix ingredients carefully (execution)
  1605. 3. Show the delicious results (display)
  1606.  
  1607. The Tool Execution System does exactly this for your CLI tools:
  1608. 1. **Confirms** if tools should run
  1609. 2. **Executes** them safely
  1610. 3. **Shows** the results clearly
  1611.  
  1612. ## Meet the Three-Step Process
  1613.  
  1614. Every tool call follows this simple pattern:
  1615.  
  1616. ```typescript
  1617. // 1. Confirm the tool should run
  1618. const shouldRun = await confirmToolUse("search");
  1619.  
  1620. // 2. Execute if approved
  1621. if (shouldRun) {
  1622. const results = await executeTool("search", {query: "pizza"});
  1623.  
  1624. // 3. Show results
  1625. displayToolResults(results);
  1626. }
  1627. ```
  1628.  
  1629. This shows the basic flow: confirm → execute → display.
  1630.  
  1631. ## Behind the Scenes
  1632.  
  1633. When you use a tool, here's what happens:
  1634.  
  1635. ```mermaid
  1636. sequenceDiagram
  1637. participant You as You
  1638. participant Confirm as Confirmation
  1639. participant Tool as The Tool
  1640. participant Display as Results
  1641.  
  1642. You->>Confirm: "Can I use search?"
  1643. Confirm-->>You: "Yes!"
  1644. You->>Tool: Runs search for "pizza"
  1645. Tool-->>Display: Returns pizza places
  1646. Display->>You: Shows delicious results
  1647. ```
  1648.  
  1649. ## Real-World Implementation
  1650.  
  1651. Let's look at how we actually confirm tool use (from `packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx`):
  1652.  
  1653. ```typescript
  1654. // Simple confirmation options
  1655. const options = [
  1656. { label: "Yes, run once", value: "once" },
  1657. { label: "No, cancel", value: "cancel" }
  1658. ];
  1659.  
  1660. // Show confirmation dialog
  1661. function confirmToolUse() {
  1662. return showMenu(options); // Returns "once" or "cancel"
  1663. }
  1664. ```
  1665.  
  1666. Key parts:
  1667. - Simple menu with choices
  1668. - Clear options for users
  1669. - Returns the user's decision
  1670.  
  1671. ## Executing Tools Safely
  1672.  
  1673. After confirmation, tools run in a protected way:
  1674.  
  1675. ```typescript
  1676. async function executeTool(name, params) {
  1677. try {
  1678. // Run in protected environment
  1679. return await safeRun(() => tools[name].execute(params));
  1680. } catch (error) {
  1681. return "Oops! Tool failed: " + error.message;
  1682. }
  1683. }
  1684. ```
  1685.  
  1686. Safety features:
  1687. - Runs in protected space
  1688. - Catches errors gracefully
  1689. - Always returns something useful
  1690.  
  1691. ## Displaying Results
  1692.  
  1693. Finally, we show results clearly:
  1694.  
  1695. ```typescript
  1696. function displayToolResults(results) {
  1697. console.log("=== Tool Results ===");
  1698. console.log(results);
  1699. console.log("===================");
  1700. }
  1701. ```
  1702.  
  1703. This simple display helps users understand what happened.
  1704.  
  1705. ## Common Patterns
  1706.  
  1707. You'll often see tools that:
  1708. 1. **Ask First**: Like our search tool confirmation
  1709. 2. **Run Safely**: Protected execution
  1710. 3. **Show Clearly**: Formatted results
  1711.  
  1712. ## What's Next?
  1713.  
  1714. Now you understand how tools get executed safely in your CLI app! In [Chapter 14: Tool Execution](14_tool_execution_.md), we'll explore more advanced execution techniques.
  1715.  
  1716. > Pro Tip: Try adding a confirmation step to a simple tool to see the execution system in action!
  1717.  
  1718. ---
  1719.  
  1720. # Chapter 14: Tool Execution
  1721.  
  1722. Welcome back! In [Chapter 13: Tool Execution System](13_tool_execution_system_.md), we learned how tools get scheduled and managed. Now, let's meet **Tool Execution** - the actual "worker" that runs your CLI tools, like a skilled chef who takes recipes and turns them into delicious meals!
  1723.  
  1724. ## Why Do We Need Tool Execution?
  1725.  
  1726. Imagine you're building a robot helper. You've given it tools (like a screwdriver and a paintbrush), but now you need it to actually *use* those tools when you ask. That's exactly what Tool Execution does:
  1727.  
  1728. 1. Takes a tool request ("Paint the wall blue")
  1729. 2. Gets the right tool (paintbrush)
  1730. 3. Executes the task carefully
  1731. 4. Shows you the beautiful blue wall!
  1732.  
  1733. ## Meet the Simple Execution Flow
  1734.  
  1735. Every tool execution follows these easy steps:
  1736.  
  1737. ```typescript
  1738. // 1. Get the tool you need
  1739. const paintTool = getTool('paintbrush');
  1740.  
  1741. // 2. Use the tool with your instructions
  1742. const result = await paintTool.execute({color: 'blue', wall: 'north'});
  1743.  
  1744. // 3. See what happened!
  1745. console.log(result); // "Painted north wall blue!"
  1746. ```
  1747.  
  1748. This shows the basic flow: find tool → execute → get results.
  1749.  
  1750. ## Behind the Scenes
  1751.  
  1752. When you execute a tool, here's what happens:
  1753.  
  1754. ```mermaid
  1755. sequenceDiagram
  1756. participant You as You
  1757. participant Registry as Tool Registry
  1758. participant Tool as The Tool
  1759.  
  1760. You->>Registry: "I need the paintbrush"
  1761. Registry->>Tool: Finds paintbrush tool
  1762. Tool->>Tool: Paints the wall
  1763. Tool-->>You: "Done painting!"
  1764. ```
  1765.  
  1766. ## Two Ways to Run Tools
  1767.  
  1768. Our system offers two execution styles:
  1769.  
  1770. 1. **Interactive Mode**: Asks for confirmation first (like a careful assistant)
  1771. 2. **Non-Interactive Mode**: Runs immediately (like an automatic machine)
  1772.  
  1773. Here's how they differ:
  1774.  
  1775. ```typescript
  1776. // Interactive execution (asks first)
  1777. await runInteractive('paintbrush', {color: 'blue'});
  1778.  
  1779. // Non-interactive (runs right away)
  1780. await runNonInteractive('paintbrush', {color: 'blue'});
  1781. ```
  1782.  
  1783. ## Real-World Execution
  1784.  
  1785. Let's look at how we actually execute tools (from `packages/core/src/core/nonInteractiveToolExecutor.ts`):
  1786.  
  1787. ```typescript
  1788. async function executeTool(toolName, params) {
  1789. // 1. Find the tool
  1790. const tool = getTool(toolName);
  1791.  
  1792. // 2. Run it safely
  1793. try {
  1794. return await tool.execute(params);
  1795. } catch (error) {
  1796. return `Oops! ${error.message}`;
  1797. }
  1798. }
  1799. ```
  1800.  
  1801. Key parts:
  1802. 1. Looks up the tool by name
  1803. 2. Runs it in a protected way
  1804. 3. Handles errors gracefully
  1805.  
  1806. ## Watching Tools Work
  1807.  
  1808. Some tools can even show progress while running:
  1809.  
  1810. ```typescript
  1811. // See live updates from the tool
  1812. await runTool('download', {file: 'cat.jpg'}, (progress) => {
  1813. console.log(`${progress}% downloaded...`);
  1814. });
  1815. ```
  1816.  
  1817. This lets you see the download percentage update in real time!
  1818.  
  1819. ## Common Patterns
  1820.  
  1821. You'll often see tools that:
  1822. 1. **Read Files**: Like our directory lister
  1823. 2. **Modify Content**: Like the file editor
  1824. 3. **Fetch Data**: Like the web searcher
  1825.  
  1826. Each follows the same simple execution pattern.
  1827.  
  1828. ## What's Next?
  1829.  
  1830. Now you understand how tools actually run in your CLI app! In [Chapter 15: File System Operations](15_file_system_operations_.md), we'll explore how tools can safely work with your computer's files.
  1831.  
  1832. > Pro Tip: Try creating a simple tool that counts files in a folder to see execution in action!
  1833.  
  1834. ---
  1835.  
  1836. # Chapter 15: File System Operations
  1837.  
  1838. Welcome back! In [Chapter 14: Tool Execution](14_tool_execution_.md), we learned how tools run in your CLI app. Now, let's meet your app's **digital librarian** - the File System Operations that carefully manage all interactions with your computer's files!
  1839.  
  1840. ## Why Do We Need File Operations?
  1841.  
  1842. Imagine you're organizing a library. You need to:
  1843. 1. Find books (search files)
  1844. 2. Add new books (create files)
  1845. 3. Update old books (edit files)
  1846. 4. Remove outdated books (delete files)
  1847.  
  1848. File System Operations do exactly this for your CLI app! They handle all file interactions safely and efficiently.
  1849.  
  1850. ## Meet the Basic File Operations
  1851.  
  1852. Here are the four main operations you'll use:
  1853.  
  1854. 1. **Reading Files**: Like opening a book to read its contents
  1855. 2. **Writing Files**: Like adding new pages to a notebook
  1856. 3. **Searching Files**: Like looking up books in a catalog
  1857. 4. **Managing Paths**: Like knowing exactly where each book belongs
  1858.  
  1859. ## A Simple Example
  1860.  
  1861. Let's read a file named "notes.txt":
  1862.  
  1863. ```typescript
  1864. import { readFile } from 'gemini-cli';
  1865.  
  1866. const content = await readFile('notes.txt');
  1867. console.log(content); // Shows the file's text
  1868. ```
  1869.  
  1870. This shows how easy it is to:
  1871. 1. Import the file operation
  1872. 2. Read the file
  1873. 3. Use its contents
  1874.  
  1875. ## How File Operations Work
  1876.  
  1877. When you read a file, here's what happens behind the scenes:
  1878.  
  1879. ```mermaid
  1880. sequenceDiagram
  1881. participant You as You
  1882. participant FS as File System
  1883. participant File as Your File
  1884.  
  1885. You->>FS: "Please read notes.txt"
  1886. FS->>File: Finds the file
  1887. File-->>FS: Returns the content
  1888. FS->>You: Gives you the text
  1889. ```
  1890.  
  1891. ## Safety First!
  1892.  
  1893. File operations include important safety checks:
  1894. 1. **Path Validation**: Ensures files are in allowed folders
  1895. 2. **Permission Checks**: Verifies you can access the file
  1896. 3. **Git Ignore**: Respects .gitignore rules automatically
  1897.  
  1898. Here's how we safely write to a file:
  1899.  
  1900. ```typescript
  1901. import { writeFile } from 'gemini-cli';
  1902.  
  1903. await writeFile('diary.txt', 'Dear diary...', {
  1904. safe: true // Enables all safety checks
  1905. });
  1906. ```
  1907.  
  1908. ## Real-World Implementation
  1909.  
  1910. Let's look at how we actually read files (from `packages/core/src/tools/read-file.ts`):
  1911.  
  1912. ```typescript
  1913. async function readFileSafe(path) {
  1914. // 1. Check if path is allowed
  1915. if (!isValidPath(path)) throw Error("Invalid path");
  1916.  
  1917. // 2. Check Git ignore rules
  1918. if (shouldIgnore(path)) return null;
  1919.  
  1920. // 3. Read the file
  1921. return fs.readFile(path);
  1922. }
  1923. ```
  1924.  
  1925. Key safety steps:
  1926. 1. Path validation
  1927. 2. Git ignore check
  1928. 3. Actual file reading
  1929.  
  1930. ## Common Patterns
  1931.  
  1932. You'll often use these file operations together:
  1933. 1. **Search → Read**: Find a file then read it
  1934. 2. **Read → Edit → Write**: Modify a file's content
  1935. 3. **Check → Create**: Make new files safely
  1936.  
  1937. ## What's Next?
  1938.  
  1939. Now you understand how your CLI app works with files safely! In [Chapter 16: File Operations](16_file_operations_.md), we'll explore more advanced ways to handle files.
  1940.  
  1941. > Pro Tip: Try creating a simple note-taking tool that saves and reads from a text file!
  1942.  
  1943. ---
  1944.  
  1945. # Chapter 16: File Operations
  1946.  
  1947. Welcome back! In [Chapter 15: File System Operations](15_file_system_operations_.md), we learned how your CLI app interacts with files. Now, let's meet your app's **digital librarian** - the File Operations that carefully handle all your file reading, writing, and searching needs!
  1948.  
  1949. ## Why Do We Need File Operations?
  1950.  
  1951. Imagine you're organizing your digital bookshelf. You need to:
  1952. 1. Find a book (search files)
  1953. 2. Read a book (read files)
  1954. 3. Add notes to a book (write files)
  1955. 4. Keep everything organized (manage files)
  1956.  
  1957. File Operations do exactly this for your CLI app! They provide safe, easy ways to work with files, just like a librarian helps you manage books.
  1958.  
  1959. ## Meet the Three Main Operations
  1960.  
  1961. Here are the key things you can do:
  1962.  
  1963. 1. **Reading Files**: Like opening a book to read its contents
  1964. 2. **Writing Files**: Like adding new pages to your notebook
  1965. 3. **Searching Files**: Like looking up books in the library catalog
  1966.  
  1967. ## A Simple Example
  1968.  
  1969. Let's read a file named "notes.txt":
  1970.  
  1971. ```typescript
  1972. import { readFile } from 'gemini-cli';
  1973.  
  1974. const content = await readFile('notes.txt');
  1975. console.log(content); // Shows the file's text
  1976. ```
  1977.  
  1978. This simple code:
  1979. 1. Imports the file operation
  1980. 2. Reads the file
  1981. 3. Shows its contents
  1982.  
  1983. ## How File Operations Work
  1984.  
  1985. When you read a file, here's what happens behind the scenes:
  1986.  
  1987. ```mermaid
  1988. sequenceDiagram
  1989. participant You as You
  1990. participant FS as File System
  1991. participant File as Your File
  1992.  
  1993. You->>FS: "Please read notes.txt"
  1994. FS->>File: Finds the file
  1995. File-->>FS: Returns the content
  1996. FS->>You: Gives you the text
  1997. ```
  1998.  
  1999. ## Safety First!
  2000.  
  2001. File operations include important safety checks:
  2002. 1. **Path Validation**: Ensures files are in allowed folders
  2003. 2. **Permission Checks**: Verifies you can access the file
  2004. 3. **Git Ignore**: Respects .gitignore rules automatically
  2005.  
  2006. Here's how we safely write to a file:
  2007.  
  2008. ```typescript
  2009. import { writeFile } from 'gemini-cli';
  2010.  
  2011. await writeFile('diary.txt', 'Dear diary...', {
  2012. safe: true // Enables all safety checks
  2013. });
  2014. ```
  2015.  
  2016. ## Real-World Implementation
  2017.  
  2018. Let's peek at how reading files works internally (simplified from our actual code):
  2019.  
  2020. ```typescript
  2021. async function readFileSafe(path) {
  2022. // 1. Check if path is allowed
  2023. if (!isValidPath(path)) throw Error("Invalid path");
  2024.  
  2025. // 2. Read the file
  2026. return fs.readFile(path);
  2027. }
  2028. ```
  2029.  
  2030. Key safety steps:
  2031. 1. Checks if the path is valid
  2032. 2. Only then reads the file
  2033.  
  2034. ## Common Patterns
  2035.  
  2036. You'll often use these operations together:
  2037. 1. **Search → Read**: Find a file then read it
  2038. 2. **Read → Edit → Write**: Modify a file's content
  2039. 3. **Check → Create**: Make new files safely
  2040.  
  2041. ## What's Next?
  2042.  
  2043. Now you understand how to safely work with files in your CLI app! In [Chapter 17: File Discovery](17_file_discovery_.md), we'll learn how to efficiently find files when you need them.
  2044.  
  2045. > Pro Tip: Try creating a simple note-taking tool that saves and reads from a text file!
  2046.  
  2047. ---
  2048.  
  2049. # Chapter 17: File Discovery
  2050.  
  2051. Welcome back! In [Chapter 16: File Operations](16_file_operations_.md), we learned how to work with individual files. Now, let's meet your CLI app's **smart metal detector** - the File Discovery system that helps find exactly the files you need while automatically skipping the ones you don't!
  2052.  
  2053. ## Why Do We Need File Discovery?
  2054.  
  2055. Imagine you're searching for treasure in your backyard. You wouldn't want your metal detector to beep for every soda can and nail - just the valuable items! File Discovery works similarly:
  2056.  
  2057. 1. It searches through folders to find files
  2058. 2. Automatically skips files listed in `.gitignore` (like temporary files)
  2059. 3. Also respects `.geminiignore` for project-specific exclusions
  2060. 4. Returns only the files you actually care about
  2061.  
  2062. ## Meet the Smart File Finder
  2063.  
  2064. File Discovery has two main jobs:
  2065.  
  2066. 1. **Finding Files**: Locates all files in a folder and its subfolders
  2067. 2. **Filtering Files**: Removes files that should be ignored
  2068.  
  2069. Here's how simple it is to use:
  2070.  
  2071. ```typescript
  2072. import { discoverFiles } from 'gemini-cli';
  2073.  
  2074. // Find all non-ignored files in current folder
  2075. const files = await discoverFiles('.');
  2076. console.log(files); // ["src/index.ts", "README.md", ...]
  2077. ```
  2078.  
  2079. This shows all files in your project, automatically skipping ones listed in `.gitignore` or `.geminiignore`.
  2080.  
  2081. ## How File Discovery Works
  2082.  
  2083. When you search for files, here's what happens behind the scenes:
  2084.  
  2085. ```mermaid
  2086. sequenceDiagram
  2087. participant You as You
  2088. participant Finder as File Discovery
  2089. participant Git as .gitignore
  2090. participant Gemini as .geminiignore
  2091.  
  2092. You->>Finder: "Find me files!"
  2093. Finder->>Git: Checks ignore rules
  2094. Git-->>Finder: "Skip these files"
  2095. Finder->>Gemini: Checks ignore rules
  2096. Gemini-->>Finder: "Also skip these"
  2097. Finder->>You: Returns filtered files
  2098. ```
  2099.  
  2100. ## Real-World Usage
  2101.  
  2102. Let's look at how we actually filter files (simplified from our code):
  2103.  
  2104. ```typescript
  2105. function filterFiles(allFiles) {
  2106. return allFiles.filter(file => {
  2107. // Skip if in .gitignore
  2108. if (isGitIgnored(file)) return false;
  2109.  
  2110. // Skip if in .geminiignore
  2111. if (isGeminiIgnored(file)) return false;
  2112.  
  2113. // Otherwise keep it
  2114. return true;
  2115. });
  2116. }
  2117. ```
  2118.  
  2119. Key parts:
  2120. 1. Takes a list of all files
  2121. 2. Checks each against ignore rules
  2122. 3. Returns only non-ignored files
  2123.  
  2124. ## Customizing File Discovery
  2125.  
  2126. You can control how strict the filtering is:
  2127.  
  2128. ```typescript
  2129. // Find files while ignoring .gitignore rules
  2130. const files = await discoverFiles('.', {
  2131. respectGitIgnore: false // Show all files
  2132. });
  2133. ```
  2134.  
  2135. This lets you see everything when you need to, like a metal detector in "show all" mode.
  2136.  
  2137. ## Common Patterns
  2138.  
  2139. You'll often use File Discovery to:
  2140. 1. **Find Source Files**: Locate all `.ts` files for processing
  2141. 2. **List Documentation**: Get all `.md` files for building help
  2142. 3. **Search Projects**: Look for specific file patterns
  2143.  
  2144. ## What's Next?
  2145.  
  2146. Now you understand how to smartly find files in your projects! In [Chapter 18: File Reference Processor](18_file_reference_processor_.md), we'll learn how to work with the files we've discovered.
  2147.  
  2148. > Pro Tip: Try creating a `.geminiignore` file to hide temporary files from your searches!
  2149.  
  2150. ---
  2151.  
  2152. # Chapter 18: File Reference Processor
  2153.  
  2154. Welcome back! In [Chapter 17: File Discovery](17_file_discovery_.md), we learned how to find files in your project. Now, let's meet your CLI's **helpful librarian** - the File Reference Processor that automatically fetches file contents when you mention them with `@` symbols, just like asking a librarian for specific books!
  2155.  
  2156. ## Why Do We Need File References?
  2157.  
  2158. Imagine you're writing an email and want to include a report. Instead of copying the whole document, you might say "See attached: annual_report.pdf". The File Reference Processor does something similar for your CLI:
  2159.  
  2160. 1. You type: `@notes.txt` in your query
  2161. 2. The processor finds and reads the file
  2162. 3. It automatically includes the contents in your request
  2163.  
  2164. This saves you from manually opening and copying files!
  2165.  
  2166. ## Meet the @ Command
  2167.  
  2168. The magic happens when you use `@` before a filename:
  2169.  
  2170. ```typescript
  2171. // Ask about a file's content
  2172. const query = "What does @config.json say about timeout?";
  2173. ```
  2174.  
  2175. The processor will:
  2176. 1. Find `config.json`
  2177. 2. Read its contents
  2178. 3. Include them with your question
  2179.  
  2180. ## How It Works Behind the Scenes
  2181.  
  2182. When you use an `@` reference, here's what happens:
  2183.  
  2184. ```mermaid
  2185. sequenceDiagram
  2186. participant You as You
  2187. participant Processor as File Processor
  2188. participant Files as Your Files
  2189.  
  2190. You->>Processor: "Read @notes.txt"
  2191. Processor->>Files: Finds notes.txt
  2192. Files-->>Processor: Returns content
  2193. Processor->>You: Includes text with query
  2194. ```
  2195.  
  2196. ## A Simple Example
  2197.  
  2198. Let's see how to use this in code:
  2199.  
  2200. ```typescript
  2201. import { processQuery } from 'gemini-cli';
  2202.  
  2203. // The processor handles @ automatically
  2204. const response = await processQuery("Explain @example.js");
  2205. ```
  2206.  
  2207. This will:
  2208. 1. Find `example.js`
  2209. 2. Add its code to your question
  2210. 3. Get an explanation from Gemini
  2211.  
  2212. ## Real-World Implementation
  2213.  
  2214. Here's a simplified version of how we process `@` commands:
  2215.  
  2216. ```typescript
  2217. function handleAtCommand(query) {
  2218. // Find all @ references
  2219. const atFiles = query.match(/@(\S+)/g);
  2220.  
  2221. // For each found file
  2222. atFiles.forEach(file => {
  2223. const content = readFile(file.substring(1));
  2224. query += `\nFile ${file} contents:\n${content}`;
  2225. });
  2226.  
  2227. return query;
  2228. }
  2229. ```
  2230.  
  2231. Key steps:
  2232. 1. Finds all `@filename` references
  2233. 2. Reads each file
  2234. 3. Appends contents to the query
  2235.  
  2236. ## Safety First!
  2237.  
  2238. The processor includes important protections:
  2239. 1. Checks file permissions first
  2240. 2. Respects `.gitignore` rules
  2241. 3. Limits file size for safety
  2242.  
  2243. ## What's Next?
  2244.  
  2245. Now you understand how to easily reference files in your queries! In [Chapter 19: Configuration System](19_configuration_system_.md), we'll learn how to customize your CLI's behavior.
  2246.  
  2247. > Pro Tip: Try using `@` with different file types (like `.txt`, `.js`) to see how Gemini responds!
  2248.  
  2249. ---
  2250.  
  2251. # Chapter 19: Configuration System
  2252.  
  2253. Welcome back! In [Chapter 18: File Reference Processor](18_file_reference_processor_.md), we learned how to automatically include file contents in our queries. Now, let's meet your CLI's **personal settings manager** - the Configuration System that remembers all your preferences, just like how your phone remembers your favorite apps and wallpaper!
  2254.  
  2255. ## Why Do We Need Configuration?
  2256.  
  2257. Imagine you're setting up a new video game. You'd want to:
  2258. 1. Save your control preferences
  2259. 2. Remember your graphics settings
  2260. 3. Keep track of your progress
  2261.  
  2262. The Configuration System does exactly this for your CLI app! It stores settings like:
  2263. - Your preferred theme (dark/light mode)
  2264. - Default tools to use
  2265. - Authentication preferences
  2266.  
  2267. ## Meet the Two-Level Settings
  2268.  
  2269. The system organizes settings in two simple layers:
  2270.  
  2271. 1. **User Settings**: Your personal preferences (like your phone's wallpaper)
  2272. 2. **Workspace Settings**: Project-specific rules (like a team's coding standards)
  2273.  
  2274. Here's how simple it is to get a setting:
  2275.  
  2276. ```typescript
  2277. import { getConfig } from 'gemini-cli';
  2278.  
  2279. // Get your theme preference
  2280. const theme = getConfig('theme');
  2281. console.log(theme); // "dark" or "light"
  2282. ```
  2283.  
  2284. This shows how easy it is to access any saved setting.
  2285.  
  2286. ## How Settings Work Together
  2287.  
  2288. When you check a setting, here's what happens behind the scenes:
  2289.  
  2290. ```mermaid
  2291. sequenceDiagram
  2292. participant You as You
  2293. participant Config as Config System
  2294. participant User as User Settings
  2295. participant Workspace as Workspace Settings
  2296.  
  2297. You->>Config: "What's my theme?"
  2298. Config->>User: Checks personal settings
  2299. User-->>Config: "dark"
  2300. Config->>Workspace: Checks project settings
  2301. Workspace-->>Config: "light" (overrides)
  2302. Config->>You: "light"
  2303. ```
  2304.  
  2305. Notice how workspace settings can override user settings when needed!
  2306.  
  2307. ## A Simple Example
  2308.  
  2309. Let's set and get a configuration value:
  2310.  
  2311. ```typescript
  2312. import { setConfig, getConfig } from 'gemini-cli';
  2313.  
  2314. // Set a user preference
  2315. setConfig('theme', 'dark', 'user');
  2316.  
  2317. // Later, get the value
  2318. const theme = getConfig('theme');
  2319. console.log(theme); // "dark"
  2320. ```
  2321.  
  2322. This shows the basic flow: set → save → retrieve later.
  2323.  
  2324. ## Real-World Implementation
  2325.  
  2326. Here's how we actually handle settings internally (simplified):
  2327.  
  2328. ```typescript
  2329. class ConfigSystem {
  2330. private userSettings = {};
  2331. private workspaceSettings = {};
  2332.  
  2333. get(key) {
  2334. // Workspace settings override user settings
  2335. return this.workspaceSettings[key] || this.userSettings[key];
  2336. }
  2337.  
  2338. set(key, value, level = 'user') {
  2339. if (level === 'workspace') {
  2340. this.workspaceSettings[key] = value;
  2341. } else {
  2342. this.userSettings[key] = value;
  2343. }
  2344. }
  2345. }
  2346. ```
  2347.  
  2348. Key parts:
  2349. - Simple storage for both setting types
  2350. - Workspace settings take priority
  2351. - Easy get/set methods
  2352.  
  2353. ## Common Patterns
  2354.  
  2355. You'll often use the Configuration System to:
  2356. 1. **Remember Preferences**: Like your favorite theme
  2357. 2. **Set Defaults**: Like which tools to always enable
  2358. 3. **Configure Projects**: Like special rules for certain folders
  2359.  
  2360. ## What's Next?
  2361.  
  2362. Now you understand how your CLI remembers all its settings! In [Chapter 20: Configuration Management](20_configuration_management_.md), we'll learn how to organize and maintain these settings effectively.
  2363.  
  2364. > Pro Tip: Try setting a custom theme preference and see it persist between sessions!
  2365.  
  2366. ---
  2367.  
  2368. # Chapter 20: Configuration Management
  2369.  
  2370. Welcome back! In [Chapter 19: Configuration System](19_configuration_system_.md), we learned how your CLI app stores settings. Now, let's meet your app's **super-organized assistant** - Configuration Management that carefully loads and combines all your preferences from different places, just like a personal assistant who gathers all your notes and reminders into one perfect system!
  2371.  
  2372. ## Why Do We Need Configuration Management?
  2373.  
  2374. Imagine you're planning a party with friends. You might have:
  2375. - Your personal preferences (favorite music)
  2376. - Group decisions (shared budget)
  2377. - Venue rules (noise restrictions)
  2378.  
  2379. Configuration Management does exactly this for your CLI app! It:
  2380. 1. Collects settings from different sources
  2381. 2. Combines them smartly
  2382. 3. Gives you one perfect set of preferences to use
  2383.  
  2384. ## Meet the Three Sources
  2385.  
  2386. Your CLI app gets settings from three main places:
  2387.  
  2388. 1. **User Settings**: Your personal preferences (like your theme choice)
  2389. 2. **Workspace Settings**: Project-specific rules (like team coding standards)
  2390. 3. **Command Line**: Temporary options (like `--debug` mode)
  2391.  
  2392. Here's how simple it is to see merged settings:
  2393.  
  2394. ```typescript
  2395. import { getMergedConfig } from 'gemini-cli';
  2396.  
  2397. // Get all settings combined
  2398. const config = getMergedConfig();
  2399. console.log(config.theme); // Shows your final theme
  2400. ```
  2401.  
  2402. This gives you one complete set of preferences, no matter where they came from!
  2403.  
  2404. ## How Settings Get Merged
  2405.  
  2406. When combining settings, here's what happens behind the scenes:
  2407.  
  2408. ```mermaid
  2409. sequenceDiagram
  2410. participant You as You
  2411. participant User as User Settings
  2412. participant Workspace as Workspace
  2413. participant CLI as Command Line
  2414.  
  2415. You->>CLI: Runs with --debug
  2416. CLI->>User: Gets your preferences
  2417. User->>Workspace: Checks project rules
  2418. Workspace-->>You: Returns final settings
  2419. ```
  2420.  
  2421. Notice how command line options can override other settings!
  2422.  
  2423. ## A Simple Example
  2424.  
  2425. Let's see how settings combine:
  2426.  
  2427. ```typescript
  2428. // User settings: { theme: "dark" }
  2429. // Workspace settings: { theme: "light" }
  2430. const config = getMergedConfig();
  2431. console.log(config.theme); // "light" (workspace wins!)
  2432. ```
  2433.  
  2434. This shows how workspace settings can override your personal ones when needed.
  2435.  
  2436. ## Real-World Implementation
  2437.  
  2438. Here's a peek at how we merge settings (simplified from our code):
  2439.  
  2440. ```typescript
  2441. function mergeSettings(user, workspace, cli) {
  2442. return {
  2443. ...user, // Start with user settings
  2444. ...workspace, // Override with workspace
  2445. ...cli // Finally apply CLI options
  2446. };
  2447. }
  2448. ```
  2449.  
  2450. Key parts:
  2451. 1. Starts with user settings as base
  2452. 2. Adds workspace settings on top
  2453. 3. Finally applies command line options
  2454.  
  2455. ## Common Patterns
  2456.  
  2457. You'll often see Configuration Management:
  2458. 1. **Resolving Conflicts**: Deciding which setting wins
  2459. 2. **Validating Values**: Ensuring settings make sense
  2460. 3. **Providing Defaults**: When no setting exists
  2461.  
  2462. ## What's Next?
  2463.  
  2464. Now you understand how your CLI combines all its settings perfectly! In [Chapter 21: Config Management](21_config_management_.md), we'll learn more advanced ways to work with these configurations.
  2465.  
  2466. > Pro Tip: Try setting different themes in user vs workspace settings to see which one wins!
  2467.  
  2468. ---
  2469.  
  2470. # Chapter 21: Config Management
  2471.  
  2472. Welcome back! In [Chapter 20: Configuration Management](20_configuration_management_.md), we learned how your CLI combines settings from different sources. Now, let's meet your app's **control center** - Config Management that stores and manages all the knobs and dials controlling your CLI's behavior, just like a soundboard that remembers all your favorite settings for different music genres!
  2473.  
  2474. ## Why Do We Need Config Management?
  2475.  
  2476. Imagine you're setting up a new smart home system. You'd want to:
  2477. 1. Save your preferred lighting colors
  2478. 2. Remember your favorite room temperatures
  2479. 3. Keep track of security settings
  2480.  
  2481. Config Management does exactly this for your CLI app! It:
  2482. - Stores all runtime settings in one place
  2483. - Provides easy access to these settings
  2484. - Acts as the single source of truth for how your app behaves
  2485.  
  2486. ## Meet the Settings Dashboard
  2487.  
  2488. Think of Config Management as your CLI's control panel with three main features:
  2489.  
  2490. 1. **Storage**: Safely keeps all settings
  2491. 2. **Access**: Provides settings when needed
  2492. 3. **Validation**: Ensures settings make sense
  2493.  
  2494. Here's how simple it is to get a setting:
  2495.  
  2496. ```typescript
  2497. import { config } from 'gemini-cli';
  2498.  
  2499. // Get the current theme
  2500. const theme = config.get('theme');
  2501. console.log(theme); // "dark" or "light"
  2502. ```
  2503.  
  2504. This shows how easy it is to access any stored setting.
  2505.  
  2506. ## How Config Management Works
  2507.  
  2508. When you request a setting, here's what happens behind the scenes:
  2509.  
  2510. ```mermaid
  2511. sequenceDiagram
  2512. participant You as You
  2513. participant Config as Config Management
  2514. participant Storage as Settings Storage
  2515.  
  2516. You->>Config: "What's my theme?"
  2517. Config->>Storage: Looks up value
  2518. Storage-->>Config: Returns "dark"
  2519. Config->>You: Gives you "dark"
  2520. ```
  2521.  
  2522. ## A Simple Example
  2523.  
  2524. Let's set and get a configuration value:
  2525.  
  2526. ```typescript
  2527. // Set the theme to dark mode
  2528. config.set('theme', 'dark');
  2529.  
  2530. // Later, retrieve it
  2531. const currentTheme = config.get('theme');
  2532. console.log(currentTheme); // "dark"
  2533. ```
  2534.  
  2535. This shows the basic flow: store → retrieve → use.
  2536.  
  2537. ## Real-World Implementation
  2538.  
  2539. Here's a peek at how we manage settings internally (simplified):
  2540.  
  2541. ```typescript
  2542. class ConfigManager {
  2543. private settings = new Map();
  2544.  
  2545. set(key, value) {
  2546. this.settings.set(key, value);
  2547. }
  2548.  
  2549. get(key) {
  2550. return this.settings.get(key);
  2551. }
  2552. }
  2553. ```
  2554.  
  2555. Key parts:
  2556. - Uses a `Map` to store settings efficiently
  2557. - Simple methods to get and set values
  2558. - Centralized access point for all settings
  2559.  
  2560. ## Common Settings
  2561.  
  2562. You'll often work with these types of settings:
  2563. 1. **UI Preferences**: Like themes and layouts
  2564. 2. **Tool Configs**: Default tools to use
  2565. 3. **System Settings**: Memory limits and timeouts
  2566.  
  2567. ## What's Next?
  2568.  
  2569. Now you understand how Config Management keeps all your CLI's settings organized! In [Chapter 22: Theme Management System](22_theme_management_system_.md), we'll explore how to customize your CLI's appearance using these settings.
  2570.  
  2571. > Pro Tip: Try setting different theme values and see how they affect your CLI's look!
  2572.  
  2573. ---
  2574.  
  2575. # Chapter 22: Theme Management System
  2576.  
  2577. Welcome back! In [Chapter 21: Config Management](21_config_management_.md), we learned how your CLI app stores all its settings. Now, let's meet your app's **fashion designer** - the Theme Management System that lets you change how your CLI looks, just like changing outfits for different occasions!
  2578.  
  2579. ## Why Do We Need Themes?
  2580.  
  2581. Imagine your favorite app only came in bright white - it would hurt your eyes at night! Themes solve this by letting you:
  2582. - Switch between light/dark modes
  2583. - Change colors to match your style
  2584. - Make code easier to read with proper highlighting
  2585.  
  2586. It's like having a wardrobe manager for your terminal's appearance!
  2587.  
  2588. ## Meet the Theme Basics
  2589.  
  2590. Themes control three main visual elements:
  2591. 1. **Background/Foreground**: Main colors (like dark mode)
  2592. 2. **Accent Colors**: Highlights for important elements
  2593. 3. **Syntax Highlighting**: Colors for code examples
  2594.  
  2595. Here's how simple it is to change themes:
  2596.  
  2597. ```typescript
  2598. import { setTheme } from 'gemini-cli';
  2599.  
  2600. // Switch to dark mode
  2601. setTheme('dark');
  2602. ```
  2603.  
  2604. This one command changes all your CLI's colors instantly!
  2605.  
  2606. ## How Themes Work Together
  2607.  
  2608. When you change themes, here's what happens behind the scenes:
  2609.  
  2610. ```mermaid
  2611. sequenceDiagram
  2612. participant You as You
  2613. participant Theme as Theme System
  2614. participant UI as Your CLI
  2615.  
  2616. You->>Theme: "Use dark theme"
  2617. Theme->>UI: Updates all colors
  2618. UI->>You: Shows new dark appearance
  2619. ```
  2620.  
  2621. ## A Simple Example
  2622.  
  2623. Let's see all available themes and pick one:
  2624.  
  2625. ```typescript
  2626. import { getThemes, setTheme } from 'gemini-cli';
  2627.  
  2628. // See all theme options
  2629. const themes = getThemes();
  2630. console.log(themes); // ["dark", "light", "github", "dracula"...]
  2631.  
  2632. // Pick the GitHub theme
  2633. setTheme('github-dark');
  2634. ```
  2635.  
  2636. This shows how easy it is to browse and apply themes.
  2637.  
  2638. ## Real-World Implementation
  2639.  
  2640. Let's peek at how themes are defined (simplified from our code):
  2641.  
  2642. ```typescript
  2643. // A simple theme definition
  2644. const darkTheme = {
  2645. name: "Dark",
  2646. colors: {
  2647. background: "#222",
  2648. text: "#eee",
  2649. accents: {
  2650. blue: "#5af",
  2651. red: "#f55"
  2652. }
  2653. }
  2654. };
  2655. ```
  2656.  
  2657. Key parts:
  2658. - Each theme has a name
  2659. - Defines color groups
  2660. - Simple structure for easy creation
  2661.  
  2662. ## Switching Between Themes
  2663.  
  2664. The system handles theme changes smoothly:
  2665.  
  2666. ```typescript
  2667. function changeTheme(name) {
  2668. // 1. Find the theme
  2669. const theme = findTheme(name);
  2670.  
  2671. // 2. Apply all colors
  2672. applyColors(theme.colors);
  2673.  
  2674. // 3. Update syntax highlighting
  2675. setSyntaxHighlighting(theme);
  2676. }
  2677. ```
  2678.  
  2679. This ensures everything updates together when you switch themes.
  2680.  
  2681. ## Common Theme Patterns
  2682.  
  2683. You'll often work with:
  2684. 1. **Dark/Light Modes**: For day/night usage
  2685. 2. **Code Themes**: Specialized for programming
  2686. 3. **Custom Themes**: Make your own color schemes
  2687.  
  2688. ## What's Next?
  2689.  
  2690. Now you understand how to customize your CLI's appearance with themes! In [Chapter 23: Theme System](23_theme_system_.md), we'll explore how to create and manage your own custom themes.
  2691.  
  2692. > Pro Tip: Try switching themes throughout the day - light for daytime, dark for nighttime!
  2693.  
  2694. ---
  2695.  
  2696. # Chapter 23: Theme System
  2697.  
  2698. Welcome back! In [Chapter 22: Theme Management System](22_theme_management_system_.md), we learned how to switch between different color themes. Now, let's explore the **Theme System** - your CLI's personal artist that paints all the colors and styles you see on screen, just like choosing different color palettes for a painting!
  2699.  
  2700. ## Why Do We Need Themes?
  2701.  
  2702. Imagine your favorite app only came in bright white - it would be hard to use at night! Themes solve this by letting you:
  2703. - Switch between light and dark modes
  2704. - Change colors to match your mood
  2705. - Make text easier to read
  2706. - Create a consistent look across your CLI
  2707.  
  2708. It's like having a magic paintbrush for your terminal!
  2709.  
  2710. ## Meet the Color Palette
  2711.  
  2712. The Theme System organizes colors into simple groups:
  2713.  
  2714. 1. **Main Colors**: Background and text colors
  2715. 2. **Accent Colors**: Highlights for important parts
  2716. 3. **Special Colors**: For code and other special text
  2717.  
  2718. Here's how simple it is to use a theme:
  2719.  
  2720. ```typescript
  2721. import { useTheme } from 'gemini-cli';
  2722.  
  2723. // Use the dark theme
  2724. useTheme('dark');
  2725. ```
  2726.  
  2727. This one command changes all your CLI's colors instantly!
  2728.  
  2729. ## How Themes Work Together
  2730.  
  2731. When you set a theme, here's what happens:
  2732.  
  2733. ```mermaid
  2734. sequenceDiagram
  2735. participant You as You
  2736. participant Theme as Theme System
  2737. participant UI as Your CLI
  2738.  
  2739. You->>Theme: "Use dark theme"
  2740. Theme->>UI: Updates all colors
  2741. UI->>You: Shows new dark look
  2742. ```
  2743.  
  2744. ## A Simple Example
  2745.  
  2746. Let's see all available themes and pick one:
  2747.  
  2748. ```typescript
  2749. import { listThemes, setTheme } from 'gemini-cli';
  2750.  
  2751. // See all theme options
  2752. const themes = listThemes();
  2753. console.log(themes); // ["dark", "light", "github", "dracula"...]
  2754.  
  2755. // Pick the Dracula theme
  2756. setTheme('dracula');
  2757. ```
  2758.  
  2759. This shows how easy it is to browse and apply themes.
  2760.  
  2761. ## Inside a Theme Definition
  2762.  
  2763. Themes are defined with simple color objects. Here's part of our dark theme:
  2764.  
  2765. ```typescript
  2766. const darkTheme = {
  2767. background: '#1E1E2E', // Dark background
  2768. text: '#CDD6F4', // Light text
  2769. accents: {
  2770. blue: '#89B4FA', // Pretty blue
  2771. red: '#F38BA8' // Soft red
  2772. }
  2773. };
  2774. ```
  2775.  
  2776. Key parts:
  2777. - Background and text colors
  2778. - Accent colors for highlights
  2779. - Simple structure anyone can understand
  2780.  
  2781. ## Changing Themes
  2782.  
  2783. The system handles theme changes smoothly:
  2784.  
  2785. ```typescript
  2786. function changeTheme(name) {
  2787. // 1. Find the theme colors
  2788. const colors = getThemeColors(name);
  2789.  
  2790. // 2. Update all UI elements
  2791. updateAllColors(colors);
  2792. }
  2793. ```
  2794.  
  2795. This ensures everything updates together when you switch themes.
  2796.  
  2797. ## Common Theme Uses
  2798.  
  2799. You'll often work with:
  2800. 1. **Dark/Light Modes**: For day/night comfort
  2801. 2. **Code Themes**: Special colors for programming
  2802. 3. **Custom Themes**: Make your own color schemes
  2803.  
  2804. ## What's Next?
  2805.  
  2806. Now you understand how to color your CLI with themes! In [Chapter 24: Markdown Rendering Engine](24_markdown_rendering_engine_.md), we'll learn how to display beautiful formatted text in your terminal.
  2807.  
  2808. > Pro Tip: Try creating a custom theme with your favorite colors!
  2809.  
  2810. ---
  2811.  
  2812. # Chapter 24: Markdown Rendering Engine
  2813.  
  2814. Welcome back! In [Chapter 23: Theme System](23_theme_system_.md), we learned how to customize your CLI's colors and appearance. Now, let's meet your app's **document translator** - the Markdown Rendering Engine that turns simple text formatting into beautiful terminal displays, just like magic ink that transforms plain notes into colorful documents!
  2815.  
  2816. ## Why Do We Need Markdown Rendering?
  2817.  
  2818. Imagine you're writing a note in your terminal:
  2819. ```
  2820. # Shopping List
  2821. - Milk
  2822. - Eggs `priority`
  2823. ```
  2824.  
  2825. You want it to look nice with:
  2826. - Big heading for "Shopping List"
  2827. - Bullet points for items
  2828. - Highlighted "priority" tag
  2829.  
  2830. The Markdown Rendering Engine does exactly this! It converts simple symbols (`#`, `-`, `` ` ``) into formatted terminal output.
  2831.  
  2832. ## Meet the Markdown Magic
  2833.  
  2834. Our engine understands these basic markdown elements:
  2835.  
  2836. 1. **Headings**: `# Big Title` becomes large text
  2837. 2. **Lists**: `- Item` becomes bullet points
  2838. 3. **Code**: `` `code` `` gets special highlighting
  2839. 4. **Formatting**: `**bold**` and `*italic*` text
  2840.  
  2841. Here's how simple it is to render markdown:
  2842.  
  2843. ```typescript
  2844. import { renderMarkdown } from 'gemini-cli';
  2845.  
  2846. // Simple markdown text
  2847. const mdText = "# Hello\nThis is **bold** text!";
  2848.  
  2849. // Render it to terminal
  2850. renderMarkdown(mdText);
  2851. ```
  2852.  
  2853. This will display:
  2854. ```
  2855. Hello
  2856. This is bold text!
  2857. ```
  2858. (With "Hello" as a heading and "bold" actually bold)
  2859.  
  2860. ## How Markdown Rendering Works
  2861.  
  2862. When you render markdown, here's what happens behind the scenes:
  2863.  
  2864. ```mermaid
  2865. sequenceDiagram
  2866. participant You as You
  2867. participant Engine as Markdown Engine
  2868. participant Terminal as Your Terminal
  2869.  
  2870. You->>Engine: "# Hello"
  2871. Engine->>Engine: Converts to big text
  2872. Engine->>Terminal: Shows formatted text
  2873. Terminal->>You: Displays beautiful heading
  2874. ```
  2875.  
  2876. ## A Simple Example
  2877.  
  2878. Let's render a more complex example:
  2879.  
  2880. ```typescript
  2881. const recipe = `
  2882. ## Chocolate Cake
  2883. Ingredients:
  2884. - 2 cups flour
  2885. - 1 cup sugar
  2886. Steps:
  2887. 1. Mix dry ingredients
  2888. 2. Bake at 350°F
  2889. `;
  2890.  
  2891. renderMarkdown(recipe);
  2892. ```
  2893.  
  2894. This will display with:
  2895. - "Chocolate Cake" as a medium header
  2896. - Bulleted ingredients
  2897. - Numbered steps
  2898.  
  2899. ## Behind the Scenes
  2900.  
  2901. The engine works in three simple steps:
  2902.  
  2903. 1. **Parsing**: Finds all markdown symbols
  2904. 2. **Converting**: Changes them to terminal codes
  2905. 3. **Rendering**: Displays the formatted text
  2906.  
  2907. Here's a peek at the parsing step (simplified):
  2908.  
  2909. ```typescript
  2910. function parseMarkdown(text) {
  2911. // Find headings
  2912. if (text.startsWith('# ')) {
  2913. return { type: 'heading', text: text.substring(2) };
  2914. }
  2915. // Find list items
  2916. if (text.startsWith('- ')) {
  2917. return { type: 'list', text: text.substring(2) };
  2918. }
  2919. }
  2920. ```
  2921.  
  2922. Key parts:
  2923. - Checks for markdown symbols
  2924. - Extracts the actual text
  2925. - Identifies the element type
  2926.  
  2927. ## Handling Complex Cases
  2928.  
  2929. The engine also manages tricky situations:
  2930. - Nested lists
  2931. - Code blocks with syntax highlighting
  2932. - Tables with proper alignment
  2933.  
  2934. ## What's Next?
  2935.  
  2936. Now you understand how to display beautiful formatted text in your terminal! In [Chapter 25: Error Handling Framework](25_error_handling_framework_.md), we'll learn how to gracefully handle when things go wrong.
  2937.  
  2938. > Pro Tip: Try mixing different markdown elements to create rich terminal documents!
  2939.  
  2940. ---
  2941.  
  2942. # Chapter 25: Error Handling Framework
  2943.  
  2944. Welcome back! In [Chapter 24: Markdown Rendering Engine](24_markdown_rendering_engine_.md), we learned how to display beautiful formatted text. Now, let's meet your CLI's **safety net** - the Error Handling Framework that catches problems before they crash your app, just like a trapeze artist's net that ensures they can perform daring tricks safely!
  2945.  
  2946. ## Why Do We Need Error Handling?
  2947.  
  2948. Imagine you're building a bridge out of toy blocks. Sometimes:
  2949. - A block might be missing (API error)
  2950. - The bridge gets too long (rate limit)
  2951. - Someone bumps the table (system crash)
  2952.  
  2953. The Error Handling Framework does three important jobs:
  2954. 1. **Catches** these problems gracefully
  2955. 2. **Explains** what went wrong in simple terms
  2956. 3. **Helps** you fix it or try again
  2957.  
  2958. ## Meet the Three Safety Nets
  2959.  
  2960. Our framework provides different safety nets for different problems:
  2961.  
  2962. 1. **API Errors**: When Gemini's servers have issues
  2963. 2. **Rate Limits**: When you make too many requests too fast
  2964. 3. **System Errors**: When your computer has problems
  2965.  
  2966. Here's how simple it is to catch an error:
  2967.  
  2968. ```typescript
  2969. import { safeRun } from 'gemini-cli';
  2970.  
  2971. // Wrap risky code in safeRun
  2972. const result = await safeRun(() => {
  2973. return fetchData(); // Might fail!
  2974. });
  2975.  
  2976. console.log(result.error?.message); // Friendly explanation
  2977. ```
  2978.  
  2979. ## How Errors Get Handled
  2980.  
  2981. When something goes wrong, here's what happens behind the scenes:
  2982.  
  2983. ```mermaid
  2984. sequenceDiagram
  2985. participant You as Your Code
  2986. participant Net as Error Handler
  2987. participant Gemini as Gemini API
  2988.  
  2989. You->>Gemini: Ask a question
  2990. Gemini-->>Net: "Too many requests!"
  2991. Net->>You: "Slow down! Try again later"
  2992. ```
  2993.  
  2994. ## A Simple Example
  2995.  
  2996. Let's handle a rate limit error:
  2997.  
  2998. ```typescript
  2999. try {
  3000. await askGemini("Tell me about space");
  3001. } catch (error) {
  3002. // The framework makes the error message friendly
  3003. console.error(error.message);
  3004. // "You're asking too fast! Wait 1 minute."
  3005. }
  3006. ```
  3007.  
  3008. ## Behind the Scenes
  3009.  
  3010. The framework checks different error types (simplified from our code):
  3011.  
  3012. ```typescript
  3013. function handleError(error) {
  3014. if (error.code === 429) {
  3015. return "Too many requests! Please wait";
  3016. }
  3017. if (error.type === "api") {
  3018. return "Gemini is having trouble right now";
  3019. }
  3020. return "Something unexpected went wrong";
  3021. }
  3022. ```
  3023.  
  3024. Key parts:
  3025. - Checks error codes
  3026. - Returns simple explanations
  3027. - Handles unknown errors safely
  3028.  
  3029. ## Common Error Patterns
  3030.  
  3031. You'll often see:
  3032. 1. **Rate Limits**: "You're asking too fast"
  3033. 2. **API Errors**: "Gemini is unavailable"
  3034. 3. **Network Issues**: "Can't connect to internet"
  3035.  
  3036. Each gets a clear, helpful message.
  3037.  
  3038. ## What's Next?
  3039.  
  3040. Now you understand how your CLI stays stable even when things go wrong! In [Chapter 26: Error Handling System](26_error_handling_system_.md), we'll explore more advanced ways to manage and recover from errors.
  3041.  
  3042. > Pro Tip: Try triggering different errors to see how the framework responds - it's designed to help!
  3043.  
  3044. ---
  3045.  
  3046. # Chapter 26: Error Handling System
  3047.  
  3048. Welcome back! In [Chapter 25: Error Handling Framework](25_error_handling_framework_.md), we learned how to catch basic errors in your CLI app. Now, let's meet your app's **safety inspector** - the Error Handling System that carefully categorizes and manages all types of errors, just like a hospital triage system that sorts patients by how urgently they need care!
  3049.  
  3050. ## Why Do We Need Error Handling?
  3051.  
  3052. Imagine your CLI app is like a busy restaurant. Sometimes things go wrong:
  3053. - The kitchen burns a dish (API error)
  3054. - Too many orders come at once (rate limit)
  3055. - A waiter drops a tray (network issue)
  3056.  
  3057. The Error Handling System helps by:
  3058. 1. **Catching** errors before they crash your app
  3059. 2. **Classifying** them by type (network, auth, etc.)
  3060. 3. **Responding** appropriately for each case
  3061.  
  3062. ## Meet the Error Categories
  3063.  
  3064. Our system organizes errors into three main types:
  3065.  
  3066. 1. **Network Errors**: Connection problems (like WiFi dropping)
  3067. 2. **Auth Errors**: Login issues (wrong password)
  3068. 3. **System Errors**: Computer problems (out of memory)
  3069.  
  3070. Here's how simple it is to handle an error:
  3071.  
  3072. ```typescript
  3073. import { handleError } from 'gemini-cli';
  3074.  
  3075. try {
  3076. // Risky operation that might fail
  3077. await fetchData();
  3078. } catch (error) {
  3079. // The system handles it appropriately
  3080. handleError(error);
  3081. }
  3082. ```
  3083.  
  3084. ## How Errors Get Processed
  3085.  
  3086. When an error occurs, here's what happens behind the scenes:
  3087.  
  3088. ```mermaid
  3089. sequenceDiagram
  3090. participant You as Your Code
  3091. participant System as Error System
  3092. participant Display as UI
  3093.  
  3094. You->>System: Error occurs!
  3095. System->>System: Checks error type
  3096. System->>Display: Shows appropriate message
  3097. Display->>You: "Network error - try again?"
  3098. ```
  3099.  
  3100. ## A Simple Example
  3101.  
  3102. Let's see how different errors get handled:
  3103.  
  3104. ```typescript
  3105. try {
  3106. await login(); // Might fail
  3107. } catch (error) {
  3108. // System automatically shows:
  3109. // - "Check your password" for auth errors
  3110. // - "No internet" for network issues
  3111. // - "System busy" for other problems
  3112. handleError(error);
  3113. }
  3114. ```
  3115.  
  3116. ## Behind the Scenes
  3117.  
  3118. The system checks error types like this (simplified):
  3119.  
  3120. ```typescript
  3121. function handleError(error) {
  3122. if (error.message.includes('network')) {
  3123. showNetworkError();
  3124. } else if (error.code === 401) {
  3125. showAuthError();
  3126. } else {
  3127. showGenericError();
  3128. }
  3129. }
  3130. ```
  3131.  
  3132. Key parts:
  3133. - Checks error messages and codes
  3134. - Shows specific messages for each type
  3135. - Has a fallback for unknown errors
  3136.  
  3137. ## Special Network Handling
  3138.  
  3139. The system includes smart retries for network issues:
  3140.  
  3141. ```typescript
  3142. async function fetchWithRetry() {
  3143. let attempts = 0;
  3144. while (attempts < 3) {
  3145. try {
  3146. return await fetchData();
  3147. } catch (error) {
  3148. if (isNetworkError(error)) {
  3149. await wait(1000); // Wait 1 second
  3150. attempts++;
  3151. } else {
  3152. throw error;
  3153. }
  3154. }
  3155. }
  3156. }
  3157. ```
  3158.  
  3159. This automatically retries network errors up to 3 times.
  3160.  
  3161. ## What's Next?
  3162.  
  3163. Now you understand how your CLI gracefully handles all types of errors! In [Chapter 27: Error Reporting](27_error_reporting_.md), we'll learn how to collect and analyze these errors to improve your app.
  3164.  
  3165. > Pro Tip: Try triggering different error types to see how the system responds uniquely to each!
  3166.  
  3167. ---
  3168.  
  3169. # Chapter 27: Error Reporting
  3170.  
  3171. Welcome back! In [Chapter 26: Error Handling System](26_error_handling_system_.md), we learned how to catch and categorize different types of errors. Now, let's meet your CLI's **black box recorder** - the Error Reporting system that carefully saves crash details to help developers fix problems, just like an airplane's black box that helps investigators understand what went wrong!
  3172.  
  3173. ## Why Do We Need Error Reporting?
  3174.  
  3175. Imagine your CLI app is like a car. Sometimes it might stall unexpectedly. Without knowing why, it's hard to fix! Error Reporting helps by:
  3176. 1. Recording what happened when errors occur
  3177. 2. Saving the "crash scene" details
  3178. 3. Helping developers understand and fix issues
  3179.  
  3180. It's like having a detective that investigates every problem automatically!
  3181.  
  3182. ## Meet the Error Report
  3183.  
  3184. When something goes wrong, the system creates a report with:
  3185. 1. **What happened**: The error message
  3186. 2. **Where it happened**: The code location (stack trace)
  3187. 3. **What you were doing**: The context (like your last command)
  3188.  
  3189. Here's how simple it is to generate a report:
  3190.  
  3191. ```typescript
  3192. import { reportError } from 'gemini-cli';
  3193.  
  3194. try {
  3195. // Something that might fail
  3196. riskyOperation();
  3197. } catch (error) {
  3198. // Creates a detailed error report
  3199. reportError(error, "Oops! Something went wrong");
  3200. }
  3201. ```
  3202.  
  3203. This saves all the details developers need to fix the issue.
  3204.  
  3205. ## How Error Reporting Works
  3206.  
  3207. When an error occurs, here's what happens behind the scenes:
  3208.  
  3209. ```mermaid
  3210. sequenceDiagram
  3211. participant You as Your Code
  3212. participant Reporter as Error Reporter
  3213. participant File as Report File
  3214.  
  3215. You->>Reporter: Error occurred!
  3216. Reporter->>Reporter: Gathers details
  3217. Reporter->>File: Saves report
  3218. Reporter->>You: "Report saved at /tmp/error123.json"
  3219. ```
  3220.  
  3221. ## A Simple Example
  3222.  
  3223. Let's see what a saved report looks like:
  3224.  
  3225. ```typescript
  3226. // Sample error report contents
  3227. {
  3228. "error": {
  3229. "message": "Network timeout",
  3230. "stack": "at fetchData (client.js:12:3)..."
  3231. },
  3232. "context": {
  3233. "lastCommand": "search pizza places",
  3234. "time": "2024-02-20T14:30:00Z"
  3235. }
  3236. }
  3237. ```
  3238.  
  3239. Key parts:
  3240. - Clear error message
  3241. - Exact code location
  3242. - What you were doing
  3243.  
  3244. ## Behind the Scenes
  3245.  
  3246. The reporter works in three simple steps (simplified from our code):
  3247.  
  3248. ```typescript
  3249. async function reportError(error) {
  3250. // 1. Create timestamp for unique filename
  3251. const timestamp = new Date().toISOString();
  3252.  
  3253. // 2. Gather error details
  3254. const report = {
  3255. message: error.message,
  3256. stack: error.stack
  3257. };
  3258.  
  3259. // 3. Save to temporary file
  3260. await saveReport(`error-${timestamp}.json`, report);
  3261. }
  3262. ```
  3263.  
  3264. Key features:
  3265. - Unique filenames prevent overwrites
  3266. - Includes both message and technical details
  3267. - Saves to a safe temporary location
  3268.  
  3269. ## Reading Error Reports
  3270.  
  3271. Developers can then use these reports to fix issues:
  3272.  
  3273. ```typescript
  3274. // Later, developers can read reports
  3275. const report = await readReport('error-2024-02-20.json');
  3276. console.log(report.message); // "Network timeout"
  3277. ```
  3278.  
  3279. This helps them understand exactly what went wrong.
  3280.  
  3281. ## What's Next?
  3282.  
  3283. Now you understand how your CLI automatically documents problems! In [Chapter 28: Telemetry System](28_telemetry_system_.md), we'll learn how your app collects usage data to improve performance.
  3284.  
  3285. > Pro Tip: Try triggering an error in your CLI and check your temp folder for the generated report!
  3286.  
  3287. ---
  3288.  
  3289. # Chapter 28: Telemetry System
  3290.  
  3291. Welcome back! In [Chapter 27: Error Reporting](27_error_reporting_.md), we learned how your CLI documents problems when they occur. Now, let's meet your app's **flight recorder** - the Telemetry System that quietly tracks important usage information to help improve the CLI, just like an airplane's black box that records flight data!
  3292.  
  3293. ## Why Do We Need Telemetry?
  3294.  
  3295. Imagine you're training for a marathon. You'd want to track:
  3296. - How far you run each day
  3297. - Your average speed
  3298. - When you take breaks
  3299.  
  3300. Telemetry does exactly this for your CLI app! It automatically collects:
  3301. - Which commands are used most
  3302. - How long operations take
  3303. - Any errors that occur
  3304. - Basic usage patterns (without personal data)
  3305.  
  3306. This helps developers understand how people use the CLI and improve it over time.
  3307.  
  3308. ## Meet the Simple Telemetry Flow
  3309.  
  3310. The telemetry system works in three easy steps:
  3311.  
  3312. 1. **Collect**: Gathers usage data as you work
  3313. 2. **Process**: Organizes the information
  3314. 3. **Report**: Sends anonymous summaries to help improve the CLI
  3315.  
  3316. Here's how simple it is to check if telemetry is enabled:
  3317.  
  3318. ```typescript
  3319. import { isTelemetryEnabled } from 'gemini-cli';
  3320.  
  3321. console.log(isTelemetryEnabled()); // true or false
  3322. ```
  3323.  
  3324. This shows whether anonymous usage reporting is active.
  3325.  
  3326. ## How Telemetry Works
  3327.  
  3328. When you use the CLI, here's what happens behind the scenes:
  3329.  
  3330. ```mermaid
  3331. sequenceDiagram
  3332. participant You as You
  3333. participant CLI as Your CLI
  3334. participant Telemetry as Telemetry System
  3335.  
  3336. You->>CLI: Runs a command
  3337. CLI->>Telemetry: Records basic usage
  3338. Telemetry->>Telemetry: Processes data
  3339. Telemetry-->>Developers: Sends anonymous reports
  3340. ```
  3341.  
  3342. ## A Simple Example
  3343.  
  3344. Let's see what data might be collected:
  3345.  
  3346. ```typescript
  3347. // Sample telemetry data for a search command
  3348. {
  3349. command: "search",
  3350. duration: 1200, // milliseconds
  3351. success: true,
  3352. toolsUsed: ["web-search"]
  3353. }
  3354. ```
  3355.  
  3356. This shows basic info about what happened, without any personal details.
  3357.  
  3358. ## Behind the Scenes
  3359.  
  3360. The telemetry system carefully organizes different types of data (simplified from our code):
  3361.  
  3362. ```typescript
  3363. class Telemetry {
  3364. private events = [];
  3365.  
  3366. record(event) {
  3367. // Remove any personal data first
  3368. const cleanEvent = removePersonalData(event);
  3369. this.events.push(cleanEvent);
  3370. }
  3371.  
  3372. sendReport() {
  3373. // Send anonymous data periodically
  3374. sendToServer(this.events);
  3375. }
  3376. }
  3377. ```
  3378.  
  3379. Key parts:
  3380. 1. Cleans data to remove personal info
  3381. 2. Stores events temporarily
  3382. 3. Sends anonymous reports
  3383.  
  3384. ## What Data Is Collected?
  3385.  
  3386. The system tracks only helpful technical information:
  3387. - Command names (like "search" or "ask")
  3388. - Performance metrics (how long things take)
  3389. - Error types (without personal details)
  3390. - Basic system info (like OS version)
  3391.  
  3392. ## Controlling Telemetry
  3393.  
  3394. You can always check or change telemetry settings:
  3395.  
  3396. ```typescript
  3397. import { getTelemetryConfig, setTelemetryEnabled } from 'gemini-cli';
  3398.  
  3399. // See current settings
  3400. console.log(getTelemetryConfig());
  3401.  
  3402. // Disable if preferred
  3403. setTelemetryEnabled(false);
  3404. ```
  3405.  
  3406. ## What's Next?
  3407.  
  3408. Now you understand how your CLI collects anonymous usage data to improve! In [Chapter 29: Telemetry Service](29_telemetry_service_.md), we'll explore how this data gets processed and used to make the CLI better.
  3409.  
  3410. > Pro Tip: Try checking your telemetry settings to see how the system works!
  3411.  
  3412. ---
  3413.  
  3414. # Chapter 29: Telemetry Service
  3415.  
  3416. Welcome back! In [Chapter 28: Telemetry System](28_telemetry_system_.md), we learned how your CLI collects anonymous usage data. Now, let's meet your app's **dashboard display** - the Telemetry Service that organizes and shows these metrics, just like your car's dashboard that shows speed, fuel level, and engine stats!
  3417.  
  3418. ## Why Do We Need a Telemetry Service?
  3419.  
  3420. Imagine driving a car with no dashboard. You wouldn't know:
  3421. - How fast you're going
  3422. - How much fuel remains
  3423. - If the engine is overheating
  3424.  
  3425. The Telemetry Service solves this for your CLI by:
  3426. 1. Tracking important metrics (like API calls and tool usage)
  3427. 2. Organizing the data clearly
  3428. 3. Making it available for display or analysis
  3429.  
  3430. ## Meet the Dashboard Metrics
  3431.  
  3432. The service tracks three main categories:
  3433.  
  3434. 1. **API Calls**: How often you talk to Gemini
  3435. 2. **Tool Usage**: Which tools you run and how long they take
  3436. 3. **Token Counts**: How many "words" Gemini processes
  3437.  
  3438. Here's how simple it is to check your session stats:
  3439.  
  3440. ```typescript
  3441. import { telemetry } from 'gemini-cli';
  3442.  
  3443. // Get current usage stats
  3444. const stats = telemetry.getMetrics();
  3445. console.log(stats.api.totalRequests); // Number of API calls
  3446. ```
  3447.  
  3448. ## How Telemetry Works
  3449.  
  3450. When you use the CLI, here's what happens behind the scenes:
  3451.  
  3452. ```mermaid
  3453. sequenceDiagram
  3454. participant You as You
  3455. participant CLI as Your CLI
  3456. participant Telemetry as Telemetry Service
  3457.  
  3458. You->>CLI: Runs a command
  3459. CLI->>Telemetry: Records the action
  3460. Telemetry->>Telemetry: Updates metrics
  3461. CLI->>You: Shows command results
  3462. ```
  3463.  
  3464. ## A Simple Example
  3465.  
  3466. Let's see what typical metrics look like:
  3467.  
  3468. ```typescript
  3469. // Sample telemetry output
  3470. {
  3471. api: {
  3472. totalRequests: 42,
  3473. totalErrors: 2,
  3474. averageLatency: 1200 // ms
  3475. },
  3476. tools: {
  3477. search: { calls: 10, success: 9 },
  3478. edit: { calls: 5, success: 5 }
  3479. }
  3480. }
  3481. ```
  3482.  
  3483. This shows how many times you've used different features and how well they worked.
  3484.  
  3485. ## Behind the Scenes
  3486.  
  3487. The service carefully counts each event (simplified from our code):
  3488.  
  3489. ```typescript
  3490. class TelemetryService {
  3491. private metrics = {
  3492. api: { calls: 0, errors: 0 },
  3493. tools: {}
  3494. };
  3495.  
  3496. recordApiCall() {
  3497. this.metrics.api.calls++;
  3498. }
  3499.  
  3500. recordToolUse(toolName) {
  3501. if (!this.metrics.tools[toolName]) {
  3502. this.metrics.tools[toolName] = 0;
  3503. }
  3504. this.metrics.tools[toolName]++;
  3505. }
  3506. }
  3507. ```
  3508.  
  3509. Key parts:
  3510. - Simple counters for each metric
  3511. - Automatic initialization of new tools
  3512. - Easy-to-read structure
  3513.  
  3514. ## Viewing Your Metrics
  3515.  
  3516. You can check your stats anytime:
  3517.  
  3518. ```typescript
  3519. // See tool usage counts
  3520. const toolCounts = telemetry.getToolCounts();
  3521. console.log(`You've used search ${toolCounts.search} times!`);
  3522. ```
  3523.  
  3524. This helps you understand your own usage patterns.
  3525.  
  3526. ## What's Next?
  3527.  
  3528. Now you understand how your CLI tracks and organizes usage metrics! In [Chapter 30: Session Statistics](30_session_statistics_.md), we'll learn how to analyze this data across multiple CLI sessions.
  3529.  
  3530. > Pro Tip: Try checking your telemetry metrics after running different commands to see how they're tracked!
  3531.  
  3532. ---
  3533.  
  3534. # Chapter 30: Session Statistics
  3535.  
  3536. Welcome back! In [Chapter 29: Telemetry Service](29_telemetry_service_.md), we learned how your CLI tracks usage metrics. Now, let's meet your app's **personal dashboard** - Session Statistics that show real-time insights about your current conversation, just like a car's dashboard that displays your speed, fuel level, and trip distance!
  3537.  
  3538. ## Why Do We Need Session Stats?
  3539.  
  3540. Imagine you're having a long conversation with Gemini. You might wonder:
  3541. - How many questions have I asked?
  3542. - Which tools were used most?
  3543. - How long has this session been active?
  3544.  
  3545. Session Statistics answer these questions by showing:
  3546. - Tool usage counts
  3547. - Model call metrics
  3548. - Performance timings
  3549. - Success/failure rates
  3550.  
  3551. All in a beautiful terminal dashboard!
  3552.  
  3553. ## Meet Your Session Dashboard
  3554.  
  3555. The stats system tracks three main categories:
  3556.  
  3557. 1. **Tool Usage**: Which tools ran and how often
  3558. 2. **Model Calls**: How many API requests were made
  3559. 3. **Performance**: How long operations took
  3560.  
  3561. Here's how simple it is to view your stats:
  3562.  
  3563. ```typescript
  3564. import { showStats } from 'gemini-cli';
  3565.  
  3566. // Display current session statistics
  3567. showStats();
  3568. ```
  3569.  
  3570. This shows a colorful dashboard in your terminal with all the key metrics.
  3571.  
  3572. ## How Stats Get Tracked
  3573.  
  3574. When you use the CLI, here's what happens behind the scenes:
  3575.  
  3576. ```mermaid
  3577. sequenceDiagram
  3578. participant You as You
  3579. participant CLI as Your CLI
  3580. participant Stats as Stats System
  3581.  
  3582. You->>CLI: Runs a command
  3583. CLI->>Stats: Records the action
  3584. Stats->>Stats: Updates counters
  3585. CLI->>You: Shows command results
  3586. ```
  3587.  
  3588. ## A Simple Example
  3589.  
  3590. Let's see what typical stats look like:
  3591.  
  3592. ```typescript
  3593. // Sample stats output
  3594. {
  3595. tools: {
  3596. search: { calls: 5, success: 4 },
  3597. edit: { calls: 2, success: 2 }
  3598. },
  3599. models: {
  3600. 'gemini-pro': { calls: 7, tokens: 1200 }
  3601. },
  3602. duration: "15 minutes"
  3603. }
  3604. ```
  3605.  
  3606. This shows you've used the search tool 5 times and made 7 model calls.
  3607.  
  3608. ## Behind the Scenes
  3609.  
  3610. The stats system carefully counts each event (simplified from our code):
  3611.  
  3612. ```typescript
  3613. class SessionStats {
  3614. private tools = {};
  3615. private models = {};
  3616.  
  3617. recordToolUse(toolName) {
  3618. if (!this.tools[toolName]) {
  3619. this.tools[toolName] = 0;
  3620. }
  3621. this.tools[toolName]++;
  3622. }
  3623. }
  3624. ```
  3625.  
  3626. Key parts:
  3627. - Simple counters for each metric
  3628. - Automatic initialization of new tools/models
  3629. - Easy-to-read structure
  3630.  
  3631. ## Viewing Your Dashboard
  3632.  
  3633. The stats dashboard shows information in clear sections:
  3634.  
  3635. 1. **Tool Usage**: Success/failure counts
  3636. 2. **Model Calls**: API request details
  3637. 3. **Performance**: Time spent on different tasks
  3638.  
  3639. You can access detailed views too:
  3640.  
  3641. ```typescript
  3642. // Show tool-specific stats
  3643. showToolStats();
  3644.  
  3645. // Show model-specific stats
  3646. showModelStats();
  3647. ```
  3648.  
  3649. ## Common Patterns
  3650.  
  3651. You'll often check stats to:
  3652. 1. **Monitor Usage**: See which tools you use most
  3653. 2. **Debug Issues**: Find failing operations
  3654. 3. **Optimize Performance**: Identify slow commands
  3655.  
  3656. ## What's Next?
  3657.  
  3658. Now you understand how to track your CLI usage with Session Statistics! In [Chapter 31: Conversation Management](31_conversation_management_.md), we'll learn how your CLI maintains context across multiple questions and answers.
  3659.  
  3660. > Pro Tip: Try running different commands and check your stats after each to see them update in real-time!
  3661.  
  3662. ---
  3663.  
  3664. # Chapter 31: Conversation Management
  3665.  
  3666. Welcome back! In [Chapter 30: Session Statistics](30_session_statistics_.md), we learned how to track our CLI usage. Now, let's meet your app's **conversation referee** - Conversation Management that decides who gets to speak next in your chat with Gemini, just like a moderator in a discussion who says "Now it's your turn to speak!"
  3667.  
  3668. ## Why Do We Need Conversation Management?
  3669.  
  3670. Imagine you're playing ping-pong with a friend. The ball goes back and forth:
  3671. - You serve (ask a question)
  3672. - Friend returns (Gemini answers)
  3673. - You hit back (follow-up question)
  3674.  
  3675. Conversation Management is like the unspoken rules that decide:
  3676. 1. When it's your turn to speak
  3677. 2. When Gemini should continue talking
  3678. 3. When the conversation naturally pauses
  3679.  
  3680. Without this, you might both talk at once or sit in awkward silence!
  3681.  
  3682. ## Meet the Turn-Taking Rules
  3683.  
  3684. The system follows three simple rules to decide who speaks next:
  3685.  
  3686. 1. **Gemini Continues**: If Gemini says "Now I'll analyze this..."
  3687. 2. **Your Turn**: If Gemini asks you a direct question
  3688. 3. **Natural Pause**: If Gemini finishes a thought and waits for you
  3689.  
  3690. Here's how simple it is to check:
  3691.  
  3692. ```typescript
  3693. import { checkNextSpeaker } from 'gemini-cli';
  3694.  
  3695. // After Gemini responds, check who goes next
  3696. const next = await checkNextSpeaker();
  3697. console.log(next); // { speaker: "user", reason: "Asked you a question" }
  3698. ```
  3699.  
  3700. ## How Turn-Taking Works
  3701.  
  3702. When deciding who speaks next, here's what happens:
  3703.  
  3704. ```mermaid
  3705. sequenceDiagram
  3706. participant You as You
  3707. participant Check as Turn Checker
  3708. participant Gemini as Gemini
  3709.  
  3710. You->>Gemini: Ask a question
  3711. Gemini->>You: Responds
  3712. You->>Check: Who speaks next?
  3713. Check->>Gemini: Analyzes last message
  3714. Gemini-->>Check: "user should speak"
  3715. Check->>You: "Your turn!"
  3716. ```
  3717.  
  3718. ## A Simple Example
  3719.  
  3720. Let's see how different responses affect turn-taking:
  3721.  
  3722. ```typescript
  3723. // Case 1: Gemini asks a question
  3724. const response1 = "What do you think about this idea?";
  3725. const next1 = await checkNextSpeaker(response1);
  3726. console.log(next1.speaker); // "user" (because you were asked)
  3727.  
  3728. // Case 2: Gemini continues working
  3729. const response2 = "Now I'll analyze the data...";
  3730. const next2 = await checkNextSpeaker(response2);
  3731. console.log(next2.speaker); // "model" (because Gemini is working)
  3732. ```
  3733.  
  3734. ## Behind the Scenes
  3735.  
  3736. The system analyzes Gemini's last message (simplified from our code):
  3737.  
  3738. ```typescript
  3739. function decideNextSpeaker(lastMessage) {
  3740. if (lastMessage.includes("I'll") || lastMessage.includes("Now I")) {
  3741. return "model"; // Gemini is continuing
  3742. }
  3743. if (lastMessage.endsWith("?")) {
  3744. return "user"; // Asked you a question
  3745. }
  3746. return "user"; // Default to your turn
  3747. }
  3748. ```
  3749.  
  3750. Key parts:
  3751. - Looks for continuing phrases
  3752. - Checks for questions
  3753. - Defaults to user's turn
  3754.  
  3755. ## Handling Special Cases
  3756.  
  3757. The system also manages tricky situations:
  3758. - When Gemini calls tools automatically
  3759. - When responses get cut off
  3760. - When no clear turn signal exists
  3761.  
  3762. ## What's Next?
  3763.  
  3764. Now you understand how your CLI manages conversation flow! In [Chapter 32: Chat Session](32_chat_session_.md), we'll explore how your entire conversation history is maintained.
  3765.  
  3766. > Pro Tip: Try asking Gemini different types of questions to see how the turn-taking changes!
  3767.  
  3768. ---
  3769.  
  3770. # Chapter 32: Chat Session
  3771.  
  3772. Welcome back! In [Chapter 31: Conversation Management](31_conversation_management_.md), we learned how your CLI decides who speaks next in a conversation. Now, let's meet your app's **memory keeper** - the Chat Session that remembers everything you and Gemini discuss, just like a notebook that keeps all your thoughts and ideas in one place!
  3773.  
  3774. ## Why Do We Need Chat Sessions?
  3775.  
  3776. Imagine you're having a long conversation with a friend about planning a trip. You wouldn't want to:
  3777. - Repeat yourself constantly
  3778. - Forget what you've already discussed
  3779. - Lose track of important details
  3780.  
  3781. The Chat Session solves this by:
  3782. 1. Remembering your entire conversation history
  3783. 2. Keeping track of who said what
  3784. 3. Managing long discussions efficiently
  3785.  
  3786. ## Meet Your Conversation Notebook
  3787.  
  3788. A Chat Session is like a digital notebook with three key features:
  3789.  
  3790. 1. **Message History**: Records every question and answer
  3791. 2. **Context Management**: Keeps the conversation flowing naturally
  3792. 3. **Memory Optimization**: Handles long chats smartly
  3793.  
  3794. Here's how simple it is to start a new session:
  3795.  
  3796. ```typescript
  3797. import { createChatSession } from 'gemini-cli';
  3798.  
  3799. // Start a new conversation
  3800. const chat = createChatSession();
  3801. ```
  3802.  
  3803. This creates a fresh session ready for your first message.
  3804.  
  3805. ## How Chat Sessions Work
  3806.  
  3807. When you chat with Gemini, here's what happens behind the scenes:
  3808.  
  3809. ```mermaid
  3810. sequenceDiagram
  3811. participant You as You
  3812. participant Session as Chat Session
  3813. participant Gemini as Gemini
  3814.  
  3815. You->>Session: "What's 2+2?"
  3816. Session->>Gemini: Sends question + history
  3817. Gemini-->>Session: Returns "4"
  3818. Session->>You: Shows answer
  3819. Session->>Session: Saves both messages
  3820. ```
  3821.  
  3822. ## A Simple Example
  3823.  
  3824. Let's have a short conversation:
  3825.  
  3826. ```typescript
  3827. // First question
  3828. await chat.sendMessage("Hi Gemini!");
  3829. // Gemini responds: "Hello! How can I help?"
  3830.  
  3831. // Follow-up question
  3832. await chat.sendMessage("What's 2+2?");
  3833. // Gemini remembers the context and responds: "4"
  3834. ```
  3835.  
  3836. The session automatically keeps track of both messages in order.
  3837.  
  3838. ## Behind the Scenes
  3839.  
  3840. The session stores messages in a simple list (simplified from our code):
  3841.  
  3842. ```typescript
  3843. class ChatSession {
  3844. private history = [];
  3845.  
  3846. addMessage(role, text) {
  3847. this.history.push({ role, text });
  3848. }
  3849.  
  3850. getHistory() {
  3851. return [...this.history]; // Return a copy
  3852. }
  3853. }
  3854. ```
  3855.  
  3856. Key parts:
  3857. - `history` array stores all messages
  3858. - `role` tracks who spoke (user or model)
  3859. - Methods to add and retrieve messages
  3860.  
  3861. ## Handling Long Conversations
  3862.  
  3863. For very long chats, the session automatically:
  3864.  
  3865. 1. **Summarizes** old messages when needed
  3866. 2. **Removes** less important parts
  3867. 3. **Keeps** key context intact
  3868.  
  3869. This ensures Gemini always has relevant context without getting overwhelmed.
  3870.  
  3871. ## Common Patterns
  3872.  
  3873. You'll often use chat sessions to:
  3874. 1. **Continue Discussions**: Pick up where you left off
  3875. 2. **Review History**: See past conversations
  3876. 3. **Start Fresh**: Clear the history when needed
  3877.  
  3878. ## What's Next?
  3879.  
  3880. Now you understand how your CLI maintains complete conversation histories! In [Chapter 33: Conversation Turn](33_conversation_turn_.md), we'll explore how individual messages are structured within these sessions.
  3881.  
  3882. > Pro Tip: Try asking follow-up questions in a chat session to see how it maintains context!
  3883.  
  3884. ---
  3885.  
  3886. # Chapter 33: Conversation Turn
  3887.  
  3888. Welcome back! In [Chapter 32: Chat Session](32_chat_session_.md), we learned how your CLI remembers entire conversations. Now, let's zoom in to examine a **Conversation Turn** - the basic building block of your chat, like a single back-and-forth in a ping-pong match!
  3889.  
  3890. ## Why Do We Need Conversation Turns?
  3891.  
  3892. Imagine you're playing catch with a friend:
  3893. 1. You throw the ball (your message)
  3894. 2. Friend catches and throws back (Gemini's response)
  3895. 3. You catch and prepare to throw again (your next move)
  3896.  
  3897. Each throw and catch is one "turn." The Conversation Turn system manages these individual exchanges by:
  3898. - Tracking who "has the ball" (whose turn it is to speak)
  3899. - Handling any tools that need to run between turns
  3900. - Managing errors if the ball gets dropped
  3901.  
  3902. ## Meet the Simple Turn Structure
  3903.  
  3904. Every conversation turn has three main parts:
  3905.  
  3906. 1. **Input**: Your message or question
  3907. 2. **Processing**: Gemini thinking or running tools
  3908. 3. **Output**: Gemini's response or result
  3909.  
  3910. Here's how simple it is to create a turn:
  3911.  
  3912. ```typescript
  3913. import { createTurn } from 'gemini-cli';
  3914.  
  3915. // Start a new turn with your message
  3916. const turn = createTurn("What's 2+2?");
  3917. ```
  3918.  
  3919. This creates a turn ready to process your question.
  3920.  
  3921. ## How Turns Work Together
  3922.  
  3923. When you send a message, here's what happens behind the scenes:
  3924.  
  3925. ```mermaid
  3926. sequenceDiagram
  3927. participant You as You
  3928. participant Turn as Conversation Turn
  3929. participant Gemini as Gemini
  3930.  
  3931. You->>Turn: "What's 2+2?"
  3932. Turn->>Gemini: Sends question
  3933. Gemini-->>Turn: Returns "4"
  3934. Turn->>You: Shows answer
  3935. ```
  3936.  
  3937. ## A Simple Example
  3938.  
  3939. Let's see a complete turn in action:
  3940.  
  3941. ```typescript
  3942. // Create and run a turn
  3943. const turn = createTurn("Hello Gemini!");
  3944. const response = await turn.run();
  3945.  
  3946. console.log(response); // "Hello! How can I help?"
  3947. ```
  3948.  
  3949. This shows the basic flow: create turn → run it → get response.
  3950.  
  3951. ## Behind the Scenes
  3952.  
  3953. The turn manages several important tasks (simplified from our code):
  3954.  
  3955. ```typescript
  3956. class ConversationTurn {
  3957. constructor(private message: string) {}
  3958.  
  3959. async run() {
  3960. // 1. Send the message to Gemini
  3961. const response = await sendToGemini(this.message);
  3962.  
  3963. // 2. Check if tools need to run
  3964. if (response.needsTool) {
  3965. await runTools(response.tools);
  3966. }
  3967.  
  3968. // 3. Return the final answer
  3969. return response.answer;
  3970. }
  3971. }
  3972. ```
  3973.  
  3974. Key parts:
  3975. 1. Sends your message
  3976. 2. Handles any required tools
  3977. 3. Returns the final response
  3978.  
  3979. ## Handling Special Cases
  3980.  
  3981. Turns also manage tricky situations:
  3982. - When Gemini needs to run tools before responding
  3983. - When responses come in multiple parts
  3984. - When errors occur during processing
  3985.  
  3986. ## What's Next?
  3987.  
  3988. Now you understand how individual conversation turns work! In [Chapter 34: System Prompts](34_system_prompts_.md), we'll learn how to guide Gemini's behavior with special instructions.
  3989.  
  3990. > Pro Tip: Try creating turns with different types of questions to see how they're processed!
  3991.  
  3992. ---
  3993.  
  3994. # Chapter 34: System Prompts
  3995.  
  3996. Welcome back! In [Chapter 33: Conversation Turn](33_conversation_turn_.md), we learned how individual messages work in your CLI conversations. Now, let's meet your app's **instruction manual** - System Prompts that guide Gemini's behavior, like a coach giving an athlete clear directions before a big game!
  3997.  
  3998. ## Why Do We Need System Prompts?
  3999.  
  4000. Imagine you're teaching a new assistant how to help with coding. You'd want to explain:
  4001. - How to write clean code
  4002. - When to ask for help
  4003. - What rules to always follow
  4004.  
  4005. System Prompts do exactly this for Gemini! They contain all the instructions that shape how Gemini:
  4006. - Responds to your questions
  4007. - Uses tools safely
  4008. - Follows coding best practices
  4009.  
  4010. ## Meet the Instruction Manual
  4011.  
  4012. Think of System Prompts as a rulebook with three main sections:
  4013.  
  4014. 1. **Core Rules**: Always follow project conventions
  4015. 2. **Safety Checks**: Explain risky commands first
  4016. 3. **Workflows**: Step-by-step plans for common tasks
  4017.  
  4018. Here's a tiny example of what a system prompt might say:
  4019.  
  4020. ```typescript
  4021. // Simplified system prompt
  4022. const instructions = `
  4023. 1. Always check existing code first
  4024. 2. Explain risky commands
  4025. 3. Keep responses short
  4026. `;
  4027. ```
  4028.  
  4029. ## How System Prompts Work
  4030.  
  4031. When you ask a question, here's what happens behind the scenes:
  4032.  
  4033. ```mermaid
  4034. sequenceDiagram
  4035. participant You as You
  4036. participant Gemini as Gemini
  4037. participant Prompts as System Prompts
  4038.  
  4039. You->>Gemini: "How do I fix this bug?"
  4040. Gemini->>Prompts: Checks the rules
  4041. Prompts-->>Gemini: "First analyze the code..."
  4042. Gemini->>You: "I'll check the code first"
  4043. ```
  4044.  
  4045. ## A Simple Example
  4046.  
  4047. Let's see how prompts affect responses:
  4048.  
  4049. ```typescript
  4050. // Without system prompt
  4051. User: "Delete all temp files"
  4052. Gemini: "Okay, deleting files..."
  4053.  
  4054. // With system prompt
  4055. User: "Delete all temp files"
  4056. Gemini: "This will permanently delete files. Continue?"
  4057. ```
  4058.  
  4059. The system prompt adds important safety checks!
  4060.  
  4061. ## Behind the Scenes
  4062.  
  4063. The system loads prompts from special files (simplified from our code):
  4064.  
  4065. ```typescript
  4066. function loadSystemPrompt() {
  4067. // Check for custom instructions
  4068. if (fs.existsSync('system.md')) {
  4069. return fs.readFileSync('system.md', 'utf8');
  4070. }
  4071. // Use default instructions
  4072. return defaultInstructions;
  4073. }
  4074. ```
  4075.  
  4076. Key parts:
  4077. 1. Looks for custom instructions
  4078. 2. Falls back to defaults
  4079. 3. Makes them available to Gemini
  4080.  
  4081. ## Customizing Prompts
  4082.  
  4083. You can create your own `system.md` file to change behavior:
  4084.  
  4085. ```markdown
  4086. # My Custom Rules
  4087. - Prefer Python over JavaScript
  4088. - Always explain changes
  4089. - Use emojis in responses 😊
  4090. ```
  4091.  
  4092. This lets you personalize how Gemini works for you!
  4093.  
  4094. ## Common Prompt Uses
  4095.  
  4096. You'll often customize prompts to:
  4097. 1. **Match Team Style**: Follow your coding conventions
  4098. 2. **Add Safety**: Extra confirmation steps
  4099. 3. **Change Tone**: More formal or casual responses
  4100.  
  4101. ## What's Next?
  4102.  
  4103. Now you understand how System Prompts guide Gemini's behavior! In [Chapter 35: Input Handling](35_input_handling_.md), we'll learn how your CLI processes what you type.
  4104.  
  4105. > Pro Tip: Try creating a simple `system.md` file to see how it changes Gemini's responses!
  4106.  
  4107. ---
  4108.  
  4109. # Chapter 35: Input Handling
  4110.  
  4111. Welcome back! In [Chapter 34: System Prompts](34_system_prompts_.md), we learned how to guide Gemini's behavior with special instructions. Now, let's meet your CLI's **keyboard wizard** - Input Handling that manages everything you type, from simple commands to complex queries, just like a skilled translator converting your thoughts into actions!
  4112.  
  4113. ## Why Do We Need Input Handling?
  4114.  
  4115. Imagine you're playing a piano with special keys that can:
  4116. - Remember songs you've played before (history)
  4117. - Suggest next notes as you play (autocomplete)
  4118. - Switch between piano and organ modes (shell toggling)
  4119.  
  4120. Input Handling does exactly this for your CLI! It transforms your keystrokes into meaningful actions by:
  4121. 1. Remembering past commands (history)
  4122. 2. Predicting what you might type next (autocomplete)
  4123. 3. Switching between chat and shell modes
  4124.  
  4125. ## Meet the Three Magic Features
  4126.  
  4127. Our input system offers three helpful tools:
  4128.  
  4129. 1. **Command History**: Press up/down to cycle through past commands
  4130. 2. **Smart Suggestions**: Get autocomplete as you type
  4131. 3. **Mode Switching**: Toggle between chat and shell with `!`
  4132.  
  4133. Here's how simple it is to use:
  4134.  
  4135. ```typescript
  4136. // When you type "hel" and press Tab
  4137. > hel
  4138. // The system suggests:
  4139. > hello
  4140. ```
  4141.  
  4142. ## How Input Handling Works
  4143.  
  4144. When you press a key, here's what happens behind the scenes:
  4145.  
  4146. ```mermaid
  4147. sequenceDiagram
  4148. participant You as You
  4149. participant Keyboard as Keyboard Input
  4150. participant Handler as Input Handler
  4151. participant Gemini as Gemini
  4152.  
  4153. You->>Keyboard: Presses "H"
  4154. Keyboard->>Handler: "H received"
  4155. Handler->>Handler: Updates command line
  4156. Handler->>You: Shows "H" on screen
  4157. ```
  4158.  
  4159. ## A Simple Example
  4160.  
  4161. Let's see history in action:
  4162.  
  4163. 1. You type: `ask about weather`
  4164. 2. Later, press ↑ (up arrow)
  4165. 3. Your previous command reappears!
  4166.  
  4167. ```typescript
  4168. // After typing some commands
  4169. > ask about weather
  4170. > list files
  4171.  
  4172. // Press up arrow
  4173. > list files [from history]
  4174. ```
  4175.  
  4176. ## Behind the Scenes
  4177.  
  4178. The input handler manages three key parts (simplified):
  4179.  
  4180. ```typescript
  4181. class InputHandler {
  4182. private history = [];
  4183. private currentInput = "";
  4184.  
  4185. handleKey(key) {
  4186. if (key === "Up") return this.showHistory();
  4187. if (key === "Tab") return this.autocomplete();
  4188. this.currentInput += key;
  4189. }
  4190. }
  4191. ```
  4192.  
  4193. Key parts:
  4194. - `history` stores past commands
  4195. - `currentInput` tracks what you're typing
  4196. - Special keys trigger different features
  4197.  
  4198. ## Smart Suggestions
  4199.  
  4200. When you type `@file`, the system suggests matching files:
  4201.  
  4202. ```typescript
  4203. // You type:
  4204. > @src/
  4205.  
  4206. // System suggests:
  4207. > @src/index.ts
  4208. > @src/utils.js
  4209. ```
  4210.  
  4211. This makes referencing files super easy!
  4212.  
  4213. ## Switching Modes
  4214.  
  4215. Press `!` to toggle between chat and shell modes:
  4216.  
  4217. ```typescript
  4218. // In chat mode
  4219. > ask about weather
  4220.  
  4221. // Press !
  4222. ! ls -la # Now in shell mode
  4223. ```
  4224.  
  4225. The border color changes to show which mode is active.
  4226.  
  4227. ## What's Next?
  4228.  
  4229. Now you understand how your CLI expertly handles all your input! In [Chapter 36: Interactive Shell Utilities](36_interactive_shell_utilities_.md), we'll explore the powerful tools available in shell mode.
  4230.  
  4231. > Pro Tip: Try pressing Tab after typing part of a filename to see autocomplete in action!
  4232.  
  4233. ---
  4234.  
  4235. # Chapter 36: Interactive Shell Utilities
  4236.  
  4237. Welcome back! In [Chapter 35: Input Handling](35_input_handling_.md), we learned how your CLI processes what you type. Now, let's meet your terminal's **helpful concierge** - Interactive Shell Utilities that make command-line work feel like a luxury hotel stay, complete with witty loading messages and smart suggestions!
  4238.  
  4239. ## Why Do We Need Shell Utilities?
  4240.  
  4241. Imagine you're checking into a fancy hotel. The concierge:
  4242. - Remembers your past stays (command history)
  4243. - Anticipates your needs (autocomplete)
  4244. - Entertains you while you wait (witty loading messages)
  4245.  
  4246. Our Interactive Shell Utilities do exactly this for your CLI! They provide:
  4247. 1. **Command History**: Cycle through past commands with up/down arrows
  4248. 2. **Smart Suggestions**: Get file and command autocomplete with Tab
  4249. 3. **Loading Entertainment**: Fun messages while waiting for responses
  4250.  
  4251. ## Meet Your Terminal Concierge
  4252.  
  4253. Let's explore the three main services:
  4254.  
  4255. ### 1. Command History - Your Personal Butler
  4256. Press ↑/↓ to cycle through past commands, just like asking the butler to recall your previous requests.
  4257.  
  4258. ```typescript
  4259. // After running these commands:
  4260. > ask about weather
  4261. > list files
  4262.  
  4263. // Press ↑ to see:
  4264. > list files
  4265. ```
  4266.  
  4267. ### 2. Smart Suggestions - The Anticipatory Assistant
  4268. Start typing a file path with `@` or a command with `/`, then press Tab for suggestions:
  4269.  
  4270. ```typescript
  4271. // Type @src/ then Tab to see:
  4272. @src/index.ts
  4273. @src/utils.js
  4274. ```
  4275.  
  4276. ### 3. Loading Messages - The Hotel Entertainer
  4277. While waiting for responses, enjoy witty phrases like:
  4278. ```
  4279. "Shipping awesomeness..."
  4280. "Counting electrons..."
  4281. "Consulting the digital spirits..."
  4282. ```
  4283.  
  4284. ## How It Works Behind the Scenes
  4285.  
  4286. When you press a key, here's what happens:
  4287.  
  4288. ```mermaid
  4289. sequenceDiagram
  4290. participant You as You
  4291. participant Keyboard as Keyboard
  4292. participant History as Command History
  4293. participant Suggest as Suggestions
  4294.  
  4295. You->>Keyboard: Presses ↑
  4296. Keyboard->>History: "Get previous command"
  4297. History-->>Keyboard: "list files"
  4298. Keyboard->>You: Shows past command
  4299. ```
  4300.  
  4301. ## A Simple Implementation
  4302.  
  4303. Here's how command history works (simplified):
  4304.  
  4305. ```typescript
  4306. class CommandHistory {
  4307. private history = [];
  4308.  
  4309. add(command) {
  4310. this.history.push(command);
  4311. }
  4312.  
  4313. getPrevious() {
  4314. return this.history[historyIndex--];
  4315. }
  4316. }
  4317. ```
  4318. This stores commands and lets you navigate them.
  4319.  
  4320. ## Customizing Your Experience
  4321.  
  4322. You can personalize the loading messages by modifying the phrases list:
  4323.  
  4324. ```typescript
  4325. const CUSTOM_PHRASES = [
  4326. "Brewing your coffee...",
  4327. "Training the AI hamsters...",
  4328. "Almost there!"
  4329. ];
  4330. ```
  4331.  
  4332. ## What's Next?
  4333.  
  4334. Now you understand how Interactive Shell Utilities make your CLI experience delightful! In [Chapter 37: Shell Command Execution](37_shell_command_execution_.md), we'll learn how your CLI actually runs the commands you enter.
  4335.  
  4336. > Pro Tip: Try pressing Tab after `@` to discover files in your project!
  4337.  
  4338. ---
  4339.  
  4340. # Chapter 37: Shell Command Execution
  4341.  
  4342. Welcome back! In [Chapter 36: Interactive Shell Utilities](36_interactive_shell_utilities_.md), we learned how your CLI makes command-line work more enjoyable. Now, let's meet your app's **command runner** - Shell Command Execution that safely runs terminal commands for you, like a trustworthy assistant who follows your instructions carefully and reports back with the results!
  4343.  
  4344. ## Why Do We Need Shell Command Execution?
  4345.  
  4346. Imagine you're teaching a new assistant how to help with computer tasks. You'd want them to:
  4347. 1. Run commands exactly as you say
  4348. 2. Show you the results clearly
  4349. 3. Stop immediately if something goes wrong
  4350.  
  4351. Shell Command Execution does exactly this! When you type commands like `ls` or `git status`, it:
  4352. - Runs them in the correct folder
  4353. - Captures all output (success or errors)
  4354. - Lets you cancel if needed
  4355. - Shows results in a readable way
  4356.  
  4357. ## Meet the Command Runner
  4358.  
  4359. Our command runner has three main jobs:
  4360.  
  4361. 1. **Execution**: Runs commands safely
  4362. 2. **Output Handling**: Captures and displays results
  4363. 3. **Control**: Lets you stop commands mid-run
  4364.  
  4365. Here's how simple it is to run a command:
  4366.  
  4367. ```typescript
  4368. import { runCommand } from 'gemini-cli';
  4369.  
  4370. // Run 'ls' to list files
  4371. const result = await runCommand('ls');
  4372. console.log(result.output); // Shows file list
  4373. ```
  4374.  
  4375. This runs the command and gives you the output.
  4376.  
  4377. ## How Command Execution Works
  4378.  
  4379. When you run a command, here's what happens behind the scenes:
  4380.  
  4381. ```mermaid
  4382. sequenceDiagram
  4383. participant You as You
  4384. participant Runner as Command Runner
  4385. participant Terminal as Your Terminal
  4386.  
  4387. You->>Runner: "Run ls"
  4388. Runner->>Terminal: Executes command
  4389. Terminal-->>Runner: Returns file list
  4390. Runner->>You: Shows results
  4391. ```
  4392.  
  4393. ## A Simple Example
  4394.  
  4395. Let's see a complete command execution:
  4396.  
  4397. ```typescript
  4398. // Run a command and handle results
  4399. const { output, error } = await runCommand('pwd');
  4400.  
  4401. if (error) {
  4402. console.error('Oops:', error);
  4403. } else {
  4404. console.log('Current folder:', output);
  4405. }
  4406. ```
  4407.  
  4408. This shows the current working directory or any errors.
  4409.  
  4410. ## Behind the Scenes
  4411.  
  4412. The runner handles commands carefully (simplified from our code):
  4413.  
  4414. ```typescript
  4415. async function runCommand(command) {
  4416. // 1. Start the command
  4417. const process = startProcess(command);
  4418.  
  4419. // 2. Collect output
  4420. let output = '';
  4421. process.stdout.on('data', (data) => {
  4422. output += data;
  4423. });
  4424.  
  4425. // 3. Wait for completion
  4426. await process.completion;
  4427. return { output };
  4428. }
  4429. ```
  4430.  
  4431. Key steps:
  4432. 1. Starts the command
  4433. 2. Collects output as it comes
  4434. 3. Returns everything when done
  4435.  
  4436. ## Safety Features
  4437.  
  4438. The runner includes important protections:
  4439. - Timeouts for long-running commands
  4440. - Binary output detection
  4441. - Proper error handling
  4442.  
  4443. ```typescript
  4444. // Run with timeout
  4445. await runCommand('long-task', { timeout: 5000 });
  4446. // Cancels after 5 seconds
  4447. ```
  4448.  
  4449. ## Common Patterns
  4450.  
  4451. You'll often use command execution to:
  4452. 1. **Check System Info**: Like `node --version`
  4453. 2. **Run Build Tools**: Like `npm install`
  4454. 3. **Manage Files**: Like `ls` or `cat`
  4455.  
  4456. ## What's Next?
  4457.  
  4458. Now you understand how your CLI safely runs terminal commands! In [Chapter 38: Shell Execution](38_shell_execution_.md), we'll explore more advanced ways to work with the shell.
  4459.  
  4460. > Pro Tip: Try running simple commands like `date` or `whoami` to see the execution system in action!
  4461.  
  4462. ---
  4463.  
  4464. # Chapter 38: Shell Execution
  4465.  
  4466. Welcome back! In [Chapter 37: Shell Command Execution](37_shell_command_execution_.md), we learned how your CLI runs terminal commands. Now, let's meet your app's **security guard** - Shell Execution that carefully checks permissions before running any system commands, like a bouncer who verifies IDs before letting anyone into a club!
  4467.  
  4468. ## Why Do We Need Shell Execution?
  4469.  
  4470. Imagine you're building a robot assistant that can run commands on your computer. You wouldn't want it to:
  4471. - Delete important files by accident
  4472. - Run dangerous commands without asking
  4473. - Access private folders without permission
  4474.  
  4475. Shell Execution solves this by:
  4476. 1. Checking if commands are allowed (like a security checklist)
  4477. 2. Asking for confirmation on risky operations
  4478. 3. Running commands in a safe environment
  4479.  
  4480. ## Meet the Command Checker
  4481.  
  4482. Shell Execution works like a careful assistant with three rules:
  4483.  
  4484. 1. **Permission Check**: Is this command allowed?
  4485. 2. **Confirmation**: Should we really run this?
  4486. 3. **Safe Execution**: Run it carefully and watch for problems
  4487.  
  4488. Here's how simple it is to run a safe command:
  4489.  
  4490. ```typescript
  4491. import { safeShell } from 'gemini-cli';
  4492.  
  4493. // Try to list files
  4494. const result = await safeShell('ls');
  4495. console.log(result); // Shows files or error if blocked
  4496. ```
  4497.  
  4498. This runs `ls` only if it passes all safety checks!
  4499.  
  4500. ## How Shell Execution Works
  4501.  
  4502. When you run a command, here's what happens behind the scenes:
  4503.  
  4504. ```mermaid
  4505. sequenceDiagram
  4506. participant You as You
  4507. participant Guard as Security Guard
  4508. participant Shell as Terminal
  4509.  
  4510. You->>Guard: "Run ls"
  4511. Guard->>Guard: Checks if allowed
  4512. Guard->>Shell: Runs only if safe
  4513. Shell-->>Guard: Returns results
  4514. Guard->>You: Shows output or error
  4515. ```
  4516.  
  4517. ## A Simple Example
  4518.  
  4519. Let's see permission checks in action:
  4520.  
  4521. ```typescript
  4522. // Safe command
  4523. await safeShell('date'); // Shows current date
  4524.  
  4525. // Dangerous command (blocked)
  4526. await safeShell('rm *'); // Error: Command not allowed
  4527. ```
  4528.  
  4529. The system automatically blocks risky commands like file deletion.
  4530.  
  4531. ## Behind the Scenes
  4532.  
  4533. The security check looks like this (simplified):
  4534.  
  4535. ```typescript
  4536. function isAllowed(command) {
  4537. const blocked = ['rm', 'format', 'shutdown'];
  4538. return !blocked.some(cmd => command.includes(cmd));
  4539. }
  4540. ```
  4541.  
  4542. Key parts:
  4543. - List of dangerous commands
  4544. - Simple check against that list
  4545. - Blocks anything risky
  4546.  
  4547. ## Safety Features
  4548.  
  4549. Shell Execution includes important protections:
  4550. - Blocks command chains (`;` or `&&`)
  4551. - Asks before running new commands
  4552. - Runs in limited environments
  4553.  
  4554. ```typescript
  4555. // Will ask for confirmation first
  4556. await safeShell('npm install', { ask: true });
  4557. ```
  4558.  
  4559. ## Common Patterns
  4560.  
  4561. You'll often use Shell Execution for:
  4562. 1. **Safe File Operations**: Like `ls` or `cat`
  4563. 2. **Build Tools**: Like `npm install` (with confirmation)
  4564. 3. **System Checks**: Like `node --version`
  4565.  
  4566. ## What's Next?
  4567.  
  4568. Now you understand how your CLI safely runs system commands! In [Chapter 39: Tool Scheduler](39_tool_scheduler_.md), we'll learn how your app manages multiple tools running at once.
  4569.  
  4570. > Pro Tip: Try running different commands to see which ones require confirmation!
  4571.  
  4572. ---
  4573.  
  4574. # Chapter 39: Tool Scheduler
  4575.  
  4576. Welcome back! In [Chapter 38: Shell Execution](38_shell_execution_.md), we learned how your CLI safely runs system commands. Now, let's meet your app's **air traffic controller** - the Tool Scheduler that carefully manages all your CLI tools, making sure they run in the right order and don't crash into each other!
  4577.  
  4578. ## Why Do We Need a Tool Scheduler?
  4579.  
  4580. Imagine you're hosting a party with multiple entertainers:
  4581. - A magician needs the stage at 7pm
  4582. - The band needs setup time before playing
  4583. - The caterers must finish before cleanup starts
  4584.  
  4585. The Tool Scheduler does exactly this for your CLI tools! It:
  4586. 1. **Organizes** when tools should run
  4587. 2. **Checks** if they're safe to execute
  4588. 3. **Tracks** their progress
  4589. 4. **Handles** any problems that come up
  4590.  
  4591. ## Meet the Tool Lifecycle
  4592.  
  4593. Every tool goes through these simple stages:
  4594.  
  4595. 1. **Scheduled**: Added to the to-do list
  4596. 2. **Validating**: Checking if it's safe to run
  4597. 3. **Awaiting Approval**: Waiting for your OK (if needed)
  4598. 4. **Executing**: Running the actual tool
  4599. 5. **Completed**: Finished successfully or with errors
  4600.  
  4601. Here's how simple it is to schedule a tool:
  4602.  
  4603. ```typescript
  4604. import { scheduleTool } from 'gemini-cli';
  4605.  
  4606. // Schedule a search tool
  4607. scheduleTool({
  4608. name: "web_search",
  4609. args: { query: "best pizza places" }
  4610. });
  4611. ```
  4612.  
  4613. This adds the search to the scheduler's queue.
  4614.  
  4615. ## How the Scheduler Works
  4616.  
  4617. When you schedule a tool, here's what happens behind the scenes:
  4618.  
  4619. ```mermaid
  4620. sequenceDiagram
  4621. participant You as You
  4622. participant Scheduler as Tool Scheduler
  4623. participant Tool as The Tool
  4624.  
  4625. You->>Scheduler: "Run web_search"
  4626. Scheduler->>Tool: Checks if safe
  4627. Tool-->>Scheduler: "Looks good!"
  4628. Scheduler->>Tool: Runs when ready
  4629. Tool-->>You: Returns pizza places
  4630. ```
  4631.  
  4632. ## A Simple Example
  4633.  
  4634. Let's schedule and run a simple tool:
  4635.  
  4636. ```typescript
  4637. // Schedule a greeting tool
  4638. const greetingCall = {
  4639. name: "greet",
  4640. args: { name: "Alice" }
  4641. };
  4642.  
  4643. // Run it through the scheduler
  4644. scheduleTool(greetingCall);
  4645. ```
  4646.  
  4647. This will:
  4648. 1. Validate the greet tool
  4649. 2. Run it immediately (since it's safe)
  4650. 3. Return "Hello Alice!"
  4651.  
  4652. ## Behind the Scenes
  4653.  
  4654. The scheduler manages tools in different states (simplified from our code):
  4655.  
  4656. ```typescript
  4657. class ToolScheduler {
  4658. private tools = [];
  4659.  
  4660. schedule(tool) {
  4661. this.tools.push({
  4662. ...tool,
  4663. status: 'scheduled'
  4664. });
  4665. this.runNextTool();
  4666. }
  4667. }
  4668. ```
  4669.  
  4670. Key parts:
  4671. - Keeps a list of scheduled tools
  4672. - Tracks each tool's status
  4673. - Runs tools when ready
  4674.  
  4675. ## Handling Special Cases
  4676.  
  4677. The scheduler also manages tricky situations:
  4678. - Tools that need approval first
  4679. - Tools that depend on others finishing
  4680. - Tools that fail mid-execution
  4681.  
  4682. ```typescript
  4683. // Tool that requires approval
  4684. scheduleTool({
  4685. name: "delete_file",
  4686. args: { file: "temp.txt" },
  4687. needsApproval: true
  4688. });
  4689. ```
  4690.  
  4691. This will pause and ask "Are you sure?" before running.
  4692.  
  4693. ## What's Next?
  4694.  
  4695. Now you understand how your CLI safely manages multiple tools! In [Chapter 40: Tool Framework](40_tool_framework_.md), we'll explore how to create your own custom tools for the scheduler to manage.
  4696.  
  4697. > Pro Tip: Try scheduling multiple tools to see how the system manages them in order!
  4698.  
  4699. ---
  4700.  
  4701. # Chapter 40: Tool Framework
  4702.  
  4703. Welcome back! In [Chapter 39: Tool Scheduler](39_tool_scheduler_.md), we learned how your CLI manages multiple tools running at once. Now, let's meet the **master builder** of your CLI - the Tool Framework that provides everything needed to create new tools, like a complete workshop where you can build any tool you can imagine!
  4704.  
  4705. ## Why Do We Need a Tool Framework?
  4706.  
  4707. Imagine you're opening a new toolbox. Inside you find:
  4708. - A hammer for nails
  4709. - A screwdriver for screws
  4710. - A wrench for bolts
  4711.  
  4712. The Tool Framework is like this toolbox for your CLI, but instead of physical tools, it helps you create digital ones! It provides:
  4713. 1. **Blueprints**: Standard ways to define tools
  4714. 2. **Materials**: Common functions all tools need
  4715. 3. **Safety Checks**: Protection against mistakes
  4716.  
  4717. ## Meet the Basic Tools
  4718.  
  4719. Let's look at three simple tools you might create:
  4720.  
  4721. 1. **Greet Tool**: Says hello to someone
  4722. 2. **Calculator**: Does simple math
  4723. 3. **File Reader**: Shows file contents
  4724.  
  4725. Each follows the same simple pattern:
  4726.  
  4727. ```typescript
  4728. interface Tool {
  4729. name: string;
  4730. description: string;
  4731. execute(params): Promise<Result>;
  4732. }
  4733. ```
  4734.  
  4735. This means every tool has:
  4736. - A name (like "greet")
  4737. - A description (what it does)
  4738. - An execute method (how to run it)
  4739.  
  4740. ## A Simple Example
  4741.  
  4742. Here's how to create a basic greet tool:
  4743.  
  4744. ```typescript
  4745. const greetTool = {
  4746. name: "greet",
  4747. description: "Says hello to someone",
  4748. execute: ({name}) => `Hello ${name}!`
  4749. };
  4750.  
  4751. // Using the tool:
  4752. const result = await greetTool.execute({name: "Alice"});
  4753. console.log(result); // "Hello Alice!"
  4754. ```
  4755.  
  4756. This shows how simple tools can be - just a name, description, and action!
  4757.  
  4758. ## How Tools Work Together
  4759.  
  4760. When you use a tool, here's what happens:
  4761.  
  4762. ```mermaid
  4763. sequenceDiagram
  4764. participant You as You
  4765. participant Framework as Tool Framework
  4766. participant Tool as The Tool
  4767.  
  4768. You->>Framework: "Use the greet tool"
  4769. Framework->>Tool: Finds and runs
  4770. Tool->>Framework: Returns greeting
  4771. Framework->>You: Shows "Hello Alice!"
  4772. ```
  4773.  
  4774. ## Behind the Scenes
  4775.  
  4776. The framework handles important tasks for every tool (simplified from our code):
  4777.  
  4778. ```typescript
  4779. class ToolFramework {
  4780. private tools = [];
  4781.  
  4782. register(tool) {
  4783. this.tools.push(tool); // Add to collection
  4784. }
  4785.  
  4786. run(name, params) {
  4787. const tool = this.tools.find(t => t.name === name);
  4788. return tool.execute(params); // Run it
  4789. }
  4790. }
  4791. ```
  4792.  
  4793. Key parts:
  4794. - Stores all registered tools
  4795. - Finds tools by name
  4796. - Runs them with provided parameters
  4797.  
  4798. ## Creating Different Tools
  4799.  
  4800. The framework makes it easy to create various tools:
  4801.  
  4802. ```typescript
  4803. // Calculator tool
  4804. const calcTool = {
  4805. name: "calculate",
  4806. description: "Does math operations",
  4807. execute: ({operation, a, b}) => eval(`${a} ${operation} ${b}`)
  4808. };
  4809.  
  4810. // File reader tool
  4811. const fileTool = {
  4812. name: "read_file",
  4813. description: "Reads file contents",
  4814. execute: async ({path}) => fs.readFile(path)
  4815. };
  4816. ```
  4817.  
  4818. Each follows the same pattern but does different work!
  4819.  
  4820. ## Common Tool Patterns
  4821.  
  4822. You'll often create tools that:
  4823. 1. **Read Data**: Like our file reader
  4824. 2. **Process Information**: Like the calculator
  4825. 3. **Modify Files**: Like a text editor
  4826.  
  4827. ## What's Next?
  4828.  
  4829. Now you understand how the Tool Framework helps build all your CLI's capabilities! In [Chapter 41: Custom Hooks](41_custom_hooks_.md), we'll learn how to add special behaviors that run before or after tools execute.
  4830.  
  4831. > Pro Tip: Try creating a simple tool that returns the current time to see the framework in action!
  4832.  
  4833. ---
  4834.  
  4835. # Chapter 41: Custom Hooks
  4836.  
  4837. Welcome back! In [Chapter 40: Tool Framework](40_tool_framework_.md), we learned how to build custom tools for your CLI. Now, let's meet your app's **special helpers** - Custom Hooks that add reusable behaviors to your tools, like magical ingredients that give your tools superpowers!
  4838.  
  4839. ## Why Do We Need Custom Hooks?
  4840.  
  4841. Imagine you're baking cookies and need to:
  4842. 1. Set a timer (so they don't burn)
  4843. 2. Check the oven temperature (for perfect baking)
  4844. 3. Know when they're ready (to take them out)
  4845.  
  4846. Custom Hooks do exactly this for your CLI tools! They provide reusable functions like:
  4847. - Timers that count seconds
  4848. - Git branch detection
  4849. - Automatic approval checks
  4850.  
  4851. Instead of writing these from scratch each time, you can use pre-made hooks!
  4852.  
  4853. ## Meet Three Simple Hooks
  4854.  
  4855. Let's look at three handy hooks you can use:
  4856.  
  4857. 1. **useTimer**: Like a kitchen timer for your tools
  4858. 2. **useGitBranchName**: Knows which git branch you're using
  4859. 3. **useAutoAccept**: Automatically approves safe actions
  4860.  
  4861. Here's how easy it is to use the timer hook:
  4862.  
  4863. ```typescript
  4864. import { useTimer } from 'gemini-cli';
  4865.  
  4866. // Start a timer that counts up every second
  4867. const seconds = useTimer(true);
  4868. console.log(`Running for ${seconds} seconds...`);
  4869. ```
  4870.  
  4871. This creates a timer that updates automatically!
  4872.  
  4873. ## How Hooks Work Together
  4874.  
  4875. When you use a hook, here's what happens behind the scenes:
  4876.  
  4877. ```mermaid
  4878. sequenceDiagram
  4879. participant You as Your Tool
  4880. participant Hook as Custom Hook
  4881. participant React as React System
  4882.  
  4883. You->>Hook: "Start timer"
  4884. Hook->>React: Sets up timer
  4885. React->>Hook: Updates every second
  4886. Hook->>You: Returns current time
  4887. ```
  4888.  
  4889. ## A Simple Example
  4890.  
  4891. Let's use the git branch hook:
  4892.  
  4893. ```typescript
  4894. import { useGitBranchName } from 'gemini-cli';
  4895.  
  4896. // Get current git branch
  4897. const branch = useGitBranchName('./');
  4898. console.log(`Working on branch: ${branch}`);
  4899. ```
  4900.  
  4901. This automatically detects and tracks your git branch!
  4902.  
  4903. ## Behind the Scenes
  4904.  
  4905. Hooks use React's magic to remember state. Here's a simplified version of the timer hook:
  4906.  
  4907. ```typescript
  4908. function useTimer(isActive) {
  4909. const [seconds, setSeconds] = useState(0);
  4910.  
  4911. useEffect(() => {
  4912. if (!isActive) return;
  4913.  
  4914. const timer = setInterval(() => {
  4915. setSeconds(s => s + 1); // Add 1 second
  4916. }, 1000);
  4917.  
  4918. return () => clearInterval(timer); // Clean up
  4919. }, [isActive]);
  4920.  
  4921. return seconds;
  4922. }
  4923. ```
  4924.  
  4925. Key parts:
  4926. - `useState` remembers the current time
  4927. - `useEffect` runs the timer
  4928. - Cleanup prevents memory leaks
  4929.  
  4930. ## Common Hook Patterns
  4931.  
  4932. You'll often use hooks for:
  4933. 1. **Timers**: Track operation duration
  4934. 2. **Git Info**: Detect branches and changes
  4935. 3. **Auto-Approval**: Skip confirmations for safe actions
  4936.  
  4937. ## What's Next?
  4938.  
  4939. Now you understand how Custom Hooks add reusable behaviors to your CLI! In [Chapter 42: Layout Management](42_layout_management_.md), we'll learn how to organize your terminal interface beautifully.
  4940.  
  4941. > Pro Tip: Try combining multiple hooks in one tool to see how they work together!
  4942.  
  4943. ---
  4944.  
  4945. # Chapter 42: Layout Management
  4946.  
  4947. Welcome back! In [Chapter 41: Custom Hooks](41_custom_hooks_.md), we learned how to add reusable behaviors to our CLI tools. Now, let's meet your terminal's **interior designer** - Layout Management that carefully arranges all your content to fit perfectly on screen, just like a smart bookshelf that automatically adjusts to hold all your books neatly!
  4948.  
  4949. ## Why Do We Need Layout Management?
  4950.  
  4951. Imagine typing a long message in your terminal. Without proper layout:
  4952. - Text might disappear off the screen
  4953. - Important parts could get cut off
  4954. - The display would look messy
  4955.  
  4956. Layout Management solves this by:
  4957. 1. Making sure content fits within terminal boundaries
  4958. 2. Handling overflow gracefully (with "show more" options)
  4959. 3. Keeping everything neatly organized
  4960.  
  4961. ## Meet the Three Layout Helpers
  4962.  
  4963. Our layout system has three main components:
  4964.  
  4965. 1. **Boxes**: Containers that hold your content
  4966. 2. **Text Wrapping**: Makes long lines fit neatly
  4967. 3. **Overflow Handling**: Manages when content is too big
  4968.  
  4969. Here's a simple example of creating a box:
  4970.  
  4971. ```typescript
  4972. import { Box, Text } from 'gemini-cli';
  4973.  
  4974. function MyComponent() {
  4975. return (
  4976. <Box width={40}>
  4977. <Text>This text stays neatly within 40 columns!</Text>
  4978. </Box>
  4979. );
  4980. }
  4981. ```
  4982.  
  4983. This creates a container that keeps your text perfectly sized.
  4984.  
  4985. ## How Layout Works Together
  4986.  
  4987. When you display content, here's what happens behind the scenes:
  4988.  
  4989. ```mermaid
  4990. sequenceDiagram
  4991. participant You as Your Component
  4992. participant Layout as Layout System
  4993. participant Terminal as Screen
  4994.  
  4995. You->>Layout: "Show this text"
  4996. Layout->>Terminal: Checks available space
  4997. Terminal-->>Layout: "You have 80 columns"
  4998. Layout->>Terminal: Fits text perfectly
  4999. Terminal->>You: Displays neat content
  5000. ```
  5001.  
  5002. ## A Simple Example
  5003.  
  5004. Let's create a component with automatic wrapping:
  5005.  
  5006. ```typescript
  5007. function LongMessage() {
  5008. return (
  5009. <Box width={30}>
  5010. <Text wrap="wrap">
  5011. This long message will automatically wrap to fit within 30 columns!
  5012. </Text>
  5013. </Box>
  5014. );
  5015. }
  5016. ```
  5017.  
  5018. The text will break into multiple lines to stay within the box's width.
  5019.  
  5020. ## Behind the Scenes
  5021.  
  5022. The layout system measures content carefully (simplified from our code):
  5023.  
  5024. ```typescript
  5025. function measureText(text, maxWidth) {
  5026. const words = text.split(' ');
  5027. let currentLine = '';
  5028. let lines = [];
  5029.  
  5030. words.forEach(word => {
  5031. if (currentLine.length + word.length <= maxWidth) {
  5032. currentLine += word + ' ';
  5033. } else {
  5034. lines.push(currentLine);
  5035. currentLine = word + ' ';
  5036. }
  5037. });
  5038.  
  5039. lines.push(currentLine);
  5040. return lines;
  5041. }
  5042. ```
  5043.  
  5044. Key steps:
  5045. 1. Splits text into words
  5046. 2. Fits as many words as possible per line
  5047. 3. Creates new lines when needed
  5048.  
  5049. ## Handling Overflow
  5050.  
  5051. When content is too tall, the system shows helpful messages:
  5052.  
  5053. ```typescript
  5054. function ShowMoreLines() {
  5055. return (
  5056. <Text color="gray">
  5057. Press ctrl-s to show more lines
  5058. </Text>
  5059. );
  5060. }
  5061. ```
  5062.  
  5063. This appears when content is truncated due to space limits.
  5064.  
  5065. ## Common Layout Patterns
  5066.  
  5067. You'll often use:
  5068. 1. **Fixed Width Boxes**: For consistent sizing
  5069. 2. **Flexible Containers**: That grow with content
  5070. 3. **Scrollable Areas**: For long content
  5071.  
  5072. ## What's Next?
  5073.  
  5074. Now you understand how to beautifully arrange content in your terminal! In [Chapter 43: Shared UI Components](43_shared_ui_components_.md), we'll explore ready-made components you can use in your CLI apps.
  5075.  
  5076. > Pro Tip: Try creating boxes with different widths to see how text automatically adjusts!
  5077.  
  5078. ---
  5079.  
  5080. # Chapter 43: Shared UI Components
  5081.  
  5082. Welcome back! In [Chapter 42: Layout Management](42_layout_management_.md), we learned how to organize content beautifully in our terminal. Now, let's meet your CLI's **building block set** - Shared UI Components that provide ready-to-use interface pieces like radio buttons and boxes, just like LEGO bricks you can snap together to build amazing terminal interfaces!
  5083.  
  5084. ## Why Do We Need Shared Components?
  5085.  
  5086. Imagine you're building a terminal app with settings. You'd need:
  5087. - Radio buttons to choose options
  5088. - Boxes to group related settings
  5089. - Text areas for input
  5090.  
  5091. Instead of building these from scratch each time, Shared UI Components provide them ready-made! They're like a toolbox full of pre-built parts that:
  5092. 1. Look consistent across your app
  5093. 2. Work the same way everywhere
  5094. 3. Save you tons of time
  5095.  
  5096. ## Meet the Component Collection
  5097.  
  5098. Our shared components include three essential pieces:
  5099.  
  5100. 1. **Radio Buttons**: For selecting one option from many
  5101. 2. **Constrained Boxes**: Containers that manage their size
  5102. 3. **Text Displays**: For showing formatted messages
  5103.  
  5104. Here's how simple it is to use a radio button:
  5105.  
  5106. ```typescript
  5107. import { RadioButtonSelect } from 'gemini-cli';
  5108.  
  5109. // Simple theme selector
  5110. const themeOptions = [
  5111. { label: "Dark", value: "dark" },
  5112. { label: "Light", value: "light" }
  5113. ];
  5114.  
  5115. function ThemePicker() {
  5116. return (
  5117. <RadioButtonSelect
  5118. items={themeOptions}
  5119. onSelect={(theme) => setTheme(theme)}
  5120. />
  5121. );
  5122. }
  5123. ```
  5124.  
  5125. This creates a clean theme selector with just a few lines!
  5126.  
  5127. ## How Components Work Together
  5128.  
  5129. When you use a radio button, here's what happens:
  5130.  
  5131. ```mermaid
  5132. sequenceDiagram
  5133. participant You as Your App
  5134. participant Radio as Radio Button
  5135. participant Terminal as Screen
  5136.  
  5137. You->>Radio: Show these options
  5138. Radio->>Terminal: Draws buttons
  5139. Terminal->>You: User selects one
  5140. You->>Radio: Gets the selection
  5141. ```
  5142.  
  5143. ## A Simple Example
  5144.  
  5145. Let's build a settings panel with multiple components:
  5146.  
  5147. ```typescript
  5148. function Settings() {
  5149. return (
  5150. <Box borderStyle="round">
  5151. <Text bold>Settings</Text>
  5152. <RadioButtonSelect items={themeOptions} />
  5153. <Text>Enter your name:</Text>
  5154. <Input />
  5155. </Box>
  5156. );
  5157. }
  5158. ```
  5159.  
  5160. This creates:
  5161. - A bordered box
  5162. - A title
  5163. - Theme radio buttons
  5164. - A text input field
  5165.  
  5166. ## Behind the Scenes
  5167.  
  5168. The radio button component works like this (simplified):
  5169.  
  5170. ```typescript
  5171. function RadioButton({ label, selected }) {
  5172. return (
  5173. <Text>
  5174. {selected ? '●' : '○'} {label}
  5175. </Text>
  5176. );
  5177. }
  5178. ```
  5179.  
  5180. Key parts:
  5181. - Shows a filled (●) or empty (○) circle
  5182. - Displays the label text
  5183. - Changes based on selection
  5184.  
  5185. ## Constrained Boxes
  5186.  
  5187. The `MaxSizedBox` component automatically fits content:
  5188.  
  5189. ```typescript
  5190. <MaxSizedBox maxWidth={40}>
  5191. <Text>This text stays within 40 columns!</Text>
  5192. </MaxSizedBox>
  5193. ```
  5194.  
  5195. This ensures content never overflows the specified width.
  5196.  
  5197. ## Common Patterns
  5198.  
  5199. You'll often use shared components to:
  5200. 1. **Build Forms**: With inputs and buttons
  5201. 2. **Create Menus**: With selectable options
  5202. 3. **Display Alerts**: In consistent boxes
  5203.  
  5204. ## What's Next?
  5205.  
  5206. Now you understand how to quickly build interfaces with Shared UI Components! In [Chapter 44: Editor Integration](44_editor_integration_.md), we'll learn how to connect your CLI with code editors for an even better workflow.
  5207.  
  5208. > Pro Tip: Try combining different components to create your own custom interfaces!
  5209.  
  5210. ---
  5211.  
  5212. # Chapter 44: Editor Integration
  5213.  
  5214. Welcome back! In [Chapter 43: Shared UI Components](43_shared_ui_components_.md), we learned how to build beautiful terminal interfaces. Now, let's meet your CLI's **universal remote control** - Editor Integration that lets you connect with different code editors, just like one remote that works with all your TV, sound system, and streaming devices!
  5215.  
  5216. ## Why Do We Need Editor Integration?
  5217.  
  5218. Imagine you're working on a coding project and want to:
  5219. 1. Open a file in your favorite editor
  5220. 2. Compare changes between versions
  5221. 3. Edit code directly from the CLI
  5222.  
  5223. Without editor integration, you'd need to manually:
  5224. - Find the file
  5225. - Open your editor
  5226. - Navigate to the right line
  5227.  
  5228. Editor Integration does all this automatically! It's like having a personal assistant who knows exactly how to work with your preferred editor.
  5229.  
  5230. ## Meet the Editor Remote Control
  5231.  
  5232. Our editor integration works with popular editors like:
  5233. - VS Code
  5234. - Vim/Neovim
  5235. - Zed
  5236. - And more!
  5237.  
  5238. Here's how simple it is to open a file:
  5239.  
  5240. ```typescript
  5241. import { openInEditor } from 'gemini-cli';
  5242.  
  5243. // Open config.json in your default editor
  5244. await openInEditor('config.json');
  5245. ```
  5246.  
  5247. This automatically launches your editor with the file ready to edit!
  5248.  
  5249. ## How Editor Integration Works
  5250.  
  5251. When you open a file, here's what happens behind the scenes:
  5252.  
  5253. ```mermaid
  5254. sequenceDiagram
  5255. participant You as You
  5256. participant CLI as Gemini CLI
  5257. participant Editor as Your Editor
  5258.  
  5259. You->>CLI: "Open config.json"
  5260. CLI->>Editor: Finds and launches editor
  5261. Editor-->>You: Shows the file ready to edit
  5262. ```
  5263.  
  5264. ## A Simple Example
  5265.  
  5266. Let's compare two file versions:
  5267.  
  5268. ```typescript
  5269. import { compareFiles } from 'gemini-cli';
  5270.  
  5271. // See differences between old and new versions
  5272. await compareFiles('old-code.js', 'new-code.js');
  5273. ```
  5274.  
  5275. This opens your editor's diff view showing all changes!
  5276.  
  5277. ## Behind the Scenes
  5278.  
  5279. The system checks which editors you have installed (simplified):
  5280.  
  5281. ```typescript
  5282. function findAvailableEditors() {
  5283. const editors = ['vscode', 'vim', 'zed'];
  5284. return editors.filter(editor => {
  5285. // Check if editor is installed
  5286. return checkEditorExists(editor);
  5287. });
  5288. }
  5289. ```
  5290.  
  5291. Key parts:
  5292. 1. Lists supported editors
  5293. 2. Checks which are installed
  5294. 3. Returns available options
  5295.  
  5296. ## Editor Commands
  5297.  
  5298. Each editor has specific commands for opening files:
  5299.  
  5300. ```typescript
  5301. const editorCommands = {
  5302. vscode: 'code --wait',
  5303. vim: 'vim',
  5304. zed: 'zed'
  5305. };
  5306. ```
  5307.  
  5308. These commands are used to launch the editors properly.
  5309.  
  5310. ## Common Uses
  5311.  
  5312. You'll often use editor integration to:
  5313. 1. **Edit Configs**: Quickly tweak settings
  5314. 2. **Review Changes**: Compare file versions
  5315. 3. **Fix Code**: Edit files directly from CLI output
  5316.  
  5317. ## What's Next?
  5318.  
  5319. Now you understand how to connect your CLI with any code editor! In [Chapter 45: Non-Interactive Mode](45_non_interactive_mode_.md), we'll learn how to run commands without user input for automation.
  5320.  
  5321. > Pro Tip: Try opening different file types to see how your editor handles them!
  5322.  
  5323. ---
  5324.  
  5325. # Chapter 45: Non-Interactive Mode
  5326.  
  5327. Welcome back! In [Chapter 44: Editor Integration](44_editor_integration_.md), we learned how to connect your CLI with code editors. Now, let's meet your app's **silent worker** - Non-Interactive Mode that lets your CLI run automatically without user input, like a robot chef that follows a recipe perfectly every time!
  5328.  
  5329. ## Why Do We Need Non-Interactive Mode?
  5330.  
  5331. Imagine you want to:
  5332. - Automatically process files every night
  5333. - Pipe questions to Gemini from another program
  5334. - Run commands from scripts without typing
  5335.  
  5336. Non-Interactive Mode makes this possible! It's like putting your CLI on autopilot - it accepts input, does the work, and gives output without any human interaction.
  5337.  
  5338. ## Meet the Silent Worker
  5339.  
  5340. Non-Interactive Mode has three simple jobs:
  5341. 1. **Take Input**: From files or other programs (stdin)
  5342. 2. **Process It**: Using Gemini's AI
  5343. 3. **Give Output**: To files or other programs (stdout)
  5344.  
  5345. Here's how simple it is to use:
  5346.  
  5347. ```bash
  5348. # Ask Gemini a question automatically
  5349. echo "What's 2+2?" | gemini-cli
  5350. # Output: 4
  5351. ```
  5352.  
  5353. This pipes your question directly to Gemini and shows the answer!
  5354.  
  5355. ## How Non-Interactive Mode Works
  5356.  
  5357. When you pipe a command, here's what happens:
  5358.  
  5359. ```mermaid
  5360. sequenceDiagram
  5361. participant Program as Other Program
  5362. participant CLI as Gemini CLI
  5363. participant Gemini as Gemini AI
  5364.  
  5365. Program->>CLI: "What's 2+2?"
  5366. CLI->>Gemini: Sends question
  5367. Gemini-->>CLI: Returns "4"
  5368. CLI->>Program: Outputs "4"
  5369. ```
  5370.  
  5371. ## A Simple Example
  5372.  
  5373. Let's process a file automatically:
  5374.  
  5375. ```bash
  5376. # File: questions.txt
  5377. What's 3×3?
  5378. Capital of France?
  5379.  
  5380. # Run Gemini on the file
  5381. cat questions.txt | gemini-cli
  5382. ```
  5383.  
  5384. This will output:
  5385. ```
  5386. 9
  5387. Paris
  5388. ```
  5389.  
  5390. ## Behind the Scenes
  5391.  
  5392. The CLI checks if it's in non-interactive mode (simplified):
  5393.  
  5394. ```typescript
  5395. if (!process.stdin.isTTY) { // If input is piped
  5396. const input = await readStdin(); // Read the input
  5397. runNonInteractive(input); // Process automatically
  5398. }
  5399. ```
  5400.  
  5401. Key parts:
  5402. 1. Checks if input is coming from a pipe
  5403. 2. Reads all the input at once
  5404. 3. Runs in non-interactive mode
  5405.  
  5406. ## Handling Tools Automatically
  5407.  
  5408. Even tools can run non-interactively:
  5409.  
  5410. ```typescript
  5411. // In non-interactive mode
  5412. if (needsApproval && !interactive) {
  5413. return "Can't run this tool automatically";
  5414. }
  5415. ```
  5416.  
  5417. This prevents risky tools from running without confirmation.
  5418.  
  5419. ## Common Uses
  5420.  
  5421. You'll often use non-interactive mode for:
  5422. 1. **Automation**: Nightly processing jobs
  5423. 2. **Scripting**: Building complex workflows
  5424. 3. **Piping**: Connecting with other CLI tools
  5425.  
  5426. ## What's Next?
  5427.  
  5428. Now you understand how to run your CLI automatically! In [Chapter 46: Utility Functions](46_utility_functions_.md), we'll explore helpful tools that make building CLI apps easier.
  5429.  
  5430. > Pro Tip: Try piping simple questions to your CLI to see non-interactive mode in action!
  5431.  
  5432. ---
  5433.  
  5434. # Chapter 46: Utility Functions
  5435.  
  5436. Welcome back! In [Chapter 45: Non-Interactive Mode](45_non_interactive_mode_.md), we learned how to run CLI commands automatically. Now, let's meet your app's **Swiss Army knife** - Utility Functions that provide handy little tools for common tasks, like a pocket toolkit with all the essentials you need for quick fixes!
  5437.  
  5438. ## Why Do We Need Utility Functions?
  5439.  
  5440. Imagine you're packing for a camping trip. You'd want:
  5441. - A small flashlight (for checking things)
  5442. - A multi-tool (for quick fixes)
  5443. - A notepad (for reminders)
  5444.  
  5445. Utility Functions are exactly this for your CLI app! They're small, reusable tools that handle common needs like:
  5446. - Cleaning up temporary files
  5447. - Checking your CLI version
  5448. - Reading user input
  5449. - Showing helpful warnings
  5450.  
  5451. ## Meet the Handy Helpers
  5452.  
  5453. Let's look at three simple utilities you'll use often:
  5454.  
  5455. 1. **Cleanup Crew**: Removes temporary files
  5456. 2. **Version Checker**: Tells you which CLI version you're using
  5457. 3. **Input Reader**: Gets text from user input
  5458.  
  5459. Here's how easy it is to check your CLI version:
  5460.  
  5461. ```typescript
  5462. import { getCliVersion } from 'gemini-cli';
  5463.  
  5464. // Get the current version
  5465. const version = await getCliVersion();
  5466. console.log(`You're using version ${version}`);
  5467. ```
  5468.  
  5469. This shows something like "You're using version 1.2.3".
  5470.  
  5471. ## How Utilities Work Together
  5472.  
  5473. When you use a utility function, here's what happens behind the scenes:
  5474.  
  5475. ```mermaid
  5476. sequenceDiagram
  5477. participant You as You
  5478. participant Utility as Utility Function
  5479. participant System as Your Computer
  5480.  
  5481. You->>Utility: "What's my version?"
  5482. Utility->>System: Checks package info
  5483. System-->>Utility: Returns "1.2.3"
  5484. Utility->>You: Shows the version
  5485. ```
  5486.  
  5487. ## A Simple Example
  5488.  
  5489. Let's clean up temporary files:
  5490.  
  5491. ```typescript
  5492. import { cleanupCheckpoints } from 'gemini-cli';
  5493.  
  5494. // Remove old temporary files
  5495. await cleanupCheckpoints();
  5496. console.log("All clean!");
  5497. ```
  5498.  
  5499. This safely deletes any leftover temporary files from previous runs.
  5500.  
  5501. ## Behind the Scenes
  5502.  
  5503. The version checker works like this (simplified):
  5504.  
  5505. ```typescript
  5506. async function getCliVersion() {
  5507. // 1. Check for override in environment
  5508. if (process.env.CLI_VERSION) {
  5509. return process.env.CLI_VERSION;
  5510. }
  5511.  
  5512. // 2. Read from package.json
  5513. const pkg = await readPackageJson();
  5514. return pkg?.version || 'unknown';
  5515. }
  5516. ```
  5517.  
  5518. Key steps:
  5519. 1. Checks environment variables first
  5520. 2. Falls back to package.json
  5521. 3. Returns "unknown" if all else fails
  5522.  
  5523. ## Reading User Input
  5524.  
  5525. Another handy utility reads typed input:
  5526.  
  5527. ```typescript
  5528. import { readStdin } from 'gemini-cli';
  5529.  
  5530. // Get text piped from another command
  5531. const input = await readStdin();
  5532. console.log(`You sent: ${input}`);
  5533. ```
  5534.  
  5535. This captures anything piped to your CLI (like `echo "hi" | gemini-cli`).
  5536.  
  5537. ## Common Utility Patterns
  5538.  
  5539. You'll often use utilities for:
  5540. 1. **Cleanup**: Removing temporary files
  5541. 2. **Info Checks**: Version, system details
  5542. 3. **Input/Output**: Reading and writing data
  5543.  
  5544. ## What's Next?
  5545.  
  5546. Now you understand how utility functions provide handy tools for common tasks! In [Chapter 47: Validation Framework](47_validation_framework_.md), we'll learn how to check if data meets certain rules.
  5547.  
  5548. > Pro Tip: Try using different utility functions to see how they simplify common tasks!
  5549.  
  5550. ---
  5551.  
  5552. # Chapter 47: Validation Framework
  5553.  
  5554. Welcome back! In [Chapter 46: Utility Functions](46_utility_functions_.md), we learned about handy helper tools for our CLI. Now, let's meet your app's **bouncer** - the Validation Framework that checks if everything is correct before letting it through, just like a club doorman who checks IDs before letting anyone inside!
  5555.  
  5556. ## Why Do We Need Validation?
  5557.  
  5558. Imagine you're running a pizza delivery app. Before sending out an order, you'd want to check:
  5559. - Does the address exist?
  5560. - Is the phone number valid?
  5561. - Did they order at least one pizza?
  5562.  
  5563. The Validation Framework does exactly this for your CLI! It makes sure:
  5564. 1. Commands have all required information
  5565. 2. Files are in allowed locations
  5566. 3. User inputs make sense
  5567.  
  5568. Without it, your app might try to deliver pizzas to "123 Fake Street" or accept orders for "minus 3 pizzas"!
  5569.  
  5570. ## Meet the Three Checks
  5571.  
  5572. Our validation system performs three main types of checks:
  5573.  
  5574. 1. **Required Fields**: Like making sure a pizza order has toppings
  5575. 2. **Correct Format**: Like checking if a phone number has 10 digits
  5576. 3. **Safety Rules**: Like not letting someone order 1000 pizzas at once
  5577.  
  5578. Here's how simple it is to validate a pizza order:
  5579.  
  5580. ```typescript
  5581. import { validateOrder } from 'pizza-cli';
  5582.  
  5583. const order = { toppings: ['cheese'], address: '123 Main St' };
  5584. const errors = validateOrder(order);
  5585.  
  5586. if (errors.length > 0) {
  5587. console.log("Order problems:", errors);
  5588. } else {
  5589. console.log("Order is valid!");
  5590. }
  5591. ```
  5592.  
  5593. This checks if the order has all needed info before processing.
  5594.  
  5595. ## How Validation Works
  5596.  
  5597. When you validate something, here's what happens behind the scenes:
  5598.  
  5599. ```mermaid
  5600. sequenceDiagram
  5601. participant You as You
  5602. participant Validator as Validation
  5603. participant Rules as Safety Rules
  5604.  
  5605. You->>Validator: "Check this order"
  5606. Validator->>Rules: "Is address valid?"
  5607. Rules-->>Validator: "Yes!"
  5608. Validator->>You: "All good!"
  5609. ```
  5610.  
  5611. ## A Simple Example
  5612.  
  5613. Let's validate a file path:
  5614.  
  5615. ```typescript
  5616. import { validatePath } from 'gemini-cli';
  5617.  
  5618. // Check if path is safe
  5619. const result = validatePath('/safe/folder/file.txt');
  5620. console.log(result.valid); // true or false
  5621. console.log(result.message); // "Path is valid" or why it's not
  5622. ```
  5623.  
  5624. This prevents accessing dangerous locations like `/etc/passwd`.
  5625.  
  5626. ## Behind the Scenes
  5627.  
  5628. The validator uses simple rules (simplified from our code):
  5629.  
  5630. ```typescript
  5631. function validatePath(path) {
  5632. const forbidden = ['/etc', '/sys', '/root'];
  5633. if (forbidden.some(f => path.startsWith(f))) {
  5634. return { valid: false, message: "Dangerous path!" };
  5635. }
  5636. return { valid: true, message: "Path is safe" };
  5637. }
  5638. ```
  5639.  
  5640. Key parts:
  5641. 1. List of banned folders
  5642. 2. Check if path starts with any
  5643. 3. Return validation result
  5644.  
  5645. ## Common Validation Patterns
  5646.  
  5647. You'll often validate:
  5648. 1. **User Input**: Like commands and queries
  5649. 2. **File Paths**: For safety
  5650. 3. **API Responses**: To ensure proper format
  5651.  
  5652. ## What's Next?
  5653.  
  5654. Now you understand how the Validation Framework keeps your CLI safe and correct! In [Chapter 48: Schema Validation](48_schema_validation_.md), we'll learn how to define more complex validation rules.
  5655.  
  5656. > Pro Tip: Try validating different file paths to see what gets allowed or blocked!
  5657.  
  5658. ---
  5659.  
  5660. # Chapter 48: Schema Validation
  5661.  
  5662. Welcome back! In [Chapter 47: Validation Framework](47_validation_framework_.md), we learned how to check if data meets basic requirements. Now, let's meet your CLI's **rule enforcer** - Schema Validation that ensures data structures match expected formats, just like a bouncer checking IDs at a club entrance to make sure everyone follows the dress code!
  5663.  
  5664. ## Why Do We Need Schema Validation?
  5665.  
  5666. Imagine you're running a pizza delivery app. Before accepting an order, you'd want to check:
  5667. - Does the order have all required fields (like toppings and address)?
  5668. - Is the phone number in the correct format?
  5669. - Are the quantities valid numbers?
  5670.  
  5671. Schema Validation does exactly this for your CLI! It acts like a strict but fair bouncer that:
  5672. 1. Checks if data has the right "shape"
  5673. 2. Verifies all required fields are present
  5674. 3. Ensures values match expected types
  5675.  
  5676. Without it, your app might accept pizza orders for "minus 3 pizzas" or deliver to "123 Fake Street"!
  5677.  
  5678. ## Meet the Simple Validator
  5679.  
  5680. Our Schema Validator works with three basic rules:
  5681.  
  5682. 1. **Required Fields**: Must-have items (like pizza toppings)
  5683. 2. **Type Checks**: Correct data types (numbers, strings, etc.)
  5684. 3. **Structure**: Proper organization (like address having street + city)
  5685.  
  5686. Here's how simple it is to validate a pizza order:
  5687.  
  5688. ```typescript
  5689. import { SchemaValidator } from 'gemini-cli';
  5690.  
  5691. // Define what a valid order looks like
  5692. const pizzaSchema = {
  5693. required: ['toppings', 'address'],
  5694. properties: {
  5695. toppings: { type: 'array' },
  5696. address: { type: 'string' }
  5697. }
  5698. };
  5699.  
  5700. // Check if an order is valid
  5701. const isValid = SchemaValidator.validate(pizzaSchema, order);
  5702. console.log(isValid); // true or false
  5703. ```
  5704.  
  5705. This checks if the order matches our pizza requirements!
  5706.  
  5707. ## How Validation Works
  5708.  
  5709. When validating data, here's what happens behind the scenes:
  5710.  
  5711. ```mermaid
  5712. sequenceDiagram
  5713. participant You as Your Code
  5714. participant Validator as Schema Validator
  5715. participant Data as Your Data
  5716.  
  5717. You->>Validator: "Check this pizza order"
  5718. Validator->>Data: "Has required toppings?"
  5719. Data-->>Validator: "Yes!"
  5720. Validator->>Data: "Is address a string?"
  5721. Data-->>Validator: "Yes!"
  5722. Validator->>You: "All good!"
  5723. ```
  5724.  
  5725. ## A Simple Example
  5726.  
  5727. Let's validate a user profile:
  5728.  
  5729. ```typescript
  5730. const profileSchema = {
  5731. required: ['name', 'age'],
  5732. properties: {
  5733. name: { type: 'string' },
  5734. age: { type: 'number' }
  5735. }
  5736. };
  5737.  
  5738. const user = { name: "Alice", age: 30 };
  5739. const isValid = SchemaValidator.validate(profileSchema, user);
  5740. // Returns true since all checks pass
  5741. ```
  5742.  
  5743. This ensures profiles have both a name (string) and age (number).
  5744.  
  5745. ## Behind the Scenes
  5746.  
  5747. The validator performs two main checks (simplified from our code):
  5748.  
  5749. ```typescript
  5750. // Check required fields
  5751. for (const field of schema.required) {
  5752. if (!(field in data)) {
  5753. return false; // Missing required field!
  5754. }
  5755. }
  5756.  
  5757. // Check types
  5758. for (const [field, rule] of Object.entries(schema.properties)) {
  5759. if (typeof data[field] !== rule.type) {
  5760. return false; // Wrong type!
  5761. }
  5762. }
  5763. ```
  5764.  
  5765. Key steps:
  5766. 1. Verifies all required fields exist
  5767. 2. Checks each field's type matches
  5768. 3. Returns true only if all checks pass
  5769.  
  5770. ## Handling Complex Data
  5771.  
  5772. The validator can also check nested structures:
  5773.  
  5774. ```typescript
  5775. const orderSchema = {
  5776. properties: {
  5777. customer: {
  5778. type: 'object',
  5779. properties: {
  5780. name: { type: 'string' }
  5781. }
  5782. }
  5783. }
  5784. };
  5785. ```
  5786.  
  5787. This ensures the customer field is an object with a name string.
  5788.  
  5789. ## What's Next?
  5790.  
  5791. Now you understand how Schema Validation keeps your CLI's data clean and correct! In [Chapter 49: Build Pipeline](49_build_pipeline_.md), we'll learn how your app gets packaged and prepared for users.
  5792.  
  5793. > Pro Tip: Try creating simple schemas for different data types to see how validation works!
  5794.  
  5795. ---
  5796.  
  5797. # Chapter 49: Build Pipeline
  5798.  
  5799. Welcome back! In [Chapter 48: Schema Validation](48_schema_validation_.md), we learned how to check if data follows the right structure. Now, let's meet your CLI's **automated factory** - the Build Pipeline that transforms your source code into a ready-to-use application, just like an assembly line that turns raw materials into finished products!
  5800.  
  5801. ## Why Do We Need a Build Pipeline?
  5802.  
  5803. Imagine you're baking cookies. You wouldn't want to:
  5804. - Mix ingredients by hand every time
  5805. - Bake each cookie separately
  5806. - Package them one at a time
  5807.  
  5808. A Build Pipeline solves this for your CLI app by automatically:
  5809. 1. Combining all code files
  5810. 2. Checking for errors
  5811. 3. Creating installable packages
  5812. 4. Testing everything works
  5813.  
  5814. It's like having a cookie factory that takes your recipe (source code) and produces perfect cookies (your app) every time!
  5815.  
  5816. ## Meet the Assembly Line
  5817.  
  5818. Our build pipeline has three simple stations:
  5819.  
  5820. 1. **Preparation**: Gets all ingredients (code files) ready
  5821. 2. **Processing**: Combines and checks everything
  5822. 3. **Packaging**: Creates the final product
  5823.  
  5824. Here's how simple it is to start a build:
  5825.  
  5826. ```bash
  5827. # Run the build pipeline
  5828. npm run build
  5829. ```
  5830.  
  5831. This single command triggers the entire process automatically!
  5832.  
  5833. ## How the Pipeline Works
  5834.  
  5835. When you run a build, here's what happens behind the scenes:
  5836.  
  5837. ```mermaid
  5838. sequenceDiagram
  5839. participant You as You
  5840. participant Prep as Preparation
  5841. participant Process as Processing
  5842. participant Package as Packaging
  5843.  
  5844. You->>Prep: "npm run build"
  5845. Prep->>Process: Gathers all code
  5846. Process->>Package: Checks and combines
  5847. Package->>You: Creates final app
  5848. ```
  5849.  
  5850. ## A Simple Example
  5851.  
  5852. Let's see what happens during a typical build:
  5853.  
  5854. 1. **Preparation**: Checks all files are present
  5855. 2. **Processing**: Combines TypeScript into JavaScript
  5856. 3. **Packaging**: Creates a `.tgz` file you can install
  5857.  
  5858. ```bash
  5859. # After running build, you get:
  5860. google-gemini-cli-1.0.0.tgz # Your finished app!
  5861. ```
  5862.  
  5863. ## Behind the Scenes
  5864.  
  5865. The build script does several important things (simplified):
  5866.  
  5867. ```javascript
  5868. // 1. Install dependencies if needed
  5869. if (!existsSync('node_modules')) {
  5870. run('npm install');
  5871. }
  5872.  
  5873. // 2. Build all packages
  5874. run('npm run build --workspaces');
  5875.  
  5876. // 3. Create final package
  5877. run('npm pack');
  5878. ```
  5879.  
  5880. Key steps:
  5881. 1. Ensures all tools are available
  5882. 2. Builds each part of your app
  5883. 3. Packages everything together
  5884.  
  5885. ## Handling Special Cases
  5886.  
  5887. The pipeline also manages tricky situations:
  5888. - Missing files
  5889. - Build errors
  5890. - Different operating systems
  5891.  
  5892. ```javascript
  5893. try {
  5894. runBuild();
  5895. } catch (error) {
  5896. console.log("Build failed!");
  5897. showHelpfulErrorMessage(error);
  5898. }
  5899. ```
  5900.  
  5901. This ensures you know exactly what went wrong if the build fails.
  5902.  
  5903. ## Common Build Patterns
  5904.  
  5905. You'll often use the build pipeline to:
  5906. 1. **Prepare Releases**: Create installable versions
  5907. 2. **Test Changes**: Verify everything works
  5908. 3. **Update Dependencies**: Get the latest tools
  5909.  
  5910. ## What's Next?
  5911.  
  5912. Now you understand how your CLI gets built and packaged automatically! In [Chapter 50: Package Management](50_package_management_.md), we'll learn how to share and install your finished application.
  5913.  
  5914. > Pro Tip: Try running the build command yourself to see the pipeline in action!
  5915.  
  5916. ---
  5917.  
  5918. # Chapter 50: Package Management
  5919.  
  5920. Welcome back! In [Chapter 49: Build Pipeline](49_build_pipeline_.md), we learned how your CLI gets built and packaged automatically. Now, let's meet your app's **librarian** - Package Management that carefully organizes all the different parts of your CLI, just like a librarian who keeps track of which books work well together!
  5921.  
  5922. ## Why Do We Need Package Management?
  5923.  
  5924. Imagine you're building a toy robot from different kits:
  5925. - The arms come from Kit A (version 2.0)
  5926. - The legs need Kit B (but only version 1.5 or higher)
  5927. - The head requires Kit C (but it conflicts with Kit A versions below 2.1)
  5928.  
  5929. Package Management solves this puzzle for your CLI by:
  5930. 1. Tracking which versions of different packages work together
  5931. 2. Making sure all parts are compatible
  5932. 3. Preventing version conflicts that could break your app
  5933.  
  5934. ## Meet the Package Organizer
  5935.  
  5936. Our Package Management system has three simple jobs:
  5937.  
  5938. 1. **Version Tracking**: Knows which versions work together
  5939. 2. **Dependency Checking**: Ensures all required packages are present
  5940. 3. **Conflict Prevention**: Stops incompatible combinations
  5941.  
  5942. Here's how simple it is to check dependencies:
  5943.  
  5944. ```typescript
  5945. import { checkDependencies } from 'gemini-cli';
  5946.  
  5947. // Verify all packages are compatible
  5948. const isValid = await checkDependencies();
  5949. console.log(isValid ? "All good!" : "Version conflict!");
  5950. ```
  5951.  
  5952. This checks if all your CLI's internal packages play nicely together.
  5953.  
  5954. ## How Package Management Works
  5955.  
  5956. When checking dependencies, here's what happens behind the scenes:
  5957.  
  5958. ```mermaid
  5959. sequenceDiagram
  5960. participant You as You
  5961. participant PM as Package Manager
  5962. participant Core as Core Package
  5963. participant CLI as CLI Package
  5964.  
  5965. You->>PM: "Check dependencies"
  5966. PM->>Core: "What version are you?"
  5967. Core-->>PM: "Version 2.0"
  5968. PM->>CLI: "Do you work with Core 2.0?"
  5969. CLI-->>PM: "Yes, I need Core >=1.5"
  5970. PM->>You: "All packages compatible!"
  5971. ```
  5972.  
  5973. ## A Simple Example
  5974.  
  5975. Let's declare some package requirements:
  5976.  
  5977. ```typescript
  5978. // In package.json
  5979. {
  5980. "name": "cli-tool",
  5981. "dependencies": {
  5982. "core-package": "^1.5.0",
  5983. "ui-package": "~2.0.3"
  5984. }
  5985. }
  5986. ```
  5987.  
  5988. This means:
  5989. - `core-package` needs version 1.5.0 or higher (but not 2.0.0)
  5990. - `ui-package` wants version 2.0.3 exactly (with only small updates allowed)
  5991.  
  5992. ## Behind the Scenes
  5993.  
  5994. The package manager checks versions like this (simplified):
  5995.  
  5996. ```typescript
  5997. function checkVersion(packageVersion, requiredVersion) {
  5998. // Check if installed version meets requirement
  5999. return semver.satisfies(packageVersion, requiredVersion);
  6000. }
  6001. ```
  6002.  
  6003. Key parts:
  6004. - `semver` library handles version comparisons
  6005. - Checks if installed version "satisfies" the requirement
  6006. - Returns true/false for compatibility
  6007.  
  6008. ## Handling Conflicts
  6009.  
  6010. When versions don't match, the system helps fix them:
  6011.  
  6012. ```typescript
  6013. async function resolveConflict() {
  6014. // Find compatible versions
  6015. const solutions = await findCompatibleVersions();
  6016.  
  6017. // Update package.json automatically
  6018. if (solutions.length > 0) {
  6019. await updatePackages(solutions[0]);
  6020. }
  6021. }
  6022. ```
  6023.  
  6024. This automatically suggests and applies fixes when possible.
  6025.  
  6026. ## Common Patterns
  6027.  
  6028. You'll often use Package Management to:
  6029. 1. **Add Features**: Install new packages
  6030. 2. **Update Safely**: Get latest compatible versions
  6031. 3. **Troubleshoot**: Fix version conflicts
  6032.  
  6033. ## What's Next?
  6034.  
  6035. Now you understand how Package Management keeps all your CLI's parts working together! In [Chapter 51: Cross-Package Import Rules](51_cross_package_import_rules_.md), we'll learn how different packages can safely share code.
  6036.  
  6037. > Pro Tip: Try checking your project's `package.json` to see real dependency examples!
  6038.  
  6039. ---
  6040.  
  6041. # Chapter 51: Cross-Package Import Rules
  6042.  
  6043. Welcome back! In [Chapter 50: Package Management](50_package_management_.md), we learned how different parts of your CLI work together. Now, let's meet your app's **border control** - Cross-Package Import Rules that ensure clean boundaries between different code packages, just like countries having clear borders with proper documentation for crossing between them!
  6044.  
  6045. ## Why Do We Need Import Rules?
  6046.  
  6047. Imagine you're organizing a big international conference with teams from different countries. You'd want:
  6048. - Each team to have their own workspace (package)
  6049. - Clear rules for visiting other teams' spaces (imports)
  6050. - Proper documentation when sharing resources (exports)
  6051.  
  6052. Cross-Package Import Rules do exactly this for your CLI's code! They:
  6053. 1. Keep different packages neatly separated
  6054. 2. Require proper documentation when code crosses boundaries
  6055. 3. Prevent messy "backdoor" access between packages
  6056.  
  6057. ## Meet the Three Border Rules
  6058.  
  6059. Our import system enforces three simple principles:
  6060.  
  6061. 1. **No Sneaky Paths**: Can't use `../` to access other packages
  6062. 2. **Proper Documentation**: Must declare what you're sharing
  6063. 3. **Clear Boundaries**: Each package has its own "territory"
  6064.  
  6065. Here's a simple example of a *bad* import that breaks the rules:
  6066.  
  6067. ```typescript
  6068. // In packageA - DON'T DO THIS!
  6069. import { helper } from '../../packageB/src/utils';
  6070. ```
  6071.  
  6072. This is like sneaking across a border without paperwork!
  6073.  
  6074. ## How Import Rules Work
  6075.  
  6076. When code tries to import something, here's what happens:
  6077.  
  6078. ```mermaid
  6079. sequenceDiagram
  6080. participant Code as Your Code
  6081. participant Checker as Import Checker
  6082. participant PackageA as Package A
  6083. participant PackageB as Package B
  6084.  
  6085. Code->>Checker: "Import from PackageB"
  6086. Checker->>PackageA: Are you allowed?
  6087. PackageA-->>Checker: Shows documentation
  6088. Checker->>PackageB: Is this shared?
  6089. PackageB-->>Checker: Yes, properly exported
  6090. Checker->>Code: Import approved!
  6091. ```
  6092.  
  6093. ## A Simple Example
  6094.  
  6095. Here's the *correct* way to import between packages:
  6096.  
  6097. ```typescript
  6098. // In packageA - DO THIS!
  6099. import { helper } from 'packageB';
  6100. ```
  6101.  
  6102. This is like using the proper border crossing with all your documents ready!
  6103.  
  6104. ## Behind the Scenes
  6105.  
  6106. The import checker works in three steps (simplified from our code):
  6107.  
  6108. ```typescript
  6109. function checkImport(filePath, importPath) {
  6110. // 1. Find which packages are involved
  6111. const fromPackage = findPackage(filePath);
  6112. const toPackage = findPackage(importPath);
  6113.  
  6114. // 2. Check if it's a cross-package import
  6115. if (fromPackage !== toPackage) {
  6116. // 3. Verify it uses proper package name
  6117. if (importPath.startsWith('.')) {
  6118. throw Error("Use package name instead of relative path!");
  6119. }
  6120. }
  6121. }
  6122. ```
  6123.  
  6124. Key parts:
  6125. 1. Identifies the source and destination packages
  6126. 2. Checks if it's crossing boundaries
  6127. 3. Enforces proper import syntax
  6128.  
  6129. ## Handling Special Cases
  6130.  
  6131. The system also manages tricky situations:
  6132. - Circular dependencies (Package A needs B which needs A)
  6133. - Deeply nested imports
  6134. - Missing package declarations
  6135.  
  6136. ```typescript
  6137. // Special case: Circular imports are allowed but warned
  6138. if (isCircular(fromPackage, toPackage)) {
  6139. console.warn("Circular dependency detected!");
  6140. }
  6141. ```
  6142.  
  6143. ## Common Patterns
  6144.  
  6145. You'll often work with:
  6146. 1. **Public APIs**: What a package officially exports
  6147. 2. **Internal Code**: Private to each package
  6148. 3. **Dependency Trees**: Which packages depend on others
  6149.  
  6150. ## What's Next?
  6151.  
  6152. Now you understand how Cross-Package Import Rules keep your CLI's code organized! In [Chapter 52: Release Process](52_release_process_.md), we'll learn how to prepare and share your finished CLI with the world.
  6153.  
  6154. > Pro Tip: Try organizing your code into separate packages to see how import rules help maintain clean boundaries!
  6155.  
  6156. ---
  6157.  
  6158. # Chapter 52: Release Process
  6159.  
  6160. Welcome back! In [Chapter 51: Cross-Package Import Rules](51_cross_package_import_rules_.md), we learned how to keep different parts of your CLI organized. Now, let's meet your app's **delivery truck** - the Release Process that packages and ships your finished CLI to users, just like a factory assembly line that carefully prepares products for delivery!
  6161.  
  6162. ## Why Do We Need a Release Process?
  6163.  
  6164. Imagine you're baking cookies to sell at a market. You wouldn't just throw them in a bag - you'd:
  6165. 1. Check each cookie is perfect (testing)
  6166. 2. Package them neatly in boxes (building)
  6167. 3. Label them clearly (versioning)
  6168. 4. Deliver to the market (publishing)
  6169.  
  6170. The Release Process does exactly this for your CLI! It's an automated workflow that:
  6171. 1. Tests everything works
  6172. 2. Packages your code neatly
  6173. 3. Adds version numbers
  6174. 4. Publishes to users
  6175.  
  6176. ## Meet the Four-Step Assembly Line
  6177.  
  6178. Our release process has four simple stations:
  6179.  
  6180. 1. **Preparation**: Gets all ingredients (code) ready
  6181. 2. **Packaging**: Combines everything into installable bundles
  6182. 3. **Versioning**: Tags each release clearly
  6183. 4. **Shipping**: Delivers to package managers
  6184.  
  6185. Here's how simple it is to start a release:
  6186.  
  6187. ```bash
  6188. # Run the release process
  6189. npm run release
  6190. ```
  6191.  
  6192. This single command triggers the entire automated workflow!
  6193.  
  6194. ## How Releases Work
  6195.  
  6196. When you run a release, here's what happens behind the scenes:
  6197.  
  6198. ```mermaid
  6199. sequenceDiagram
  6200. participant You as You
  6201. participant Prep as Preparation
  6202. participant Package as Packaging
  6203. participant Ship as Shipping
  6204.  
  6205. You->>Prep: "npm run release"
  6206. Prep->>Prep: Runs all tests
  6207. Prep->>Package: Creates install packages
  6208. Package->>Ship: Publishes to npm
  6209. Ship->>You: "Release complete!"
  6210. ```
  6211.  
  6212. ## A Simple Example
  6213.  
  6214. Let's see what happens during a typical release:
  6215.  
  6216. 1. **Preparation**: Checks all tests pass
  6217. 2. **Packaging**: Creates `.tgz` files
  6218. 3. **Versioning**: Tags as "v1.2.3"
  6219. 4. **Shipping**: Uploads to npm registry
  6220.  
  6221. ```bash
  6222. # After running release, you get:
  6223. Successfully published:
  6224. ```
  6225.  
  6226. ## Behind the Scenes
  6227.  
  6228. The release script does several important checks (simplified):
  6229.  
  6230. ```javascript
  6231. // 1. Verify all tests pass
  6232. if (!runTests()) {
  6233. throw Error("Tests failed - fix before releasing!");
  6234. }
  6235.  
  6236. // 2. Update version numbers
  6237. updateVersion('1.2.3');
  6238.  
  6239. // 3. Publish packages
  6240. publishToNpm();
  6241. ```
  6242.  
  6243. Key steps:
  6244. 1. Ensures everything works
  6245. 2. Sets the version
  6246. 3. Shares with the world
  6247.  
  6248. ## Handling Special Cases
  6249.  
  6250. The process also manages tricky situations:
  6251. - Release candidates (test versions)
  6252. - Different environments
  6253. - Failed publishes
  6254.  
  6255. ```javascript
  6256. if (isReleaseCandidate) {
  6257. publishWithTag('rc'); // Mark as test version
  6258. } else {
  6259. publishWithTag('latest'); // Official release
  6260. }
  6261. ```
  6262.  
  6263. ## Common Release Patterns
  6264.  
  6265. You'll often use the release process to:
  6266. 1. **Share Updates**: Publish new features
  6267. 2. **Test Changes**: Release candidate versions
  6268. 3. **Fix Bugs**: Patch versions for problems
  6269.  
  6270. ## What's Next?
  6271.  
  6272. Now you understand how your CLI gets shared with users through the Release Process! In [Chapter 53: Privacy Notices](53_privacy_notices_.md), we'll learn how your app communicates important privacy information to users.
  6273.  
  6274. > Pro Tip: Try running the release process with `--dry-run` to see what would happen without actually publishing!
  6275.  
  6276. ---
  6277.  
  6278. # Chapter 53: Privacy Notices
  6279.  
  6280. Welcome back! In [Chapter 52: Release Process](52_release_process_.md), we learned how to prepare and share your CLI with users. Now, let's meet your app's **legal translator** - Privacy Notices that clearly explain how user data is handled, just like a friendly guide who explains the rules before you enter a new place!
  6281.  
  6282. ## Why Do We Need Privacy Notices?
  6283.  
  6284. Imagine you're signing up for a new app. You'd want to know:
  6285. - What information the app collects
  6286. - How they'll use your data
  6287. - Who can see your information
  6288.  
  6289. Privacy Notices do exactly this for your CLI! They:
  6290. 1. Show different policies based on how you're logged in
  6291. 2. Explain data collection clearly
  6292. 3. Let users make informed choices
  6293.  
  6294. For example, free users might see different privacy terms than paid enterprise users.
  6295.  
  6296. ## Meet the Notice Types
  6297.  
  6298. Your CLI shows three main types of privacy notices:
  6299.  
  6300. 1. **Free Tier Notice**: For individual users
  6301. 2. **Enterprise Notice**: For business accounts
  6302. 3. **API Key Notice**: For developers using API keys
  6303.  
  6304. Here's how simple it is to show the right notice:
  6305.  
  6306. ```typescript
  6307. import { showPrivacyNotice } from 'gemini-cli';
  6308.  
  6309. // Automatically shows the correct notice
  6310. showPrivacyNotice(authType);
  6311. ```
  6312.  
  6313. This displays the appropriate policy based on how the user is authenticated.
  6314.  
  6315. ## How Privacy Notices Work
  6316.  
  6317. When checking which notice to show, here's what happens:
  6318.  
  6319. ```mermaid
  6320. sequenceDiagram
  6321. participant You as User
  6322. participant CLI as Your CLI
  6323. participant Auth as Authentication
  6324.  
  6325. You->>CLI: Runs command
  6326. CLI->>Auth: Checks login type
  6327. Auth-->>CLI: "Free tier user"
  6328. CLI->>You: Shows free tier notice
  6329. ```
  6330.  
  6331. ## A Simple Example
  6332.  
  6333. Let's see how different users get different notices:
  6334.  
  6335. ```typescript
  6336. // Free user sees this notice:
  6337. "Google may use your data to improve services"
  6338.  
  6339. // Enterprise user sees:
  6340. "Your company's agreement governs data use"
  6341.  
  6342. // API user sees:
  6343. "API terms of service apply"
  6344. ```
  6345.  
  6346. Each notice matches the user's account type.
  6347.  
  6348. ## Behind the Scenes
  6349.  
  6350. The system checks auth type to pick the right notice (simplified):
  6351.  
  6352. ```typescript
  6353. function getNotice(authType) {
  6354. switch(authType) {
  6355. case 'FREE': return FreeNotice;
  6356. case 'ENTERPRISE': return PaidNotice;
  6357. case 'API_KEY': return APINotice;
  6358. default: return DefaultNotice;
  6359. }
  6360. }
  6361. ```
  6362.  
  6363. Key parts:
  6364. - Simple switch statement
  6365. - Matches auth type to notice
  6366. - Has a default fallback
  6367.  
  6368. ## Real-World Implementation
  6369.  
  6370. In our actual code (`packages/cli/src/ui/privacy/PrivacyNotice.tsx`), we handle more cases:
  6371.  
  6372. ```typescript
  6373. function PrivacyNoticeText({ authType }) {
  6374. switch (authType) {
  6375. case AuthType.USE_GEMINI:
  6376. return <GeminiPrivacyNotice />;
  6377. case AuthType.USE_VERTEX_AI:
  6378. return <CloudPaidPrivacyNotice />;
  6379. default:
  6380. return <CloudFreePrivacyNotice />;
  6381. }
  6382. }
  6383. ```
  6384.  
  6385. This component renders the appropriate notice component.
  6386.  
  6387. ## Common Patterns
  6388.  
  6389. You'll often see privacy notices that:
  6390. 1. **Vary By User Type**: Different for free/paid users
  6391. 2. **Include Links**: To full policies
  6392. 3. **Get Consent**: For data collection
  6393.  
  6394. ## What's Next?
  6395.  
  6396. Now you understand how Privacy Notices keep users informed about data handling! In [Chapter 54: Context Management](54_context_management_.md), we'll learn how your CLI maintains conversation history and settings.
  6397.  
  6398. > Pro Tip: Try logging in different ways to see how the privacy notices change!
  6399.  
  6400. ---
  6401.  
  6402. # Chapter 54: Context Management
  6403.  
  6404. Welcome back! In [Chapter 53: Privacy Notices](53_privacy_notices_.md), we learned how your CLI communicates important privacy information to users. Now, let's meet your app's **memory keeper** - Context Management that tracks and displays all the important details about your current work environment, just like a smart dashboard in a car that shows your speed, fuel level, and navigation!
  6405.  
  6406. ## Why Do We Need Context Management?
  6407.  
  6408. Imagine you're working on a coding project. You'd want to know:
  6409. - Which files you're currently working with
  6410. - What branch you're on in Git
  6411. - How much memory your CLI is using
  6412. - Any errors that might have occurred
  6413.  
  6414. Context Management does exactly this! It's like having a personal assistant who constantly updates you about:
  6415. 1. **Files**: What documents are open
  6416. 2. **Projects**: Which folder you're working in
  6417. 3. **System**: How your computer resources are being used
  6418.  
  6419. ## Meet Your CLI Dashboard
  6420.  
  6421. The Context Management system shows three main types of information:
  6422.  
  6423. 1. **File Context**: Currently open files and their status
  6424. 2. **Project Context**: The folder and Git branch you're working in
  6425. 3. **System Context**: Memory usage and performance stats
  6426.  
  6427. Here's how simple it is to check your current context:
  6428.  
  6429. ```typescript
  6430. import { getContext } from 'gemini-cli';
  6431.  
  6432. // See your current working context
  6433. const context = getContext();
  6434. console.log(context.currentDirectory); // "/projects/my-app"
  6435. ```
  6436.  
  6437. This shows basic information about where you're working.
  6438.  
  6439. ## How Context Works
  6440.  
  6441. When you run a command, here's what happens behind the scenes:
  6442.  
  6443. ```mermaid
  6444. sequenceDiagram
  6445. participant You as You
  6446. participant Context as Context Manager
  6447. participant Git as Git
  6448. participant System as Your Computer
  6449.  
  6450. You->>Context: "What's my context?"
  6451. Context->>Git: Checks current branch
  6452. Git-->>Context: "main branch"
  6453. Context->>System: Checks memory
  6454. System-->>Context: "2GB used"
  6455. Context->>You: Returns all info
  6456. ```
  6457.  
  6458. ## A Simple Example
  6459.  
  6460. Let's see what typical context looks like:
  6461.  
  6462. ```typescript
  6463. {
  6464. currentDirectory: "/projects/gemini-cli",
  6465. gitBranch: "main",
  6466. openFiles: ["src/index.ts", "README.md"],
  6467. memoryUsage: "1.2GB"
  6468. }
  6469. ```
  6470.  
  6471. This tells you:
  6472. - You're in the "gemini-cli" folder
  6473. - On the "main" Git branch
  6474. - With two files open
  6475. - Using 1.2GB of memory
  6476.  
  6477. ## Behind the Scenes
  6478.  
  6479. The context manager gathers information from different sources (simplified):
  6480.  
  6481. ```typescript
  6482. function gatherContext() {
  6483. return {
  6484. // Get current folder
  6485. currentDirectory: process.cwd(),
  6486.  
  6487. // Check Git branch
  6488. gitBranch: getGitBranch(),
  6489.  
  6490. // Check memory usage
  6491. memoryUsage: process.memoryUsage()
  6492. };
  6493. }
  6494. ```
  6495.  
  6496. Key parts:
  6497. 1. Uses Node's `process` for basic info
  6498. 2. Calls Git for branch details
  6499. 3. Combines everything into one object
  6500.  
  6501. ## Displaying Context
  6502.  
  6503. The CLI shows this information in the footer:
  6504.  
  6505. ```typescript
  6506. function Footer() {
  6507. const context = useContext();
  6508. return (
  6509. <Text>
  6510. {context.currentDirectory} | {context.gitBranch} | {context.memoryUsage}
  6511. </Text>
  6512. );
  6513. }
  6514. ```
  6515.  
  6516. This creates a helpful status bar at the bottom of your terminal.
  6517.  
  6518. ## Common Patterns
  6519.  
  6520. You'll often use context to:
  6521. 1. **Check Location**: See your current folder
  6522. 2. **Monitor Resources**: Watch memory usage
  6523. 3. **Track Changes**: See Git branch status
  6524.  
  6525. ## What's Next?
  6526.  
  6527. Now you understand how Context Management keeps you informed about your work environment! In [Chapter 55: User Context Management](55_user_context_management_.md), we'll learn how to personalize and save your preferences across sessions.
  6528.  
  6529. > Pro Tip: Try running different commands and watch how the context information updates in real-time!
  6530.  
  6531. ---
  6532.  
  6533. # Chapter 55: User Context Management
  6534.  
  6535. Welcome back! In [Chapter 54: Context Management](54_context_management_.md), we learned how your CLI tracks your current work environment. Now, let's meet your app's **personal assistant** - User Context Management that remembers your preferences and identity across sessions, just like a helpful butler who knows exactly how you like your coffee every morning!
  6536.  
  6537. ## Why Do We Need User Context?
  6538.  
  6539. Imagine you're using a shared computer. You'd want:
  6540. - Your settings to stay the same when you return
  6541. - The CLI to remember who you are
  6542. - Your preferences to carry over between sessions
  6543.  
  6544. User Context Management does exactly this! It's like having a digital assistant that:
  6545. 1. Remembers your login (even after closing the app)
  6546. 2. Saves your preferences (like theme colors)
  6547. 3. Keeps your work organized (with unique IDs)
  6548.  
  6549. ## Meet Your Digital ID Card
  6550.  
  6551. The system tracks three key things about you:
  6552.  
  6553. 1. **Installation ID**: A unique number for your computer
  6554. 2. **Google Account**: If you're logged in (optional)
  6555. 3. **Preferences**: Your saved settings
  6556.  
  6557. Here's how simple it is to get your installation ID:
  6558.  
  6559. ```typescript
  6560. import { getInstallationId } from 'gemini-cli';
  6561.  
  6562. // Get your unique computer ID
  6563. const id = getInstallationId();
  6564. console.log(id); // "a1b2c3d4-..."
  6565. ```
  6566.  
  6567. This ID stays the same every time you use the CLI on this computer.
  6568.  
  6569. ## How User Context Works
  6570.  
  6571. When you start the CLI, here's what happens behind the scenes:
  6572.  
  6573. ```mermaid
  6574. sequenceDiagram
  6575. participant You as You
  6576. participant CLI as Gemini CLI
  6577. participant Files as Your Computer
  6578.  
  6579. You->>CLI: Starts the app
  6580. CLI->>Files: Checks for existing ID
  6581. Files-->>CLI: "No ID found"
  6582. CLI->>Files: Creates new ID
  6583. Files-->>CLI: "ID: a1b2c3d4"
  6584. CLI->>You: Ready with your ID!
  6585. ```
  6586.  
  6587. ## A Simple Example
  6588.  
  6589. Let's see how the system manages your identity:
  6590.  
  6591. ```typescript
  6592. // First run - creates new ID
  6593. const firstId = getInstallationId();
  6594.  
  6595. // Later runs - same ID
  6596. const sameId = getInstallationId();
  6597. console.log(firstId === sameId); // true
  6598. ```
  6599.  
  6600. This ensures you keep the same ID across sessions.
  6601.  
  6602. ## Behind the Scenes
  6603.  
  6604. The system stores your ID in a special file (simplified):
  6605.  
  6606. ```typescript
  6607. function getInstallationId() {
  6608. // 1. Check if ID file exists
  6609. if (fileExists('installation_id')) {
  6610. return readFile('installation_id');
  6611. }
  6612.  
  6613. // 2. If not, create new ID
  6614. const newId = generateRandomId();
  6615. saveToFile('installation_id', newId);
  6616. return newId;
  6617. }
  6618. ```
  6619.  
  6620. Key steps:
  6621. 1. Looks for existing ID
  6622. 2. Creates new one if needed
  6623. 3. Saves it for next time
  6624.  
  6625. ## Handling Google Accounts
  6626.  
  6627. If you log in with Google, it adds extra info:
  6628.  
  6629. ```typescript
  6630. function getUserIdentity() {
  6631. const googleId = getGoogleAccountId();
  6632. if (googleId) {
  6633. return `google:${googleId}`;
  6634. }
  6635. return `local:${getInstallationId()}`;
  6636. }
  6637. ```
  6638.  
  6639. This combines your computer ID with Google info if available.
  6640.  
  6641. ## Common Patterns
  6642.  
  6643. You'll often see user context used to:
  6644. 1. **Personalize Experience**: Remember your settings
  6645. 2. **Track Usage**: (Anonymously) improve the app
  6646. 3. **Secure Access**: Verify it's really you
  6647.  
  6648. ## What's Next?
  6649.  
  6650. Now you understand how User Context Management keeps track of your preferences and identity! In [Chapter 56: Event Logging](56_event_logging_.md), we'll learn how your CLI records important actions to help improve the app.
  6651.  
  6652. > Pro Tip: Try checking your installation ID file in `~/.gemini/installation_id` to see how it's stored!
  6653.  
  6654. ---
  6655.  
  6656. # Chapter 56: Event Logging
  6657.  
  6658. Welcome back! In [Chapter 55: User Context Management](55_user_context_management_.md), we learned how your CLI remembers your preferences and identity. Now, let's meet your app's **flight recorder** - Event Logging that quietly tracks important activities in your CLI, just like an airplane's black box that records everything happening during a flight!
  6659.  
  6660. ## Why Do We Need Event Logging?
  6661.  
  6662. Imagine you're a pilot. After each flight, you'd want to review:
  6663. - What route you took
  6664. - How the engines performed
  6665. - Any issues that came up
  6666.  
  6667. Event Logging does exactly this for your CLI! It automatically records:
  6668. 1. Commands you run
  6669. 2. Tools you use
  6670. 3. Errors that occur
  6671. 4. System performance
  6672.  
  6673. This helps developers improve the CLI by understanding how people actually use it.
  6674.  
  6675. ## Meet the Simple Logger
  6676.  
  6677. Event Logging works like a helpful assistant taking notes with three simple rules:
  6678.  
  6679. 1. **Be Quiet**: Runs in the background without bothering you
  6680. 2. **Be Helpful**: Only records useful information
  6681. 3. **Be Safe**: Never collects personal data
  6682.  
  6683. Here's how simple it is to log an event:
  6684.  
  6685. ```typescript
  6686. import { logEvent } from 'gemini-cli';
  6687.  
  6688. // Log when a tool runs
  6689. logEvent('tool_used', { name: 'search', duration: 1200 });
  6690. ```
  6691.  
  6692. This records that the search tool ran and took 1.2 seconds.
  6693.  
  6694. ## How Event Logging Works
  6695.  
  6696. When something happens in your CLI, here's what occurs behind the scenes:
  6697.  
  6698. ```mermaid
  6699. sequenceDiagram
  6700. participant You as You
  6701. participant CLI as Your CLI
  6702. participant Logger as Event Logger
  6703.  
  6704. You->>CLI: Runs search tool
  6705. CLI->>Logger: "Tool ran: search"
  6706. Logger->>Logger: Records the event
  6707. CLI->>You: Shows search results
  6708. ```
  6709.  
  6710. ## A Simple Example
  6711.  
  6712. Let's see what typical logged events look like:
  6713.  
  6714. ```typescript
  6715. // Sample event when asking a question
  6716. {
  6717. type: "question_asked",
  6718. text: "What's the weather?", // (shortened for privacy)
  6719. length: 18 // Characters
  6720. }
  6721.  
  6722. // Sample tool event
  6723. {
  6724. type: "tool_ran",
  6725. name: "file_edit",
  6726. duration: 500 // Milliseconds
  6727. }
  6728. ```
  6729.  
  6730. These show what happened without revealing private details.
  6731.  
  6732. ## Behind the Scenes
  6733.  
  6734. The logger works in three simple steps (simplified from our code):
  6735.  
  6736. ```typescript
  6737. class EventLogger {
  6738. private events = [];
  6739.  
  6740. log(type, data) {
  6741. // 1. Create event with timestamp
  6742. const event = {
  6743. type,
  6744. time: new Date(),
  6745. ...data
  6746. };
  6747.  
  6748. // 2. Add to event list
  6749. this.events.push(event);
  6750.  
  6751. // 3. Occasionally send batches
  6752. if (this.events.length > 10) {
  6753. this.sendEvents();
  6754. }
  6755. }
  6756. }
  6757. ```
  6758.  
  6759. Key parts:
  6760. 1. Creates event objects
  6761. 2. Stores them temporarily
  6762. 3. Sends in batches for efficiency
  6763.  
  6764. ## What Gets Logged?
  6765.  
  6766. The system carefully tracks only helpful technical information:
  6767. - Command names (like "search" or "ask")
  6768. - Performance metrics (how long things take)
  6769. - Error types (without personal details)
  6770. - Basic system info (like OS version)
  6771.  
  6772. ## Controlling Logging
  6773.  
  6774. You can always check or change logging settings:
  6775.  
  6776. ```typescript
  6777. import { isLoggingEnabled, setLoggingEnabled } from 'gemini-cli';
  6778.  
  6779. // See current setting
  6780. console.log(isLoggingEnabled());
  6781.  
  6782. // Disable if preferred
  6783. setLoggingEnabled(false);
  6784. ```
  6785.  
  6786. ## What's Next?
  6787.  
  6788. Now you understand how Event Logging helps improve your CLI by recording usage patterns! In [Chapter 57: Activity Logger](57_activity_logger_.md), we'll explore more advanced ways to track and analyze CLI activities.
  6789.  
  6790. > Pro Tip: Try running different commands and check your event logs to see what gets recorded!
  6791.  
  6792. ---
  6793.  
  6794. # Chapter 57: Activity Logger
  6795.  
  6796. Welcome back! In [Chapter 56: Event Logging](56_event_logging_.md), we learned how your CLI records important actions. Now, let's meet your app's **time machine** - the Activity Logger that remembers everything you do, allowing you to revisit past conversations or pick up where you left off, just like a journal that keeps all your thoughts and adventures safe to read later!
  6797.  
  6798. ## Why Do We Need an Activity Logger?
  6799.  
  6800. Imagine you're having an important conversation with Gemini about a coding project, and suddenly:
  6801. - Your computer crashes
  6802. - You need to take a break
  6803. - You want to review what you discussed earlier
  6804.  
  6805. The Activity Logger solves these problems by:
  6806. 1. Recording your entire conversation history
  6807. 2. Saving checkpoints so you can resume later
  6808. 3. Letting you review past interactions
  6809.  
  6810. It's like having a personal secretary who takes perfect notes of everything you do!
  6811.  
  6812. ## Meet Your Digital Notebook
  6813.  
  6814. The Activity Logger works like a smart notebook with three key features:
  6815.  
  6816. 1. **Session History**: Records every message in your conversation
  6817. 2. **Checkpoints**: Saves important moments to return to
  6818. 3. **Search**: Lets you find past conversations easily
  6819.  
  6820. Here's how simple it is to log an activity:
  6821.  
  6822. ```typescript
  6823. import { activityLogger } from 'gemini-cli';
  6824.  
  6825. // Log a user message
  6826. await activityLogger.logMessage('user', 'How do I fix this bug?');
  6827. ```
  6828.  
  6829. This adds your question to the session history automatically.
  6830.  
  6831. ## How Activity Logging Works
  6832.  
  6833. When you chat with Gemini, here's what happens behind the scenes:
  6834.  
  6835. ```mermaid
  6836. sequenceDiagram
  6837. participant You as You
  6838. participant Logger as Activity Logger
  6839. participant File as Log File
  6840.  
  6841. You->>Logger: "How do I fix this bug?"
  6842. Logger->>File: Saves message with timestamp
  6843. File-->>Logger: Confirms save
  6844. Logger->>You: Continues conversation
  6845. ```
  6846.  
  6847. ## A Simple Example
  6848.  
  6849. Let's see how to save and load checkpoints:
  6850.  
  6851. ```typescript
  6852. // Save current conversation state
  6853. await activityLogger.saveCheckpoint(conversation);
  6854.  
  6855. // Later, load it back
  6856. const savedConversation = await activityLogger.loadCheckpoint();
  6857. ```
  6858.  
  6859. This lets you pause and resume your work anytime!
  6860.  
  6861. ## Behind the Scenes
  6862.  
  6863. The logger stores messages in a simple format (simplified from our code):
  6864.  
  6865. ```typescript
  6866. interface LogEntry {
  6867. sessionId: string; // Which conversation
  6868. messageId: number; // Message number
  6869. type: 'user' | 'model'; // Who sent it
  6870. message: string; // The actual text
  6871. timestamp: string; // When it happened
  6872. }
  6873. ```
  6874.  
  6875. Key parts:
  6876. - Each message gets a unique ID
  6877. - Tracks who sent it (you or Gemini)
  6878. - Includes exact timing
  6879.  
  6880. ## Real-World Implementation
  6881.  
  6882. Here's how we actually save logs (simplified from `packages/core/src/core/logger.ts`):
  6883.  
  6884. ```typescript
  6885. async function saveLog(entry) {
  6886. // 1. Read existing logs
  6887. const allLogs = await readLogFile();
  6888.  
  6889. // 2. Add new entry
  6890. allLogs.push(entry);
  6891.  
  6892. // 3. Save back to file
  6893. await writeLogFile(allLogs);
  6894. }
  6895. ```
  6896.  
  6897. Key steps:
  6898. 1. Gets current log contents
  6899. 2. Adds the new message
  6900. 3. Saves everything back
  6901.  
  6902. ## Handling Special Cases
  6903.  
  6904. The logger also manages tricky situations:
  6905. - Corrupted log files (makes backups)
  6906. - Concurrent access (prevents conflicts)
  6907. - Large histories (handles them efficiently)
  6908.  
  6909. ## What's Next?
  6910.  
  6911. Now you understand how the Activity Logger keeps track of all your CLI interactions! In [Chapter 58: File Processing Pipeline](58_file_processing_pipeline_.md), we'll learn how your CLI handles file operations efficiently.
  6912.  
  6913. > Pro Tip: Try using `loadCheckpoint()` after restarting your CLI to continue right where you left off!
  6914.  
  6915. ---
  6916.  
  6917. # Chapter 58: File Processing Pipeline
  6918.  
  6919. Welcome back! In [Chapter 57: Activity Logger](57_activity_logger_.md), we learned how your CLI remembers all your past conversations. Now, let's meet your app's **file inspector** - the File Processing Pipeline that automatically reads and understands different file types, just like a smart scanner that can tell whether a document is a recipe, a photo, or a contract!
  6920.  
  6921. ## Why Do We Need a File Processing Pipeline?
  6922.  
  6923. Imagine you're working on a project with:
  6924. - Text files (like notes or code)
  6925. - Images (screenshots or diagrams)
  6926. - PDFs (reports or documentation)
  6927.  
  6928. When you ask Gemini about these files, it needs to:
  6929. 1. Know what type each file is
  6930. 2. Read it correctly (text vs binary)
  6931. 3. Prepare it for Gemini to understand
  6932.  
  6933. The File Processing Pipeline does all this automatically! It's like having a personal assistant who can:
  6934. - Read your handwritten notes (text files)
  6935. - Describe photos (images)
  6936. - Summarize PDFs (documents)
  6937.  
  6938. ## Meet the Three-Step Process
  6939.  
  6940. The pipeline works in three simple steps:
  6941.  
  6942. 1. **Detection**: What kind of file is this? (Text, image, PDF)
  6943. 2. **Reading**: Get the file's contents safely
  6944. 3. **Preparing**: Format it for Gemini to use
  6945.  
  6946. Here's how simple it is to process a file:
  6947.  
  6948. ```typescript
  6949. import { processFile } from 'gemini-cli';
  6950.  
  6951. // Process a file automatically
  6952. const result = await processFile('notes.txt');
  6953. console.log(result.content); // Shows the file's text
  6954. ```
  6955.  
  6956. This automatically detects `notes.txt` as a text file and reads its contents.
  6957.  
  6958. ## How File Processing Works
  6959.  
  6960. When you give the pipeline a file, here's what happens:
  6961.  
  6962. ```mermaid
  6963. sequenceDiagram
  6964. participant You as You
  6965. participant Pipeline as File Pipeline
  6966. participant File as Your File
  6967.  
  6968. You->>Pipeline: "Read notes.txt"
  6969. Pipeline->>File: Checks file type
  6970. File-->>Pipeline: "It's text!"
  6971. Pipeline->>File: Reads contents
  6972. File-->>Pipeline: Returns text
  6973. Pipeline->>You: Gives formatted content
  6974. ```
  6975.  
  6976. ## A Simple Example
  6977.  
  6978. Let's process different file types:
  6979.  
  6980. ```typescript
  6981. // Text file
  6982. const textResult = await processFile('notes.txt');
  6983. // Returns the text content
  6984.  
  6985. // Image file
  6986. const imageResult = await processFile('diagram.png');
  6987. // Returns a description Gemini can understand
  6988.  
  6989. // PDF file
  6990. const pdfResult = await processFile('report.pdf');
  6991. // Extracts text from the PDF
  6992. ```
  6993.  
  6994. The pipeline handles each file type differently behind the scenes.
  6995.  
  6996. ## Behind the Scenes
  6997.  
  6998. The pipeline first detects the file type (simplified from our code):
  6999.  
  7000. ```typescript
  7001. function detectFileType(filePath) {
  7002. const extension = filePath.split('.').pop();
  7003.  
  7004. if (['txt', 'md', 'js'].includes(extension)) {
  7005. return 'text';
  7006. }
  7007. if (['png', 'jpg'].includes(extension)) {
  7008. return 'image';
  7009. }
  7010. if (extension === 'pdf') {
  7011. return 'pdf';
  7012. }
  7013. return 'unknown';
  7014. }
  7015. ```
  7016.  
  7017. Key parts:
  7018. 1. Checks the file extension
  7019. 2. Categorizes as text, image, or PDF
  7020. 3. Handles unknown types safely
  7021.  
  7022. ## Reading Different Files
  7023.  
  7024. Then it reads each type appropriately:
  7025.  
  7026. ```typescript
  7027. async function readFile(filePath, type) {
  7028. if (type === 'text') {
  7029. return fs.readFile(filePath, 'utf8');
  7030. }
  7031. if (type === 'image' || type === 'pdf') {
  7032. return fs.readFile(filePath); // Binary data
  7033. }
  7034. }
  7035. ```
  7036.  
  7037. Text files get read as UTF-8, while images/PDFs are read as binary data.
  7038.  
  7039. ## Safety Features
  7040.  
  7041. The pipeline includes important protections:
  7042. - Checks file permissions first
  7043. - Limits file sizes for safety
  7044. - Handles errors gracefully
  7045.  
  7046. ```typescript
  7047. try {
  7048. return await processFile('notes.txt');
  7049. } catch (error) {
  7050. console.log("Couldn't read file:", error.message);
  7051. }
  7052. ```
  7053.  
  7054. ## What's Next?
  7055.  
  7056. Now you understand how the File Processing Pipeline handles different file types automatically! In [Chapter 59: API Server Interface](59_api_server_interface_.md), we'll learn how your CLI communicates with Gemini's servers.
  7057.  
  7058. > Pro Tip: Try processing different file types to see how the pipeline handles each one!
  7059.  
  7060. ---
  7061.  
  7062. # Chapter 59: API Server Interface
  7063.  
  7064. Welcome back! In [Chapter 58: File Processing Pipeline](58_file_processing_pipeline_.md), we learned how your CLI handles different file types. Now, let's meet your app's **telephone operator** - the API Server Interface that connects your CLI to Gemini's powerful brain, just like a helpful receptionist who routes your calls to the right department!
  7065.  
  7066. ## Why Do We Need an API Server Interface?
  7067.  
  7068. Imagine you're calling a big company. Instead of dialing each department directly, you call the main number and the operator:
  7069. 1. Connects you to the right person
  7070. 2. Translates your request into their system
  7071. 3. Brings back the answer in a way you understand
  7072.  
  7073. The API Server Interface does exactly this for your CLI! It:
  7074. 1. Routes your questions to the correct Gemini service
  7075. 2. Formats your requests properly
  7076. 3. Returns the responses in a clean, usable way
  7077.  
  7078. ## Meet the Helpful Operator
  7079.  
  7080. Our API Server Interface has three simple jobs:
  7081.  
  7082. 1. **Connection**: Links your CLI to Gemini's servers
  7083. 2. **Translation**: Converts between your CLI's format and Gemini's
  7084. 3. **Delivery**: Brings back responses quickly and reliably
  7085.  
  7086. Here's how simple it is to ask a question through the interface:
  7087.  
  7088. ```typescript
  7089. import { askGemini } from 'gemini-cli';
  7090.  
  7091. // Ask Gemini a question
  7092. const response = await askGemini("What's 2+2?");
  7093. console.log(response); // "4"
  7094. ```
  7095.  
  7096. This shows how easy it is to get answers through the interface!
  7097.  
  7098. ## How the Interface Works
  7099.  
  7100. When you ask a question, here's what happens behind the scenes:
  7101.  
  7102. ```mermaid
  7103. sequenceDiagram
  7104. participant You as You
  7105. participant CLI as Your CLI
  7106. participant Interface as API Interface
  7107. participant Gemini as Gemini Servers
  7108.  
  7109. You->>CLI: "What's 2+2?"
  7110. CLI->>Interface: Formats question
  7111. Interface->>Gemini: Sends to correct server
  7112. Gemini-->>Interface: Returns "4"
  7113. Interface->>CLI: Formats response
  7114. CLI->>You: Shows answer
  7115. ```
  7116.  
  7117. ## A Simple Example
  7118.  
  7119. Let's see how the interface handles different requests:
  7120.  
  7121. ```typescript
  7122. // Simple question
  7123. await askGemini("Hello!");
  7124.  
  7125. // File processing request
  7126. await processFileWithGemini("notes.txt");
  7127.  
  7128. // Tool execution
  7129. await runToolThroughGemini("search", {query: "pizza"});
  7130. ```
  7131.  
  7132. Each request gets routed to the right Gemini service automatically.
  7133.  
  7134. ## Behind the Scenes
  7135.  
  7136. The interface carefully manages connections (simplified from our code):
  7137.  
  7138. ```typescript
  7139. class ApiInterface {
  7140. async sendRequest(type, data) {
  7141. // 1. Find the right service
  7142. const service = this.findService(type);
  7143.  
  7144. // 2. Format the request
  7145. const formatted = service.formatRequest(data);
  7146.  
  7147. // 3. Send and get response
  7148. return await service.send(formatted);
  7149. }
  7150. }
  7151. ```
  7152.  
  7153. Key steps:
  7154. 1. Identifies which service to use
  7155. 2. Prepares the request properly
  7156. 3. Handles the response
  7157.  
  7158. ## Handling Different Requests
  7159.  
  7160. The interface is smart enough to route various request types:
  7161.  
  7162. ```typescript
  7163. // Routes to content generation
  7164. interface.sendRequest('generate', {prompt: "Hello"});
  7165.  
  7166. // Routes to embeddings
  7167. interface.sendRequest('embed', {text: "Hello"});
  7168.  
  7169. // Routes to token counting
  7170. interface.sendRequest('count', {text: "Hello"});
  7171. ```
  7172.  
  7173. Each type goes to the appropriate Gemini service behind the scenes.
  7174.  
  7175. ## Safety Features
  7176.  
  7177. The interface includes important protections:
  7178. - Automatic retries if connections fail
  7179. - Timeouts to prevent hanging
  7180. - Error handling for bad responses
  7181.  
  7182. ```typescript
  7183. try {
  7184. return await askGemini("What's 2+2?");
  7185. } catch (error) {
  7186. console.log("Oops! Let me try again...");
  7187. }
  7188. ```
  7189.  
  7190. ## What's Next?
  7191.  
  7192. Now you understand how the API Server Interface connects your CLI to Gemini's powerful services! In [Chapter 60: Command Processing](60_command_processing_.md), we'll learn how your CLI understands and executes the commands you type.
  7193.  
  7194. > Pro Tip: Try asking different types of questions to see how the interface handles each one!
  7195.  
  7196. ---
  7197.  
  7198. # Chapter 60: Command Processing
  7199.  
  7200. Welcome back! In [Chapter 59: API Server Interface](59_api_server_interface_.md), we learned how your CLI connects to Gemini's powerful servers. Now, let's meet your app's **traffic director** - Command Processing that handles special instructions starting with `/` or `@`, just like a helpful receptionist who routes your calls to the right department!
  7201.  
  7202. ## Why Do We Need Command Processing?
  7203.  
  7204. Imagine you're in a fancy hotel. You might say:
  7205. - "/help" to call the front desk
  7206. - "@roomservice" to order food
  7207. - "!lights" to control your room
  7208.  
  7209. Command Processing does exactly this for your CLI! It recognizes special commands like:
  7210. - `/help` - Shows help information
  7211. - `@file.txt` - Includes a file's contents
  7212. - `!ls` - Runs a shell command
  7213.  
  7214. Without it, your CLI wouldn't know these are special instructions needing special handling!
  7215.  
  7216. ## Meet the Command Types
  7217.  
  7218. Your CLI understands three main command types:
  7219.  
  7220. 1. **Slash Commands**: Start with `/` (like `/help`)
  7221. 2. **At Commands**: Start with `@` (like `@notes.txt`)
  7222. 3. **Bang Commands**: Start with `!` (like `!ls`)
  7223.  
  7224. Here's how simple it is to use them:
  7225.  
  7226. ```typescript
  7227. // Ask for help
  7228. "/help"
  7229.  
  7230. // Include a file
  7231. "@config.json"
  7232.  
  7233. // Run a shell command
  7234. "!date"
  7235. ```
  7236.  
  7237. ## How Command Processing Works
  7238.  
  7239. When you type a command, here's what happens:
  7240.  
  7241. ```mermaid
  7242. sequenceDiagram
  7243. participant You as You
  7244. participant CLI as Your CLI
  7245. participant Processor as Command Processor
  7246.  
  7247. You->>CLI: Types "/help"
  7248. CLI->>Processor: "Is this a special command?"
  7249. Processor->>Processor: Checks first character
  7250. Processor-->>CLI: "Yes, it's a help command!"
  7251. CLI->>You: Shows help menu
  7252. ```
  7253.  
  7254. ## A Simple Example
  7255.  
  7256. Let's see how different commands get processed:
  7257.  
  7258. ```typescript
  7259. // Slash command (shows help)
  7260. processCommand("/help");
  7261.  
  7262. // At command (includes file)
  7263. processCommand("@notes.txt");
  7264.  
  7265. // Bang command (runs shell)
  7266. processCommand("!pwd");
  7267. ```
  7268.  
  7269. Each type triggers different actions in your CLI.
  7270.  
  7271. ## Behind the Scenes
  7272.  
  7273. The processor checks commands like this (simplified):
  7274.  
  7275. ```typescript
  7276. function processCommand(input) {
  7277. if (input.startsWith('/')) {
  7278. handleSlashCommand(input); // Like /help
  7279. }
  7280. else if (input.startsWith('@')) {
  7281. handleAtCommand(input); // Like @file.txt
  7282. }
  7283. else if (input.startsWith('!')) {
  7284. handleBangCommand(input); // Like !ls
  7285. }
  7286. else {
  7287. // Regular message to Gemini
  7288. sendToGemini(input);
  7289. }
  7290. }
  7291. ```
  7292.  
  7293. Key parts:
  7294. 1. Checks the first character
  7295. 2. Routes to the right handler
  7296. 3. Handles regular messages too
  7297.  
  7298. ## Handling Slash Commands
  7299.  
  7300. The system has many built-in slash commands:
  7301.  
  7302. ```typescript
  7303. const slashCommands = {
  7304. '/help': showHelp,
  7305. '/clear': clearScreen,
  7306. '/theme': changeTheme
  7307. };
  7308. ```
  7309.  
  7310. These are like shortcuts for common actions.
  7311.  
  7312. ## Real-World Implementation
  7313.  
  7314. In our actual code (`packages/cli/src/ui/hooks/slashCommandProcessor.ts`), we handle commands like:
  7315.  
  7316. ```typescript
  7317. // Help command
  7318. if (command === '/help') {
  7319. setShowHelp(true);
  7320. }
  7321. // Theme command
  7322. else if (command === '/theme') {
  7323. openThemeDialog();
  7324. }
  7325. ```
  7326.  
  7327. Each command triggers specific actions in your CLI.
  7328.  
  7329. ## What's Next?
  7330.  
  7331. Now you understand how Command Processing handles special instructions in your CLI! In [Chapter 61: Content Correction System](61_content_correction_system_.md), we'll learn how Gemini can help fix mistakes in your content.
  7332.  
  7333. > Pro Tip: Try different commands like `/help` and `!date` to see how they work!
  7334.  
  7335. ---
  7336.  
  7337. # Chapter 61: Content Correction System
  7338.  
  7339.  
  7340. ---
  7341.  
  7342. # Chapter 62: Content Correction
  7343.  
  7344. Welcome back! In [Chapter 61: Content Correction System](61_content_correction_system_.md), we learned how Gemini can help fix mistakes in files. Now, let's meet your CLI's **helpful proofreader** - Content Correction that automatically fixes formatting and syntax errors in your files, just like an editor who cleans up your writing before publishing!
  7345.  
  7346. ## Why Do We Need Content Correction?
  7347.  
  7348. Imagine you're writing an important document. You might:
  7349. - Make typos or grammar mistakes
  7350. - Forget proper formatting
  7351. - Use inconsistent styles
  7352.  
  7353. Content Correction does exactly this for your code and text files! When you save a file, it:
  7354. 1. Checks for common errors
  7355. 2. Fixes formatting automatically
  7356. 3. Keeps your code clean and consistent
  7357.  
  7358. It's like having a personal assistant who proofreads everything you write!
  7359.  
  7360. ## Meet the Auto-Fixer
  7361.  
  7362. Content Correction handles three main tasks:
  7363.  
  7364. 1. **Formatting**: Fixes indentation and spacing
  7365. 2. **Syntax**: Corrects code structure
  7366. 3. **Style**: Makes everything consistent
  7367.  
  7368. Here's how simple it is to use:
  7369.  
  7370. ```typescript
  7371. import { correctContent } from 'gemini-cli';
  7372.  
  7373. // Fix the formatting in some code
  7374. const fixedCode = await correctContent('const x=5;');
  7375. console.log(fixedCode); // "const x = 5;" (added space)
  7376. ```
  7377.  
  7378. This automatically adds missing spaces around the equals sign.
  7379.  
  7380. ## How Correction Works
  7381.  
  7382. When you correct content, here's what happens behind the scenes:
  7383.  
  7384. ```mermaid
  7385. sequenceDiagram
  7386. participant You as You
  7387. participant Corrector as Content Corrector
  7388. participant Gemini as Gemini AI
  7389.  
  7390. You->>Corrector: "const x=5;"
  7391. Corrector->>Gemini: "Fix this code"
  7392. Gemini-->>Corrector: "const x = 5;"
  7393. Corrector->>You: Returns corrected code
  7394. ```
  7395.  
  7396. ## A Simple Example
  7397.  
  7398. Let's fix some Python code:
  7399.  
  7400. ```typescript
  7401. const pythonCode = `
  7402. def hello():
  7403. print("Hello") # Missing indent
  7404. `;
  7405.  
  7406. const fixed = await correctContent(pythonCode);
  7407. console.log(fixed);
  7408. // Output:
  7409. // def hello():
  7410. // print("Hello") # Now properly indented
  7411. ```
  7412.  
  7413. The corrector automatically adds the missing indentation.
  7414.  
  7415. ## Behind the Scenes
  7416.  
  7417. The corrector uses simple rules first (simplified from our code):
  7418.  
  7419. ```typescript
  7420. async function correctContent(text) {
  7421. // 1. Try basic formatting fixes
  7422. const simpleFix = trySimpleFixes(text);
  7423. if (simpleFix !== text) return simpleFix;
  7424.  
  7425. // 2. Ask Gemini for complex fixes
  7426. return await askGeminiToFix(text);
  7427. }
  7428. ```
  7429.  
  7430. Key steps:
  7431. 1. Attempts quick fixes first
  7432. 2. Uses Gemini for harder problems
  7433. 3. Returns the best corrected version
  7434.  
  7435. ## Common Fixes
  7436.  
  7437. You'll often see corrections for:
  7438. 1. **Indentation**: Adding missing tabs/spaces
  7439. 2. **Spacing**: Around operators like = and +
  7440. 3. **Syntax**: Fixing broken code structure
  7441.  
  7442. ## What's Next?
  7443.  
  7444. Now you understand how Content Correction keeps your files clean and error-free! In [Chapter 63: Content Diffing](63_content_diffing_.md), we'll learn how to compare file versions to see what changed.
  7445.  
  7446. > Pro Tip: Try correcting different code snippets to see what improvements Gemini suggests!
  7447.  
  7448. ---
  7449.  
  7450. # Chapter 63: Content Diffing
  7451.  
  7452. Welcome back! In [Chapter 62: Content Correction](62_content_correction_.md), we learned how Gemini can help fix mistakes in your files. Now, let's meet your CLI's **time-traveling detective** - Content Diffing that shows exactly what changed between file versions, just like comparing two photos to spot the differences!
  7453.  
  7454. ## Why Do We Need Content Diffing?
  7455.  
  7456. Imagine you're writing a story and want to see:
  7457. - What changes you made since yesterday
  7458. - Which lines were added or removed
  7459. - If any important parts got deleted by mistake
  7460.  
  7461. Content Diffing does exactly this for your files! It:
  7462. 1. Compares two versions of text
  7463. 2. Highlights all differences
  7464. 3. Shows additions in green and deletions in red
  7465.  
  7466. It's like having a magic highlighter for your changes!
  7467.  
  7468. ## Meet the Text Comparator
  7469.  
  7470. Content Diffing has three simple jobs:
  7471.  
  7472. 1. **Compare**: Looks at old and new text
  7473. 2. **Analyze**: Finds all differences
  7474. 3. **Display**: Shows changes clearly
  7475.  
  7476. Here's how simple it is to compare two versions:
  7477.  
  7478. ```typescript
  7479. import { showDiff } from 'gemini-cli';
  7480.  
  7481. // Compare old and new versions
  7482. showDiff("Hello world", "Hello there");
  7483. ```
  7484.  
  7485. This will display:
  7486. ```
  7487. Hello world
  7488. Hello there
  7489. ```
  7490. With "world" in red (removed) and "there" in green (added).
  7491.  
  7492. ## How Diffing Works
  7493.  
  7494. When you compare files, here's what happens behind the scenes:
  7495.  
  7496. ```mermaid
  7497. sequenceDiagram
  7498. participant You as You
  7499. participant Diff as Diff Tool
  7500. participant Old as Old Version
  7501. participant New as New Version
  7502.  
  7503. You->>Diff: Compare these!
  7504. Diff->>Old: Gets original text
  7505. Diff->>New: Gets new text
  7506. Diff->>Diff: Finds differences
  7507. Diff->>You: Shows changes
  7508. ```
  7509.  
  7510. ## A Simple Example
  7511.  
  7512. Let's see a real code comparison:
  7513.  
  7514. ```typescript
  7515. const oldCode = `
  7516. function greet() {
  7517. return "Hello";
  7518. }
  7519. `;
  7520.  
  7521. const newCode = `
  7522. function greet(name) {
  7523. return "Hello " + name;
  7524. }
  7525. `;
  7526.  
  7527. showDiff(oldCode, newCode);
  7528. ```
  7529.  
  7530. This will highlight:
  7531. - The added `(name)` parameter
  7532. - The changed return line
  7533.  
  7534. ## Behind the Scenes
  7535.  
  7536. The diff tool works line-by-line (simplified):
  7537.  
  7538. ```typescript
  7539. function findDifferences(oldText, newText) {
  7540. // 1. Split into lines
  7541. const oldLines = oldText.split('\n');
  7542. const newLines = newText.split('\n');
  7543.  
  7544. // 2. Compare each line
  7545. return compareLines(oldLines, newLines);
  7546. }
  7547. ```
  7548.  
  7549. Key steps:
  7550. 1. Breaks text into lines
  7551. 2. Compares them one by one
  7552. 3. Marks additions and deletions
  7553.  
  7554. ## Viewing Changes
  7555.  
  7556. The system shows differences in an easy-to-read format:
  7557.  
  7558. ```
  7559. function greet() {
  7560. +function greet(name) {
  7561. - return "Hello";
  7562. + return "Hello " + name;
  7563. }
  7564. ```
  7565.  
  7566. Where:
  7567. - `+` marks added lines (green)
  7568. - `-` marks removed lines (red)
  7569.  
  7570. ## Common Uses
  7571.  
  7572. You'll often use Content Diffing to:
  7573. 1. **Review Edits**: See what changed in your code
  7574. 2. **Check Corrections**: Verify Gemini's fixes
  7575. 3. **Compare Versions**: Look at file history
  7576.  
  7577. ## What's Next?
  7578.  
  7579. Now you understand how Content Diffing helps track changes in your files! In [Chapter 64: File System Utilities](64_file_system_utilities_.md), we'll explore more tools for working with files and folders.
  7580.  
  7581. > Pro Tip: Try comparing different versions of a file to see all your changes highlighted!
  7582.  
  7583. ---
  7584.  
  7585. # Chapter 64: File System Utilities
  7586.  
  7587. Welcome back! In [Chapter 63: Content Diffing](63_content_diffing_.md), we learned how to compare different versions of files. Now, let's meet your CLI's **digital GPS** - File System Utilities that help you navigate and organize files effortlessly, just like a map app that shows you the best routes through your computer's folders!
  7588.  
  7589. ## Why Do We Need File System Utilities?
  7590.  
  7591. Imagine you're exploring a new city without a map. You might:
  7592. - Get lost in unfamiliar neighborhoods (folders)
  7593. - Waste time going in circles (repeating searches)
  7594. - Miss important landmarks (files)
  7595.  
  7596. File System Utilities solve these problems by providing:
  7597. 1. **Path Helpers**: Shortcuts for common file operations
  7598. 2. **Smart Navigation**: Tools to find files quickly
  7599. 3. **Safety Checks**: Protection against dangerous locations
  7600.  
  7601. It's like having a friendly tour guide for your computer's file system!
  7602.  
  7603. ## Meet Your File System Guides
  7604.  
  7605. Our utilities offer three main navigation tools:
  7606.  
  7607. 1. **Path Shorteners**: Make long file paths easier to read
  7608. 2. **Relative Paths**: Show how to get from one folder to another
  7609. 3. **Safe Escaping**: Handle spaces in file names properly
  7610.  
  7611. Here's how simple it is to shorten a long path:
  7612.  
  7613. ```typescript
  7614. import { shortenPath } from 'gemini-cli';
  7615.  
  7616. // Make a long path readable
  7617. const short = shortenPath('/users/me/projects/gemini-cli/src/index.ts');
  7618. console.log(short); // "/users/.../gemini-cli/src/index.ts"
  7619. ```
  7620.  
  7621. This keeps the important parts while hiding the middle sections.
  7622.  
  7623. ## How Path Utilities Work
  7624.  
  7625. When you shorten a path, here's what happens behind the scenes:
  7626.  
  7627. ```mermaid
  7628. sequenceDiagram
  7629. participant You as You
  7630. participant Utility as Path Utility
  7631. participant Path as Long Path
  7632.  
  7633. You->>Utility: "Shorten this path"
  7634. Utility->>Path: Analyzes structure
  7635. Path-->>Utility: Returns segments
  7636. Utility->>Utility: Keeps start/end
  7637. Utility->>You: Returns shortened version
  7638. ```
  7639.  
  7640. ## A Simple Example
  7641.  
  7642. Let's find the relative path between two folders:
  7643.  
  7644. ```typescript
  7645. import { makeRelative } from 'gemini-cli';
  7646.  
  7647. // How to get from /projects to /projects/gemini-cli/src
  7648. const relative = makeRelative('/projects/gemini-cli/src', '/projects');
  7649. console.log(relative); // "gemini-cli/src"
  7650. ```
  7651.  
  7652. This shows the "directions" from one folder to another.
  7653.  
  7654. ## Behind the Scenes
  7655.  
  7656. The path utilities use simple logic (simplified from our code):
  7657.  
  7658. ```typescript
  7659. function shortenPath(fullPath, maxLength = 35) {
  7660. // 1. Split path into parts
  7661. const parts = fullPath.split('/');
  7662.  
  7663. // 2. If too long, keep first/last parts
  7664. if (fullPath.length > maxLength) {
  7665. return `${parts[0]}/.../${parts[parts.length-1]}`;
  7666. }
  7667.  
  7668. // 3. Otherwise return full path
  7669. return fullPath;
  7670. }
  7671. ```
  7672.  
  7673. Key steps:
  7674. 1. Breaks path into segments
  7675. 2. Checks if it's too long
  7676. 3. Simplifies if needed
  7677.  
  7678. ## Handling Special Cases
  7679.  
  7680. The utilities also manage tricky situations:
  7681. - Paths with spaces (escapes them properly)
  7682. - Home directory shortcuts (converts `~` to full path)
  7683. - Different operating systems (handles Windows/Mac paths)
  7684.  
  7685. ```typescript
  7686. // Escape spaces in a path
  7687. const safePath = escapePath('my documents/file.txt');
  7688. // Returns "my\ documents/file.txt"
  7689. ```
  7690.  
  7691. ## Common Patterns
  7692.  
  7693. You'll often use these utilities to:
  7694. 1. **Display Paths**: Show clean paths in your UI
  7695. 2. **Navigate Folders**: Move between directories
  7696. 3. **Handle User Input**: Process file paths safely
  7697.  
  7698. ## What's Next?
  7699.  
  7700. Now you understand how File System Utilities help navigate your computer's folders! In [Chapter 65: History Management](65_history_management_.md), we'll learn how your CLI remembers past commands and conversations.
  7701.  
  7702. > Pro Tip: Try using `shortenPath` with different lengths to see how it adapts to your needs!
  7703.  
  7704. ---
  7705.  
  7706. # Chapter 65: History Management
  7707.  
  7708. Welcome back! In [Chapter 64: File System Utilities](64_file_system_utilities_.md), we learned how to navigate files and folders in your CLI. Now, let's meet your app's **memory keeper** - History Management that remembers all your past commands and conversations, just like a notebook that keeps track of everything you've discussed with Gemini!
  7709.  
  7710. ## Why Do We Need History Management?
  7711.  
  7712. Imagine you're having a long conversation with a friend. You wouldn't want to:
  7713. - Repeat yourself constantly
  7714. - Forget important details you discussed earlier
  7715. - Lose track of the conversation flow
  7716.  
  7717. History Management solves these problems by:
  7718. 1. Remembering every message in your chat
  7719. 2. Preventing duplicate messages
  7720. 3. Giving each message a unique ID
  7721. 4. Letting you save and load conversations
  7722.  
  7723. It's like having a perfect memory for your CLI chats!
  7724.  
  7725. ## Meet Your Conversation Notebook
  7726.  
  7727. The History Manager works like a smart notebook with three key features:
  7728.  
  7729. 1. **Message Tracking**: Records every question and answer
  7730. 2. **Duplicate Prevention**: Skips identical back-to-back messages
  7731. 3. **ID Assignment**: Gives each message a unique number
  7732.  
  7733. Here's how simple it is to add a message to history:
  7734.  
  7735. ```typescript
  7736. import { useHistory } from 'gemini-cli';
  7737.  
  7738. const { addItem } = useHistory();
  7739. addItem({ type: 'user', text: 'Hello!' }, Date.now());
  7740. ```
  7741.  
  7742. This adds "Hello!" to your chat history with a unique timestamp-based ID.
  7743.  
  7744. ## How History Works
  7745.  
  7746. When you send a message, here's what happens behind the scenes:
  7747.  
  7748. ```mermaid
  7749. sequenceDiagram
  7750. participant You as You
  7751. participant History as History Manager
  7752. participant Chat as Your Chat
  7753.  
  7754. You->>History: "Add this message"
  7755. History->>History: Checks for duplicates
  7756. History->>History: Assigns unique ID
  7757. History->>Chat: Adds to conversation
  7758. Chat->>You: Shows updated history
  7759. ```
  7760.  
  7761. ## A Simple Example
  7762.  
  7763. Let's see how duplicate prevention works:
  7764.  
  7765. ```typescript
  7766. // First message
  7767. addItem({ type: 'user', text: 'Hi!' }, Date.now());
  7768.  
  7769. // Same message again (won't be added)
  7770. addItem({ type: 'user', text: 'Hi!' }, Date.now());
  7771. ```
  7772.  
  7773. The second "Hi!" gets skipped because it's identical to the last message.
  7774.  
  7775. ## Behind the Scenes
  7776.  
  7777. The history manager uses simple counters (simplified from our code):
  7778.  
  7779. ```typescript
  7780. let messageCounter = 0;
  7781.  
  7782. function addMessage(text) {
  7783. // Check if same as last message
  7784. if (lastMessage === text) return;
  7785.  
  7786. // Add with unique ID
  7787. const id = Date.now() + (messageCounter++);
  7788. history.push({ id, text });
  7789. }
  7790. ```
  7791.  
  7792. Key parts:
  7793. 1. Checks for duplicates
  7794. 2. Creates unique IDs
  7795. 3. Adds to history array
  7796.  
  7797. ## Managing Your History
  7798.  
  7799. You can also clear or load saved conversations:
  7800.  
  7801. ```typescript
  7802. // Clear all history
  7803. clearItems();
  7804.  
  7805. // Load saved chat
  7806. loadHistory(savedChat);
  7807. ```
  7808.  
  7809. This lets you start fresh or continue old conversations.
  7810.  
  7811. ## Common Patterns
  7812.  
  7813. You'll often use history management to:
  7814. 1. **Review Past Chats**: See what you discussed earlier
  7815. 2. **Continue Conversations**: Pick up where you left off
  7816. 3. **Save Important Talks**: Keep useful discussions
  7817.  
  7818. ## What's Next?
  7819.  
  7820. Now you understand how History Management keeps track of all your CLI conversations! In [Chapter 66: Memory Management](66_memory_management_.md), we'll learn how your app efficiently handles large amounts of data.
  7821.  
  7822. > Pro Tip: Try using the up/down arrows to navigate through your command history!
  7823.  
  7824. ---
  7825.  
  7826. # Chapter 66: Memory Management
  7827.  
  7828. Welcome back! In [Chapter 65: History Management](65_history_management_.md), we learned how your CLI remembers past conversations. Now, let's meet your app's **digital librarian** - Memory Management that organizes and retrieves reference materials, just like a helpful librarian who knows exactly where every book is stored!
  7829.  
  7830. ## Why Do We Need Memory Management?
  7831.  
  7832. Imagine you're writing a research paper and need to:
  7833. 1. Find notes from last week
  7834. 2. Include quotes from reference books
  7835. 3. Combine information from different sources
  7836.  
  7837. Memory Management does exactly this for your CLI! It:
  7838. - Organizes hierarchical memory files (like a library catalog)
  7839. - Processes imports between files (like following references)
  7840. - Retrieves exactly what you need when you ask
  7841.  
  7842. ## Meet Your Digital Library
  7843.  
  7844. Think of Memory Management as having three simple tools:
  7845.  
  7846. 1. **File Finder**: Locates all your memory files
  7847. 2. **Import Processor**: Combines content from different files
  7848. 3. **Content Organizer**: Structures everything neatly
  7849.  
  7850. Here's how simple it is to find memory files:
  7851.  
  7852. ```typescript
  7853. import { findMemoryFiles } from 'gemini-cli';
  7854.  
  7855. // Find all memory files in current folder
  7856. const files = await findMemoryFiles('./');
  7857. console.log(files); // ["notes.md", "references.md"]
  7858. ```
  7859.  
  7860. This shows all available memory files in your project.
  7861.  
  7862. ## How Memory Works Together
  7863.  
  7864. When you access memory files, here's what happens:
  7865.  
  7866. ```mermaid
  7867. sequenceDiagram
  7868. participant You as You
  7869. participant Finder as File Finder
  7870. participant Processor as Import Processor
  7871. participant Files as Your Files
  7872.  
  7873. You->>Finder: "Find memory files"
  7874. Finder->>Files: Searches folders
  7875. Files-->>Finder: Returns file list
  7876. Finder->>Processor: "Combine these files"
  7877. Processor->>You: Returns organized content
  7878. ```
  7879.  
  7880. ## A Simple Example
  7881.  
  7882. Let's see how to combine files with imports:
  7883.  
  7884. ```markdown
  7885. <!-- In main.md -->
  7886. # My Notes
  7887. @references.md
  7888. ```
  7889.  
  7890. ```markdown
  7891. <!-- In references.md -->
  7892. - Source: Gemini CLI Docs
  7893. ```
  7894.  
  7895. The system will combine them into:
  7896. ```
  7897. # My Notes
  7898. - Source: Gemini CLI Docs
  7899. ```
  7900.  
  7901. ## Behind the Scenes
  7902.  
  7903. The import processor works like this (simplified):
  7904.  
  7905. ```typescript
  7906. async function processImports(content) {
  7907. // Find all @import statements
  7908. const imports = content.match(/@(\S+)/g);
  7909.  
  7910. // For each import, read that file
  7911. for (const imp of imports) {
  7912. const importedContent = await readFile(imp);
  7913. content = content.replace(imp, importedContent);
  7914. }
  7915.  
  7916. return content;
  7917. }
  7918. ```
  7919.  
  7920. Key steps:
  7921. 1. Finds `@filename` references
  7922. 2. Reads each imported file
  7923. 3. Combines everything together
  7924.  
  7925. ## Safety Features
  7926.  
  7927. Memory Management includes important protections:
  7928. - Prevents circular imports (A imports B which imports A)
  7929. - Checks file permissions
  7930. - Handles errors gracefully
  7931.  
  7932. ## What's Next?
  7933.  
  7934. Now you understand how Memory Management organizes your CLI's reference materials! In [Chapter 67: Request/Response Formatting](67_request_response_formatting_.md), we'll learn how your CLI structures messages to Gemini's servers.
  7935.  
  7936. > Pro Tip: Try creating simple `.md` files with `@` imports to see how they combine automatically!
  7937.  
  7938. ---
  7939.  
  7940. # Chapter 67: Request/Response Formatting
  7941.  
  7942. Welcome back! In [Chapter 66: Memory Management](66_memory_management_.md), we learned how your CLI organizes and retrieves reference materials. Now, let's meet your app's **package wrapping department** - Request/Response Formatting that carefully prepares messages for Gemini and unpacks its responses, just like gift wrapping presents before sending and carefully unwrapping the replies!
  7943.  
  7944. ## Why Do We Need Request/Response Formatting?
  7945.  
  7946. Imagine you're sending a package to a friend. You wouldn't just throw items loose in a box - you'd:
  7947. 1. Wrap each item carefully (formatting)
  7948. 2. Include clear labels (metadata)
  7949. 3. Pack everything neatly (structure)
  7950.  
  7951. Request/Response Formatting does exactly this for your CLI's messages! It:
  7952. 1. Packages your questions properly for Gemini
  7953. 2. Unpacks Gemini's responses neatly
  7954. 3. Handles special content like files and code
  7955.  
  7956. Without it, your messages might arrive scrambled or Gemini's replies could be hard to understand!
  7957.  
  7958. ## Meet the Gift Wrapping Station
  7959.  
  7960. Our formatting system has two main jobs:
  7961.  
  7962. 1. **Request Wrapping**: Preparing your messages for sending
  7963. 2. **Response Unwrapping**: Making Gemini's replies easy to use
  7964.  
  7965. Here's how simple it is to format a basic question:
  7966.  
  7967. ```typescript
  7968. import { formatRequest } from 'gemini-cli';
  7969.  
  7970. // Wrap a simple question
  7971. const wrappedQuestion = formatRequest("What's 2+2?");
  7972. console.log(wrappedQuestion); // {text: "What's 2+2?"}
  7973. ```
  7974.  
  7975. This creates a properly structured message object ready for Gemini.
  7976.  
  7977. ## How Formatting Works
  7978.  
  7979. When you ask a question, here's what happens behind the scenes:
  7980.  
  7981. ```mermaid
  7982. sequenceDiagram
  7983. participant You as You
  7984. participant Wrapper as Request Wrapper
  7985. participant Gemini as Gemini API
  7986.  
  7987. You->>Wrapper: "What's 2+2?"
  7988. Wrapper->>Wrapper: Adds formatting
  7989. Wrapper->>Gemini: Sends neat package
  7990. Gemini-->>Wrapper: Returns response
  7991. Wrapper->>You: Unpacks clean answer
  7992. ```
  7993.  
  7994. ## A Simple Example
  7995.  
  7996. Let's format different types of requests:
  7997.  
  7998. ```typescript
  7999. // Text question
  8000. formatRequest("Hello Gemini!");
  8001.  
  8002. // File content
  8003. formatRequest({file: "notes.txt"});
  8004.  
  8005. // Code snippet
  8006. formatRequest({code: "function hello() { return 'Hi!'; }"});
  8007. ```
  8008.  
  8009. Each gets wrapped appropriately for Gemini to understand.
  8010.  
  8011. ## Behind the Scenes
  8012.  
  8013. The formatter checks content types (simplified from our code):
  8014.  
  8015. ```typescript
  8016. function formatRequest(content) {
  8017. if (typeof content === 'string') {
  8018. return { text: content }; // Simple text
  8019. }
  8020. if (content.file) {
  8021. return { file: readFile(content.file) }; // File content
  8022. }
  8023. if (content.code) {
  8024. return { code: content.code }; // Code block
  8025. }
  8026. }
  8027. ```
  8028.  
  8029. Key parts:
  8030. 1. Handles plain text directly
  8031. 2. Reads files when needed
  8032. 3. Preserves code structure
  8033.  
  8034. ## Handling Responses
  8035.  
  8036. The system also unpacks Gemini's replies:
  8037.  
  8038. ```typescript
  8039. function unpackResponse(response) {
  8040. if (response.text) {
  8041. return response.text; // Simple answer
  8042. }
  8043. if (response.files) {
  8044. return response.files; // File references
  8045. }
  8046. }
  8047. ```
  8048.  
  8049. This ensures you always get responses in a usable format.
  8050.  
  8051. ## Common Patterns
  8052.  
  8053. You'll often use formatting for:
  8054. 1. **Simple Questions**: Basic text queries
  8055. 2. **File Operations**: Sending/receiving files
  8056. 3. **Code Help**: Sharing and discussing code
  8057.  
  8058. ## What's Next?
  8059.  
  8060. Now you understand how Request/Response Formatting prepares messages for Gemini! In [Chapter 68: Gemini Stream Processing](68_gemini_stream_processing_.md), we'll learn how your CLI handles responses that come in multiple parts.
  8061.  
  8062. > Pro Tip: Try formatting different types of content to see how they get packaged for Gemini!
  8063.  
  8064. ---
  8065.  
  8066. # Chapter 68: Gemini Stream Processing
  8067.  
  8068. Welcome back! In [Chapter 67: Request/Response Formatting](67_request_response_formatting_.md), we learned how your CLI packages messages for Gemini. Now, let's meet your app's **conversation manager** - Gemini Stream Processing that handles the back-and-forth flow with Gemini, just like a telephone operator connecting your calls and making sure everyone gets their turn to speak!
  8069.  
  8070. ## Why Do We Need Stream Processing?
  8071.  
  8072. Imagine you're having a phone conversation where:
  8073. - You ask a question ("What's the weather?")
  8074. - Gemini starts answering ("It's currently sunny...")
  8075. - More details keep coming ("...with a high of 75°F...")
  8076. - The answer arrives in pieces over time
  8077.  
  8078. Stream Processing manages this entire flow by:
  8079. 1. Sending your questions to Gemini
  8080. 2. Receiving responses piece by piece
  8081. 3. Showing updates as they arrive
  8082. 4. Handling any tools Gemini needs to use
  8083.  
  8084. Without it, your conversation would feel choppy and disconnected!
  8085.  
  8086. ## Meet the Conversation Flow
  8087.  
  8088. Stream Processing handles three main tasks:
  8089.  
  8090. 1. **Sending**: Your questions to Gemini
  8091. 2. **Receiving**: Responses as they stream in
  8092. 3. **Managing**: Tools or follow-up questions
  8093.  
  8094. Here's how simple it is to start a conversation:
  8095.  
  8096. ```typescript
  8097. import { startStream } from 'gemini-cli';
  8098.  
  8099. // Ask a question and get streaming responses
  8100. const stream = startStream("What's the weather?");
  8101. ```
  8102.  
  8103. This begins the conversation and prepares to receive Gemini's response.
  8104.  
  8105. ## How Streaming Works
  8106.  
  8107. When you ask a question, here's what happens:
  8108.  
  8109. ```mermaid
  8110. sequenceDiagram
  8111. participant You as You
  8112. participant Stream as Stream Processor
  8113. participant Gemini as Gemini
  8114.  
  8115. You->>Stream: "What's the weather?"
  8116. Stream->>Gemini: Sends question
  8117. Gemini-->>Stream: "It's currently sunny..."
  8118. Stream->>You: Shows first part
  8119. Gemini-->>Stream: "...with a high of 75°F"
  8120. Stream->>You: Updates with more
  8121. ```
  8122.  
  8123. ## A Simple Example
  8124.  
  8125. Let's see streaming in action:
  8126.  
  8127. ```typescript
  8128. // Start the stream
  8129. const stream = startStream("Tell me about dogs");
  8130.  
  8131. // Handle responses as they arrive
  8132. for await (const chunk of stream) {
  8133. console.log(chunk); // Shows pieces of the answer
  8134. }
  8135. ```
  8136.  
  8137. This will display Gemini's response in parts as they become available.
  8138.  
  8139. ## Behind the Scenes
  8140.  
  8141. The stream processor works in three steps (simplified from our code):
  8142.  
  8143. ```typescript
  8144. async function processStream(question) {
  8145. // 1. Send the question
  8146. const connection = connectToGemini(question);
  8147.  
  8148. // 2. Receive chunks
  8149. for await (const chunk of connection) {
  8150. // 3. Show each piece
  8151. displayChunk(chunk);
  8152. }
  8153. }
  8154. ```
  8155.  
  8156. Key parts:
  8157. 1. Establishes the connection
  8158. 2. Listens for response pieces
  8159. 3. Displays them as they arrive
  8160.  
  8161. ## Handling Special Cases
  8162.  
  8163. The processor also manages:
  8164. - Network interruptions (automatically retries)
  8165. - Long responses (shows "..." while waiting)
  8166. - Tool requests (pauses to run tools)
  8167.  
  8168. ```typescript
  8169. // Example of handling a tool request
  8170. stream.on('tool', (tool) => {
  8171. runTool(tool); // Runs the requested tool
  8172. });
  8173. ```
  8174.  
  8175. ## Common Patterns
  8176.  
  8177. You'll often use stream processing for:
  8178. 1. **Long Answers**: That come in multiple parts
  8179. 2. **Interactive Chats**: Where you respond to Gemini
  8180. 3. **Tool-Using Queries**: That require external actions
  8181.  
  8182. ## What's Next?
  8183.  
  8184. Now you understand how Gemini Stream Processing manages your conversation flow! In [Chapter 69: Extension System](69_extension_system_.md), we'll learn how to add new capabilities to your CLI.
  8185.  
  8186. > Pro Tip: Try asking Gemini a complex question to see the response stream in pieces!
  8187.  
  8188. ---
  8189.  
  8190. # Chapter 69: Extension System
  8191.  
  8192. Welcome back! In [Chapter 68: Gemini Stream Processing](68_gemini_stream_processing_.md), we learned how your CLI manages conversations with Gemini. Now, let's meet your app's **plugin store** - the Extension System that lets you add new features to your CLI, just like installing apps on your phone to get more capabilities!
  8193.  
  8194. ## Why Do We Need Extensions?
  8195.  
  8196. Imagine your CLI is like a basic phone - it can make calls and send texts, but you want more. Extensions let you:
  8197. - Add new tools (like a calculator app)
  8198. - Connect to other services (like social media apps)
  8199. - Customize your experience (like new themes)
  8200.  
  8201. Without extensions, your CLI would be limited to only what comes built-in. With them, you can teach it new tricks!
  8202.  
  8203. ## Meet the Three Simple Parts
  8204.  
  8205. Extensions work through three easy concepts:
  8206.  
  8207. 1. **Extension Packages**: Bundles of new functionality (like app install files)
  8208. 2. **Configuration Files**: Instructions for how to install them
  8209. 3. **Loading System**: The process that adds them to your CLI
  8210.  
  8211. Here's how simple it is to load extensions:
  8212.  
  8213. ```typescript
  8214. import { loadExtensions } from 'gemini-cli';
  8215.  
  8216. // Load all available extensions
  8217. const extensions = loadExtensions();
  8218. console.log(extensions[0].name); // Shows first extension's name
  8219. ```
  8220.  
  8221. This finds and prepares all extensions in your system.
  8222.  
  8223. ## How Extensions Work Together
  8224.  
  8225. When you load extensions, here's what happens:
  8226.  
  8227. ```mermaid
  8228. sequenceDiagram
  8229. participant You as You
  8230. participant CLI as Your CLI
  8231. participant Extensions as Extensions Folder
  8232.  
  8233. You->>CLI: "Load extensions"
  8234. CLI->>Extensions: Checks folders
  8235. Extensions-->>CLI: Returns extension list
  8236. CLI->>You: Ready to use new features!
  8237. ```
  8238.  
  8239. ## A Simple Example
  8240.  
  8241. Let's look at a basic extension configuration:
  8242.  
  8243. ```json
  8244. // In gemini-extension.json
  8245. {
  8246. "name": "weather-tool",
  8247. "version": "1.0",
  8248. "contextFileName": "weather.md"
  8249. }
  8250. ```
  8251.  
  8252. This defines:
  8253. - The extension's name
  8254. - Its version
  8255. - A file with instructions
  8256.  
  8257. ## Behind the Scenes
  8258.  
  8259. The extension loader works in three steps (simplified from our code):
  8260.  
  8261. ```typescript
  8262. function loadExtension(folder) {
  8263. // 1. Find config file
  8264. const config = readConfig(folder);
  8265.  
  8266. // 2. Check required fields
  8267. if (!config.name || !config.version) return null;
  8268.  
  8269. // 3. Prepare extension
  8270. return {
  8271. config,
  8272. files: findContextFiles(config)
  8273. };
  8274. }
  8275. ```
  8276.  
  8277. Key parts:
  8278. 1. Looks for configuration
  8279. 2. Validates the extension
  8280. 3. Gets it ready to use
  8281.  
  8282. ## Finding Extensions
  8283.  
  8284. The system checks two main locations:
  8285. 1. Your project folder (for workspace-specific extensions)
  8286. 2. Your home directory (for personal extensions)
  8287.  
  8288. ```typescript
  8289. const extensions = [
  8290. ...loadFromFolder(projectPath),
  8291. ...loadFromFolder(homePath)
  8292. ];
  8293. ```
  8294.  
  8295. This combines extensions from both locations.
  8296.  
  8297. ## Common Extension Uses
  8298.  
  8299. You'll often use extensions to:
  8300. 1. **Add Tools**: Like weather lookup or calculators
  8301. 2. **Connect Services**: Link to other APIs
  8302. 3. **Customize**: Change how your CLI looks or works
  8303.  
  8304. ## What's Next?
  8305.  
  8306. Now you understand how the Extension System lets you add new powers to your CLI! In [Chapter 70: MCP Tools](70_mcp_tools_.md), we'll explore special extensions that connect to remote services.
  8307.  
  8308. > Pro Tip: Try creating a simple `gemini-extension.json` file to see how extensions are configured!
  8309.  
  8310. ---
  8311.  
  8312. # Chapter 70: MCP Tools
  8313.  
  8314. Welcome back! In [Chapter 69: Extension System](69_extension_system_.md), we learned how to add new features to your CLI. Now, let's meet your app's **international translator** - MCP Tools that connect your CLI to powerful remote services, just like having a personal interpreter who helps you communicate with experts around the world!
  8315.  
  8316. ## Why Do We Need MCP Tools?
  8317.  
  8318. Imagine you're traveling in a foreign country and need:
  8319. - A local guide (to show you around)
  8320. - A translator (to help you communicate)
  8321. - A connection to special services (like medical help)
  8322.  
  8323. MCP Tools do exactly this for your CLI! They:
  8324. 1. Connect to remote servers with special tools
  8325. 2. Translate between your CLI and those services
  8326. 3. Let you use powerful features from anywhere
  8327.  
  8328. For example, you could ask Gemini to "Check server status in Tokyo" and an MCP Tool would connect to a Tokyo server to get the answer!
  8329.  
  8330. ## Meet the Remote Helpers
  8331.  
  8332. MCP Tools work through three simple concepts:
  8333.  
  8334. 1. **Discovery**: Finding available remote tools
  8335. 2. **Permission**: Asking before using them
  8336. 3. **Execution**: Running the tools safely
  8337.  
  8338. Here's how simple it is to discover remote tools:
  8339.  
  8340. ```typescript
  8341. import { discoverMcpTools } from 'gemini-cli';
  8342.  
  8343. // Find tools from a server
  8344. const tools = await discoverMcpTools('tokyo-server');
  8345. console.log(tools[0].name); // "server-monitor"
  8346. ```
  8347.  
  8348. This shows all tools available from the "tokyo-server".
  8349.  
  8350. ## How MCP Tools Work
  8351.  
  8352. When you use a remote tool, here's what happens:
  8353.  
  8354. ```mermaid
  8355. sequenceDiagram
  8356. participant You as You
  8357. participant CLI as Your CLI
  8358. participant MCP as MCP Tool
  8359. participant Server as Remote Server
  8360.  
  8361. You->>CLI: "Check Tokyo server"
  8362. CLI->>MCP: Finds the right tool
  8363. MCP->>You: "Allow this connection?"
  8364. You->>MCP: "Yes!"
  8365. MCP->>Server: Runs the check
  8366. Server-->>MCP: Returns status
  8367. MCP->>You: Shows results
  8368. ```
  8369.  
  8370. ## A Simple Example
  8371.  
  8372. Let's use a remote monitoring tool:
  8373.  
  8374. ```typescript
  8375. // Get the server status tool
  8376. const monitor = mcpTools.find(t => t.name === 'server-status');
  8377.  
  8378. // Run it (will ask for permission first)
  8379. const result = await monitor.run({ location: 'tokyo' });
  8380. console.log(result); // "Tokyo server: Online"
  8381. ```
  8382.  
  8383. This safely connects to the remote server and returns its status.
  8384.  
  8385. ## Behind the Scenes
  8386.  
  8387. The MCP Tool system checks permissions (simplified from our code):
  8388.  
  8389. ```typescript
  8390. class McpTool {
  8391. async checkPermission() {
  8392. if (this.trusted) return true; // No need to ask
  8393.  
  8394. // Show confirmation dialog
  8395. return askUser(`Allow ${this.server} to run ${this.name}?`);
  8396. }
  8397. }
  8398. ```
  8399.  
  8400. Key parts:
  8401. 1. Checks if the server is trusted
  8402. 2. Asks for user confirmation if not
  8403. 3. Only runs after getting permission
  8404.  
  8405. ## Safety Features
  8406.  
  8407. MCP Tools include important protections:
  8408. - Always ask before connecting to new servers
  8409. - Remember your permission choices
  8410. - Timeout if responses take too long
  8411.  
  8412. ```typescript
  8413. // Run with 5-second timeout
  8414. await tool.run(params, { timeout: 5000 });
  8415. ```
  8416.  
  8417. ## Common Uses
  8418.  
  8419. You'll often use MCP Tools for:
  8420. 1. **Remote Monitoring**: Checking servers worldwide
  8421. 2. **Specialized Services**: Accessing unique tools
  8422. 3. **Team Collaboration**: Sharing tools securely
  8423.  
  8424. ## What's Next?
  8425.  
  8426. Now you understand how MCP Tools connect your CLI to powerful remote services! In [Chapter 71: File Discovery Service](71_file_discovery_service_.md), we'll learn how your CLI efficiently finds files when you need them.
  8427.  
  8428. > Pro Tip: Try discovering available MCP Tools from different servers to see what special features they offer!
  8429.  
  8430. ---
  8431.  
  8432. # Chapter 71: File Discovery Service
  8433.  
  8434. Welcome back! In [Chapter 70: MCP Tools](70_mcp_tools_.md), we learned how to connect your CLI to powerful remote services. Now, let's meet your app's **digital detective** - the File Discovery Service that helps you quickly find files in your project, just like a searchlight that instantly spots what you're looking for in a dark room!
  8435.  
  8436. ## Why Do We Need File Discovery?
  8437.  
  8438. Imagine you're working on a big coding project with hundreds of files. You need to:
  8439. - Find all JavaScript files (`*.js`)
  8440. - Locate configuration files (`config.*`)
  8441. - Search for specific function names
  8442.  
  8443. Manually looking through folders would take forever! The File Discovery Service solves this by:
  8444. 1. Searching your entire project instantly
  8445. 2. Filtering files by name, type, or content
  8446. 3. Respecting ignore rules (like `.gitignore`)
  8447.  
  8448. It's like having a super-powered search engine just for your code!
  8449.  
  8450. ## Meet the File Finder
  8451.  
  8452. The File Discovery Service has two simple jobs:
  8453.  
  8454. 1. **Finding Files**: Locates all files matching your criteria
  8455. 2. **Filtering Files**: Skips files you want to ignore
  8456.  
  8457. Here's how easy it is to find all JavaScript files:
  8458.  
  8459. ```typescript
  8460. import { findFiles } from 'gemini-cli';
  8461.  
  8462. // Find all .js files
  8463. const jsFiles = await findFiles('*.js');
  8464. console.log(jsFiles); // ["src/index.js", "utils/helper.js", ...]
  8465. ```
  8466.  
  8467. This returns an array of all JavaScript files in your project.
  8468.  
  8469. ## How File Discovery Works
  8470.  
  8471. When you search for files, here's what happens behind the scenes:
  8472.  
  8473. ```mermaid
  8474. sequenceDiagram
  8475. participant You as You
  8476. participant Finder as File Finder
  8477. participant Project as Project Files
  8478.  
  8479. You->>Finder: "Find *.js files"
  8480. Finder->>Project: Searches all folders
  8481. Project-->>Finder: Returns matching files
  8482. Finder->>You: Shows JavaScript files
  8483. ```
  8484.  
  8485. ## A Simple Example
  8486.  
  8487. Let's find configuration files:
  8488.  
  8489. ```typescript
  8490. // Find all config files
  8491. const configFiles = await findFiles('config.*');
  8492. console.log(configFiles); // ["config.json", "config.dev.yml"]
  8493. ```
  8494.  
  8495. This searches for any file starting with "config." regardless of extension.
  8496.  
  8497. ## Behind the Scenes
  8498.  
  8499. The service works in three simple steps (simplified from our code):
  8500.  
  8501. ```typescript
  8502. async function findFiles(pattern) {
  8503. // 1. Get all files in project
  8504. const allFiles = getAllFiles();
  8505.  
  8506. // 2. Filter by pattern
  8507. return allFiles.filter(file =>
  8508. file.match(new RegExp(pattern))
  8509. );
  8510. }
  8511. ```
  8512.  
  8513. Key parts:
  8514. 1. Gets every file in your project
  8515. 2. Checks which match your search pattern
  8516. 3. Returns the matches
  8517.  
  8518. ## Smart Filtering
  8519.  
  8520. The service automatically respects ignore rules:
  8521.  
  8522. ```typescript
  8523. // In .gitignore
  8524. node_modules/
  8525. temp/
  8526.  
  8527. // These won't appear in search results!
  8528. await findFiles('*'); // Skips node_modules and temp
  8529. ```
  8530.  
  8531. This prevents cluttering results with files you want to ignore.
  8532.  
  8533. ## Common Uses
  8534.  
  8535. You'll often use file discovery to:
  8536. 1. **Find Source Files**: Locate all `.ts` or `.js` files
  8537. 2. **Search Configs**: Look for configuration files
  8538. 3. **Check Documentation**: Find all `.md` files
  8539.  
  8540. ## What's Next?
  8541.  
  8542. Now you understand how the File Discovery Service helps you quickly find files in your projects! In [Chapter 72: Git Integration](72_git_integration_.md), we'll learn how your CLI works with Git repositories.
  8543.  
  8544. > Pro Tip: Try different search patterns like `*.md` or `test/*.js` to see what files you can discover!
  8545.  
  8546. ---
  8547.  
  8548. # Chapter 72: Git Integration
  8549.  
  8550. Welcome back! In [Chapter 71: File Discovery Service](71_file_discovery_service_.md), we learned how to quickly find files in your project. Now, let's meet your CLI's **time machine** - Git Integration that lets you travel back to previous versions of your code, just like rewinding a movie to see an earlier scene!
  8551.  
  8552. ## Why Do We Need Git Integration?
  8553.  
  8554. Imagine you're writing a story and accidentally delete a paragraph. Wouldn't it be great to:
  8555. - Go back to yesterday's version
  8556. - See what changed
  8557. - Restore what you deleted
  8558.  
  8559. Git Integration does exactly this for your code! It:
  8560. 1. Takes snapshots of your project (called "commits")
  8561. 2. Lets you compare different versions
  8562. 3. Helps undo mistakes by restoring old versions
  8563.  
  8564. It's like having an "undo button" for your entire project!
  8565.  
  8566. ## Meet the Three Time Travel Tools
  8567.  
  8568. Git Integration provides three simple ways to work with code history:
  8569.  
  8570. 1. **Snapshots**: Save the current state of your code
  8571. 2. **Comparison**: See what changed between versions
  8572. 3. **Restore**: Go back to an earlier version
  8573.  
  8574. Here's how easy it is to save a snapshot:
  8575.  
  8576. ```typescript
  8577. import { git } from 'gemini-cli';
  8578.  
  8579. // Save current code state
  8580. await git.saveSnapshot("Added login feature");
  8581. console.log("Snapshot saved!");
  8582. ```
  8583.  
  8584. This creates a permanent record you can return to later.
  8585.  
  8586. ## How Git Integration Works
  8587.  
  8588. When you save a snapshot, here's what happens:
  8589.  
  8590. ```mermaid
  8591. sequenceDiagram
  8592. participant You as You
  8593. participant Git as Git Service
  8594. participant Files as Your Files
  8595.  
  8596. You->>Git: "Save snapshot"
  8597. Git->>Files: Records all file states
  8598. Files-->>Git: Returns file data
  8599. Git->>Git: Stores compressed version
  8600. Git->>You: "Snapshot saved!"
  8601. ```
  8602.  
  8603. ## A Simple Example
  8604.  
  8605. Let's see how to restore an old version:
  8606.  
  8607. ```typescript
  8608. // List all snapshots
  8609. const snapshots = await git.listSnapshots();
  8610. console.log(snapshots); // ["Added login", "Fixed bug", ...]
  8611.  
  8612. // Restore the first one
  8613. await git.restoreSnapshot(snapshots[0]);
  8614. console.log("Back to previous version!");
  8615. ```
  8616.  
  8617. This lets you undo changes and return to any saved state.
  8618.  
  8619. ## Behind the Scenes
  8620.  
  8621. The Git service works like this (simplified):
  8622.  
  8623. ```typescript
  8624. class GitService {
  8625. async saveSnapshot(message) {
  8626. // 1. Record all file changes
  8627. const changes = detectFileChanges();
  8628.  
  8629. // 2. Store them permanently
  8630. storeChanges(message, changes);
  8631. }
  8632. }
  8633. ```
  8634.  
  8635. Key steps:
  8636. 1. Checks what files changed
  8637. 2. Saves them with your message
  8638. 3. Compresses to save space
  8639.  
  8640. ## Safety Features
  8641.  
  8642. Git Integration includes important protections:
  8643. - Never deletes your original files
  8644. - Keeps multiple backup versions
  8645. - Lets you preview changes before restoring
  8646.  
  8647. ```typescript
  8648. // See what would change
  8649. const preview = await git.previewRestore(snapshot);
  8650. console.log(preview.changes); // Files that would be modified
  8651. ```
  8652.  
  8653. ## Common Uses
  8654.  
  8655. You'll often use Git Integration to:
  8656. 1. **Recover Mistakes**: Undo bad changes
  8657. 2. **Compare Versions**: See how code evolved
  8658. 3. **Experiment Safely**: Try ideas knowing you can undo
  8659.  
  8660. ## What's Next?
  8661.  
  8662. Now you understand how Git Integration acts as a time machine for your code! In our next chapters, we'll explore more ways to enhance your CLI experience.
  8663.  
  8664. > Pro Tip: Try making small changes and creating snapshots to see how easy it is to travel through your code's history!
  8665.  
  8666. ---
  8667.  
Tags: Gemini
Add Comment
Please, Sign In to add comment