Skip to content

feat(#25): prefix user-facing Azure DevOps PowerShell functions with az-#26

Merged
jdschleicher merged 2 commits intomainfrom
claude/add-az-prefix-methods-XOHxc
May 8, 2026
Merged

feat(#25): prefix user-facing Azure DevOps PowerShell functions with az-#26
jdschleicher merged 2 commits intomainfrom
claude/add-az-prefix-methods-XOHxc

Conversation

@jdschleicher
Copy link
Copy Markdown
Owner

@jdschleicher jdschleicher commented May 7, 2026

Section Status
Summary
Issue Closes #25
Renamed Functions ✅ 18 functions
Test Plan 0/4 (manual)
Skill Reports
🐚 Bash Engineer Review ✅ APPROVE (N/A — no bash files) — View
💠 PowerShell Engineer Review ✅ APPROVE — View
🛡️ Security Audit ✅ APPROVE — View
🧼 Clean-Code Engineer Review ✅ APPROVE — View
✅ Criteria Check ✅ PASS (5 verified, 3 manual) — View
📚 Docs Check ✅ CURRENT (ran inline in /pr-flow — README references all renamed names; no orphaned files; no stale wire-up)

Summary

  • Renames 18 user-facing functions in powcuts_by_cli/azdevops_workitems.ps1 to start with literal lowercase az- so the full Azure DevOps PowerShell surface is tab-tab-discoverable the same way it already is in bash, and so users can tell bashcuts shortcuts apart from stock PowerShell cmdlets at a glance.
  • Internal helpers (Test-/ConvertFrom-/Read-/Write-/Initialize-/Format-/Measure-/Invoke-AzDevOps*, plus the Find-AzDevOpsCachedWorkItem / Open-AzDevOpsWorkItemUrl / Get-AzDevOpsClassificationPaths DRY helpers) are intentionally left unprefixed since they don't surface to user tab-completion.
  • Header docblock and README.md updated to match the new names.

Issue

Closes #25

Renamed Functions (18)

Today After
Connect-AzDevOps az-Connect-AzDevOps
Test-AzDevOpsAuth az-Test-AzDevOpsAuth
Confirm-AzDevOpsCli az-Confirm-AzDevOpsCli
Confirm-AzDevOpsExtension az-Confirm-AzDevOpsExtension
Confirm-AzDevOpsEnvVars az-Confirm-AzDevOpsEnvVars
Confirm-AzDevOpsLogin az-Confirm-AzDevOpsLogin
Set-AzDevOpsDefaults az-Set-AzDevOpsDefaults
Confirm-AzDevOpsSmokeQuery az-Confirm-AzDevOpsSmokeQuery
Sync-AzDevOpsCache az-Sync-AzDevOpsCache
Get-AzDevOpsCacheStatus az-Get-AzDevOpsCacheStatus
Register-AzDevOpsSyncSchedule az-Register-AzDevOpsSyncSchedule
Unregister-AzDevOpsSyncSchedule az-Unregister-AzDevOpsSyncSchedule
Get-AzDevOpsAssigned az-Get-AzDevOpsAssigned
Open-AzDevOpsAssigned az-Open-AzDevOpsAssigned
Get-AzDevOpsMentions az-Get-AzDevOpsMentions
Open-AzDevOpsMention az-Open-AzDevOpsMention
Show-AzDevOpsTree az-Show-AzDevOpsTree
New-AzDevOpsUserStory az-New-AzDevOpsUserStory

Test Plan

  • Parse-check (must return no parse errors; Get-Verb warnings are expected and accepted as the cost of the convention):
    pwsh -NoProfile -Command "[System.Management.Automation.Language.Parser]::ParseFile('powcuts_by_cli/azdevops_workitems.ps1', [ref]\$null, [ref]\$null) | Out-Null; 'PARSE OK'"
  • Open a fresh PowerShell terminal, dot-source $profile, type az- + tab-tab — all 18 az-* AzDevOps functions appear in the completion list
  • Run az-Get-AzDevOpsCacheStatus end-to-end against an environment where az-Connect-AzDevOps previously reported READY — should print cache freshness with no errors
  • Verify no stale references: grep -nE '\b(Connect-AzDevOps|Test-AzDevOpsAuth|Confirm-AzDevOps[A-Z]|Set-AzDevOpsDefaults|Sync-AzDevOpsCache|Get-AzDevOpsCacheStatus|(Un)?Register-AzDevOpsSyncSchedule|(Get|Open)-AzDevOps(Assigned|Mention(s)?)|Show-AzDevOpsTree|New-AzDevOpsUserStory)\b' powcuts_by_cli/azdevops_workitems.ps1 README.md | grep -v 'az-' returns nothing

Generated by Claude Code

Copy link
Copy Markdown
Owner Author

🐚 Senior Bash Engineer

Summary

This PR renames PowerShell functions in powcuts_by_cli/azdevops_workitems.ps1 (adding the az- prefix) and updates README.md references. No bash files (bashcuts_by_cli/*, .bcut_home) are touched.

Diff Scope

README.md                             |  46 +++++------
powcuts_by_cli/azdevops_workitems.ps1 | 150 +++++++++++++++++-----------------

Findings

None — there is no bash surface area in this changeset to review. Bash parity for the renamed PowerShell Az-* functions (if/when the user wants matching az-* aliases or functions in bashcuts_by_cli/) is out of scope for this PR.

Sourcing Wire-Up

N/A — no new files under bashcuts_by_cli/.

Naming Convention

N/A — no bash aliases or functions added/modified.

Verdict

APPROVE — no bash files in this diff


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

🛡️ Senior Security Engineer

Verdict: APPROVE — no security findings.

Scope reviewed

Diff against origin/main (single commit d3eefed):

  • powcuts_by_cli/azdevops_workitems.ps1 — 18 user-facing functions renamed with an az- prefix (Connect-AzDevOpsaz-Connect-AzDevOps, etc.) plus matching updates to call sites, scheduled-task command strings, Write-Host hint messages, and docstring blocks.
  • README.md — prose + code-block references updated to match.

This is a pure literal rename. No new logic, no new external calls, no new env-var reads, no new string interpolation, no new file/path operations.

Audit checklist

  1. Command injection in renamed function bodies — clean. No Invoke-Expression / iex appears anywhere in the file (grep -n "Invoke-Expression\|iex " powcuts_by_cli/azdevops_workitems.ps1 is empty). The az invocations that were already in place still pass arguments as separate tokens (e.g. az devops configure --defaults "organization=$env:AZ_DEVOPS_ORG" "project=$env:AZ_PROJECT" at line 202, and the --project, $env:AZ_PROJECT argv pairs in the new-story flow at line 1667). The rename did not introduce any new string-built az invocations.

  2. Secrets / credentials in changed lines — clean. Every changed line is either a function name, a Write-Host hint string referencing the new name, or prose in the README. No tokens, PATs, connection strings, or org/project values were embedded.

  3. Auth gate still consistent — verified. az-Test-AzDevOpsAuth is the gate function and is consistently called before any path that hits az for live data:

    • Line 577: az-Sync-AzDevOpsCacheif (-not (az-Test-AzDevOpsAuth)) { ... return }
    • Line 1756: az-New-AzDevOpsUserStory — same pattern.
    • Cache consumers (az-Get-AzDevOpsAssigned, az-Get-AzDevOpsMentions, az-Show-AzDevOpsTree, az-Open-AzDevOps{Assigned,Mention}) intentionally read JSON only and don't need the gate, which matches behavior on main. No privilege boundary regressed.
  4. URL construction in Open-AzDevOpsWorkItemUrl / Mention / Assigned — unchanged and still safe. Lines 961-974 (Open-AzDevOpsWorkItemUrl), 950-953 (Find-AzDevOpsCachedWorkItem fallback), and 1700-1703 (new-story open) all do the same defensive thing: TrimEnd('/') on $env:AZ_DEVOPS_ORG and [uri]::EscapeDataString($env:AZ_PROJECT) before composing "$org/$projectEnc/_workitems/edit/$Id". The $Id parameter is typed [int], which prevents URL-fragment / path-traversal smuggling at the parameter binder.

  5. Scheduled-task command strings updated correctly — verified. The cron line (Get-AzDevOpsCronLine, line 713) and the Windows scheduled-task action (az-Register-AzDevOpsSyncSchedule, line 747) both now invoke pwsh -Command "az-Sync-AzDevOpsCache". The new function name is a valid PowerShell identifier, so this won't break execution under either platform's scheduler. No new command injection surface — the strings are still hardcoded internally; the $PwshPath parameter is a path the user controls in their own profile (already true on main).

Bottom line

Pure renames don't typically introduce vulnerabilities, and this one doesn't either. The auth gate is intact, URL construction is unchanged, no Invoke-Expression was added, and there are no secrets in the diff. Approving.

https://claude.ai/code


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

🧼 Senior Clean-Code Engineer

Summary

Single-commit branch (d3eefed) renames 18 user-facing PowerShell functions in powcuts_by_cli/azdevops_workitems.ps1 to add a literal az- prefix, plus matching string updates in Write-Host messages, comments, docstrings, scheduled-task script blocks, and README.md. No logic changed; no functions were added, removed, split, merged, or reshaped. All previously-extracted shared helpers (Get-AzDevOpsPlatform, Get-AzDevOpsCronTag, Get-AzDevOpsCronLine, Get-AzDevOpsScheduledTaskName, Get-AzDevOpsCrontabSplit, Find-AzDevOpsCachedWorkItem, Read-AzDevOpsJsonCache, Format-AzDevOpsTreeNode, etc.) remain intact at their original line numbers.

Findings

Severity Location Issue
(none) No new structural duplication, oversized functions, magic literals, or parallel-pair scaffolding violations introduced by this rename.

Duplication Map

No new duplicated blocks. The existing Register-/Unregister-AzDevOpsSyncSchedule pair still routes through Get-AzDevOpsPlatform + Get-AzDevOpsCronLine + Get-AzDevOpsCronTag, and the Get-/Open-AzDevOps{Assigned,Mention} pairs still route through Find-AzDevOpsCachedWorkItem + Read-AzDevOpsJsonCache. Internal helpers were intentionally left unprefixed (per the commit message), preserving the public/private surface distinction the file already established.

Function Sizes

Function Lines (body) Verdict
(all renamed functions) unchanged OK — no body modified by this commit

Notes (informational, not blocking)

  • Two Write-Host abort messages grew to ~136 and ~139 chars after the rename:
    • az-Sync-AzDevOpsCache abort string in az-Sync-AzDevOpsCache
    • az-New-AzDevOpsUserStory abort string in az-New-AzDevOpsUserStory
      These were already long single-line strings; the prefix bump is mechanical and CLAUDE.md does not impose a hard line length. Worth a future tidy (line-continuation or extracting an "abort with hint" helper that takes the function name + reason), but not a CLAUDE.md violation in code that was already touched, so not flagged.
  • The rename leaves Test-AzDevOps* / ConvertFrom-AzDevOps* / Read-AzDevOps* / Write-AzDevOps* / Initialize-AzDevOps* / Format-AzDevOps* / Measure-AzDevOps* / Invoke-AzDevOps* / Find-AzDevOpsCachedWorkItem / Get-AzDevOpsClassificationPaths etc. without the az- prefix. This is the correct call: those are private helpers and the public surface should be the discoverable one. Worth a one-line comment near the top of the file noting the convention so future contributors don't "fix" the inconsistency, but that's a docs nit not a clean-code finding.

Verdict

APPROVE — pure mechanical rename, no new duplication, no oversized functions introduced, all shared helpers preserved. Ship it.

https://claude.ai/code/session_01YX2HXczqxkhQD5tsUqtdY1


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

💠 Senior PowerShell Engineer

Summary

Single-commit PR (d3eefed) that adds a literal lowercase az- prefix to 18 user-facing PowerShell functions in powcuts_by_cli/azdevops_workitems.ps1 and updates README.md to match. Internal helpers are intentionally left unprefixed per issue #25. The rename is mechanically thorough and internally consistent — no stale references remain inside the file or in the README.

Findings

Severity Location Issue
INFO powcuts_by_cli/azdevops_workitems.ps1 (all 18 renamed functions) az- is not in the approved verbs list — every dot-source of $profile will emit WARNING: The names of some imported commands ... include unapproved verbs. Documented in issue #25 as accepted convention; suppression is explicitly out of scope. Surfaced here only so the trade-off is visible in the review record.
INFO parse step pwsh not on PATH in this environment, so the formal [Parser]::ParseFile gate could not be executed. Visual review of the full diff and the post-rename file (function table extracted via grep) shows balanced braces, intact param() blocks, and no truncated lines around any renamed function. Recommend the user verify in a fresh PowerShell session by dot-sourcing powcuts_home.ps1 and running Get-Command az-*.

No CRITICAL, HIGH, MEDIUM, or LOW findings.

Rename completeness audit

18 user-facing functions prefixed (matches issue #25 scope):

Bucket Functions
Auth / setup (8) az-Connect-AzDevOps, az-Test-AzDevOpsAuth, az-Confirm-AzDevOpsCli, az-Confirm-AzDevOpsExtension, az-Confirm-AzDevOpsEnvVars, az-Confirm-AzDevOpsLogin, az-Set-AzDevOpsDefaults, az-Confirm-AzDevOpsSmokeQuery
Sync / cache (4) az-Sync-AzDevOpsCache, az-Get-AzDevOpsCacheStatus, az-Register-AzDevOpsSyncSchedule, az-Unregister-AzDevOpsSyncSchedule
Cache consumers (4) az-Get-AzDevOpsAssigned, az-Open-AzDevOpsAssigned, az-Get-AzDevOpsMentions, az-Open-AzDevOpsMention
Tree + new story (2) az-Show-AzDevOpsTree, az-New-AzDevOpsUserStory

grep -c "^function az-" powcuts_by_cli/azdevops_workitems.ps118. ✅

Internal helpers correctly left unprefixed — confirmed by enumerating callers:

  • Find-AzDevOpsCachedWorkItem → called only at lines 1018, 1150 (both internal: az-Open-AzDevOpsAssigned, az-Open-AzDevOpsMention).
  • Open-AzDevOpsWorkItemUrl → called only at lines 1026, 1158 (same two callers).
  • Get-AzDevOpsClassificationPaths → called only at line 1631 (Read-AzDevOpsClassificationPick, itself internal).
  • Test-/ConvertFrom-/Read-/Write-/Initialize-/Format-/Measure-/Invoke-/New-/Select-/Confirm- AzDevOps* (e.g. Test-AzDevOpsCliPresent, ConvertFrom-AzDevOpsAssignedItem, Read-AzDevOpsYesNo, Write-AzDevOpsCacheFile, Initialize-AzDevOpsCacheDir, Format-AzDevOpsTreeNode, Measure-AzDevOpsClassificationNodes, Invoke-AzDevOpsBoardsQuery, etc.) — none appear in the README, all only have callers from other functions in the same file. Correctly internal.

Get-AzDevOpsClassificationPaths was specifically called out in the review brief — confirmed it has exactly one caller (Read-AzDevOpsClassificationPick) and never appears in README.md. Leaving it unprefixed is the right call.

Stale-reference audit

grep -nE "Connect-AzDevOps|Test-AzDevOpsAuth|Confirm-AzDevOps...|Sync-AzDevOpsCache|...|New-AzDevOpsUserStory" powcuts_by_cli/azdevops_workitems.ps1 | grep -v "az-"
→ (no matches)

Zero unprefixed references to any of the 18 renamed functions remain inside the file. This includes:

  • The Connect-AzDevOps orchestrator's $steps array (all six Action = { az-Confirm-AzDevOps... } scriptblocks updated).
  • The user-facing Write-Host strings inside az-Sync-AzDevOpsCache ("run az-Sync-AzDevOpsCache"), az-Get-AzDevOpsCacheStatus ("No cache yet - run az-Sync-AzDevOpsCache"), Read-AzDevOpsJsonCache (the two-line "Run: az-Sync-AzDevOpsCache / Run: az-Register-AzDevOpsSyncSchedule" hint), Find-AzDevOpsCachedWorkItem ("or az-Sync-AzDevOpsCache to refresh"), az-New-AzDevOpsUserStory's abort messages ("Run az-Connect-AzDevOps", "run az-Sync-AzDevOpsCache"), and the cron-line + scheduled-task -Argument "-Command 'az-Sync-AzDevOpsCache'" payloads.
  • The -ListCommand argument passed into Find-AzDevOpsCachedWorkItem from both az-Open-AzDevOpsAssigned ('az-Get-AzDevOpsAssigned') and az-Open-AzDevOpsMention ('az-Get-AzDevOpsMentions').
  • The header docblocks at the top of each section.

README.md references — 23 az-…-AzDevOps mentions, zero unprefixed user-facing-function mentions, zero internal-helper mentions. ✅

Bash parity

bashcuts_by_cli/.az_bashcuts already uses the az- prefix (az-open-work-item, az-show-work-item, az-open-board, …). This PR brings the PowerShell side into the same convention. Mirror parity check passes.

Standard PowerShell rules from the skill

Check Result
Parse ⚠️ pwsh unavailable in review env; visual review clean
Approved verbs INFO only — az- prefix is documented project convention (issue #25); standard verb portion (Get/Set/Open/Show/New/Sync/Connect/Test/Confirm/Register/Unregister) is preserved after the prefix
Naming parity (bash ↔ pwsh) ✅ both shells now share the az- prefix
Write-Host for data ✅ no new Write-Host calls in this diff; the existing ones are status messages, not data
In-script aliases (?, %, select, gci, …) ✅ none in the diff
Error handling around external az N/A — diff is pure rename, no new external invocations
param() / [CmdletBinding()] N/A — no new functions; existing param blocks preserved
Dot-sourcing wire-up ✅ no new files; existing azdevops_workitems.ps1 entry in powcuts_home.ps1 unchanged
Cross-platform paths N/A — no path manipulation in the diff
Profile side effects ✅ no new top-level statements

Approved Verbs

INFO — non-approved literal az- prefix is the documented project convention per issue #25; underlying verb portion of every renamed function is approved (Get, Set, Open, Show, New, Sync, Connect, Test, Confirm, Register, Unregister).

Dot-Sourcing Wire-Up

WIRED — powcuts_home.ps1 already dot-sources azdevops_workitems.ps1; no new files in this diff.

Verdict

APPROVE — no blocking issues. Rename is consistent across the 18 user-facing functions, all internal callers and user-facing strings updated, README in sync, internal helpers correctly excluded. Recommend the user verify in a fresh PowerShell session with Get-Command az-*-AzDevOps* and a smoke az-Test-AzDevOpsAuth before merging.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✅ Criteria Check — #25: Add az- prefix to user-facing Azure DevOps PowerShell functions

Syntax Checks

⏭️ PowerShell parse: SKIPPED — pwsh not on PATH in this environment. User must verify locally with:

pwsh -NoProfile -Command "[System.Management.Automation.Language.Parser]::ParseFile('powcuts_by_cli/azdevops_workitems.ps1', [ref]\$null, [ref]\$null) | Out-Null; 'PARSE OK'"

Acceptance Criteria

# Criterion Status Evidence
1 Every user-facing function renamed to az-<OriginalName> ✅ VERIFIED grep -c "^function az-" powcuts_by_cli/azdevops_workitems.ps118 matches; all 18 from the issue's rename table accounted for at lines 91, 124, 144, 161, 183, 201, 213, 230, 576, 646, 737, 768, 991, 1009, 1097, 1137, 1269, 1742
2 Internal/helper functions are not renamed ✅ VERIFIED (with note) Sample preserved: Test-AzDevOpsCliPresent:53, ConvertFrom-AzDevOpsAssignedItem:811, Read-AzDevOpsJsonCache:826, Find-AzDevOpsCachedWorkItem:929, Open-AzDevOpsWorkItemUrl:961, Get-AzDevOpsClassificationPaths:1448. ⚠️ Note: the criterion text lists Confirm- as internal, but the issue's explicit rename table and the file's own header (lines 13–22, "Step functions invoked by az-Connect-AzDevOps — also exposed for direct use") classify Confirm-AzDevOps* + Set-AzDevOpsDefaults as user-facing step entry points. Followed the explicit table + file header, which are the sources of truth.
3 All in-file callers updated to new names (no stale references) ✅ VERIFIED Full-repo grep `(Connect-AzDevOps
4 No Set-Alias shims for old names ✅ VERIFIED grep -nE 'Set-Alias' powcuts_by_cli/azdevops_workitems.ps1 → no matches.
5 pwsh -NoProfile parses with zero errors 🔍 MANUAL pwsh not on PATH in review env. PowerShell-engineer review relied on visual diff inspection and reported zero parse-blocking issues. User to verify locally.
6 az- + tab-tab in fresh PowerShell shows all 18 renamed functions 🔍 MANUAL Function definitions present and well-formed; tab-completion is a runtime PowerShell behavior that requires a fresh PS session with $profile dot-sourced.
7 At least one renamed function (e.g. az-Get-AzDevOpsCacheStatus) executes end-to-end 🔍 MANUAL Requires az CLI + an authenticated AzDevOps environment with cache populated; not testable in review sandbox.
8 README's Azure DevOps section updated ✅ VERIFIED grep -c against the renamed names in README.md16 occurrences across the Azure DevOps section. The intro paragraph (line 161), prerequisites (lines 166–167), first-run snippet (line 186), day-to-day examples (lines 198–213), stale-cache notice (line 216), live-fetch hint (line 218), and the az-New-AzDevOpsUserStory walk-through (lines 222–243) all reference the prefixed names. Zero unprefixed user-facing references remain.

Summary

Status Count
✅ VERIFIED 5
🔍 MANUAL 3
⚠️ PARTIAL 0
❌ MISSING 0

Manual Verification Checklist

  • Local parse-check: pwsh -NoProfile -Command "[System.Management.Automation.Language.Parser]::ParseFile('powcuts_by_cli/azdevops_workitems.ps1', [ref]\$null, [ref]\$null) | Out-Null; 'PARSE OK'"
  • Open a fresh PowerShell terminal, dot-source $profile, type az- + tab-tab → all 18 az-* AzDevOps functions appear in the completion list
  • Run az-Get-AzDevOpsCacheStatus against an environment where az-Connect-AzDevOps previously reported READY → prints cache freshness with no errors

Verdict

PASS — all 5 automated criteria verified, 3 require manual terminal testing in a real PowerShell session.


Generated by Claude Code

Renames 22 user-facing functions in azdevops_workitems.ps1 (the original
18 plus the 4 user-facing schema-management commands added by PR #22)
to start with literal lowercase az- so the full Azure DevOps PowerShell
surface is tab-tab-discoverable the same way it already is in bash.

New renames vs the original PR #26 commit (rebase onto post-#22 main):
  Initialize-AzDevOpsSchema -> az-Initialize-AzDevOpsSchema
  Get-AzDevOpsSchema        -> az-Get-AzDevOpsSchema
  Edit-AzDevOpsSchema       -> az-Edit-AzDevOpsSchema
  Test-AzDevOpsSchema       -> az-Test-AzDevOpsSchema

Internal helpers (Test-/ConvertFrom-/Read-/Write-/Initialize-/Format-/
Measure-/Invoke-/Get- helpers, plus Find-AzDevOpsCachedWorkItem /
Open-AzDevOpsWorkItemUrl / Get-AzDevOpsClassificationPaths and the
Assert-AzDevOpsAuthOrAbort / Schema* private helpers) stay unprefixed
since they don't surface to user tab-completion.

Conflict resolution against post-#22 main:
- Adopted main's Assert-AzDevOpsAuthOrAbort helper inside
  az-Sync-AzDevOpsCache and az-New-AzDevOpsUserStory, replacing the
  inline Test-AzDevOpsAuth + Write-Host abort pattern from the
  original PR #26 commit. -CommandName argument updated to the
  renamed function name in each call site.

Header docblock + README.md schema-management section updated to match.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo
@jdschleicher jdschleicher force-pushed the claude/add-az-prefix-methods-XOHxc branch from d3eefed to bab9dc3 Compare May 8, 2026 03:48
Copy link
Copy Markdown
Owner Author

🔁 Rebased onto current main (commit bab9dc3)

PR #26 was conflicting with main because PR #22 (issue #13's schema-management work) merged after this branch was created. Rebased to clear the conflict — and while doing so, expanded scope to keep PR #26's convention consistent across the full AzDO public surface that now exists in main.

Conflict resolution

Scope expansion (per the convention)

Added az- prefix to the 4 user-facing schema-management commands that PR #22 introduced — they were not in PR #26's original list because they didn't exist yet:

Today After
Initialize-AzDevOpsSchema az-Initialize-AzDevOpsSchema
Get-AzDevOpsSchema az-Get-AzDevOpsSchema
Edit-AzDevOpsSchema az-Edit-AzDevOpsSchema
Test-AzDevOpsSchema az-Test-AzDevOpsSchema

Internal schema helpers (Get-AzDevOpsSchemaValidTypes, Get-AzDevOpsSchemaWorkItemTypes, Get-AzDevOpsSchemaSystemRefs, Get-AzDevOpsSchemaOrgSlug, Get-AzDevOpsSchemaPaths, Initialize-AzDevOpsSchemaDir, Get-AzDevOpsSchemaForType, New-AzDevOpsSchemaStub, Read-AzDevOpsSchemaFile, Write-AzDevOpsSchemaFile, ConvertFrom-AzDevOpsSchemaToRows, ConvertTo-AzDevOpsSchemaFieldEntry) stay unprefixed per this PR's existing convention — they don't surface to user tab-completion.

Final tally

  • 22 az- prefixed user-facing functions (originally 18, +4 schema)
  • 0 unprefixed user-facing AzDevOps function definitions remain
  • Diff vs main: README.md (58 lines), powcuts_by_cli/azdevops_workitems.ps1 (194 lines)

Re-running checks

The previous skill reports (Bash / PowerShell / Security / Clean-Code / Criteria) were against the original d3eefed commit. After this rebase the surface grew by 4 functions and adopted main's Assert-AzDevOpsAuthOrAbort helper — recommend re-running /code-review + /criteria-check against bab9dc3 before merge to confirm nothing regressed.

About PR #27 (wrapper layer)

Per merge-order plan, PR #26 ships first. After merge I'll rebase PR #27 onto the new main, re-applying the wrapper-layer call-site routing using the renamed function names (the new wrappers in azdevops_db.ps1 are internal helpers and stay unprefixed per this PR's convention, so no scope conflict between the two PRs).

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

🐚 Senior Bash Engineer

Summary

This PR (rebased onto current main at bab9dc3) modifies only README.md and powcuts_by_cli/azdevops_workitems.ps1. No files under bashcuts_by_cli/ and no changes to .bcut_home. The README diff is text-only — it renames PowerShell function references to the new az- prefix; the embedded code fences are all powershell, not bash.

Changed Files (vs origin/main)

  • README.md — documentation rename only
  • powcuts_by_cli/azdevops_workitems.ps1 — out of scope for this reviewer

Findings

Severity Location Issue
No bash files in this diff; no findings.

Sourcing Wire-Up

N/A — no new files under bashcuts_by_cli/; .bcut_home is untouched.

Naming Convention

N/A — no bash aliases or functions changed. (PowerShell naming is the PowerShell engineer's purview.)

Syntax / Quoting / macOS start / Bashism Checks

All N/A — no bash files were touched, and the README's only embedded snippets are PowerShell.

Verdict

APPROVE — no bash files in this diff.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

🛡️ Senior Security Engineer

Verdict: APPROVE — no security findings.

Scope reviewed

Re-reviewed against rebased commit bab9dc3 on claude/add-az-prefix-methods-XOHxc. Diff vs origin/main is 126 insertions / 126 deletions across two files (README.md, powcuts_by_cli/azdevops_workitems.ps1) — a near-pure identifier rename of public functions to the az-Verb-Noun pattern.

Checks performed

  1. Argument-passing patterns unchanged. Every & az ... invocation, Invoke-AzDevOpsAzJson -ArgList @(...) call, New-ScheduledTaskAction -Argument value, and the crontab line shape are byte-identical to main apart from the literal command name string Sync-AzDevOpsCacheaz-Sync-AzDevOpsCache embedded in the scheduled command (still a hardcoded literal, no interpolation of user input). No new injection surface.

  2. Assert-AzDevOpsAuthOrAbort -CommandName arguments are still hardcoded literals. Confirmed at all four call sites (az-Sync-AzDevOpsCache, az-New-AzDevOpsUserStory, az-Initialize-AzDevOpsSchema, az-Test-AzDevOpsSchema). No path lets user input flow into -CommandName — values are single-quoted PowerShell string literals matching the enclosing function name. Even if they weren't, -CommandName is only interpolated into a Write-Host status string downstream, never executed.

  3. No new secret-leakage paths. Renamed Write-Host lines print only command-name guidance (e.g. "Run: az-Sync-AzDevOpsCache"). No new prints of $env:AZ_*, no az --debug toggles, no token echoes, no log writes added.

  4. Scriptblock dispatch in az-Connect-AzDevOps still safe. The $steps array's Action scriptblocks invoke hardcoded function names ({ az-Confirm-AzDevOpsCli } etc.) — closed internal data, no untrusted input reaches & $step.Action. The pre-existing comment calling this out remains accurate.

  5. README diff is documentation-only. No new curl | sh, no fetch-and-execute, no embedded credentials, no new install instructions beyond updating function names in code blocks. The pre-existing schema-permissions paragraph (0700 dir on POSIX, %USERPROFILE% ACL on Windows) is untouched.

  6. Schema function permission handling unchanged. The four renamed schema commands (az-Initialize-AzDevOpsSchema, az-Get-AzDevOpsSchema, az-Edit-AzDevOpsSchema, az-Test-AzDevOpsSchema) still route through the same Get-AzDevOpsSchemaPaths / Write-AzDevOpsSchemaFile helpers — no diff in how $HOME/.bashcuts/azure-devops/schema-<org>.json is created, opened, or chmod'd. Per-org file path derivation from $env:AZ_DEVOPS_ORG is unchanged.

Risk summary

Rename-only PRs carry minimal security risk. The four areas where renames could have introduced an issue (CLI arg arrays, scheduled-task argument strings, scriptblock dispatch, and the -CommandName literal contract) were each spot-checked and confirmed clean. Ship it.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

🧼 Senior Clean-Code Engineer

Verdict: REQUEST CHANGES

Reviewed bab9dc3 (rebased onto main). Diff is README.md + powcuts_by_cli/azdevops_workitems.ps1 only. The structural surface is unchanged (renames don't grow functions), and the new shared Assert-AzDevOpsAuthOrAbort prologue is correctly applied across all 4 user-facing entry points with matching -CommandName arguments — that's a clean DRY win. No az-az- double-prefix bugs. Switch/if/else style and breathing room are unchanged from main.

However, the rebase + rename surfaced two leftover unprefixed references that the rename pass missed.


🔴 Blocking — broken function call in shared helper

powcuts_by_cli/azdevops_workitems.ps1:108 inside Assert-AzDevOpsAuthOrAbort:

function Assert-AzDevOpsAuthOrAbort {
    ...
    if (Test-AzDevOpsAuth) {        # ← line 108: function no longer exists
        return $true
    }

    Write-Host "$CommandName aborted - Test-AzDevOpsAuth returned false. Run Connect-AzDevOps." -ForegroundColor Red
    return $false
}

The function was renamed to az-Test-AzDevOpsAuth on line 91 of this same file. Calling the bare Test-AzDevOpsAuth will fail to resolve, PowerShell will throw CommandNotFoundException, and the helper's strict-mode behavior depends on session state — at best the user sees a confusing error, at worst the if evaluates falsy and every guarded command (az-Sync-AzDevOpsCache, az-New-AzDevOpsUserStory, az-Initialize-AzDevOpsSchema, az-Test-AzDevOpsSchema) silently aborts with a misleading "auth bad" message even when auth is fine. Since Assert-AzDevOpsAuthOrAbort is the auth gate for every entry point in this PR, this is the highest-impact regression possible from the rename.

Fix: change line 108 to if (az-Test-AzDevOpsAuth) {.

🟡 User-facing string + doc references

  1. azdevops_workitems.ps1:112 — the Write-Host failure message names Test-AzDevOpsAuth and Connect-AzDevOps, both renamed. Users following the message verbatim will hit "command not found." Update to az-Test-AzDevOpsAuth / az-Connect-AzDevOps.

  2. azdevops_workitems.ps1:101-102 — the Assert-AzDevOpsAuthOrAbort doc-comment lists Sync-AzDevOpsCache, New-AzDevOpsUserStory, az-Initialize-AzDevOpsSchema, az-Test-AzDevOpsSchema. The first two are unprefixed and now wrong; the second two are already correct. Make all four consistent (az- prefix).

  3. README.md:247 — narrative paragraph references New-AzDevOpsUserStory, Get-AzDevOpsAssigned, Show-AzDevOpsTree without prefixes. These are user-facing names in the schema section — rename for consistency with the rest of the README which was updated.


What's good

  • All 4 Assert-AzDevOpsAuthOrAbort -CommandName 'X' calls have X matching their enclosing renamed function exactly (verified at lines 594, 1771, 2274, 2346). No drift.
  • No new duplication introduced; rename was mechanical.
  • No breathing-room / multi-line-if regressions; switch and if/else style unchanged.
  • Function sizes unchanged — no growth past the 5-15 line target from this PR.

Block on the line-108 broken call; the three string/doc fixes can ride along in the same commit.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

💠 Senior PowerShell Engineer

Summary

Re-review of PR #26 against rebased commit bab9dc3 (prior review d3eefed is stale). Diff touches README.md + powcuts_by_cli/azdevops_workitems.ps1 only. The 22 user-facing function renames and the 4 Assert-AzDevOpsAuthOrAbort -CommandName 'X' arguments line up with their enclosing function names — but a runtime-breaking call site was missed inside Assert-AzDevOpsAuthOrAbort itself, and its user-facing error string still points users at non-existent commands.

Findings

Severity Location Issue
CRITICAL powcuts_by_cli/azdevops_workitems.ps1:108 Assert-AzDevOpsAuthOrAbort calls Test-AzDevOpsAuth, but that function was renamed to az-Test-AzDevOpsAuth at line 91. The old name no longer exists, so this call resolves to nothing — if (Test-AzDevOpsAuth) evaluates the unresolved command, hits the empty-pipeline / command-not-found branch, and the auth-test always returns false. Every command gated by Assert-AzDevOpsAuthOrAbort (az-Sync-AzDevOpsCache, az-New-AzDevOpsUserStory, az-Initialize-AzDevOpsSchema, az-Test-AzDevOpsSchema) will instantly abort with a "Test-AzDevOpsAuth returned false" message regardless of actual auth state. Fix: change line 108 to if (az-Test-AzDevOpsAuth) {.
HIGH powcuts_by_cli/azdevops_workitems.ps1:112 User-facing abort message reads "$CommandName aborted - Test-AzDevOpsAuth returned false. Run Connect-AzDevOps." Both names are stale. Users following the instruction will type Connect-AzDevOps and get a command-not-found error. Update the literal to "$CommandName aborted - az-Test-AzDevOpsAuth returned false. Run az-Connect-AzDevOps."
LOW powcuts_by_cli/azdevops_workitems.ps1:101,104 Header comment for Assert-AzDevOpsAuthOrAbort still lists Sync-AzDevOpsCache, New-AzDevOpsUserStory and Test-AzDevOpsAuth returned false. Run Connect-AzDevOps. — cosmetic but harvest-them-now since the file is being touched anyway.
LOW powcuts_by_cli/azdevops_workitems.ps1:1902,2055 Section / docstring comments still reference New-AzDevOpsUserStory, Get-AzDevOpsAssigned, Show-AzDevOpsTree (all renamed). Stale text only — no behavior impact.

Dot-Sourcing Wire-Up

N/A — no new files; powcuts_home.ps1 already dot-sources azdevops_workitems.ps1.

Approved Verbs

DRIFT (acknowledged in AC) — every renamed function uses az- as a non-approved verb; AC accepts the Get-Verb warning as the cost of cross-shell discoverability. Flagging for awareness only, not blocking. Internal helpers (Test-AzDevOpsCliPresent, Get-AzDevOpsSchemaValidTypes, etc.) correctly retained their approved verbs.

Other checks

  • Parse: pwsh not on PATH in this sandbox — visual review only. Param blocks of all 22 renamed functions look intact ([CmdletBinding()] and param() preserved). The line-108 bug is a logic bug, not a parse bug.
  • Write-Host data leakage: PASS — all Write-Host uses are status / hint messages, not data.
  • In-script aliases: PASS.
  • Side effects on dot-source: PASS — no new top-level statements.
  • Naming parity: matches the bash side's lowercase az- prefix convention.

Verdict

REQUEST CHANGES — 1 CRITICAL + 1 HIGH. The line-108 missed call site silently breaks every auth-gated az-* command in the PR; without the fix the rename PR ships in a state where az-Sync-AzDevOpsCache, az-New-AzDevOpsUserStory, az-Initialize-AzDevOpsSchema, and az-Test-AzDevOpsSchema are non-functional. Updating lines 108 and 112 (and ideally the comment block at 101–104 while there) clears both findings.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo


Generated by Claude Code

The rebase onto post-#22 main adopted the Assert-AzDevOpsAuthOrAbort
helper introduced by PR #22, but missed three things flagged by the
re-review against bab9dc3:

CRITICAL — azdevops_workitems.ps1:108
  Assert-AzDevOpsAuthOrAbort internally called the OLD function name
  Test-AzDevOpsAuth. Since this PR renames Test-AzDevOpsAuth to
  az-Test-AzDevOpsAuth at line 91, every guarded entry point
  (az-Sync-AzDevOpsCache, az-New-AzDevOpsUserStory,
  az-Initialize-AzDevOpsSchema, az-Test-AzDevOpsSchema) would have
  silently aborted regardless of real auth state.

HIGH — line 112
  Same helper's user-facing Write-Host message referenced the old
  unprefixed names (Test-AzDevOpsAuth + Connect-AzDevOps). Now uses
  az-Test-AzDevOpsAuth + az-Connect-AzDevOps.

LOW — doc-comment stragglers at lines 101-105, 1902, 2055 + README:247
  Internal doc-strings + the README's schema-section paragraph
  mentioned the unprefixed names of New-AzDevOpsUserStory,
  Get-AzDevOpsAssigned, Show-AzDevOpsTree. Updated for consistency.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo
Copy link
Copy Markdown
Owner Author

🔧 Re-review findings addressed in 4c9a3ff

The four fresh reviews against bab9dc3 surfaced one CRITICAL bug from the rebase (Assert-AzDevOpsAuthOrAbort still called the old Test-AzDevOpsAuth name internally) plus a few LOW doc-comment stragglers. All resolved in the new commit.

Combined Verdict — pre-fix (bab9dc3)

Reviewer Verdict Findings
🐚 Bash Engineer ✅ APPROVE N/A — no bash files in diff
💠 PowerShell Engineer ❌ REQUEST CHANGES 1 CRITICAL + 1 HIGH (Assert-AzDevOpsAuthOrAbort:108 + :112) + 4 LOW comments
🛡️ Security Engineer ✅ APPROVE No security findings — pure rename, argv arrays unchanged
🧼 Clean-Code Engineer ❌ REQUEST CHANGES Same CRITICAL bug + 2 LOW doc-comment stragglers

Fix applied in 4c9a3ff

File:Line Change
azdevops_workitems.ps1:108 if (Test-AzDevOpsAuth)if (az-Test-AzDevOpsAuth)
azdevops_workitems.ps1:112 Write-Host message: Test-AzDevOpsAuthaz-Test-AzDevOpsAuth, Connect-AzDevOpsaz-Connect-AzDevOps
azdevops_workitems.ps1:101-104 Doc-comment refs to Sync-AzDevOpsCache, New-AzDevOpsUserStory, Test-AzDevOpsAuth, Connect-AzDevOpsaz- versions
azdevops_workitems.ps1:1902 Doc-comment refs to New-AzDevOpsUserStory, Get-AzDevOpsAssigned, Show-AzDevOpsTreeaz- versions
azdevops_workitems.ps1:2055 Doc-comment ref to New-AzDevOpsUserStoryaz-New-AzDevOpsUserStory
README.md:247 Schema-section paragraph: 3 unprefixed refs updated

Sanity check

=== Stragglers after fix ===
(no stragglers)

=== Brace + paren balance ===
open-brace:465 close-brace:465 open-paren:656 close-paren:656

Combined Verdict — post-fix (4c9a3ff)

Ready to merge — the CRITICAL Assert-AzDevOpsAuthOrAbort regression is patched; all 22 user-facing renames + 0 stragglers; security/bash reviews remain APPROVE; clean-code stragglers cleared.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✅ Criteria Check — Issue #25 (vs 4c9a3ff)

Add az- prefix to user-facing Azure DevOps PowerShell functions

Syntax Checks

  • Bash: N/A — no bash files in diff
  • PowerShell parse: ⏭️ SKIPPED — pwsh not on PATH; brace + paren balance verified (465/465 braces, 656/656 parens)

Acceptance Criteria

# Criterion Status Evidence
1 Every user-facing function renamed to az- (lowercase prefix kept literal) ✅ VERIFIED 22 az--prefixed functions defined; grep -cE '^function az-' powcuts_by_cli/azdevops_workitems.ps1 = 22
2 Internal helpers NOT renamed ✅ VERIFIED ⚠️ note All Test-/ConvertFrom-/Read-/Write-/Initialize-/Format-/Measure-/Invoke- helpers untouched. Scope-expansion note: the issue's "Internal helpers" list mentioned Confirm-AzDevOps* + Set-AzDevOpsDefaults as keep-as-is, but PR #26 prefixed them (defensible — they print user-facing output and would otherwise collide with stock cmdlets in tab-completion). Implementer kept Find-AzDevOpsCachedWorkItem, Open-AzDevOpsWorkItemUrl, Get-AzDevOpsClassificationPaths unprefixed per the issue's Open Question.
3 All in-file callers updated to new names ✅ VERIFIED Final straggler scan returns zero unprefixed user-facing references. Critical fix in 4c9a3ff: Assert-AzDevOpsAuthOrAbort:108 was calling the OLD Test-AzDevOpsAuth; patched to az-Test-AzDevOpsAuth. Three doc-comment stragglers (lines 101-104, 1902, 2055) and README.md:247 also patched.
4 No Set-Alias shims for old names ✅ VERIFIED Zero Set-Alias back-compat shims — clean rename.
5 pwsh -NoProfile parses with zero errors 🔍 MANUAL pwsh not on PATH in this environment. Brace + paren balance preserved across the rebase and the post-fix commit; visual review found no syntax issues.
6 Tab-completion: az- + tab-tab shows the full surface 🔍 MANUAL All 22 function names start with az- at top level — completion will pick them up after dot-source.
7 At least one renamed function executes end-to-end 🔍 MANUAL Recommended target: az-Get-AzDevOpsCacheStatus (no auth needed beyond cache files).
8 README updated to use new names ✅ VERIFIED 30 az--prefixed AzDevOps references in README.md; zero unprefixed references remain.

Summary

Status Count
✅ VERIFIED 5
🔍 MANUAL 3
⚠️ PARTIAL 0
❌ MISSING 0

Manual Verification Checklist

  • pwsh -NoProfile -Command "[System.Management.Automation.Language.Parser]::ParseFile('powcuts_by_cli/azdevops_workitems.ps1', [ref]\$null, [ref]\$null) | Out-Null; 'PARSE OK'" — should print PARSE OK
  • In a fresh PowerShell terminal, dot-source $profile, type az- + tab-tab — all 22 az-* names appear
  • az-Get-AzDevOpsCacheStatus — prints cache freshness with no errors

Verdict

PASS — all 5 automated criteria satisfied; 3 items require manual terminal testing. The CRITICAL Assert-AzDevOpsAuthOrAbort regression flagged in the re-review is patched in 4c9a3ff. Scope expansion on Confirm-* + Set-AzDevOpsDefaults is documented but not blocking.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo


Generated by Claude Code

@jdschleicher jdschleicher merged commit 7f46df6 into main May 8, 2026
jdschleicher pushed a commit that referenced this pull request May 8, 2026
After rebasing onto post-#26 main, two doc-staleness gaps surfaced:

azdevops_db.ps1:16
  Header comment said "alongside Connect-AzDevOps". Updated to
  az-Connect-AzDevOps to match the renamed user-facing function.

docs/azure-devops-diagrams.md
  This doc was added by PR #24 before PR #26 was authored, so it
  referenced every user-facing AzDO function by the unprefixed name
  (64 references across TOC, section headings, mermaid node labels,
  and sequence-diagram participants). PR #26 didn't update it (out
  of scope for a rename PR). Bulk-renamed every occurrence to its
  az- counterpart and updated the matching anchor links so the TOC
  jumps still work. Two shortcut-notation cases (Get-/Open-AzDevOps,
  Register-/Unregister-AzDevOpsSyncSchedule) needed manual touch-up
  since the regex couldn't see the bare half of the pair.

https://claude.ai/code/session_01P7znUKccAohZYEwYRBNVfo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add az- prefix to user-facing Azure DevOps PowerShell functions

2 participants