diff --git a/.agents/skills/tiny-ps-chapter-test-loop/SKILL.md b/.agents/skills/tiny-ps-chapter-test-loop/SKILL.md new file mode 100644 index 0000000..fa4b74d --- /dev/null +++ b/.agents/skills/tiny-ps-chapter-test-loop/SKILL.md @@ -0,0 +1,20 @@ +--- +name: tiny-ps-chapter-test-loop +description: Use when changing a Tiny PowerShell Projects chapter and you need the expected validation loop from chapter tests to full regression. +--- + +# Tiny PowerShell Chapter Test Loop + +## When to use +- You are editing a chapter script or `solution*.ps1` file. +- You want the fastest feedback loop before broader regression. + +## Workflow +1. Work inside the chapter directory and keep `solution1.ps1` intact as a known baseline when possible. +2. Run `./AllTest.ps1` in that chapter to execute `test.ps1` against each `solution*.ps1`. +3. When the chapter passes, run `pwsh -NoProfile -File ./RunAllTests.ps1` from the repository root. +4. Note unrelated existing failures separately instead of changing other chapters opportunistically. + +## Output +- Chapter-local Pester results for all `solution*.ps1` variants. +- A repository-wide regression result before finalizing changes. diff --git a/.agents/skills/tiny-ps-deterministic-random/SKILL.md b/.agents/skills/tiny-ps-deterministic-random/SKILL.md new file mode 100644 index 0000000..30e05a8 --- /dev/null +++ b/.agents/skills/tiny-ps-deterministic-random/SKILL.md @@ -0,0 +1,20 @@ +--- +name: tiny-ps-deterministic-random +description: Use when a chapter relies on randomness and you need reproducible PowerShell behavior plus stable Pester assertions. +--- + +# Tiny PowerShell Deterministic Random + +## When to use +- The script uses `Get-Random` or `[Random]`. +- Tests or examples need exact output for a known seed. + +## Workflow +1. Add a seed parameter and support the chapter's expected short and long flag names when tests or README require them. +2. Initialize randomness exactly once near the start with `Get-Random -SetSeed` or `[Random]::new($seed)`. +3. Keep the sequence of random calls stable so the same seed keeps producing the same output. +4. Add Pester examples that assert exact results for chosen seeds and representative option combinations. + +## Output +- Stable, repeatable output for the same seed. +- Pester tests that lock in deterministic random behavior. diff --git a/.agents/skills/tiny-ps-input-normalization/SKILL.md b/.agents/skills/tiny-ps-input-normalization/SKILL.md new file mode 100644 index 0000000..457ed77 --- /dev/null +++ b/.agents/skills/tiny-ps-input-normalization/SKILL.md @@ -0,0 +1,20 @@ +--- +name: tiny-ps-input-normalization +description: Use when a chapter accepts either literal text or a file path and should normalize input once before processing. +--- + +# Tiny PowerShell Input Normalization + +## When to use +- The script can receive literal text or a path to a file. +- The rest of the logic should not care where the content came from. + +## Workflow +1. Accept a single text-or-path parameter unless the chapter already defines a clearer contract. +2. Use `Test-Path` early to detect file input and read content once with `Get-Content -Raw` for whole-text transforms or line-based reads only when required. +3. Normalize the input near the top so downstream logic works on content, not file paths. +4. Add tests for both direct text and file input using the same expected output where appropriate. + +## Output +- One normalized content flow regardless of whether input came from a file or the command line. +- Paired tests covering both input forms. diff --git a/.agents/skills/tiny-ps-regex-text-transform/SKILL.md b/.agents/skills/tiny-ps-regex-text-transform/SKILL.md new file mode 100644 index 0000000..f32aead --- /dev/null +++ b/.agents/skills/tiny-ps-regex-text-transform/SKILL.md @@ -0,0 +1,20 @@ +--- +name: tiny-ps-regex-text-transform +description: Use when a chapter transforms text with regex while preserving delimiters, punctuation, and casing expectations. +--- + +# Tiny PowerShell Regex Text Transform + +## When to use +- You are mutating words or characters inside larger text. +- Whitespace-only splitting would lose punctuation or structure. + +## Workflow +1. Identify whether the chapter needs token replacement (`[regex]::Replace`) or token-preserving splitting (`[regex]::Split`). +2. Transform only the matched text, leaving separators and non-target characters untouched. +3. Preserve casing intentionally when examples or tests expect it. +4. Add examples for punctuation, apostrophes, short words, and mixed-case input. + +## Output +- Text transforms that preserve surrounding structure. +- Focused tests for punctuation and edge-case tokens. diff --git a/.claude/commands/tiny-ps-chapter-test-loop.md b/.claude/commands/tiny-ps-chapter-test-loop.md new file mode 100644 index 0000000..3171178 --- /dev/null +++ b/.claude/commands/tiny-ps-chapter-test-loop.md @@ -0,0 +1,21 @@ +--- +description: Use when changing a Tiny PowerShell Projects chapter and you need the expected validation loop from chapter tests to full regression. +argument-hint: "[chapter directory]" +allowed-tools: Read, Write, Edit, Glob, Grep, Bash(pwsh:*) +--- + +# Tiny PowerShell Chapter Test Loop + +## When to use +- You are editing a chapter script or `solution*.ps1` file. +- You want the fastest feedback loop before broader regression. + +## Workflow +1. Work inside the chapter directory and keep `solution1.ps1` intact as a known baseline when possible. +2. Run `./AllTest.ps1` in that chapter to execute `test.ps1` against each `solution*.ps1`. +3. When the chapter passes, run `pwsh -NoProfile -File ./RunAllTests.ps1` from the repository root. +4. Note unrelated existing failures separately instead of changing other chapters opportunistically. + +## Output +- Chapter-local Pester results for all `solution*.ps1` variants. +- A repository-wide regression result before finalizing changes. diff --git a/.claude/commands/tiny-ps-deterministic-random.md b/.claude/commands/tiny-ps-deterministic-random.md new file mode 100644 index 0000000..5dfdc24 --- /dev/null +++ b/.claude/commands/tiny-ps-deterministic-random.md @@ -0,0 +1,21 @@ +--- +description: Use when a chapter relies on randomness and you need reproducible PowerShell behavior plus stable Pester assertions. +argument-hint: "[random behavior to make deterministic]" +allowed-tools: Read, Write, Edit, Glob, Grep, Bash(pwsh:*) +--- + +# Tiny PowerShell Deterministic Random + +## When to use +- The script uses `Get-Random` or `[Random]`. +- Tests or examples need exact output for a known seed. + +## Workflow +1. Add a seed parameter and support the chapter's expected short and long flag names when tests or README require them. +2. Initialize randomness exactly once near the start with `Get-Random -SetSeed` or `[Random]::new($seed)`. +3. Keep the sequence of random calls stable so the same seed keeps producing the same output. +4. Add Pester examples that assert exact results for chosen seeds and representative option combinations. + +## Output +- Stable, repeatable output for the same seed. +- Pester tests that lock in deterministic random behavior. diff --git a/.claude/commands/tiny-ps-input-normalization.md b/.claude/commands/tiny-ps-input-normalization.md new file mode 100644 index 0000000..b58315d --- /dev/null +++ b/.claude/commands/tiny-ps-input-normalization.md @@ -0,0 +1,21 @@ +--- +description: Use when a chapter accepts either literal text or a file path and should normalize input once before processing. +argument-hint: "[input contract]" +allowed-tools: Read, Write, Edit, Glob, Grep, Bash(pwsh:*) +--- + +# Tiny PowerShell Input Normalization + +## When to use +- The script can receive literal text or a path to a file. +- The rest of the logic should not care where the content came from. + +## Workflow +1. Accept a single text-or-path parameter unless the chapter already defines a clearer contract. +2. Use `Test-Path` early to detect file input and read content once with `Get-Content -Raw` for whole-text transforms or line-based reads only when required. +3. Normalize the input near the top so downstream logic works on content, not file paths. +4. Add tests for both direct text and file input using the same expected output where appropriate. + +## Output +- One normalized content flow regardless of whether input came from a file or the command line. +- Paired tests covering both input forms. diff --git a/.claude/commands/tiny-ps-regex-text-transform.md b/.claude/commands/tiny-ps-regex-text-transform.md new file mode 100644 index 0000000..2f18d62 --- /dev/null +++ b/.claude/commands/tiny-ps-regex-text-transform.md @@ -0,0 +1,21 @@ +--- +description: Use when a chapter transforms text with regex while preserving delimiters, punctuation, and casing expectations. +argument-hint: "[text transform behavior]" +allowed-tools: Read, Write, Edit, Glob, Grep, Bash(pwsh:*) +--- + +# Tiny PowerShell Regex Text Transform + +## When to use +- You are mutating words or characters inside larger text. +- Whitespace-only splitting would lose punctuation or structure. + +## Workflow +1. Identify whether the chapter needs token replacement (`[regex]::Replace`) or token-preserving splitting (`[regex]::Split`). +2. Transform only the matched text, leaving separators and non-target characters untouched. +3. Preserve casing intentionally when examples or tests expect it. +4. Add examples for punctuation, apostrophes, short words, and mixed-case input. + +## Output +- Text transforms that preserve surrounding structure. +- Focused tests for punctuation and edge-case tokens. diff --git a/.github/skills/tiny-ps-chapter-test-loop/SKILL.md b/.github/skills/tiny-ps-chapter-test-loop/SKILL.md new file mode 100644 index 0000000..fa4b74d --- /dev/null +++ b/.github/skills/tiny-ps-chapter-test-loop/SKILL.md @@ -0,0 +1,20 @@ +--- +name: tiny-ps-chapter-test-loop +description: Use when changing a Tiny PowerShell Projects chapter and you need the expected validation loop from chapter tests to full regression. +--- + +# Tiny PowerShell Chapter Test Loop + +## When to use +- You are editing a chapter script or `solution*.ps1` file. +- You want the fastest feedback loop before broader regression. + +## Workflow +1. Work inside the chapter directory and keep `solution1.ps1` intact as a known baseline when possible. +2. Run `./AllTest.ps1` in that chapter to execute `test.ps1` against each `solution*.ps1`. +3. When the chapter passes, run `pwsh -NoProfile -File ./RunAllTests.ps1` from the repository root. +4. Note unrelated existing failures separately instead of changing other chapters opportunistically. + +## Output +- Chapter-local Pester results for all `solution*.ps1` variants. +- A repository-wide regression result before finalizing changes. diff --git a/.github/skills/tiny-ps-deterministic-random/SKILL.md b/.github/skills/tiny-ps-deterministic-random/SKILL.md new file mode 100644 index 0000000..30e05a8 --- /dev/null +++ b/.github/skills/tiny-ps-deterministic-random/SKILL.md @@ -0,0 +1,20 @@ +--- +name: tiny-ps-deterministic-random +description: Use when a chapter relies on randomness and you need reproducible PowerShell behavior plus stable Pester assertions. +--- + +# Tiny PowerShell Deterministic Random + +## When to use +- The script uses `Get-Random` or `[Random]`. +- Tests or examples need exact output for a known seed. + +## Workflow +1. Add a seed parameter and support the chapter's expected short and long flag names when tests or README require them. +2. Initialize randomness exactly once near the start with `Get-Random -SetSeed` or `[Random]::new($seed)`. +3. Keep the sequence of random calls stable so the same seed keeps producing the same output. +4. Add Pester examples that assert exact results for chosen seeds and representative option combinations. + +## Output +- Stable, repeatable output for the same seed. +- Pester tests that lock in deterministic random behavior. diff --git a/.github/skills/tiny-ps-input-normalization/SKILL.md b/.github/skills/tiny-ps-input-normalization/SKILL.md new file mode 100644 index 0000000..457ed77 --- /dev/null +++ b/.github/skills/tiny-ps-input-normalization/SKILL.md @@ -0,0 +1,20 @@ +--- +name: tiny-ps-input-normalization +description: Use when a chapter accepts either literal text or a file path and should normalize input once before processing. +--- + +# Tiny PowerShell Input Normalization + +## When to use +- The script can receive literal text or a path to a file. +- The rest of the logic should not care where the content came from. + +## Workflow +1. Accept a single text-or-path parameter unless the chapter already defines a clearer contract. +2. Use `Test-Path` early to detect file input and read content once with `Get-Content -Raw` for whole-text transforms or line-based reads only when required. +3. Normalize the input near the top so downstream logic works on content, not file paths. +4. Add tests for both direct text and file input using the same expected output where appropriate. + +## Output +- One normalized content flow regardless of whether input came from a file or the command line. +- Paired tests covering both input forms. diff --git a/.github/skills/tiny-ps-regex-text-transform/SKILL.md b/.github/skills/tiny-ps-regex-text-transform/SKILL.md new file mode 100644 index 0000000..f32aead --- /dev/null +++ b/.github/skills/tiny-ps-regex-text-transform/SKILL.md @@ -0,0 +1,20 @@ +--- +name: tiny-ps-regex-text-transform +description: Use when a chapter transforms text with regex while preserving delimiters, punctuation, and casing expectations. +--- + +# Tiny PowerShell Regex Text Transform + +## When to use +- You are mutating words or characters inside larger text. +- Whitespace-only splitting would lose punctuation or structure. + +## Workflow +1. Identify whether the chapter needs token replacement (`[regex]::Replace`) or token-preserving splitting (`[regex]::Split`). +2. Transform only the matched text, leaving separators and non-target characters untouched. +3. Preserve casing intentionally when examples or tests expect it. +4. Add examples for punctuation, apostrophes, short words, and mixed-case input. + +## Output +- Text transforms that preserve surrounding structure. +- Focused tests for punctuation and edge-case tokens. diff --git a/AI_WORKFLOW_SHORTLIST.md b/AI_WORKFLOW_SHORTLIST.md new file mode 100644 index 0000000..8f0b6a5 --- /dev/null +++ b/AI_WORKFLOW_SHORTLIST.md @@ -0,0 +1,43 @@ +# AI Workflow Packaging Shortlist + +## Compact shortlist + +| Repeated workflow | Supporting evidence | Frequency / confidence | Recommended form | Why create (or skip) | +| --- | --- | --- | --- | --- | +| Run chapter-level tests while iterating on `solution*.ps1` | `AllTest.ps1` exists in 22 chapter folders; each chapter has `test.ps1`; root README explains the `solution*.ps1` loop | 22 chapters / High | Extend existing | Already automated well by chapter `AllTest.ps1`; no new asset needed | +| Run full regression after local chapter changes | `RunAllTests.ps1` loops all numbered chapter folders and executes `AllTest.ps1`; README emphasizes running tests after each change | Repository-wide / High | Skill/playbook | Worth documenting as a consistent maintainer + agent workflow | +| Author the same AI skill across multiple harness layouts | Open issues `#12`, `#14`, `#16`, `#18`; related open PRs `#13`, `#15`, `#17`, `#19`; active `copilot/*ai-skills*` branches | Repeated in recent repo activity / High | Script | Manual copy/edit across `.github/.agents/.claude` is repetitive and error-prone | +| Add release/changelog automation | No release workflow, tags pipeline, or changelog process found in this branch | Low evidence / Low | Skip | Needs stronger maintainer signal before introducing publishing automation | + +## Created high-confidence missing items + +### `New-AISkillScaffold.ps1` (script) + +Creates a synchronized starter skill in all three harness locations from one command: + +- `.github/skills//SKILL.md` +- `.agents/skills//SKILL.md` +- `.claude/commands/.md` + +This packages the repeated cross-harness AI skill authoring workflow into one repeatable step with clear outputs. + +### Usage + +```powershell +pwsh -NoProfile -File ./New-AISkillScaffold.ps1 \ + -SkillName tiny-ps-example \ + -Description "Use when implementing a repeatable Tiny PowerShell Projects workflow." +``` + +Use `-Force` to overwrite existing scaffolded files. + +### Repository-derived skill set + +- `tiny-ps-chapter-test-loop` + - Packages the repeated chapter-first, repo-second validation workflow documented in `README.md` and implemented by `AllTest.ps1` plus `RunAllTests.ps1`. +- `tiny-ps-deterministic-random` + - Encodes the repeated seeded-random pattern used in chapters such as `09_abuse`, `10_telephone`, `12_ransom`, `16_scrambler`, `19_wod`, and `20_password`. +- `tiny-ps-regex-text-transform` + - Captures the repeated regex-first text transformation approach used in `08_apples_and_bananas`, `15_kentucky_friar`, `16_scrambler`, and `17_mad_libs`. +- `tiny-ps-input-normalization` + - Packages the recurring "literal text or file path" input handling found in chapters such as `05_howler`, `10_telephone`, `12_ransom`, and `15_kentucky_friar`. diff --git a/New-AISkillScaffold.ps1 b/New-AISkillScaffold.ps1 new file mode 100644 index 0000000..d2a97b3 --- /dev/null +++ b/New-AISkillScaffold.ps1 @@ -0,0 +1,97 @@ +param( + [Parameter(Mandatory)] + [ValidatePattern('^[a-z0-9][a-z0-9-]*$')] + [string]$SkillName, + + [Parameter(Mandatory)] + [string]$Description, + + [string]$Title, + + [string]$ArgumentHint = '[task context]', + + [switch]$Force +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +if ([string]::IsNullOrWhiteSpace($Title)) { + $Title = ((($SkillName -replace '-', ' ').Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { + if ($_.Length -gt 1) { $_.Substring(0, 1).ToUpper() + $_.Substring(1) } + else { $_.ToUpper() } + }) -join ' ') +} + +function Write-TemplateFile { + param( + [Parameter(Mandatory)] + [string]$Path, + + [Parameter(Mandatory)] + [string]$Content + ) + + $directory = Split-Path -Path $Path -Parent + if ($directory) { + New-Item -Path $directory -ItemType Directory -Force | Out-Null + } + + if ((Test-Path -Path $Path) -and -not $Force) { + throw "File already exists: $Path`nUse -Force to overwrite." + } + + Set-Content -Path $Path -Value $Content +} + +$sharedSkillBody = @" +--- +name: $SkillName +description: $Description +--- + +# $Title + +## When to use +- TODO: Describe trigger conditions. + +## Workflow +1. TODO: Define stable inputs. +2. TODO: Execute repeatable steps. +3. TODO: Validate clear output or stopping condition. + +## Output +- TODO: Describe expected output. +"@ + +$claudeBody = @" +--- +description: $Description +argument-hint: $ArgumentHint +allowed-tools: Read, Write, Edit, Glob, Grep, Bash(pwsh:*) +--- + +# $Title + +## When to use +- TODO: Describe trigger conditions. + +## Workflow +1. TODO: Define stable inputs. +2. TODO: Execute repeatable steps. +3. TODO: Validate clear output or stopping condition. + +## Output +- TODO: Describe expected output. +"@ + +$targets = @( + @{ Path = ".github/skills/$SkillName/SKILL.md"; Content = $sharedSkillBody }, + @{ Path = ".agents/skills/$SkillName/SKILL.md"; Content = $sharedSkillBody }, + @{ Path = ".claude/commands/$SkillName.md"; Content = $claudeBody } +) + +foreach ($target in $targets) { + Write-TemplateFile -Path $target.Path -Content $target.Content + Write-Host "Created $($target.Path)" +}