8.4 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 04-input-sources | 05 | cli |
|
|
|
|
|
|
|
|
|
~3min | 2026-04-05 |
Phase 4 Plan 5: Scan Command Source Wiring Summary
Wires every Phase 4 input adapter (Dir, Git, Stdin, URL, Clipboard) through cmd/scan.go via a new selectSource dispatcher and six new CLI flags, making INPUT-01 through INPUT-05 reachable from the command line and satisfying the INPUT-06 integration requirement.
Performance
- Duration: ~3 min (135s)
- Started: 2026-04-05T12:21:08Z
- Completed: 2026-04-05T12:23:23Z
- Tasks: 1 (TDD: RED → GREEN)
- Files created: 1 (cmd/scan_sources_test.go)
- Files modified: 1 (cmd/scan.go)
Accomplishments
- Added
selectSource(args, sourceFlags) (sources.Source, error)with full dispatch logic for all five Phase 4 sources plus legacy FileSource - Added six new cobra flags:
--git,--url,--clipboard,--since,--max-file-size,--insecure - Relaxed
scanCmd.ArgsfromExactArgs(1)toMaximumNArgs(1)so--urland--clipboardcan run without a positional target - Added clear mutual-exclusion errors when
--git,--url,--clipboardare combined, and when--url/--clipboardare paired with a positional path - 13-case unit test suite covering every dispatch branch, including
--sinceparse-error path - Downstream pipeline (engine.Scan, storage.SaveFinding, output, exit codes) untouched — source selection is the only change
Example Invocations
# Directory (DirSource, default)
keyhunter scan ./pkg
# Single file (FileSource, unchanged behavior)
keyhunter scan main.go
# Git history (GitSource with optional --since)
keyhunter scan --git ./some-repo --since 2024-01-01
# Stdin (StdinSource)
echo "API_KEY=xxx" | keyhunter scan -
cat creds.env | keyhunter scan stdin
# Remote URL (URLSource, no positional)
keyhunter scan --url https://example.com/config.js
# Clipboard (ClipboardSource, no positional)
keyhunter scan --clipboard
# Exclusions forwarded to DirSource
keyhunter scan ./src --exclude "*.log" --exclude "tmp/**"
selectSource Dispatch Branches
| Input | Result |
|---|---|
--clipboard (no args) |
*sources.ClipboardSource |
--url https://... (no args) |
*sources.URLSource |
--git <path> |
*sources.GitSource |
--git <path> --since YYYY-MM-DD |
*sources.GitSource with Since set |
positional stdin or - |
*sources.StdinSource |
| positional directory | *sources.DirSource (+ excludes) |
| positional file | *sources.FileSource |
Two of {--git, --url, --clipboard} |
error: "mutually exclusive" |
--url or --clipboard + positional |
error: "does not accept a positional argument" |
| no args and no selector flag | error: "missing target" |
--since not YYYY-MM-DD |
error: "must be YYYY-MM-DD" |
--git + stdin token |
error: "cannot be combined with stdin" |
Task Commits
- Task 1 RED —
9105ca1test(04-05): add failing tests for selectSource dispatcher - Task 1 GREEN —
b151e88feat(04-05): wire all Phase 4 sources through scan command
Files Created/Modified
- Created:
cmd/scan_sources_test.go(112 lines, 13 test cases) - Modified:
cmd/scan.go(+121, -15) — added flags, selectSource helper, dispatch call site,timeimport
Test Results
Full selectSource suite under -race:
| Test | Result |
|---|---|
| TestSelectSource_Directory | PASS |
| TestSelectSource_File | PASS |
| TestSelectSource_Git | PASS |
| TestSelectSource_GitSince | PASS |
| TestSelectSource_GitSinceBadFormat | PASS |
| TestSelectSource_URL | PASS |
| TestSelectSource_URLRejectsPositional | PASS |
| TestSelectSource_Clipboard | PASS |
| TestSelectSource_ClipboardRejectsPositional | PASS |
| TestSelectSource_Stdin (stdin + -) | PASS |
| TestSelectSource_MutuallyExclusive | PASS |
| TestSelectSource_MissingTarget | PASS |
| TestSelectSource_DirForwardsExcludes | PASS |
Full repo suite: go test ./... -race -count=1 → all packages ok (cmd, engine, engine/sources, providers, storage). Phase 1-3 tests still green.
Decisions Made
- sourceFlags struct over many parameters: Keeps the test surface tiny (callers fabricate a struct literal) and makes adding future selectors (e.g.
--archive) trivial without breaking signatures. - Stat-based Dir vs File: A single positional auto-dispatches on
os.Stat().IsDir(). No new--dirflag needed — users just point at a path and it "does the right thing". --sinceparsing happens in selectSource: So the invalid-format error is unit-testable and produces a CLI-friendly message rather than a raw time.Parse error.
Deviations from Plan
None — plan executed exactly as written. RED/GREEN TDD cycle completed in one iteration with no fixes needed beyond the initial plan specification.
Issues Encountered
None.
Known Stubs
None. --max-file-size and --insecure are wired as cobra flag declarations (per plan requirement) but are not yet consumed by any source — they are forward-compatibility hooks for Phase 5+ and documented as such in the flag help text. The plan explicitly requested the flag declarations; the downstream wiring is out of scope.
User Setup Required
None.
Next Phase Readiness
- All Phase 4 input adapters are now reachable from the CLI.
keyhunter scan --helplists every new flag with descriptive help text.- Phase 5 (verification) can build on top of
scanCfg.Verifywhich was already present and remains untouched. - Future wiring of
--max-file-sizeand--insecureinto DirSource/URLSource respectively is a small follow-up (one line each).
Self-Check: PASSED
- cmd/scan.go: FOUND (modified)
- cmd/scan_sources_test.go: FOUND
- Commit
9105ca1(RED): FOUND in git log - Commit
b151e88(GREEN): FOUND in git log go build ./...: exit 0go test ./... -race -count=1: all packages okgrep -c selectSource cmd/scan.go: 4 (≥2 required)grep sources.New(Dir|Git|Stdin|URL|Clipboard)Source cmd/scan.go: 5 hitsgrep "mutually exclusive" cmd/scan.go: 1 hitgo run . scan --helplists --git, --url, --clipboard, --since, --insecure: confirmed
Phase: 04-input-sources Plan: 05 Completed: 2026-04-05