Commit graph

378 commits

Author SHA1 Message Date
Snider
cbd41e6837 feat(help): add markdown parsing and section extraction
Implements #137: markdown parsing and section extraction for help system.

- Add Topic and Section types for help content structure
- Add Frontmatter type for YAML metadata parsing
- Add ParseTopic() to parse markdown files into Topic structs
- Add ExtractFrontmatter() to extract YAML frontmatter
- Add ExtractSections() to extract headings and content
- Add GenerateID() to create URL-safe anchor IDs
- Add comprehensive tests following _Good/_Bad naming convention

This is the foundation for the display-agnostic help system (#133).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 23:14:49 +00:00
Snider
547c65f264 feat(io): Migrate filesystem access to pkg/io Medium abstraction (#172)
* feat(io): add pkg/io with symlink-safe path validation

- Add pkg/io with Medium interface for filesystem abstraction
- Add pkg/io/local with sandboxed filesystem implementation
- Add symlink-safe path validation to prevent bypass attacks
- Add sentinel errors (ErrPathTraversal, ErrSymlinkTraversal)
- Add NewSandboxed() for creating sandboxed Medium instances
- Add MockMedium for testing

Closes #169

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(io): extend Medium interface with Delete, Rename, List, Stat operations

Add missing filesystem operations to Medium interface:
- Delete(path) - removes file or empty directory
- DeleteAll(path) - removes path and contents recursively
- Rename(old, new) - moves or renames files/directories
- Exists(path) - checks if path exists
- IsDir(path) - checks if path is a directory
- List(path) - returns directory contents as []os.DirEntry
- Stat(path) - returns file info as os.FileInfo

Implements both local.Medium and MockMedium with full support.

Closes #102

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(io): MockMedium.Read returns os.ErrNotExist for consistency

Ensures os.IsNotExist(err) works with MockMedium like with real filesystem.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 22:50:55 +00:00
Snider
f47e8211fb feat(mcp): add workspace root validation to prevent path traversal (#100)
* feat(mcp): add workspace root validation to prevent path traversal

- Add workspaceRoot field to Service for restricting file operations
- Add WithWorkspaceRoot() option for configuring the workspace directory
- Add validatePath() helper to check paths are within workspace
- Apply validation to all file operation handlers
- Default to current working directory for security
- Add comprehensive tests for path validation

Closes #82

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: move CLI commands from pkg/ to internal/cmd/

- Move 18 CLI command packages to internal/cmd/ (not externally importable)
- Keep 16 library packages in pkg/ (externally importable)
- Update all import paths throughout codebase
- Cleaner separation between CLI logic and reusable libraries

CLI commands moved: ai, ci, dev, docs, doctor, gitcmd, go, monitor,
php, pkgcmd, qa, sdk, security, setup, test, updater, vm, workspace

Libraries remaining: agentic, build, cache, cli, container, devops,
errors, framework, git, i18n, io, log, mcp, process, release, repos

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(mcp): use pkg/io Medium for sandboxed file operations

Replace manual path validation with pkg/io.Medium for all file operations.
This delegates security (path traversal, symlink bypass) to the sandboxed
local.Medium implementation.

Changes:
- Add io.NewSandboxed() for creating sandboxed Medium instances
- Refactor MCP Service to use io.Medium instead of direct os.* calls
- Remove validatePath and resolvePathWithSymlinks functions
- Update tests to verify Medium-based behaviour

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: correct import path and workflow references

- Fix pkg/io/io.go import from core-gui to core
- Update CI workflows to use internal/cmd/updater path

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(security): address CodeRabbit review issues for path validation

- pkg/io/local: add symlink resolution and boundary-aware containment
  - Reject absolute paths in sandboxed Medium
  - Use filepath.EvalSymlinks to prevent symlink bypass attacks
  - Fix prefix check to prevent /tmp/root matching /tmp/root2

- pkg/mcp: fix resolvePath to validate and return errors
  - Changed resolvePath from (string) to (string, error)
  - Update deleteFile, renameFile, listDirectory, fileExists to handle errors
  - Changed New() to return (*Service, error) instead of *Service
  - Properly propagate option errors instead of silently discarding

- pkg/io: wrap errors with E() helper for consistent context
  - Copy() and MockMedium.Read() now use coreerr.E()

- tests: rename to use _Good/_Bad/_Ugly suffixes per coding guidelines
  - Fix hardcoded /tmp in TestPath to use t.TempDir()
  - Add TestResolvePath_Bad_SymlinkTraversal test

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: fix gofmt formatting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: fix gofmt formatting across all files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 21:59:34 +00:00
Snider
c58bc3e344 feat(cli): add NO_COLOR environment variable support (#98)
Implement the NO_COLOR standard (https://no-color.org/) for CLI output.
When NO_COLOR is set (to any value), ANSI color codes are disabled.

Changes:
- Add init() to check NO_COLOR and TERM=dumb environment variables
- Add ColorEnabled() to query current color state
- Add SetColorEnabled() to programmatically enable/disable colors
- Modify AnsiStyle.Render() to return plain text when colors disabled
- Update UseASCII() to also disable colors (consistent with ASCII mode)
- Add comprehensive tests for color enable/disable functionality

Usage:
  NO_COLOR=1 core dev status  # Runs without color output
  TERM=dumb core dev status   # Also disables colors

Closes #87

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 16:40:03 +00:00
Snider
9b678f21a0 docs(process): add docstrings to Logger interface methods (#97)
Add missing documentation to Logger interface methods and NopLogger
implementation to satisfy 80% docstring coverage threshold.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 16:12:01 +00:00
Snider
f9ed8bab2e feat(dev): add confirmation prompt to apply command (#96)
Add safety confirmation prompt to `core dev apply` before executing
shell commands. This prevents accidental execution of destructive
commands pasted from untrusted sources or generated by AI agents.

Changes:
- Add --yes/-y flag to skip confirmation prompt
- Show warning and require explicit "y" confirmation before execution
- Allow --dry-run to bypass confirmation (no actual execution)
- Use existing cli.Confirm with Required() for mandatory response

Usage:
  core dev apply --command="rm -rf ."     # Prompts for confirmation
  core dev apply --command="..." --yes    # Skips confirmation
  core dev apply --command="..." --dry-run # No execution, no prompt

Closes #81

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 16:06:04 +00:00
Snider
04e70d9cda fix(core): add thread-safety to global Core instance (#95)
Protect the global `instance` variable with sync.RWMutex to prevent
data races when SetInstance/App() are called concurrently (especially
in tests).

Changes:
- Add instanceMu mutex to protect instance variable
- Update App() to use RLock for reading
- Update SetInstance() to use Lock for writing
- Add GetInstance() for non-panicking access
- Add ClearInstance() for test cleanup
- Update tests to use new thread-safe functions
- Add concurrent access test with race detector

Closes #84

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 16:03:44 +00:00
Snider
f2bbb71875 fix(agentic): use context.TODO instead of nil Context (#94)
Replace nil Context parameters with context.TODO() to comply with
staticcheck SA1012: "do not pass a nil Context, even if a function
permits it; pass context.TODO if you are unsure about which Context
to use"

Closes #78

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 15:58:26 +00:00
Snider
efd952dab6 feat(process): add Logger interface for exec wrapper (#93)
- Define Logger interface with Debug and Error methods
- Add NopLogger as default (no-op implementation)
- Add SetDefaultLogger/DefaultLogger for package-level config
- Add WithLogger method for per-command logger injection
- Log commands at DEBUG level before execution
- Log failures at ERROR level with error details
- Add comprehensive tests for logger functionality

Compatible with pkg/log.Logger and other structured loggers.

Closes #90

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 15:55:26 +00:00
Snider
e8f479f65c feat(process): add standardized exec wrapper (#91)
* feat(process): add standardized exec wrapper

- Adds pkg/process/exec/exec.go with context and logging support
- Implements Command, Run, Output, CombinedOutput, RunQuiet helpers
- Enforces context usage (falls back to background if nil, pending strict enforcement)
- Standardizes error wrapping for exec.ExitError

* fix(process): remove unused cli import

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style(process): fix trailing whitespace

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:39:44 +00:00
Snider
c36e4f72a3 style(update): fix trailing newline in cmd.go
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:46:17 +00:00
Snider
7789f422e0 fix(update): use build tags for platform-specific watcher code
Split platform-specific functions into separate files:
- cmd_unix.go: Unix implementation using Setpgid and signal 0
- cmd_windows.go: Windows implementation using CREATE_NEW_PROCESS_GROUP
  and OpenProcess for PID checking

Fixes Windows cross-compilation error where Setpgid field doesn't exist.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:19:32 +00:00
Snider
e4b47f9d29 refactor(update): use watcher pattern for auto-restart
Replace the direct exec-based restart with a spawned watcher process:
- Add hidden --watch-pid flag for internal use
- spawnWatcher() spawns background process before update
- watchAndRestart() polls for parent death, then restarts binary
- Uses signal 0 on Unix to check if process is alive
- Windows fallback spawns new process and exits

This approach is safer because:
- Parent exits cleanly before restart (no file locking issues)
- Watcher is detached from parent process group
- Works reliably across platforms

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:14:51 +00:00
Snider
0ef41ef642 feat(update): auto-restart after update to load new version
Uses syscall.Exec on Unix to replace the current process with the
updated binary, running --version to confirm. On Windows, falls back
to a message asking to restart manually.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:09:32 +00:00
Snider
03727e18bb feat(cli): add core update command for self-updating
- `core update` - Update to latest stable release
- `core update check` - Check for updates without applying
- `core update --channel=dev` - Update to latest dev build
- `core update --force` - Force update even if already on latest

Uses the existing updater package with GitHub releases support.
Automatically detects platform (OS/arch) and downloads correct binary.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:06:49 +00:00
Snider
3423e48682 fix(test): use manual cleanup for TestDevOps_Boot_Good_Success
The test was flaky because t.TempDir() fails cleanup when files are
added asynchronously by the container manager. Using os.MkdirTemp with
manual os.RemoveAll cleanup handles this gracefully.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:55:10 +00:00
Snider
c409f25de4 ci: simplify to single QA job (Dev Release handles multi-target builds) 2026-02-01 11:47:57 +00:00
Snider
74cc00ec24 ci: skip lint until golangci-lint supports Go 1.25 2026-02-01 11:38:54 +00:00
Snider
a422c18c0e feat(ci): add core setup ci and dogfood CLI in workflows
- Add `core setup ci` command for generating installation scripts
  - Supports bash, powershell, and GitHub Actions YAML output
  - Configurable via .core/ci.yaml
  - Auto-detects platform and uses Homebrew/Scoop/direct download

- Update all GitHub workflows to use global `core` binary:
  - ci.yml: Uses `core go qa` for all quality checks
  - coverage.yml: Uses `core go cov` for coverage
  - release.yml: Uses `core build --ci` for cross-compilation
  - dev-release.yml: Uses `core build --ci` for all targets

- Add .core/ci.yaml with default configuration

This ensures the CLI dogfoods itself across all CI operations,
validating the framework that the Web3 ecosystem builds from.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:36:59 +00:00
Snider
aeb852c5e5 ci: use core CLI for QA and standardize workflows
- ci.yml: Download latest dev release, run `core go qa`, build matrix
- release.yml: Use go-version-file, consistent artifact handling
- dev-release.yml: Add checksums, cleaner version string
- coverage.yml: Standardize setup-go version, add CLI verification

All workflows now use:
- go-version-file for consistent Go version
- upload-artifact@v4 / download-artifact@v4
- Proper version injection via ldflags

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:05:26 +00:00
Snider
1afa35d3c6 feat(build): inject version from git tag at build time
- Taskfile now injects AppVersion via ldflags
- Shows git tag (e.g., v1.0.0) when built from a tag
- Shows "dev" when built from non-tagged commit
- Add dist/ to .gitignore for build artifacts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:55:57 +00:00
Snider
0072650fd9 feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default

- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(build): minimal output by default, add missing i18n

- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add root-level `core git` command

- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(qa): add docblock coverage checking

Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)

The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review feedback

- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add docstrings for 100% coverage

Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: standardize line endings to LF

Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review feedback

- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review feedback (round 2)

- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
Snider
fa8e5334a5 feat(i18n): expand CLI translations and fix noun form detection
- Fix loader to properly detect noun form objects by checking for
  one/other structure before processing, preventing false positives
  on objects that happen to be under gram.noun.* path
- Add comprehensive i18n strings for CLI commands including long
  descriptions, flag help text, and status labels
- Add .claude/ project settings for Claude Code integration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 07:39:49 +00:00
Snider
29683c1ce7 fix(security): resolve CodeQL and npm vulnerabilities
- Fix integer conversion in hexToRGB using 8-bit ParseUint instead of
  64-bit ParseInt to avoid potential overflow on 32-bit systems
- Update npm dependencies to fix Angular XSRF, XSS and MCP SDK vulnerabilities

Resolves 3 CodeQL alerts and 8 npm high severity vulnerabilities.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 07:04:04 +00:00
Snider
d52f1080a5 docs: add CI and coverage badges to README
Added badges for:
- Codecov coverage
- Go Test Coverage workflow status
- Code Scanning workflow status
- Go version
- EUPL-1.2 license

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:59:00 +00:00
Snider
ebc67ed727 fix(devops): fix flaky test cleanup in TestDevOps_Boot_Good_FreshFlag
Use os.MkdirTemp with explicit cleanup instead of t.TempDir() to avoid
cleanup errors when subdirectories are created during test execution.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:53:15 +00:00
Snider
13f7e29894 chore(deps): update GitHub Actions and Go modules (#73)
GitHub Actions:
- actions/checkout v4 → v6
- actions/upload-artifact v4 → v6
- github/codeql-action v3 → v4
- arduino/setup-task v1 → v2

Go modules:
- golang.org/x/mod v0.31.0 → v0.32.0
- golang.org/x/exp updated
- aead.dev/minisign v0.2.0 → v0.3.0
- github.com/go-openapi/jsonpointer v0.21.0 → v0.22.4
- github.com/go-openapi/swag v0.23.0 → v0.25.4
- github.com/google/jsonschema-go v0.3.0 → v0.4.2
- github.com/mailru/easyjson v0.9.0 → v0.9.1
- github.com/tidwall/match v1.1.1 → v1.2.0
- github.com/woodsbury/decimal128 v1.3.0 → v1.4.0

Also fixed fmt.Errorf with non-constant format string in security package.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:46:54 +00:00
Snider
ba88455efb feat(php): add --json and --sarif flags to QA commands (#69)
* feat(github): add issue templates and auto-labeler

- Add bug_report.yml and feature_request.yml templates
- Add config.yml for issue creation options
- Add auto-label.yml workflow to label issues based on content

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(php): add --json and --sarif flags to QA commands

Adds machine-readable output support to PHP quality assurance commands:

- test: --json flag for JUnit XML output
- fmt: --json flag for JSON formatted output from Pint
- stan: --json and --sarif flags for PHPStan output
- psalm: --json and --sarif flags for Psalm output
- qa: --json flag for JSON summary output

SARIF output enables integration with GitHub Security tab for
static analysis results.

Closes #51

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(php): address CodeRabbit review feedback

- Guard progress messages when JSON/SARIF output is enabled
- Guard success messages when JSON/SARIF output is enabled
- Guard QA results display when JSON output is enabled
- Rename misleading JSON field to JUnit in TestOptions (outputs JUnit XML)
- Add mutual exclusion validation for --json and --sarif flags
- Remove empty conditional block in auto-label workflow
- Add i18n translation for json_sarif_exclusive error

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(php): additional CodeRabbit fixes

- Rename test --json flag to --junit (outputs JUnit XML, not JSON)
- Add actual JSON marshaling for QA command JSON output
- Add JSON tags to QARunResult and QACheckRunResult structs
- Add i18n translation for junit flag

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:32:35 +00:00
Snider
af9fd33b2a fix(release): add proper release workflow with version injection
- Make AppVersion injectable via ldflags at build time
- Replace GoReleaser with simple GitHub Actions workflow
- Build for linux/darwin/windows on amd64/arm64
- Generate checksums.txt for integrity verification
- Inject version from git tag into binary

Fixes #37

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:21:29 +00:00
Snider
d731afc298 feat(dev): add safe git operations for AI agents (#71)
* feat(dev): add safe git operations for AI agents

Adds agent-safe commands to prevent common git mistakes:

- `core dev sync <file> --to="pattern"`: Sync files across repos
  - Auto-pulls before copying (safe sync)
  - Optional commit with --message
  - Optional push with --push
  - Dry-run mode with --dry-run

- `core dev apply --command="..."`: Run commands across repos
  - Execute shell commands in each repo
  - Execute scripts with --script
  - Optional commit/push after changes
  - Continue on error with --continue
  - Filter repos with --repos

Safety features:
- Never force push
- Auto-pull before push on rejection
- Report failures without stopping other repos
- Dry-run support for previewing changes

Closes #53

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(dev): address CodeRabbit review feedback

- Use errors.E() for consistent error handling in cmd_apply.go and cmd_file_sync.go
- Add path traversal validation to reject ".." in source paths
- Execute scripts directly to honor shebangs (not via sh)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:11:24 +00:00
Snider
d3031d6b73 feat(php): add CI/CD pipeline command (#72)
* feat(php): add CI/CD pipeline command

Adds `core php ci` command for CI/CD integration:

- Runs all QA checks in optimal order (test, stan, psalm, fmt, audit, security)
- Generates combined reports in multiple formats:
  - JSON (--json) for machine consumption
  - Markdown summary (--summary) for PR comments
  - SARIF (--sarif) for static analysis tools
- Uploads SARIF to GitHub Security tab (--upload-sarif)
- Configurable failure threshold (--fail-on=critical|high|warning)

Example usage:
  core php ci                    # Run full pipeline
  core php ci --json             # Output JSON report
  core php ci --summary          # Output markdown for PR
  core php ci --sarif --upload-sarif  # Generate and upload SARIF

Closes #52

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(php): address CodeRabbit review feedback on CI command

- Remove unused --parallel flag
- Validate git SHA before SARIF upload
- Properly handle and validate SARIF generation output
- Exit with correct code when --json flag is used and pipeline fails

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:11:00 +00:00
Snider
f407d04eef feat(security): add core security command for vulnerability alerts (#66)
* feat(security): add core security command for vulnerability alerts

Adds `core security` command area to expose GitHub security data:
- `core security alerts` - aggregated view of all security alerts
- `core security deps` - Dependabot vulnerability alerts with upgrade paths
- `core security scan` - CodeQL and code scanning alerts
- `core security secrets` - secret scanning alerts

Features:
- Filter by --repo, --severity (critical,high,medium,low)
- JSON output with --json for AI agent consumption
- Aggregated summary with severity breakdown
- Shows patched versions for easy upgrades

Closes #48

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(security): address CodeRabbit review feedback

- Remove unused flattened fields from DependabotAlert struct
- Add Unknown field to AlertSummary for unrecognized severities
- Add doc comments for exported Add and String methods
- Use cli.Wrap for contextual error wrapping
- Fix secret scanning summary counting after filter
- Remove unused --vulnerable flag from deps command
- Fix JSON output to only include open alerts in secrets command

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(security): handle json.MarshalIndent errors

Address CodeRabbit review feedback by properly handling errors from
json.MarshalIndent in all security subcommands instead of ignoring them.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:04:21 +00:00
Snider
a4971fe0df feat(monitor): add security findings aggregation command (#68)
* feat(monitor): add security findings aggregation command

Implements `core monitor` to aggregate security findings from GitHub:
- Code scanning alerts (Semgrep, Trivy, Gitleaks, CodeQL, etc.)
- Dependabot vulnerability alerts
- Secret scanning alerts

Features:
- Scan current repo, specific repo, or all repos via registry
- Filter by severity (--severity critical,high)
- JSON output for piping to other tools (--json)
- Grouped output by repo with severity highlighting

Closes #49

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(monitor): address CodeRabbit review feedback

- Fix DependabotAlert JSON parsing with proper nested struct for
  dependency.manifest_path field
- Remove unnecessary --jq flag from code scanning API call
- Fix truncate() to use runes for proper UTF-8 handling
- Sort repo names for deterministic output ordering
- Document hardcoded org fallback behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(monitor): improve error handling per CodeRabbit review

- Use errors.E() consistently instead of errors.Wrap()
- Pass underlying errors to errors.E() for better context
- Return errors from fetch functions instead of swallowing
- Distinguish expected conditions (feature not enabled) from real errors
- Display fetch warnings in non-JSON mode
- Continue scanning other repos even if one fails

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 05:44:46 +00:00
Snider
36dc56f789 feat(github): add complexity labels with heuristic detection
- Add complexity dropdown to feature request template
- Auto-detect complexity from dropdown selection
- Heuristic fallback based on: checklist count, code blocks,
  section headers, file references, and keywords

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 05:32:50 +00:00
Snider
1cdd050520 feat(github): add issue templates and auto-labeler
- Add bug_report.yml and feature_request.yml templates
- Add config.yml for issue creation options
- Add auto-label.yml workflow to label issues based on content

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 05:26:23 +00:00
Snider
15d803c0e7 feat(qa,dev): add issues, health, and workflow commands (#67)
- qa issues: intelligent issue triage with priority grouping
  - Groups: needs response, ready to work, blocked, needs triage
  - Flags: --mine, --triage, --blocked
  Closes #61

- qa health: aggregate CI health across all repos
  - Shows passing/failing/pending summary
  - Flag: --problems for filtering
  Closes #63

- dev workflow: CI template management
  - list: show workflows across repos
  - sync: copy workflow to repos (with --dry-run)
  Closes #54

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 05:20:46 +00:00
Snider
17ca111a1c fix(container): fix flaky test temp directory cleanup race
Use manual temp directory management with time.Sleep before cleanup
to avoid race condition where state file writes race with t.TempDir's
automatic cleanup.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:06:03 +00:00
Snider
25b73fa79e fix(sdk): run Docker containers as current user to fix CI cleanup
Docker containers were creating files as root, causing Go test cleanup
to fail with "permission denied". Now passes --user flag on Unix systems
to run containers as the current user.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:01:40 +00:00
Snider
ebbe01c427 feat(qa): add review command for PR status (#64)
* feat(qa): add qa watch command for CI monitoring (#47)

Implements `core qa watch` to monitor GitHub Actions after a push:
- Polls workflow runs for a commit until completion
- Shows live progress with pass/fail counts
- On failure, shows job name, failed step, and link to logs
- Exits with appropriate code (0 = passed, 1 = failed)

Usage:
  core qa watch              # Watch current repo's HEAD
  core qa watch --repo X     # Watch specific repo
  core qa watch --timeout 5m # Custom timeout

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(qa): address CodeRabbit feedback on watch command

- Add length check before slicing commitSha to prevent panic on short SHAs
- Count all non-success conclusions as failures (cancelled, timed_out, etc.)
- Use errors.E/Wrap pattern for consistent error handling with operation context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(qa): add context-aware commands and log parsing

- Use exec.CommandContext with timeout context for all gh invocations
  so commands are cancelled when deadline expires
- Implement fetchErrorFromLogs using 'gh run view --log-failed'
  to extract first meaningful error line from failed workflows
- Pass context through call chain for proper timeout propagation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(qa): add review command for PR status (#62)

Add `core qa review` command to show PR review status with actionable
next steps. Answers: "What do I need to do to get my PRs merged?"
and "What reviews am I blocking?"

Features:
- Shows your open PRs with merge status (CI, reviews, conflicts)
- Shows PRs where your review is requested
- Provides actionable suggestions (rebase, address feedback, etc.)
- Flags: --mine, --requested, --repo

Closes #62

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(qa): add review command for PR status (#62)

Add `core qa review` command to show PR review status with actionable
next steps. Answers: "What do I need to do to get my PRs merged?"
and "What reviews am I blocking?"

Features:
- Shows your open PRs with merge status (CI, reviews, conflicts)
- Shows PRs where your review is requested
- Provides actionable suggestions (rebase, address feedback, etc.)
- Flags: --mine, --requested, --repo

Closes #62

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(qa): address CodeRabbit feedback on review command

- Fix truncate to use runes for UTF-8 safe string slicing
- Remove unused user parameter from showMyPRs and showRequestedReviews
- Remove unused getCurrentUser function

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(qa): remove duplicate i18n block and improve error handling

- Remove duplicate cmd.qa block in en_GB.json
- Use errors.E consistently for error wrapping
- Require --repo flag when not in a git repository

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:56:48 +00:00
Snider
a0088a34a8 fix(i18n): restore missing translation keys for health command (#65)
* fix(i18n): restore missing translation keys for health command

The locale consolidation in 39de3c2 removed keys still used by
cmd_health.go. Added back:
- cmd.dev.health.* keys (long, repos, to_push, to_pull, etc.)
- common.status.* keys (dirty, clean, synced, up_to_date)
- common.flag.registry

Also fixed workspace.LoadConfig() returning default PackagesDir
when no .core/workspace.yaml exists, which was overriding repo
paths from repos.yaml.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add nil checks for workspace.LoadConfig callers

LoadConfig now returns nil when no .core/workspace.yaml exists.
Added defensive nil checks to all callers to prevent panics.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: align workspace.LoadConfig error handling

Both call sites now gracefully ignore errors and fall back to defaults,
since workspace config is optional for setup commands.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:55:01 +00:00
Snider
e813c1f07e feat(qa): add qa watch command for CI monitoring (#60)
* feat(qa): add qa watch command for CI monitoring (#47)

Implements `core qa watch` to monitor GitHub Actions after a push:
- Polls workflow runs for a commit until completion
- Shows live progress with pass/fail counts
- On failure, shows job name, failed step, and link to logs
- Exits with appropriate code (0 = passed, 1 = failed)

Usage:
  core qa watch              # Watch current repo's HEAD
  core qa watch --repo X     # Watch specific repo
  core qa watch --timeout 5m # Custom timeout

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(qa): address CodeRabbit feedback on watch command

- Add length check before slicing commitSha to prevent panic on short SHAs
- Count all non-success conclusions as failures (cancelled, timed_out, etc.)
- Use errors.E/Wrap pattern for consistent error handling with operation context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(qa): add context-aware commands and log parsing

- Use exec.CommandContext with timeout context for all gh invocations
  so commands are cancelled when deadline expires
- Implement fetchErrorFromLogs using 'gh run view --log-failed'
  to extract first meaningful error line from failed workflows
- Pass context through call chain for proper timeout propagation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:37:16 +00:00
Snider
11b47cb07f feat(setup): add github command for repo configuration (#59)
* feat(setup): add github command for repo configuration (#45)

Implements `core setup github` to configure GitHub repos with org
standards including labels, webhooks, branch protection, and security
settings. Supports dry-run mode, per-repo or all-repos operation, and
selective sync of specific settings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(setup): address CodeRabbit feedback on github command

- Sort map keys for deterministic diff output in github_diff.go
- Preserve partial results by adding changes before continue on errors
- Reject conflicting --repo and --all flags with clear error message
- Allow empty webhook URLs (skip instead of error) for optional env vars
- Add content_type comparison in webhook sync
- Add required_status_checks comparison in branch protection sync
- Add DisableDependabotSecurityUpdates for bidirectional security control

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(setup): address additional CodeRabbit feedback

- Use filepath.Join for OS-portable path construction in github_config.go
- Fix stringSliceEqual to use frequency counting for proper duplicate handling
- Simplify change accumulation with variadic append

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:37:06 +00:00
Snider
75d4057fe0 feat(workspace): implement workspace.yaml support
- Add pkg/workspace package with config and commands
- Integrate with pkg/php/cmd.go for context switching
- Refactor pkg/repos to use pkg/workspace for config
- Register workspace commands in full variant
2026-02-01 02:18:19 +00:00
Snider
10277c6094 fix(docs): respect workspace.yaml packages_dir setting (fixes #46) (#55)
* fix(docs): respect workspace.yaml packages_dir setting (fixes #46)

* fix(workspace): improve config loading logic (CR feedback)

- Expand ~ before resolving relative paths in cmd_registry
- Handle LoadWorkspaceConfig errors properly
- Update Repo.Path when PackagesDir overrides default
- Validate workspace config version
- Add unit tests for workspace config loading

* docs: add comments and increase test coverage (CR feedback)

- Add docstrings to exported functions in pkg/cli
- Add unit tests for Semantic Output (pkg/cli/output.go)
- Add unit tests for CheckBuilder (pkg/cli/check.go)
- Add unit tests for IPC Query/Perform (pkg/framework/core)

* fix(test): fix panics and failures in php package tests

- Fix panic in TestLookupLinuxKit_Bad by mocking paths
- Fix assertion errors in TestGetSSLDir_Bad and TestGetPackageInfo_Bad
- Fix formatting in test files

* fix(test): correct syntax in services_extended_test.go

* fix(ci): point coverage workflow to go.mod instead of go.work

* fix(ci): build CLI before running coverage

* fix(ci): run go generate for updater package in coverage workflow

* fix(github): allow dry-run publish without gh CLI authentication

Moves validation check after dry-run check so tests can verify dry-run behavior in CI environments.
2026-02-01 01:59:27 +00:00
Snider
b02b57e6fb fix: add Windows compatibility for process management (#58)
Add build tags to separate Unix and Windows process handling in pkg/php:

- services_unix.go: Unix-specific process group handling (Setpgid, Getpgid, Kill)
- services_windows.go: Windows-compatible alternatives using os.Signal
- services.go: Use platform-agnostic helper functions

The pkg/php package now compiles on Windows. Process termination works
via os.Interrupt/os.Kill instead of Unix signals.

Fixes #56

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 01:56:44 +00:00
Snider
0c5e0c6435 fix(vm): use double-dash flags for linuxkit build command (#57)
LinuxKit v1.8.2+ requires double-dash flags (--format, --name, etc.)
instead of single-dash flags. The old flags were being parsed incorrectly,
e.g., `-name` was interpreted as `-n` with value `ame`.

Files updated:
- pkg/build/builders/linuxkit.go
- pkg/php/container.go
- pkg/release/publishers/linuxkit.go
- pkg/release/publishers/linuxkit_test.go

Fixes #50

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 01:49:00 +00:00
Snider
cdcb489d7b refactor: migrate all pkg/* to cli abstraction
- Replaces lipgloss/fmt with cli.* functions
- Adds unit tests for new cli components
- Fixes all build errors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:54:01 +00:00
Snider
f07e5bb3ff feat(cli): add DX-focused semantic output patterns
- Check() fluent builder for check results
- Task() for task headers
- Section() for section headers
- Hint() for labelled hints
- Severity() for severity-styled output
- Result() for pass/fail results

Consuming packages now have zero display logic.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:54:01 +00:00
Snider
6ae9e6544a feat(cli): add HLCRF layout system
- Layout parser for variant strings
- Terminal renderer with support for nested layouts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:54:01 +00:00
Snider
a5b7544b6c chore: remove charmbracelet dependencies
Zero external dependencies for CLI output.
Binary size reduced.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:54:01 +00:00