* chore(io): migrate pkg/devops to Medium abstraction
This commit migrates the pkg/devops package to use the io.Medium abstraction instead of direct calls to io.Local or the os package.
Changes:
- Updated DevOps, ImageManager, and Manifest structs to hold an io.Medium.
- Updated New, NewImageManager, and LoadConfig to accept an io.Medium.
- Updated ImageSource interface and its implementations (GitHubSource, CDNSource) to accept io.Medium in Download method.
- Refactored internal helper functions (hasFile, hasPackageScript, etc.) to use io.Medium.
- Updated all unit tests and CLI entry points to pass the appropriate io.Medium.
This migration improves the testability and flexibility of the devops package by allowing for different storage backends.
* chore(io): migrate pkg/devops to Medium abstraction
This commit completes the migration of the pkg/devops package to the io.Medium abstraction.
Changes:
- Refactored DevOps, ImageManager, and Manifest structs to use io.Medium for storage operations.
- Updated New, NewImageManager, and LoadConfig to accept an io.Medium.
- Updated ImageSource interface and its implementations (GitHubSource, CDNSource) to accept io.Medium in Download method.
- Refactored internal helper functions (hasFile, hasPackageScript, etc.) to use io.Medium.
- Updated all unit tests and CLI entry points to pass the appropriate io.Medium.
- Fixed formatting issues in test files.
This migration enables easier testing and supports alternative storage backends.
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes#107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes#104, closes#106, closes#108, closes#111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes#105, closes#107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs(audit): add dependency security audit report
Complete security audit of all project dependencies:
- Run govulncheck: No vulnerabilities found
- Run go mod verify: All modules verified
- Document 15 direct dependencies and 161 indirect
- Assess supply chain risks: Low risk overall
- Verify lock files are committed with integrity hashes
- Provide CI integration recommendations
Closes#185
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ci): build core CLI from source instead of downloading release
The workflows were trying to download from a non-existent release URL.
Now builds the CLI directly using `go build` with version injection.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: trigger CI with updated workflow
* chore(ci): add workflow_dispatch trigger for manual runs
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* 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>
* fix(test): use manual cleanup for TestDevOps_Boot_Good_FreshWithNoExisting
Fixes flaky test that fails with "TempDir RemoveAll cleanup: directory
not empty" by using os.MkdirTemp with t.Cleanup instead of t.TempDir().
This is the same fix applied to TestDevOps_Boot_Good_Success in 8effbda.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(help): address CodeRabbit review feedback
- Add CRLF line ending support to frontmatter regex
- Add empty frontmatter block support
- Use filepath.Base/Ext for cross-platform path handling
- Add tests for CRLF and empty frontmatter cases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(help): add full-text search functionality (#175)
* fix(test): use manual cleanup for TestDevOps_Boot_Good_FreshWithNoExisting
Fixes flaky test that fails with "TempDir RemoveAll cleanup: directory
not empty" by using os.MkdirTemp with t.Cleanup instead of t.TempDir().
This is the same fix applied to TestDevOps_Boot_Good_Success in 8effbda.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(help): add full-text search functionality
Implements #139: full-text search for help topics.
- Add searchIndex with inverted index for fast lookups
- Add tokenize() for case-insensitive word extraction
- Add Search() with relevance ranking:
- Exact word matches score 1.0
- Prefix matches score 0.5
- Title matches get 2.0 boost
- Add snippet extraction for search result context
- Add section-level matching for precise results
- Add comprehensive tests following _Good/_Bad naming
Search features:
- Case-insensitive matching
- Partial word matching (prefix)
- Title boost (matches in title rank higher)
- Section-level results
- Snippet extraction with context
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(help): address CodeRabbit review feedback
- Add CRLF line ending support to frontmatter regex
- Add empty frontmatter block support
- Use filepath.Base/Ext for cross-platform path handling
- Add tests for CRLF and empty frontmatter cases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(help): use rune-based slicing for UTF-8 safe snippets
Address CodeRabbit feedback: byte-based slicing can corrupt multi-byte
UTF-8 characters. Now uses rune-based indexing for snippet extraction.
- Convert content to []rune before slicing
- Convert byte position to rune position for match location
- Add UTF-8 validation tests with Japanese text
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(help): use correct string for byte-to-rune conversion in extractSnippet
strings.ToLower can change byte lengths for certain Unicode characters
(e.g., K U+212A 3 bytes → k 1 byte). Since matchPos is a byte index from
strings.Index(contentLower, word), the rune conversion must also use
contentLower to maintain correct index alignment.
Fixes CodeRabbit review feedback.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
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>
* 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>
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>
- Move cmd/core/cmd/* to cmd/* (flatten directory structure)
- Update module path from github.com/host-uk/core/cmd/core to github.com/host-uk/core
- Remove go.mod files from pkg/* (single module now)
- Simplify pkg/mcp to file operations only (no GUI deps)
- GUI features (display, webview, process) stay in core-gui/pkg/mcp
- Fix import aliases (sdkpkg) for package name conflicts
- Remove old backup directory (cmdbk)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move CLI commands into subdirectories matching command hierarchy:
dev/, go/, php/, build/, ci/, sdk/, pkg/, vm/, docs/, setup/, doctor/, test/, ai/
- Create shared/ package for common styles and utilities
- Add new `core ai` root command with claude subcommand
- Update package declarations and imports across all files
- Create commands.go entry points for each package
- Remove GUI-related files (moved to core-gui repo)
This makes the filesystem structure match the CLI command structure,
improving context capture and code organization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create new pkg.go with search, install, list, update, outdated subcommands
- Remove separate search.go and install.go files
- Update root.go to use AddPkgCommands instead of individual commands
- Update skill documentation with pkg commands in quick reference, decision tree, and common mistakes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Starts Claude in immutable dev environment with auth forwarding.
Auto-boots VM, mounts project, forwards credentials.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Mounts project via SSHFS and runs auto-detected dev server.
Supports Laravel, Node.js, PHP, Go, Python projects.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Auto-detects test framework from project files.
Supports .core/test.yaml for custom configuration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Connects to dev VM via SSH (default) or serial console (--console).
Supports SSH agent forwarding for credential access.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Manages dev VM lifecycle using LinuxKitManager.
Supports fresh boot, status checking, graceful stop.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Manages image downloads, manifest tracking, and update checking.
Tries sources in priority order (GitHub, CDN).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Loads ~/.core/config.yaml with image source preferences.
Defaults to auto-detection with host-uk/core-images.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>