Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,31 @@ Do not deviate from this structure when editing or adding chapter content.
| Devcontainer updated | `.devcontainer/devcontainer.json`, Chapter 00 (setup instructions) |
| Image or banner changed | `assets/` directory, any README referencing the image |
| Copilot CLI version requirements change | Chapter 00, Chapter 01, `.devcontainer/devcontainer.json` |

<!-- rtk-instructions v2 -->
# RTK — Token-Optimized CLI

**rtk** is a CLI proxy that filters and compresses command outputs, saving 60-90% tokens.

## Rule

Always prefix shell commands with `rtk`:

```bash
# Instead of: Use:
git status rtk git status
git log -10 rtk git log -10
cargo test rtk cargo test
docker ps rtk docker ps
kubectl get pods rtk kubectl pods
Comment on lines +83 to +87
```

## Meta commands (use directly)

```bash
rtk gain # Token savings dashboard
rtk gain --history # Per-command savings history
rtk discover # Find missed rtk opportunities
rtk proxy <cmd> # Run raw (no filtering) but track usage
```
<!-- /rtk-instructions -->
12 changes: 12 additions & 0 deletions .github/hooks/rtk-rewrite.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "rtk hook copilot",
"cwd": ".",
"timeout": 5
}
]
}
}
Comment on lines +1 to +12
13 changes: 13 additions & 0 deletions .rtk/filters.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Project-local RTK filters — commit this file with your repo.
# Filters here override user-global and built-in filters.
# Docs: https://github.com/rtk-ai/rtk#custom-filters
schema_version = 1

# Example: suppress build noise from a custom tool
# [filters.my-tool]
# description = "Compact my-tool output"
# match_command = "^my-tool\\s+build"
# strip_ansi = true
# strip_lines_matching = ["^\\s*$", "^Downloading", "^Installing"]
# max_lines = 30
# on_empty = "my-tool: ok"
16 changes: 1 addition & 15 deletions samples/book-app-project/book_app.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
import sys
from books import BookCollection
from utils import show_books


# Global collection instance
collection = BookCollection()


def show_books(books):
"""Display books in a user-friendly format."""
if not books:
print("No books found.")
return

print("\nYour Book Collection:\n")

for index, book in enumerate(books, start=1):
status = "✓" if book.read else " "
print(f"{index}. [{status}] {book.title} by {book.author} ({book.year})")

print()


def handle_list():
books = collection.list_books()
show_books(books)
Expand Down
40 changes: 33 additions & 7 deletions samples/book-app-project/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,34 @@ def print_menu():


def get_user_choice() -> str:
return input("Choose an option (1-5): ").strip()
while True:
choice = input("Choose an option (1-5): ").strip()
if choice in {"1", "2", "3", "4", "5"}:
return choice
print("Invalid choice. Please enter a number between 1 and 5.")
Comment on lines 10 to +15


def get_book_details():
title = input("Enter book title: ").strip()
"""Prompt the user for book details and return them.

Prompts (via standard input) for the following fields:
- title: required. The function will re-prompt until a non-empty title is provided.
- author: optional. An empty string is allowed.
- publication year: optional. The function attempts to convert input to int; if conversion
fails the year defaults to 0 and a message is printed.

Returns:
tuple[str, str, int]: A 3-tuple of (title, author, year).

Side effects:
- Prints prompts and validation messages to stdout.
"""
while True:
title = input("Enter book title: ").strip()
if title:
break
print("Title cannot be empty. Please enter a title.")

author = input("Enter author: ").strip()

year_input = input("Enter publication year: ").strip()
Expand All @@ -25,12 +48,15 @@ def get_book_details():
return title, author, year


def print_books(books):
def show_books(books):
if not books:
print("No books in your collection.")
print("No books found.")
return

print("\nYour Books:")
print("\nYour Book Collection:\n")

for index, book in enumerate(books, start=1):
status = "✅ Read" if book.read else "📖 Unread"
print(f"{index}. {book.title} by {book.author} ({book.year}) - {status}")
status = "✓" if book.read else " "
print(f"{index}. [{status}] {book.title} by {book.author} ({book.year})")

print()