Repository navigation
[AI-613] history: explicit scope selection + --private - #58
Conversation
Designs three scope flags (--all/--org/--repo) plus interactive picker fallback, a mandatory confirmation prompt (skippable with --yes), and a --private override that post-imports PUT visibility=none for each session. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nine TDD-shaped tasks covering ImportScope type, pure parser/filter/ formatter helpers, Spectre picker wrappers, HistoryCommand pipeline integration, --private post-import visibility loop, Program.cs wiring, setup tip + help text, AOT publish check, and manual smoke. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…config load Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the bare HandleHistory call with scope resolution: parse ImportScopeFlags, detect the current repo, resolve the active profile, and pass scope/skipConfirmation/forcePrivate/activeProfile/currentRepo to HandleHistory.
Review Summary by Qodo[AI-613] Add explicit scope selection and confirmation to history import
WalkthroughsDescription• Add explicit scope selection for kapacitor history with --all, --org, --repo <owner/name>, and --repo . flags • Implement interactive Spectre picker when no scope flag on TTY; mandatory confirmation prompt before import • Add --private flag to mark imported sessions as owner-only via post-import visibility API calls • Enforce non-interactive mode requires both scope flag and --yes to prevent accidental uploads Diagramflowchart LR
A["CLI args"] -->|ParseFlags| B["ImportScopeArgs"]
B -->|Resolve| C["ImportScope<br/>All/Org/Repo"]
C -->|null scope| D["HistoryScopePrompt<br/>RunPicker"]
D --> E["Resolved Scope"]
E -->|Apply| F["HistoryScopeFilter"]
F --> G["Filtered transcripts"]
G -->|PromptConfirm| H["Confirmation summary"]
H -->|User confirms| I["Import sessions"]
I -->|forcePrivate| J["SetVisibilityNone<br/>POST loop"]
J --> K["Complete"]
File Changes1. src/kapacitor/Commands/ImportScope.cs
|
Code Review by Qodo
1.
|
RunPicker prints the specific reason (default profile / no repos detected) before returning null. The trailing "Scope selection cancelled." in HandleHistory obscured that real reason and was misleading — Spectre's SelectionPrompt has no graceful cancel path today, so a null return is always an error state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both tests captured progress via `new Progress<T>(events.Add)` and then slept `Task.Delay(50)` hoping the SynchronizationContext-marshalled callbacks had landed. On Linux CI the window was occasionally tight and the assertions raced ahead of the callbacks. Replace with a synchronous IProgress<T> that appends in the calling thread — events are guaranteed to be in the list by the time the awaited Import* call returns. Sleeps removed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: update history command for explicit scope selection Aligns README with PR #58 (AI-613): quick-start uses --org, and the CLI reference documents the required scope flags, picker fallback, confirmation prompt, --yes, --private, and the non-interactive scope+--yes requirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: clarify --org and --repo . scope semantics Addresses Qodo review findings on #60: - --org doesn't look up org metadata; it uses the active profile *name* literally as the GitHub org login. Works after `kapacitor setup` (which names the profile after the picked tenant), errors on `default`, and matches zero sessions for arbitrarily-named profiles like `work`/`oss`. README now spells this out and points users to --repo <owner/name> as the fallback. - --repo . requires the cwd to be in a git repo with an origin remote. Inline comment updated to call that out. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: use generic owner/repo placeholder in --repo examples Avoid leaking a specific org into the public README examples. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Replaces the default-import behaviour of
kapacitor historywith an explicit scope choice and a mandatory confirmation prompt, so users can't accidentally upload sessions from personal/private repos.--all,--org,--repo <owner/name>,--repo .(current cwd's repo). Mutually exclusive.--yes/-y.--private: after import,PUT /api/sessions/{id}/visibility {"visibility":"none"}for every session imported in this run.--yes— missing either errors with exit 1.--cwd,--session,--min-lines,--since, and theexcluded_reposprofile setting continue to work and compose as additional filters on top of the new scope step.Setup gains a one-line tip after completion:
Optional: import past sessions with kapacitor history --org. Help text is updated to document every flag and the picker fallback.Migration
CI/scripts currently calling
kapacitor historywithout a flag on non-TTY will start erroring. Pass--all --yesfor the prior behaviour. This is intentional — AI-613 is specifically about eliminating accidental uploads, and a silent default in automation can drift over time.Test plan
ImportScopeArgsTests(parser + resolver, 15 tests),HistoryScopeFilterTests(5 tests),HistoryScopePromptTests(formatter + repo-choices, 7 tests). All 528 unit tests pass.HistoryPrivateImportTests(WireMock — verifies one PUT per session id, request body{"visibility":"none"}, and that one 500 doesn't abort the loop). All 6 integration tests pass.kapacitor history(picker path; pick each of the three options; verify confirmation; answer N cancels with exit 0)kapacitor history --all --yes(no picker, no prompt, immediate import)KAPACITOR_PROFILE=default kapacitor history --org(errors with "tenant-bound profile")kapacitor history --repo . --yesinside a git repo (only this repo's sessions match)cd /tmp && kapacitor history --repo .(errors with "not a git repo")kapacitor history --repo EventStore/kapacitor --yes --private(summary showsvisibility: private (--private); imported sessions showvisibility: noneon the server)kapacitor history < /dev/null(errors "--all, --org, or --repo")kapacitor history --all < /dev/null(errors "--yes is required")kapacitor history --all --org --yes(errors "mutually exclusive")Spec:
docs/superpowers/specs/2026-05-13-ai-613-history-import-scope-design.mdPlan:
docs/superpowers/plans/2026-05-13-ai-613-history-import-scope.mdCloses AI-613.
🤖 Generated with Claude Code