Generative and agentic AI have reshaped software development in a few short months. This is more than asking a chatbot for help; it’s a mindset shift and a cultural transformation in how we design, generate and maintain code.
Claude Code is one of the most advanced agentic tools for code generation, but like any generative system it can produce incorrect or low quality output. See the sloop content on Instagram, AI used carelessly, it can create the same "surface level" results you see on social platforms, attractive but unreliable.
In this post I’ll show how to use Claude Code in a PowerShell project: we’ll build a module to automate GitHub issue management.
First, a quick intro: Claude Code is part of Anthropic’s ecosystem (alongside Claude.ai, the Claude API and Claude CoWork). Claude Code is designed as an agentic coding assistant rather than a simple chatbot.
You can download it here
Claude Code is not a Chatbot, it is an AI Agent; it follow a workflow, gets the context, analyzes, plan the work and creates the code. In Claude Code, you don’t ask a question, you specify the result you want and the agent executes.
There is one important notion in Claude Code (and other AI tools), the Context. Context is the agent’s working memory, measured in tokens. It’s critical to manage. Claude Code sessions typically support large contexts (hundreds of thousands of tokens, depending on your plan). Monitor usage with the /context command; if you approach ~60% capacity, run /compact to reduce context size and avoid degraded behaviours.
The first best practice with Claude Code, is to keep a CLAUDE.md at the project root: treat it like a brief for the agent. Describe the project goals, constraints, runtime targets and coding conventions. That file becomes the agent’s persistent context, so you manage an agentic collaborator rather than a stateless LLM chat.
You can generate CLAUDE.md with the /init command: when run against an existing codebase, the agent analyses the repository and drafts the brief based on discovered files and patterns.
In this tutorial we start from an empty folder; you can author CLAUDE.md manually or ask Claude Code to create it for you.
"Create a new CLAUDE.md file in this folder with these instructions, PowerShell module for GitHub Issue Automation, named psGTIssue, the module will use classes, private function and public function, it run with PwSh 7 on Linux, MacOS and Windows. The project structure include, src, tests and build folder, the code should respect the camel case notation for variable and authorized verb for function (get-something), Pester will be used for unit testing"
You should have something like this:
# CLAUDE.md — psGTIssue Project Instructions
## Project Overview
**Module name:** `psGTIssue`
**Purpose:** PowerShell module for GitHub Issue Automation
**Runtime:** PowerShell 7 (pwsh) — cross-platform: Linux, macOS, Windows
---
## Project Structure
psGTIssue/
├── src/
│ ├── Classes/ # PowerShell classes
│ ├── Private/ # Private (internal) functions
│ ├── Public/ # Public (exported) functions
│ └── psGTIssue.psm1 # Module root — dot-sources all classes, private, public
├── tests/
│ ├── Unit/ # Pester unit tests mirroring src/ structure
│ └── Integration/ # Integration tests (optional)
├── build/ # Build output and scripts
│ └── psGTIssue.psd1 # Module manifest (generated or maintained here)
└── CLAUDE.md
---
## Coding Conventions
### Naming
- **Variables:** camelCase — `$issueTitle`, `$repoOwner`, `$pageNumber`
- **Parameters:** camelCase — `param([string]$issueTitle)`
- **Classes:** PascalCase — `class GitHubIssue`, `class IssueFilter`
- **Functions:** Approved PowerShell verb + PascalCase noun — `Get-GtIssue`, `New-GtIssue`, `Set-GtIssue`, `Remove-GtIssue`, `Invoke-GtIssueAction`
- **Private functions:** same verb-noun convention, not exported — `Get-GtApiHeader`, `ConvertTo-GtIssueObject`
- **Constants / enum values:** camelCase
### Approved Verbs
Always use verbs from `Get-Verb`. Common ones for this module:
---
Now, we can create the project structure. First, create the project skeleton. Use a prompt such as Create the project structure and Claude will scaffold folders, a .psd1 manifest, a .psm1 module file, a build.ps1 script and Pester test stubs.
"Create a public function that list all issue for a given repository, param are repository, organization name and a switch all, open, close"
Now we can create a function that list all issue for a repository
The agent will create several files, a function to call the GitHub API, a function to retrieve all issues in the repository and test files.
You see that the prompt used are optimised to create a function, the prompt should be optimised to get the result. If you want a modification, you should be precise on the result you want.
For example, using a switch for the parameter $State is not a great idead
We can ask Claude to replace the switch parameter in the Get-GtIssueList to a simple validateSet parameter with All, Open, Closed.
"replace the switch parameter in the Get-GtIssueList to a simple validateSet parameter with All, Open, Closed in the
@psGTIssue\src\Public\Get-GtIssueList.ps1"
You can work directly on a file work by using @ here @psGTIssue\src\Public\Get-GtIssueList.ps1 it will cost less in token as Claude will not have to search for the file.
Now it is time to check the status of the session with /context. The command will show the percentage used by the session. If the number is higher than 60% you should run the command /compact
It is a good practice to name the session (and its context) so you can retrieve it later.
/rename buildGitHubIssuePwSh
To restart the session
claude --resume "buildGitHubIssuePwSh"
Review generated code carefully. Common issues: the agent may prefer Write-Verbose over Write-Debug, and it might scaffold a .psm1 that dynamically dot sources files at runtime. For best practice a static .psm1 that explicitly imports and exports functions and classes is better; this improves readability, testability and module loading behaviours.
You can encode these conventions in CLAUDE.md, but they’re generic PowerShell best practices you’ll want in every project.
Claude Code supports skills; reusable instruction sets that tell the agent how to behave in specific contexts. Create a PowerShell module skill to enforce coding conventions, file layout and test patterns across projects.
All you need to do is to create a folder in .claude/skills/ and create the file SKILL.md.
You can ask Claude for that
"Create the folder ./claude/skills/powershell-module at the root and add the file SKILL.md"
Claude will create the file for you with some elements
- Trigger conditions for when the skill applies
- Naming conventions summary
- Function templates (public & private)
- Class template
- Module dot-source order
- API call rules
- Pester test patterns
- File placement checklist
You can add an header
---
name: powershell-module
description: conventions and guidelines for building PowerShell modules
argument-hint: "[check|fix]"
---
And information about write-verbose and write-debug and psm1 generation.
### write-verbose?/write-debug?
- Use `Write-Verbose` for informational messages that may be helpful for debugging but are not critical to the user, only visible when the `-Verbose` switch is used.
- Use `Write-Debug` for detailed debugging information that is typically only relevant when troubleshooting specific issues. This can be enabled with the `-Debug` switch when running the function.
- Avoid using `Write-Host` for regular output; reserve it for special cases where you want to display colored or formatted output directly to the console. For standard output, return objects or use `Write-Output`.
### psm1 file
- The `.psm1` file should contain all individual functions and class files, and the `Export-ModuleMember` call to specify which public functions are exported. The build script will handle the creation of the `.psm1` manifest file, so you do not need to create that manually.
- All actual code (functions, classes) should live in separate `.ps1` files under the `src/` directory, organized into `Public`, `Private`, and `Classes` subdirectories.
Once conventions live in a skill, you can simplify CLAUDE.md and rely on the skill for enforcement. Skills are shareable, store them in a repo so your teams can reuse the same conventions and templates.
Another way to extend Claude Code is to use sub-agent. Sub-agent is a separate agent that use its own context (it doesn’t impact your session) specialised in one task. The task must be specific and should not be related to any other task in your current session.
Agents are located inside ./claude/agents folder.
We can ask Claude code to create the agent
Create the folder ./claude/agents/ at the root and add the file security-check.md
Claude will create the markdown file with some security check; you can review them and add your own check.
You can run the check
Start security check with the sub agent security-check
Claude will produce a report in the terminal you can review and then act on it.
Claude Code is a powerful agentic coding tool; it lets you manage a team of coding agents as if you had human collaborators. That power demands discipline: be precise in your briefs, test outputs, and maintain human oversight. Agents can produce useful code quickly, but they also make mistakes; you must validate, adapt, and own the result.
In short
Core commands and session hygiene
/init — generate CLAUDE.md from an existing repo.
/context — show token usage (monitor session memory).
/compact — reduce context when usage is high.
/rename — name the session for later resume.
claude --resume "" — resume a named session.
1st rule of Claude: compact when usage approaches 60–80% of context capacity.
Project files
CLAUDE.md — project brief (goals, constraints, runtime, conventions).
.claude/skills/powershell-module/SKILL.md — reusable PowerShell conventions and templates.
.claude/agents/ — sub‑agents for isolated tasks (security, linting).
Top comments (0)