Commit graph

772 commits

Author SHA1 Message Date
Snider
a3e1de3f77 fix(updater): resolve PkgVersion duplicate declaration
Remove var PkgVersion from updater.go since go generate creates
const PkgVersion in version.go. Track version.go in git to ensure
builds work without running go generate first.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 02:18:08 +00:00
Snider
68b84445ca Merge IO batch fixes 2026-02-02 02:04:53 +00:00
Snider
6cf3e745c9 Merge IO batch fixes 2026-02-02 02:04:46 +00:00
Snider
fb0fc447ef Merge IO batch fixes 2026-02-02 02:04:36 +00:00
Snider
e6d1bd22d2 fix(io): address Copilot review feedback
- Fix MockMedium.Rename: collect keys before mutating maps during iteration
- Fix .git checks to use Exists instead of List (handles worktrees/submodules)
- Fix cmd_sync.go: use DeleteAll for recursive directory removal

Files updated:
- pkg/io/io.go: safe map iteration in Rename
- internal/cmd/setup/cmd_bootstrap.go: Exists for .git checks
- internal/cmd/setup/cmd_registry.go: Exists for .git checks
- internal/cmd/pkgcmd/cmd_install.go: Exists for .git checks
- internal/cmd/pkgcmd/cmd_manage.go: Exists for .git checks
- internal/cmd/docs/cmd_sync.go: DeleteAll for recursive delete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 02:03:47 +00:00
Snider
413c7b823a Merge IO batch 2026-02-02 01:47:54 +00:00
Snider
e52542835a Merge IO batch 2026-02-02 01:47:31 +00:00
Snider
aadd286ee7 Merge IO batch 2026-02-02 01:41:10 +00:00
Snider
fd8a4a03fc Merge Gemini's IO migration work
Combines both IO migration efforts:
- Gemini's migrations: sdk, pkgcmd, workspace, dev, docs, setup
- Extended Medium interface with Delete, DeleteAll, Rename, List, Stat, Exists, IsDir

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:38:19 +00:00
Snider
8bfb0c65ab chore(io): migrate pkg/cli/daemon.go to Medium abstraction
Replaces direct os calls with io.Local:
- os.ReadFile -> io.Local.Read
- os.WriteFile -> io.Local.Write
- os.Remove -> io.Local.Delete
- os.MkdirAll -> io.Local.EnsureDir

Closes #107

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:25:07 +00:00
Snider
8992328175 Merge io-batch to get Medium interface with Delete 2026-02-02 01:24:12 +00:00
Snider
f709b4fb81 chore(log): migrate pkg/errors imports to pkg/log
Migrates all internal packages from pkg/errors to pkg/log:
- internal/cmd/monitor
- internal/cmd/qa
- internal/cmd/dev
- pkg/agentic

Closes #130

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:19:12 +00:00
Snider
144cda8181 chore(errors): create deprecation alias pointing to pkg/log
Makes pkg/errors a thin compatibility layer that re-exports from pkg/log.
All error handling functions now have canonical implementations in pkg/log.

Migration guide in package documentation:
- errors.Error -> log.Err
- errors.E -> log.E
- errors.Code -> log.NewCode
- errors.New -> log.NewError

Fixes behavior consistency:
- E(op, msg, nil) now creates an error (for errors without cause)
- Wrap(nil, op, msg) returns nil (for conditional wrapping)
- WrapCode returns nil only when both err is nil AND code is empty

Closes #128

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:17:22 +00:00
Snider
42781f075d Merge log-batch to get error helpers for deprecation 2026-02-02 01:13:41 +00:00
Snider
8b63fa8ecc feat(log): add error creation and log-and-return helpers
Implements issues #129 and #132:

- Add Err struct with Op, Msg, Err, Code fields for structured errors
- Add E(), Wrap(), WrapCode(), NewCode() for error creation
- Add Is(), As(), NewError(), Join() as stdlib wrappers
- Add Op(), ErrCode(), Message(), Root() for introspection
- Add LogError(), LogWarn(), Must() for combined log-and-return

Closes #129
Closes #132

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:11:46 +00:00
Snider
8941fd3431 chore(io): migrate internal/cmd/setup to Medium abstraction
Migrated all direct os.* filesystem calls to use io.Local:
- cmd_repo.go: os.MkdirAll -> io.Local.EnsureDir, os.WriteFile -> io.Local.Write, os.Stat -> io.Local.IsFile
- cmd_bootstrap.go: os.MkdirAll -> io.Local.EnsureDir, os.Stat -> io.Local.IsDir/Exists, os.ReadDir -> io.Local.List
- cmd_registry.go: os.MkdirAll -> io.Local.EnsureDir, os.Stat -> io.Local.Exists
- cmd_ci.go: os.ReadFile -> io.Local.Read
- github_config.go: os.ReadFile -> io.Local.Read, os.Stat -> io.Local.Exists

Refs #116

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:01:01 +00:00
Snider
ec6eca99d8 chore(io): migrate internal/cmd/docs and internal/cmd/dev to Medium
- internal/cmd/docs: Replace os.Stat, os.ReadFile, os.WriteFile,
  os.MkdirAll, os.RemoveAll with io.Local equivalents
- internal/cmd/dev: Replace os.Stat, os.ReadFile, os.WriteFile,
  os.MkdirAll, os.ReadDir with io.Local equivalents
- Fix local.Medium to allow absolute paths when root is "/" for
  full filesystem access (io.Local use case)

Refs #113, #114

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:52:29 +00:00
Snider
3db61841bd chore(io): Migrate internal/cmd/sdk, pkgcmd, and workspace to Medium abstraction 2026-02-02 00:49:09 +00:00
Snider
b053206e95 feat(io): extend Medium interface with Delete, Rename, List, Stat operations
Adds the following methods to the Medium interface:
- Delete(path) - remove a file or empty directory
- DeleteAll(path) - recursively remove a file or directory
- Rename(old, new) - move/rename a file or directory
- List(path) - list directory entries (returns []fs.DirEntry)
- Stat(path) - get file information (returns fs.FileInfo)
- Exists(path) - check if path exists
- IsDir(path) - check if path is a directory

Implements these methods in both local.Medium (using os package)
and MockMedium (in-memory for testing). Includes FileInfo and
DirEntry types for mock implementations.

This enables migration of direct os.* calls to the Medium
abstraction for consistent path validation and testability.

Refs #101

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:37:52 +00:00
Snider
d73ed87485 chore(io): Complete migration of internal/cmd/dev/* to Medium abstraction 2026-02-02 00:34:37 +00:00
Snider
cb7bd792f0 chore(io): Migrate internal/cmd/setup/* to Medium abstraction 2026-02-02 00:33:00 +00:00
Snider
9d6ffaf219 chore(io): Migrate internal/cmd/dev/* to Medium abstraction
Fixes #114
2026-02-02 00:29:44 +00:00
Snider
aaa7739749 chore(io): Migrate internal/cmd/docs/* to Medium abstraction
Fixes #113
2026-02-02 00:26:24 +00:00
Snider
2851d772a7 feat(cli): batch implementation placeholder
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:25:27 +00:00
Snider
0d7333849c feat(log): batch implementation placeholder
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:25:14 +00:00
Snider
32a9822305 feat(errors): batch implementation placeholder
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:25:01 +00:00
Snider
954498ca82 feat(help): batch implementation placeholder
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:24:45 +00:00
Snider
ea6d045327 feat(io): batch implementation placeholder
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:24:30 +00:00
Snider
e91481c285 feat(io): Migrate pkg/mcp to use Medium abstraction
Fixes #103
2026-02-02 00:24:19 +00:00
Snider
dd9c0a8ca5 feat(mcp): batch implementation placeholder
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:24:03 +00:00
Snider
7e8ff413d0 feat(mcp): Add TCP transport
Fixes #126
2026-02-02 00:22:06 +00:00
Snider
804142320d chore: remove binary 2026-02-02 00:19:38 +00:00
Snider
f574cae2a8 feat(help): Add CLI help command
Fixes #136
2026-02-02 00:19:10 +00:00
Snider
12779ef67c feat(help): add markdown parsing and section extraction (#174)
* 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 3423e48.

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 3423e48.

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>
2026-02-02 00:07:32 +00:00
Snider
8c550d2360 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>
2026-02-01 23:33:51 +00:00
Snider
2b68a26a1b 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>
2026-02-01 23:30:30 +00:00
Snider
df7ff9f128 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 3423e48.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 23:28:54 +00:00
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
13b0efda16 feat(cli): add NO_COLOR environment variable support
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:33:45 +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
21357e1260 docs(process): add docstrings to Logger interface methods
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:09:02 +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
61bdb820e8 feat(dev): add confirmation prompt to apply command
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:03:18 +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
eefc914f52 fix(core): add thread-safety to global Core instance
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 15:58:03 +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