Polish unplanned-work WPF flow: parent Feature, open-task button, trimmed debrief, az-job spinner#165
Conversation
…164) Four refinements to az-Start-UnplannedWork, all gated to the unplanned call site so the shared Pomodoro timer debrief form is unchanged: - New-UnplannedWorkStory now prompts for a parent Feature on the first daily-story creation (orphan-safe; cached/existing stories skip it) and links it via Invoke-AzDevOpsParentLink. Extracted Read-UnplannedParentFeature. - Invoke-UnplannedDebriefWpf drops -Items so the read-only captured-items review list is omitted (items already flush to the Task description), and passes -OpenAction so an "Open in Azure DevOps" button opens the new Task. - Show-WpfTimerDebrief gains a defaulted -OpenLabel knob so the open button caption is configurable without touching the timer's wording. - New-WpfProgressWindow (pow_common.ps1): a non-modal spinner+status window wrapping the at-stop az-boards chain so the user sees which step is running; a no-op stub off Windows where the per-step Write-Host lines remain. Diagram doc updated for the new parent-link, progress window, and open button. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NKnjPmNLKwW7KiZgkoaNHa
🐚 Senior Bash EngineerAPPROVE — no bash files in this diff This branch changed only PowerShell files ( Generated by Claude Code |
🛡️ Senior Security EngineerVerdict: PASS — no security findings. Reviewed the PowerShell changes on this branch (
Nothing exploitable is introduced by this diff. Generated by Claude Code |
🧼 Senior Clean-Code EngineerSummaryThree PowerShell files changed: a new Findings
Duplication Map
Function Sizes
Magic NumbersThe new window inlines Breathing RoomTwo blank lines between all new top-level functions ✓. Internal logical groups (param block → guard → brush set → window → border → row → controller) are separated by single blank lines ✓. No gratuitous triple blanks. Clean. Premature Abstraction
VerdictAPPROVE — well-factored. New WPF helpers reuse the existing brush/spinner seams rather than copy them; the two flagged items are LOW notes (an idiomatic null-default and inline layout literals that match the surrounding style), neither blocking. No HIGH duplicated-branch or parallel-pair-scaffolding violations. Generated by Claude Code |
💠 Senior PowerShell EngineerSummaryThree Findings
Detailed Notes (no change required)
Dot-Sourcing Wire-UpWIRED — no new files added; Approved VerbsPASS — VerdictAPPROVE — no critical/high issues. The MEDIUM Generated by Claude Code |
Drop the redundant () from no-arg controller members so & invokes the scriptblock directly (& $Progress.Suspend), matching the parameterized & $Progress.SetStatus 'text' form. The old & $Progress.Suspend() worked only because the members are void-returning; this removes the latent footgun flagged in PowerShell review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NKnjPmNLKwW7KiZgkoaNHa
📄 Docs CheckVerdict: CURRENT — no README edits warranted. This branch is a PowerShell-only refinement to the existing Structural checks:
README staleness:
No auto-fixes applied. Generated by Claude Code |
✅ Criteria Check — #164: Polish the unplanned-work WPF flowMapped every acceptance criterion to the branch diff ( Syntax Checks
Acceptance Criteria
Summary
Manual Verification Checklist (fresh PowerShell terminal on Windows)
Verdict✅ PASS — all 8 code-evidenced criteria are met with concrete diff references; the 2 remaining (PowerShell parse-clean + runtime behavior on Windows) require hands-on Windows verification and are deferred to the user ( 🤖 Generated with Claude Code Generated by Claude Code |
📐 AzDO Diagrams CheckVerdict: CURRENT — TriggerTRIGGERED — changed Azure DevOps source files:
Diagram Doc TouchedTOUCHED — Function / behavior coverage
Edge targets verified to exist as real nodes: az subcommand driftNo new Edits appliedNone. The diagram was already updated correctly as part of this branch; no gaps found. 🤖 Automated Generated by Claude Code |
Navigation
How it works
az-Start-UnplannedWorkruns the session, then at stop spins up a non-modal WPF progress window that narrates the at-stopaz boardschain. On the first daily-story creation it now prompts for a parent Feature and links the story under it; later firefights reuse the cached story and skip the prompt. The debrief reuses the shared timer form, re-labelled and given an "Open in Azure DevOps" button.flowchart TD Start([az-Start-UnplannedWork]):::pub Prog["New-WpfProgressWindow<br/>spinner + status line<br/>no-op stub off Windows"]:::pub Daily[Get-UnplannedWorkDailyStory] Cached{cached or existing<br/>story today?} NewStory[New-UnplannedWorkStory] Parent["Read-UnplannedParentFeature<br/>pick parent Feature"]:::pub Orphan["Resolve-AzDevOpsOrphanParent<br/>orphan-safe fallback"]:::priv Link[Invoke-AzDevOpsParentLink]:::priv Task[create + link firefight Task] Debrief[Invoke-UnplannedDebrief] Form["Show-WpfTimerDebrief<br/>drops captured-items list<br/>Open in Azure DevOps button"]:::pub Open["az-Open-WorkItemById<br/>via -OpenAction / -OpenLabel"]:::io Start --> Prog Start --> Daily Daily --> Cached Cached -- yes --> Task Cached -- no, first today --> NewStory NewStory --> Parent Parent --> Orphan Parent -.link.-> Link NewStory --> Task Task --> Debrief Debrief -- flush items, close window --> Form Form -- click --> Open Prog -. per-step status .-> Debrief classDef pub fill:#1f3a5f,stroke:#4ea3ff,color:#fff classDef priv fill:#3a3a3a,stroke:#999,color:#fff classDef io fill:#5a4a1a,stroke:#e0c060,color:#fffSummary
Four refinements to
az-Start-UnplannedWork(PowerShell/Windows-only), all gated to the unplanned call site so the shared Pomodoro timer debrief form is unchanged:New-UnplannedWorkStoryprompts for a parent Feature and links it; cached/existing stories skip the prompt; a skipped/failed pick falls back to parentless without aborting the session.Invoke-UnplannedDebriefWpfno longer passes-Items, so the redundant read-only "Captured items" list is gone (items already flush to the Task description).-OpenAction, surfacing an "Open in Azure DevOps" button that opens the just-created Task (reachable even after a failed post).New-WpfProgressWindowwraps the at-stopaz boardschain (find/create story → create Task → save items) with a per-step status line, so the user isn't staring at a frozen terminal. No-op stub off Windows, where the existingWrite-Hostlines remain the feedback.Issue
Closes #164
Changes
powcuts_by_cli/azdevops_unplanned.ps1— newRead-UnplannedParentFeature;New-UnplannedWorkStoryparent pick +Invoke-AzDevOpsParentLink;-Progressthreaded throughGet-UnplannedWorkDailyStory/Invoke-UnplannedDebrief/ the orchestrator;Invoke-UnplannedDebriefWpfdrops-Items, adds-OpenAction/-OpenLabel.powcuts_by_cli/pow_common.ps1— newNew-WpfProgressWindow(+ private no-opNew-WpfProgressController).powcuts_by_cli/pow_timer.ps1—Show-WpfTimerDebriefgains a defaulted-OpenLabelknob (timer keeps'Open work item'; unplanned passes'Open in Azure DevOps').docs/azure-devops-diagrams.md— section-11 flowchart, dependency map, and prose updated.Test Plan (Windows PowerShell — WPF, can't run in CI)
.ps1files parse cleanly ([System.Management.Automation.Language.Parser]::ParseFile(...))az boardsjobs runStart-TimerSession) is unchanged — no list change, no extra button, no spinner regression🤖 Generated with Claude Code
Generated by Claude Code