Repository navigation
doc: updated contributors file - #2
Merged
Merged
Conversation
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |
fredbi
added a commit
to fredbi/codescan
that referenced
this pull request
Jun 2, 2026
Add cmd/genspec-tui, a bubbletea front-end for the codescan spec generator: a source-tree explorer (left), the generated spec as JSON/YAML (right), and diagnostics (bottom). It regenerates one spec for the whole scanned scope on demand (decision C); disk is the source of truth. - Separate module (cmd/genspec-tui/go.mod) so the bubbletea/lipgloss dependency tree never pollutes the lean library; wired via a committed go.work monorepo (go.work.sum ignored). - codescan.Run wired through async tea.Cmds, with CLI flags mirroring codescan.Options: -workdir, -packages, -scan-models. Ctrl-J/Ctrl-Y toggle JSON/YAML; r rescans; scan errors render in the diagnostics pane (the pre-grammar2 v0 of that panel). - Source-tree explorer: pruned to Go-bearing paths, expand/collapse, cursor + scroll, vim/arrow navigation. - Clipboard (c): layered tool → OSC 52 → tmux-passthrough copy, ported from fredbi/git-janitor; copies the focused pane. - Disable gomod* linters (noise under a multi-module workspace). Structure (root model + enum keybindings + bordered panels) borrows from fredbi/git-janitor. The TUI's diagnostics fill in once it rebases onto the grammar2 work post-merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> fix(genspec-tui): mute scanner's global logger to protect the alt-screen codescan emits warnings (unsupported type kinds, skipped builtins, …) through the standard log package, whose default sink is stderr — which paints over bubbletea's alt-screen and corrupts the TUI. Discard it for the lifetime of the program. Reflection (see plan §9): the scanner should be silent by default and take an injected sink, and its semantic warnings are really diagnostics that belong in the OnDiagnostic stream rather than the global logger. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): live reload via debounced fsnotify watcher Watch the workdir tree and regenerate the whole-scope spec on any source change — the decision-C model, where the user typically edits in their own IDE and the TUI just reflects the result. - watcher.go: recursively watches every (non-vendored, non-hidden) directory, re-adds dirs created at runtime, and emits a coalesced signal on *.go changes or package add/remove. - model.go: a waitForFS listen loop bridges the watcher channel into bubbletea; a generation-token debounce (300ms) collapses save bursts into one rescan. Watcher is best-effort — if it fails to start, `r` (manual rescan) still works. - main.go: model.Close() tears the watcher down on exit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): header line, scan spinner + stats, mouse focus/scroll UX honing round 1 (chrome & navigation): - Header line at the top: app name, shortened workdir, active format, and spec stats (N paths / N defs). Moves the workdir out of the bottom line, which is now pure key-help (no longer conflated). [Fred's go-openapi#5] - Scan spinner: a bubbles/spinner animates while a scan is in flight (the multi-second packages.Load no longer looks frozen); the header shows "scanning"/"ready". One tick loop is kept even across rescans. [go-openapi#2] - Mouse: click a pane to focus it, wheel scrolls the pane under the cursor (tree moves its cursor; viewports scroll natively). No Tab required. [go-openapi#1] - scanResultMsg now carries path/definition counts for the header. These widgets model the eventual web app: header bar, loading indicator, click-to-focus, hover-scroll. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): in-spec search (/ , n/N) with match highlight UX honing go-openapi#3. Press / to open a search input over the status line; Enter runs a case-insensitive search of the spec pane, highlighting every match and scrolling to the first; n/N step forward/back (wrapping); Esc clears. The header shows "match i/n". Search state lives on the Spec panel and survives format toggles and rescans; Content() (clipboard) stays the raw, unhighlighted text. Lays groundwork reused by the upcoming tree↔spec linkage (scroll-to-line). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): scanner-options popup (toggle + apply-on-close) UX honing go-openapi#6, modeled on git-janitor's quick-actions overlay. Press o to open a centered modal listing the scanner's boolean options — ScanModels, SkipExtensions, SetXNullableForPointers, RefAliases, TransparentAliases, DescWithRef. Move with up/down or j/k, toggle with space/enter, esc/o to apply & close (rescans only if something changed). The model now holds the scan as a codescan.Options value; runScan takes it by value (stable snapshot per scan). Popup rows bind to the option booleans by pointer, so the modal is a thin view over the live config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): tree↔spec linkage seam + naive locator UX honing go-openapi#4 — the wiring and interface, with a placeholder behind it (real position data comes with the grammar/diagnostic rebase). - SourceLinker interface (linkage.go): maps a source Selection to candidate SpecTargets. This is the seam; the real linker will be backed by per-symbol source positions (the LSP target). Documented as such. - naiveLinker: placeholder that extracts a file's exported Go type names and anchors them in the rendered spec by string match (ambiguous and format-dependent — exactly what the position-backed linker will fix). - Spec.JumpTo(substr): scroll the spec to the first matching line without disturbing search state. - Wiring: Enter on a file in the tree jumps the spec to its definition and focuses the spec; dirs still expand/collapse. Header/status updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): describe each scanner option in the options popup The codescan option names (SkipExtensions, DescWithRef, …) are cryptic for non-maintainers (and maintainers). Each toggle row now carries a short plain-English description, aligned in a column and dimmed; the cursor row highlights label + description together. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): show scan duration in the header runScan now times the codescan.Run + render work and reports it on scanResultMsg. The header's ready indicator shows it human-readably: "ready (947ms)", "ready (3s)", "ready (1m 3s)" (minute form drops a zero-second remainder, e.g. "2m"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): read-only file viewer in the left pane The tree only browsed; there was no way to see a file's content. The left pane now has two modes — browse (tree) and view (file source): - Enter on a file opens it in a scrollable read-only viewer (title shows the path relative to workdir); Esc returns to the tree. - Linkage moves from Enter to g (jump the spec to the selection's definition), so Enter is the intuitive "open". - The viewer scrolls (wheel/jk), copies (c), and reloads from disk on each rescan so an external edit reflects here too. No editing/highlighting yet — the eventual editor is a VIM/VS-Code integration; this is the watch+view step. Help line is mode-aware. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): basic file editing (bubbles/textarea) + save-to-disk The left pane's file view is now a line-numbered editor: - Enter opens a file into a textarea (focused, capturing input); type to edit. - Ctrl-S writes the buffer to disk — the watcher then fires a rescan, so the spec reflects the edit (disk stays the source of truth, decision B). - Esc returns to the tree; Tab moves focus to the spec (editor blurs/refocuses via syncEditFocus on focus changes and clicks); Ctrl-Q quits. - A "●" marks unsaved edits in the file title; Dirty()/MarkClean() track it. - Dropped the auto-reload-on-rescan from the read-only viewer — it would clobber unsaved edits; the editor owns its buffer now. Not a full editor (no highlighting/undo beyond textarea's) — the eventual editor is a VIM/VS-Code integration; this is the "basic editing is already something" step. The line-numbered buffer also sets up line-based cross-refs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> ci: switch workflows to monorepo variants Now that the repo is a go.work monorepo (root module + cmd/genspec-tui), adopt the go-openapi monorepo CI layout (matching testify), keeping the existing pinned ci-workflows ref (v0.2.17, which already ships these): - go-test.yml → go-test-monorepo.yml (auto-detects modules, tests each via the committed go.work; cross-module coverage with -coverpkg). - bump-release.yml → bump-release-monorepo.yml (+ pull-requests: write at the job level). - tag-release.yml: release.yml gains is-monorepo: true (per-module tags + monorepo release notes). scanner/codeql/auto-merge/contributors are unchanged (not monorepo-specific). The integration suite stays green under the workspace because the scanner forces GOWORK=off internally (see 5c54824). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(scrambler): L0 minimize pass for shareable issue repros Add internal/scrambler, a pure go/ast files-in/files-out transform that minimizes a Go source tree to a small, shareable bug repro while preserving exactly what codescan reads. L0 (Minimize) prunes everything the scanner never reads: - reachability closure from the annotation roots over the type graph (rules R1-R6: signature vs whole-body walk, methods, typed consts/vars, const-block grouping for iota/reference safety); - function bodies emptied via a named-return rewrite (bodies that enclose an annotation are kept verbatim); - now-unused imports removed with a toolchain-free, removal-only AST pass (no goimports/go binary, so it stays WASM-portable). The package never imports codescan: the fidelity oracle (re-scan and compare) lives in an external test. That oracle copies the fixtures tree, applies the minimized output, re-scans, and asserts the produced spec is byte-identical to the original across petstore, classification and five enhancement fixtures. Building it surfaced three codescan comment-scanning subtleties the oracle now guards: mid-line annotations (// X swagger:route), package-doc swagger:meta in a declaration-less file, and swagger:response types declared inside a function body. Design: .claude/plans/anonymizer-repro-tool.md; build plan: .claude/plans/scrambler-L0-build.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com> ci: mono-repo config for dependabot Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
fredbi
added a commit
to fredbi/codescan
that referenced
this pull request
Jun 3, 2026
Add cmd/genspec-tui, a bubbletea front-end for the codescan spec generator: a source-tree explorer (left), the generated spec as JSON/YAML (right), and diagnostics (bottom). It regenerates one spec for the whole scanned scope on demand (decision C); disk is the source of truth. - Separate module (cmd/genspec-tui/go.mod) so the bubbletea/lipgloss dependency tree never pollutes the lean library; wired via a committed go.work monorepo (go.work.sum ignored). - codescan.Run wired through async tea.Cmds, with CLI flags mirroring codescan.Options: -workdir, -packages, -scan-models. Ctrl-J/Ctrl-Y toggle JSON/YAML; r rescans; scan errors render in the diagnostics pane (the pre-grammar2 v0 of that panel). - Source-tree explorer: pruned to Go-bearing paths, expand/collapse, cursor + scroll, vim/arrow navigation. - Clipboard (c): layered tool → OSC 52 → tmux-passthrough copy, ported from fredbi/git-janitor; copies the focused pane. - Disable gomod* linters (noise under a multi-module workspace). Structure (root model + enum keybindings + bordered panels) borrows from fredbi/git-janitor. The TUI's diagnostics fill in once it rebases onto the grammar2 work post-merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> fix(genspec-tui): mute scanner's global logger to protect the alt-screen codescan emits warnings (unsupported type kinds, skipped builtins, …) through the standard log package, whose default sink is stderr — which paints over bubbletea's alt-screen and corrupts the TUI. Discard it for the lifetime of the program. Reflection (see plan §9): the scanner should be silent by default and take an injected sink, and its semantic warnings are really diagnostics that belong in the OnDiagnostic stream rather than the global logger. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): live reload via debounced fsnotify watcher Watch the workdir tree and regenerate the whole-scope spec on any source change — the decision-C model, where the user typically edits in their own IDE and the TUI just reflects the result. - watcher.go: recursively watches every (non-vendored, non-hidden) directory, re-adds dirs created at runtime, and emits a coalesced signal on *.go changes or package add/remove. - model.go: a waitForFS listen loop bridges the watcher channel into bubbletea; a generation-token debounce (300ms) collapses save bursts into one rescan. Watcher is best-effort — if it fails to start, `r` (manual rescan) still works. - main.go: model.Close() tears the watcher down on exit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): header line, scan spinner + stats, mouse focus/scroll UX honing round 1 (chrome & navigation): - Header line at the top: app name, shortened workdir, active format, and spec stats (N paths / N defs). Moves the workdir out of the bottom line, which is now pure key-help (no longer conflated). [Fred's go-openapi#5] - Scan spinner: a bubbles/spinner animates while a scan is in flight (the multi-second packages.Load no longer looks frozen); the header shows "scanning"/"ready". One tick loop is kept even across rescans. [go-openapi#2] - Mouse: click a pane to focus it, wheel scrolls the pane under the cursor (tree moves its cursor; viewports scroll natively). No Tab required. [go-openapi#1] - scanResultMsg now carries path/definition counts for the header. These widgets model the eventual web app: header bar, loading indicator, click-to-focus, hover-scroll. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): in-spec search (/ , n/N) with match highlight UX honing go-openapi#3. Press / to open a search input over the status line; Enter runs a case-insensitive search of the spec pane, highlighting every match and scrolling to the first; n/N step forward/back (wrapping); Esc clears. The header shows "match i/n". Search state lives on the Spec panel and survives format toggles and rescans; Content() (clipboard) stays the raw, unhighlighted text. Lays groundwork reused by the upcoming tree↔spec linkage (scroll-to-line). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): scanner-options popup (toggle + apply-on-close) UX honing go-openapi#6, modeled on git-janitor's quick-actions overlay. Press o to open a centered modal listing the scanner's boolean options — ScanModels, SkipExtensions, SetXNullableForPointers, RefAliases, TransparentAliases, DescWithRef. Move with up/down or j/k, toggle with space/enter, esc/o to apply & close (rescans only if something changed). The model now holds the scan as a codescan.Options value; runScan takes it by value (stable snapshot per scan). Popup rows bind to the option booleans by pointer, so the modal is a thin view over the live config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): tree↔spec linkage seam + naive locator UX honing go-openapi#4 — the wiring and interface, with a placeholder behind it (real position data comes with the grammar/diagnostic rebase). - SourceLinker interface (linkage.go): maps a source Selection to candidate SpecTargets. This is the seam; the real linker will be backed by per-symbol source positions (the LSP target). Documented as such. - naiveLinker: placeholder that extracts a file's exported Go type names and anchors them in the rendered spec by string match (ambiguous and format-dependent — exactly what the position-backed linker will fix). - Spec.JumpTo(substr): scroll the spec to the first matching line without disturbing search state. - Wiring: Enter on a file in the tree jumps the spec to its definition and focuses the spec; dirs still expand/collapse. Header/status updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): describe each scanner option in the options popup The codescan option names (SkipExtensions, DescWithRef, …) are cryptic for non-maintainers (and maintainers). Each toggle row now carries a short plain-English description, aligned in a column and dimmed; the cursor row highlights label + description together. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): show scan duration in the header runScan now times the codescan.Run + render work and reports it on scanResultMsg. The header's ready indicator shows it human-readably: "ready (947ms)", "ready (3s)", "ready (1m 3s)" (minute form drops a zero-second remainder, e.g. "2m"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): read-only file viewer in the left pane The tree only browsed; there was no way to see a file's content. The left pane now has two modes — browse (tree) and view (file source): - Enter on a file opens it in a scrollable read-only viewer (title shows the path relative to workdir); Esc returns to the tree. - Linkage moves from Enter to g (jump the spec to the selection's definition), so Enter is the intuitive "open". - The viewer scrolls (wheel/jk), copies (c), and reloads from disk on each rescan so an external edit reflects here too. No editing/highlighting yet — the eventual editor is a VIM/VS-Code integration; this is the watch+view step. Help line is mode-aware. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): basic file editing (bubbles/textarea) + save-to-disk The left pane's file view is now a line-numbered editor: - Enter opens a file into a textarea (focused, capturing input); type to edit. - Ctrl-S writes the buffer to disk — the watcher then fires a rescan, so the spec reflects the edit (disk stays the source of truth, decision B). - Esc returns to the tree; Tab moves focus to the spec (editor blurs/refocuses via syncEditFocus on focus changes and clicks); Ctrl-Q quits. - A "●" marks unsaved edits in the file title; Dirty()/MarkClean() track it. - Dropped the auto-reload-on-rescan from the read-only viewer — it would clobber unsaved edits; the editor owns its buffer now. Not a full editor (no highlighting/undo beyond textarea's) — the eventual editor is a VIM/VS-Code integration; this is the "basic editing is already something" step. The line-numbered buffer also sets up line-based cross-refs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> ci: switch workflows to monorepo variants Now that the repo is a go.work monorepo (root module + cmd/genspec-tui), adopt the go-openapi monorepo CI layout (matching testify), keeping the existing pinned ci-workflows ref (v0.2.17, which already ships these): - go-test.yml → go-test-monorepo.yml (auto-detects modules, tests each via the committed go.work; cross-module coverage with -coverpkg). - bump-release.yml → bump-release-monorepo.yml (+ pull-requests: write at the job level). - tag-release.yml: release.yml gains is-monorepo: true (per-module tags + monorepo release notes). scanner/codeql/auto-merge/contributors are unchanged (not monorepo-specific). The integration suite stays green under the workspace because the scanner forces GOWORK=off internally (see 5c54824). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(scrambler): L0 minimize pass for shareable issue repros Add internal/scrambler, a pure go/ast files-in/files-out transform that minimizes a Go source tree to a small, shareable bug repro while preserving exactly what codescan reads. L0 (Minimize) prunes everything the scanner never reads: - reachability closure from the annotation roots over the type graph (rules R1-R6: signature vs whole-body walk, methods, typed consts/vars, const-block grouping for iota/reference safety); - function bodies emptied via a named-return rewrite (bodies that enclose an annotation are kept verbatim); - now-unused imports removed with a toolchain-free, removal-only AST pass (no goimports/go binary, so it stays WASM-portable). The package never imports codescan: the fidelity oracle (re-scan and compare) lives in an external test. That oracle copies the fixtures tree, applies the minimized output, re-scans, and asserts the produced spec is byte-identical to the original across petstore, classification and five enhancement fixtures. Building it surfaced three codescan comment-scanning subtleties the oracle now guards: mid-line annotations (// X swagger:route), package-doc swagger:meta in a declaration-less file, and swagger:response types declared inside a function body. Design: .claude/plans/anonymizer-repro-tool.md; build plan: .claude/plans/scrambler-L0-build.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com> ci: mono-repo config for dependabot Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
fredbi
added a commit
to fredbi/codescan
that referenced
this pull request
Jun 3, 2026
Add cmd/genspec-tui, a bubbletea front-end for the codescan spec generator: a source-tree explorer (left), the generated spec as JSON/YAML (right), and diagnostics (bottom). It regenerates one spec for the whole scanned scope on demand (decision C); disk is the source of truth. - Separate module (cmd/genspec-tui/go.mod) so the bubbletea/lipgloss dependency tree never pollutes the lean library; wired via a committed go.work monorepo (go.work.sum ignored). - codescan.Run wired through async tea.Cmds, with CLI flags mirroring codescan.Options: -workdir, -packages, -scan-models. Ctrl-J/Ctrl-Y toggle JSON/YAML; r rescans; scan errors render in the diagnostics pane (the pre-grammar2 v0 of that panel). - Source-tree explorer: pruned to Go-bearing paths, expand/collapse, cursor + scroll, vim/arrow navigation. - Clipboard (c): layered tool → OSC 52 → tmux-passthrough copy, ported from fredbi/git-janitor; copies the focused pane. - Disable gomod* linters (noise under a multi-module workspace). Structure (root model + enum keybindings + bordered panels) borrows from fredbi/git-janitor. The TUI's diagnostics fill in once it rebases onto the grammar2 work post-merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> fix(genspec-tui): mute scanner's global logger to protect the alt-screen codescan emits warnings (unsupported type kinds, skipped builtins, …) through the standard log package, whose default sink is stderr — which paints over bubbletea's alt-screen and corrupts the TUI. Discard it for the lifetime of the program. Reflection (see plan §9): the scanner should be silent by default and take an injected sink, and its semantic warnings are really diagnostics that belong in the OnDiagnostic stream rather than the global logger. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): live reload via debounced fsnotify watcher Watch the workdir tree and regenerate the whole-scope spec on any source change — the decision-C model, where the user typically edits in their own IDE and the TUI just reflects the result. - watcher.go: recursively watches every (non-vendored, non-hidden) directory, re-adds dirs created at runtime, and emits a coalesced signal on *.go changes or package add/remove. - model.go: a waitForFS listen loop bridges the watcher channel into bubbletea; a generation-token debounce (300ms) collapses save bursts into one rescan. Watcher is best-effort — if it fails to start, `r` (manual rescan) still works. - main.go: model.Close() tears the watcher down on exit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): header line, scan spinner + stats, mouse focus/scroll UX honing round 1 (chrome & navigation): - Header line at the top: app name, shortened workdir, active format, and spec stats (N paths / N defs). Moves the workdir out of the bottom line, which is now pure key-help (no longer conflated). [Fred's go-openapi#5] - Scan spinner: a bubbles/spinner animates while a scan is in flight (the multi-second packages.Load no longer looks frozen); the header shows "scanning"/"ready". One tick loop is kept even across rescans. [go-openapi#2] - Mouse: click a pane to focus it, wheel scrolls the pane under the cursor (tree moves its cursor; viewports scroll natively). No Tab required. [go-openapi#1] - scanResultMsg now carries path/definition counts for the header. These widgets model the eventual web app: header bar, loading indicator, click-to-focus, hover-scroll. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): in-spec search (/ , n/N) with match highlight UX honing go-openapi#3. Press / to open a search input over the status line; Enter runs a case-insensitive search of the spec pane, highlighting every match and scrolling to the first; n/N step forward/back (wrapping); Esc clears. The header shows "match i/n". Search state lives on the Spec panel and survives format toggles and rescans; Content() (clipboard) stays the raw, unhighlighted text. Lays groundwork reused by the upcoming tree↔spec linkage (scroll-to-line). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): scanner-options popup (toggle + apply-on-close) UX honing go-openapi#6, modeled on git-janitor's quick-actions overlay. Press o to open a centered modal listing the scanner's boolean options — ScanModels, SkipExtensions, SetXNullableForPointers, RefAliases, TransparentAliases, DescWithRef. Move with up/down or j/k, toggle with space/enter, esc/o to apply & close (rescans only if something changed). The model now holds the scan as a codescan.Options value; runScan takes it by value (stable snapshot per scan). Popup rows bind to the option booleans by pointer, so the modal is a thin view over the live config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): tree↔spec linkage seam + naive locator UX honing go-openapi#4 — the wiring and interface, with a placeholder behind it (real position data comes with the grammar/diagnostic rebase). - SourceLinker interface (linkage.go): maps a source Selection to candidate SpecTargets. This is the seam; the real linker will be backed by per-symbol source positions (the LSP target). Documented as such. - naiveLinker: placeholder that extracts a file's exported Go type names and anchors them in the rendered spec by string match (ambiguous and format-dependent — exactly what the position-backed linker will fix). - Spec.JumpTo(substr): scroll the spec to the first matching line without disturbing search state. - Wiring: Enter on a file in the tree jumps the spec to its definition and focuses the spec; dirs still expand/collapse. Header/status updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): describe each scanner option in the options popup The codescan option names (SkipExtensions, DescWithRef, …) are cryptic for non-maintainers (and maintainers). Each toggle row now carries a short plain-English description, aligned in a column and dimmed; the cursor row highlights label + description together. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): show scan duration in the header runScan now times the codescan.Run + render work and reports it on scanResultMsg. The header's ready indicator shows it human-readably: "ready (947ms)", "ready (3s)", "ready (1m 3s)" (minute form drops a zero-second remainder, e.g. "2m"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): read-only file viewer in the left pane The tree only browsed; there was no way to see a file's content. The left pane now has two modes — browse (tree) and view (file source): - Enter on a file opens it in a scrollable read-only viewer (title shows the path relative to workdir); Esc returns to the tree. - Linkage moves from Enter to g (jump the spec to the selection's definition), so Enter is the intuitive "open". - The viewer scrolls (wheel/jk), copies (c), and reloads from disk on each rescan so an external edit reflects here too. No editing/highlighting yet — the eventual editor is a VIM/VS-Code integration; this is the watch+view step. Help line is mode-aware. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): basic file editing (bubbles/textarea) + save-to-disk The left pane's file view is now a line-numbered editor: - Enter opens a file into a textarea (focused, capturing input); type to edit. - Ctrl-S writes the buffer to disk — the watcher then fires a rescan, so the spec reflects the edit (disk stays the source of truth, decision B). - Esc returns to the tree; Tab moves focus to the spec (editor blurs/refocuses via syncEditFocus on focus changes and clicks); Ctrl-Q quits. - A "●" marks unsaved edits in the file title; Dirty()/MarkClean() track it. - Dropped the auto-reload-on-rescan from the read-only viewer — it would clobber unsaved edits; the editor owns its buffer now. Not a full editor (no highlighting/undo beyond textarea's) — the eventual editor is a VIM/VS-Code integration; this is the "basic editing is already something" step. The line-numbered buffer also sets up line-based cross-refs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> ci: switch workflows to monorepo variants Now that the repo is a go.work monorepo (root module + cmd/genspec-tui), adopt the go-openapi monorepo CI layout (matching testify), keeping the existing pinned ci-workflows ref (v0.2.17, which already ships these): - go-test.yml → go-test-monorepo.yml (auto-detects modules, tests each via the committed go.work; cross-module coverage with -coverpkg). - bump-release.yml → bump-release-monorepo.yml (+ pull-requests: write at the job level). - tag-release.yml: release.yml gains is-monorepo: true (per-module tags + monorepo release notes). scanner/codeql/auto-merge/contributors are unchanged (not monorepo-specific). The integration suite stays green under the workspace because the scanner forces GOWORK=off internally (see 5c54824). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(scrambler): L0 minimize pass for shareable issue repros Add internal/scrambler, a pure go/ast files-in/files-out transform that minimizes a Go source tree to a small, shareable bug repro while preserving exactly what codescan reads. L0 (Minimize) prunes everything the scanner never reads: - reachability closure from the annotation roots over the type graph (rules R1-R6: signature vs whole-body walk, methods, typed consts/vars, const-block grouping for iota/reference safety); - function bodies emptied via a named-return rewrite (bodies that enclose an annotation are kept verbatim); - now-unused imports removed with a toolchain-free, removal-only AST pass (no goimports/go binary, so it stays WASM-portable). The package never imports codescan: the fidelity oracle (re-scan and compare) lives in an external test. That oracle copies the fixtures tree, applies the minimized output, re-scans, and asserts the produced spec is byte-identical to the original across petstore, classification and five enhancement fixtures. Building it surfaced three codescan comment-scanning subtleties the oracle now guards: mid-line annotations (// X swagger:route), package-doc swagger:meta in a declaration-less file, and swagger:response types declared inside a function body. Design: .claude/plans/anonymizer-repro-tool.md; build plan: .claude/plans/scrambler-L0-build.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com> ci: mono-repo config for dependabot Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
fredbi
added a commit
to fredbi/codescan
that referenced
this pull request
Jun 12, 2026
Add cmd/genspec-tui, a bubbletea front-end for the codescan spec generator: a source-tree explorer (left), the generated spec as JSON/YAML (right), and diagnostics (bottom). It regenerates one spec for the whole scanned scope on demand (decision C); disk is the source of truth. - Separate module (cmd/genspec-tui/go.mod) so the bubbletea/lipgloss dependency tree never pollutes the lean library; wired via a committed go.work monorepo (go.work.sum ignored). - codescan.Run wired through async tea.Cmds, with CLI flags mirroring codescan.Options: -workdir, -packages, -scan-models. Ctrl-J/Ctrl-Y toggle JSON/YAML; r rescans; scan errors render in the diagnostics pane (the pre-grammar2 v0 of that panel). - Source-tree explorer: pruned to Go-bearing paths, expand/collapse, cursor + scroll, vim/arrow navigation. - Clipboard (c): layered tool → OSC 52 → tmux-passthrough copy, ported from fredbi/git-janitor; copies the focused pane. - Disable gomod* linters (noise under a multi-module workspace). Structure (root model + enum keybindings + bordered panels) borrows from fredbi/git-janitor. The TUI's diagnostics fill in once it rebases onto the grammar2 work post-merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> fix(genspec-tui): mute scanner's global logger to protect the alt-screen codescan emits warnings (unsupported type kinds, skipped builtins, …) through the standard log package, whose default sink is stderr — which paints over bubbletea's alt-screen and corrupts the TUI. Discard it for the lifetime of the program. Reflection (see plan §9): the scanner should be silent by default and take an injected sink, and its semantic warnings are really diagnostics that belong in the OnDiagnostic stream rather than the global logger. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): live reload via debounced fsnotify watcher Watch the workdir tree and regenerate the whole-scope spec on any source change — the decision-C model, where the user typically edits in their own IDE and the TUI just reflects the result. - watcher.go: recursively watches every (non-vendored, non-hidden) directory, re-adds dirs created at runtime, and emits a coalesced signal on *.go changes or package add/remove. - model.go: a waitForFS listen loop bridges the watcher channel into bubbletea; a generation-token debounce (300ms) collapses save bursts into one rescan. Watcher is best-effort — if it fails to start, `r` (manual rescan) still works. - main.go: model.Close() tears the watcher down on exit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): header line, scan spinner + stats, mouse focus/scroll UX honing round 1 (chrome & navigation): - Header line at the top: app name, shortened workdir, active format, and spec stats (N paths / N defs). Moves the workdir out of the bottom line, which is now pure key-help (no longer conflated). [Fred's go-openapi#5] - Scan spinner: a bubbles/spinner animates while a scan is in flight (the multi-second packages.Load no longer looks frozen); the header shows "scanning"/"ready". One tick loop is kept even across rescans. [go-openapi#2] - Mouse: click a pane to focus it, wheel scrolls the pane under the cursor (tree moves its cursor; viewports scroll natively). No Tab required. [go-openapi#1] - scanResultMsg now carries path/definition counts for the header. These widgets model the eventual web app: header bar, loading indicator, click-to-focus, hover-scroll. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): in-spec search (/ , n/N) with match highlight UX honing go-openapi#3. Press / to open a search input over the status line; Enter runs a case-insensitive search of the spec pane, highlighting every match and scrolling to the first; n/N step forward/back (wrapping); Esc clears. The header shows "match i/n". Search state lives on the Spec panel and survives format toggles and rescans; Content() (clipboard) stays the raw, unhighlighted text. Lays groundwork reused by the upcoming tree↔spec linkage (scroll-to-line). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): scanner-options popup (toggle + apply-on-close) UX honing go-openapi#6, modeled on git-janitor's quick-actions overlay. Press o to open a centered modal listing the scanner's boolean options — ScanModels, SkipExtensions, SetXNullableForPointers, RefAliases, TransparentAliases, DescWithRef. Move with up/down or j/k, toggle with space/enter, esc/o to apply & close (rescans only if something changed). The model now holds the scan as a codescan.Options value; runScan takes it by value (stable snapshot per scan). Popup rows bind to the option booleans by pointer, so the modal is a thin view over the live config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): tree↔spec linkage seam + naive locator UX honing go-openapi#4 — the wiring and interface, with a placeholder behind it (real position data comes with the grammar/diagnostic rebase). - SourceLinker interface (linkage.go): maps a source Selection to candidate SpecTargets. This is the seam; the real linker will be backed by per-symbol source positions (the LSP target). Documented as such. - naiveLinker: placeholder that extracts a file's exported Go type names and anchors them in the rendered spec by string match (ambiguous and format-dependent — exactly what the position-backed linker will fix). - Spec.JumpTo(substr): scroll the spec to the first matching line without disturbing search state. - Wiring: Enter on a file in the tree jumps the spec to its definition and focuses the spec; dirs still expand/collapse. Header/status updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): describe each scanner option in the options popup The codescan option names (SkipExtensions, DescWithRef, …) are cryptic for non-maintainers (and maintainers). Each toggle row now carries a short plain-English description, aligned in a column and dimmed; the cursor row highlights label + description together. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): show scan duration in the header runScan now times the codescan.Run + render work and reports it on scanResultMsg. The header's ready indicator shows it human-readably: "ready (947ms)", "ready (3s)", "ready (1m 3s)" (minute form drops a zero-second remainder, e.g. "2m"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): read-only file viewer in the left pane The tree only browsed; there was no way to see a file's content. The left pane now has two modes — browse (tree) and view (file source): - Enter on a file opens it in a scrollable read-only viewer (title shows the path relative to workdir); Esc returns to the tree. - Linkage moves from Enter to g (jump the spec to the selection's definition), so Enter is the intuitive "open". - The viewer scrolls (wheel/jk), copies (c), and reloads from disk on each rescan so an external edit reflects here too. No editing/highlighting yet — the eventual editor is a VIM/VS-Code integration; this is the watch+view step. Help line is mode-aware. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(genspec-tui): basic file editing (bubbles/textarea) + save-to-disk The left pane's file view is now a line-numbered editor: - Enter opens a file into a textarea (focused, capturing input); type to edit. - Ctrl-S writes the buffer to disk — the watcher then fires a rescan, so the spec reflects the edit (disk stays the source of truth, decision B). - Esc returns to the tree; Tab moves focus to the spec (editor blurs/refocuses via syncEditFocus on focus changes and clicks); Ctrl-Q quits. - A "●" marks unsaved edits in the file title; Dirty()/MarkClean() track it. - Dropped the auto-reload-on-rescan from the read-only viewer — it would clobber unsaved edits; the editor owns its buffer now. Not a full editor (no highlighting/undo beyond textarea's) — the eventual editor is a VIM/VS-Code integration; this is the "basic editing is already something" step. The line-numbered buffer also sets up line-based cross-refs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> ci: switch workflows to monorepo variants Now that the repo is a go.work monorepo (root module + cmd/genspec-tui), adopt the go-openapi monorepo CI layout (matching testify), keeping the existing pinned ci-workflows ref (v0.2.17, which already ships these): - go-test.yml → go-test-monorepo.yml (auto-detects modules, tests each via the committed go.work; cross-module coverage with -coverpkg). - bump-release.yml → bump-release-monorepo.yml (+ pull-requests: write at the job level). - tag-release.yml: release.yml gains is-monorepo: true (per-module tags + monorepo release notes). scanner/codeql/auto-merge/contributors are unchanged (not monorepo-specific). The integration suite stays green under the workspace because the scanner forces GOWORK=off internally (see 5c54824). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> feat(scrambler): L0 minimize pass for shareable issue repros Add internal/scrambler, a pure go/ast files-in/files-out transform that minimizes a Go source tree to a small, shareable bug repro while preserving exactly what codescan reads. L0 (Minimize) prunes everything the scanner never reads: - reachability closure from the annotation roots over the type graph (rules R1-R6: signature vs whole-body walk, methods, typed consts/vars, const-block grouping for iota/reference safety); - function bodies emptied via a named-return rewrite (bodies that enclose an annotation are kept verbatim); - now-unused imports removed with a toolchain-free, removal-only AST pass (no goimports/go binary, so it stays WASM-portable). The package never imports codescan: the fidelity oracle (re-scan and compare) lives in an external test. That oracle copies the fixtures tree, applies the minimized output, re-scans, and asserts the produced spec is byte-identical to the original across petstore, classification and five enhancement fixtures. Building it surfaced three codescan comment-scanning subtleties the oracle now guards: mid-line annotations (// X swagger:route), package-doc swagger:meta in a declaration-less file, and swagger:response types declared inside a function body. Design: .claude/plans/anonymizer-repro-tool.md; build plan: .claude/plans/scrambler-L0-build.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com> ci: mono-repo config for dependabot Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated changes by create-pull-request GitHub action