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
7 changes: 7 additions & 0 deletions .github/uvs.csv
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,10 @@
"05/01",738
"05/02",529
"05/03",571
"05/04",1171
"05/05",982
"05/06",934
"05/07",996
"05/08",1034
"05/09",455
"05/10",481
7 changes: 7 additions & 0 deletions .github/views.csv
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,10 @@
"05/01",2013
"05/02",1317
"05/03",1336
"05/04",2124
"05/05",2018
"05/06",1906
"05/07",2121
"05/08",2393
"05/09",1097
"05/10",1003
5 changes: 5 additions & 0 deletions 01-setup-and-first-steps/copilot_programmatic_mode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Review all Python files in the book app
for file in samples/book-app-project/*.py; do
echo "Reviewing $file..."
copilot --allow-all -p "Quick code quality review of @$file - critical issues only"
done
14 changes: 14 additions & 0 deletions 05-skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ While auto-triggering is the primary way skills work, you can also **invoke skil

This gives you explicit control when you want to ensure a specific skill is used.

#### Combining Multiple Skills in One Message

You can invoke **more than one skill in a single message**, and the skill slash command can appear anywhere in your prompt — not just at the beginning. This is handy when you want two different checks done in one go:

```bash
> Check @samples/book-app-project/book_app.py with /code-checklist and also run /generate-tests for it

> Review the auth module /security-audit then /code-checklist the result
```
Comment on lines +109 to +112

Copilot will apply each named skill in the same response, saving you from sending multiple separate messages.

> 💡 **Tip**: Put the skill slash commands wherever they feel most natural in your sentence. You can put them at the start, middle, or end of your message.

> 📝 **Skills vs Agents Invocation**: Don't confuse skill invocation with agent invocation:
> - **Skills**: `/skill-name <prompt>`, e.g., `/code-checklist Check this file`
> - **Agents**: `/agent` (select from list) or `copilot --agent <name>` (command line)
Expand Down
1,105 changes: 1,105 additions & 0 deletions current-session.html

Large diffs are not rendered by default.

292 changes: 292 additions & 0 deletions current-session.md

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions samples/book-app-project-cs/BookApp.csproj.lscache
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
version=1

# This file caches language service data to improve the performance of C# Dev Kit.
# It is not intended for manual editing. It can safely be deleted and will be
# regenerated automatically. For more information, see https://aka.ms/lscache
#
# To control where cache files are stored, use the following VS Code setting:
# "dotnet.projectsystem.cacheInProjectFolder": true

[project]
language=C#
primary
lastDtbSucceeded

[properties]
AssemblyName=BookApp
CommandLineArgsForDesignTimeEvaluation=-langversion:13.0 -define:TRACE
CompilerGeneratedFilesOutputPath=
MaxSupportedLangVersion=13.0
ProjectAssetsFile=<PATH>obj/project.assets.json
RootNamespace=BookApp
RunAnalyzers=
RunAnalyzersDuringLiveAnalysis=
SolutionPath=<PATH>../../copilot-cli-for-beginners.sln
TargetFrameworkIdentifier=.NETCoreApp
TargetPath=<PATH>bin/Debug/net10.0/BookApp.dll
TargetRefPath=<PATH>obj/Debug/net10.0/ref/BookApp.dll
TemporaryDependencyNodeTargetIdentifier=net10.0

[commandLineArguments]
/noconfig
/unsafe-
/checked-
/nowarn:1701,1702,1701,1702
/fullpaths
/nostdlib+
/errorreport:prompt
/warn:1
/define:TRACE;DEBUG;NET;NET10_0;NETCOREAPP;NET5_0_OR_GREATER;NET6_0_OR_GREATER;NET7_0_OR_GREATER;NET8_0_OR_GREATER;NET9_0_OR_GREATER;NETCOREAPP1_0_OR_GREATER;NETCOREAPP1_1_OR_GREATER;NETCOREAPP2_0_OR_GREATER;NETCOREAPP2_1_OR_GREATER;NETCOREAPP2_2_OR_GREATER;NETCOREAPP3_0_OR_GREATER;NETCOREAPP3_1_OR_GREATER
/highentropyva+
/nullable:enable
/debug+
/debug:portable
/filealign:512
/optimize-
/out:obj/Debug/net10.0/BookApp.dll
/refout:obj/Debug/net10.0/refint/BookApp.dll
/target:exe
/warnaserror-
/utf8output
/deterministic+
/langversion:13.0
/warnaserror+:NU1605,SYSLIB0011

[sourceFiles]
Models/Book.cs
obj/Debug/net10.0/
.NETCoreApp,Version=v10.0.AssemblyAttributes.cs
BookApp.AssemblyInfo.cs
BookApp.GlobalUsings.g.cs
Program.cs
Services/BookCollection.cs

[analyzerReferences]
../../../../../../usr/lib/dotnet/sdk/9.0.203/Sdks/Microsoft.NET.Sdk/analyzers/
Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll
Microsoft.CodeAnalysis.NetAnalyzers.dll

[analyzerConfigFiles]
../../../../../../usr/lib/dotnet/sdk/9.0.203/Sdks/Microsoft.NET.Sdk/codestyle/cs/build/config/analysislevelstyle_default.globalconfig
obj/Debug/net10.0/BookApp.GeneratedMSBuildEditorConfig.editorconfig
Comment on lines +1 to +71
72 changes: 72 additions & 0 deletions samples/book-app-project-cs/Tests/BookApp.Tests.csproj.lscache
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
version=1

# This file caches language service data to improve the performance of C# Dev Kit.
# It is not intended for manual editing. It can safely be deleted and will be
# regenerated automatically. For more information, see https://aka.ms/lscache
#
# To control where cache files are stored, use the following VS Code setting:
# "dotnet.projectsystem.cacheInProjectFolder": true

[project]
language=C#
primary
lastDtbSucceeded

[properties]
AssemblyName=BookApp.Tests
CommandLineArgsForDesignTimeEvaluation=-langversion:13.0 -define:TRACE
CompilerGeneratedFilesOutputPath=
MaxSupportedLangVersion=13.0
ProjectAssetsFile=<PATH>obj/project.assets.json
RootNamespace=BookApp.Tests
RunAnalyzers=
RunAnalyzersDuringLiveAnalysis=
SolutionPath=<PATH>../../../copilot-cli-for-beginners.sln
TargetFrameworkIdentifier=.NETCoreApp
TargetPath=<PATH>bin/Debug/net10.0/BookApp.Tests.dll
TargetRefPath=<PATH>obj/Debug/net10.0/ref/BookApp.Tests.dll
TemporaryDependencyNodeTargetIdentifier=net10.0

[commandLineArguments]
/noconfig
/unsafe-
/checked-
/nowarn:1701,1702,1701,1702
/fullpaths
/nostdlib+
/errorreport:prompt
/warn:1
/define:TRACE;DEBUG;NET;NET10_0;NETCOREAPP;NET5_0_OR_GREATER;NET6_0_OR_GREATER;NET7_0_OR_GREATER;NET8_0_OR_GREATER;NET9_0_OR_GREATER;NETCOREAPP1_0_OR_GREATER;NETCOREAPP1_1_OR_GREATER;NETCOREAPP2_0_OR_GREATER;NETCOREAPP2_1_OR_GREATER;NETCOREAPP2_2_OR_GREATER;NETCOREAPP3_0_OR_GREATER;NETCOREAPP3_1_OR_GREATER
/highentropyva+
/nullable:enable
/debug+
/debug:portable
/filealign:512
/optimize-
/out:obj/Debug/net10.0/BookApp.Tests.dll
/refout:obj/Debug/net10.0/refint/BookApp.Tests.dll
/target:library
/warnaserror-
/utf8output
/deterministic+
/langversion:13.0
/warnaserror+:NU1605,SYSLIB0011

[sourceFiles]
BookCollectionTests.cs
obj/Debug/net10.0/
.NETCoreApp,Version=v10.0.AssemblyAttributes.cs
BookApp.Tests.AssemblyInfo.cs
BookApp.Tests.GlobalUsings.g.cs

[metadataReferences]
../obj/Debug/net10.0/ref/BookApp.dll

[analyzerReferences]
../../../../../../../usr/lib/dotnet/sdk/9.0.203/Sdks/Microsoft.NET.Sdk/analyzers/
Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll
Microsoft.CodeAnalysis.NetAnalyzers.dll

[analyzerConfigFiles]
../../../../../../../usr/lib/dotnet/sdk/9.0.203/Sdks/Microsoft.NET.Sdk/codestyle/cs/build/config/analysislevelstyle_default.globalconfig
obj/Debug/net10.0/BookApp.Tests.GeneratedMSBuildEditorConfig.editorconfig
Comment on lines +1 to +72
1 change: 1 addition & 0 deletions samples/book-app-project/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ It can add, remove, and list books. Also mark them as read.
```bash
python book_app.py list
python book_app.py add
python book_app.py mark-read
python book_app.py find
python book_app.py remove
python book_app.py help
Expand Down
139 changes: 84 additions & 55 deletions samples/book-app-project/book_app.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
import sys
from books import BookCollection


# 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")
from collections.abc import Callable

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()
from books import BookCollection
from utils import display_books, display_help


def handle_list():
def handle_list(collection: BookCollection) -> int:
books = collection.list_books()
show_books(books)
display_books(books)
return 0


def handle_add():
def handle_add(collection: BookCollection) -> int:
print("\nAdd a New Book\n")

title = input("Title: ").strip()
Expand All @@ -37,62 +22,106 @@ def handle_add():
year = int(year_str) if year_str else 0
collection.add_book(title, author, year)
print("\nBook added successfully.\n")
return 0
except ValueError as e:
print(f"\nError: {e}\n")
return 1


def handle_remove():
def handle_remove(collection: BookCollection) -> int:
print("\nRemove a Book\n")

title = input("Enter the title of the book to remove: ").strip()
collection.remove_book(title)
if not title:
print("\nError: Title cannot be empty.\n")
return 1

if collection.remove_book(title):
print("\nBook removed successfully.\n")
return 0

print("\nError: Book not found.\n")
return 1


def handle_mark_read(collection: BookCollection) -> int:
print("\nMark a Book as Read\n")

print("\nBook removed if it existed.\n")
title = input("Enter the title of the book to mark as read: ").strip()
if not title:
print("\nError: Title cannot be empty.\n")
return 1

if collection.mark_as_read(title):
print("\nBook marked as read.\n")
return 0

def handle_find():
print("\nError: Book not found.\n")
return 1


def handle_find(collection: BookCollection) -> int:
print("\nFind Books by Author\n")

author = input("Author name: ").strip()
if not author:
print("\nError: Author cannot be empty.\n")
return 1

books = collection.find_by_author(author)

show_books(books)
display_books(books)
return 0


CollectionCommandHandler = Callable[[BookCollection], int]
CommandHandler = Callable[[], int]


def handle_help() -> int:
display_help()
return 0

def show_help():
print("""
Book Collection Helper

Commands:
list - Show all books
add - Add a new book
remove - Remove a book by title
find - Find books by author
help - Show this help message
""")
def create_collection_command(handler: CollectionCommandHandler) -> CommandHandler:
def command() -> int:
try:
collection = BookCollection()
except (OSError, ValueError) as e:
print(f"Error: {e}")
return 1

return handler(collection)

def main():
if len(sys.argv) < 2:
show_help()
return
return command

command = sys.argv[1].lower()

if command == "list":
handle_list()
elif command == "add":
handle_add()
elif command == "remove":
handle_remove()
elif command == "find":
handle_find()
elif command == "help":
show_help()
else:
COMMAND_HANDLERS: dict[str, CommandHandler] = {
"list": create_collection_command(handle_list),
"add": create_collection_command(handle_add),
"mark-read": create_collection_command(handle_mark_read),
"remove": create_collection_command(handle_remove),
"find": create_collection_command(handle_find),
"help": handle_help,
}


def main(argv: list[str] | None = None) -> int:
args = argv if argv is not None else sys.argv[1:]

if not args:
return handle_help()

command = args[0].lower()

handler = COMMAND_HANDLERS.get(command)
if handler is None:
print("Unknown command.\n")
show_help()
display_help()
return 1

return handler()


if __name__ == "__main__":
main()
raise SystemExit(main())
Loading
Loading