Commit graph

15 commits

Author SHA1 Message Date
Snider
b6fbb781d5 ci(workflows): use host-uk/build@dev for releases (#264)
* ci(workflows): use host-uk/build@dev for releases

- Replace manual Go bootstrap with host-uk/build@dev action
- Add matrix builds for linux/amd64, linux/arm64, darwin/universal, windows/amd64
- Update README URLs from Snider/Core to host-uk/core
- Simplify artifact handling with merge-multiple

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

* docs(mkdocs): update repo references to host-uk/core

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

* chore(coderabbit): disable auto-review, manual trigger only

Trigger with @coderabbitai review to control costs.

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

* feat(ci): implement semver release channels

- Rename dev-release.yml → alpha-release.yml
- Alpha builds: v0.0.4-alpha.{run_number} (prerelease)
- Add pr-build.yml for draft releases
- PR builds: v0.0.4-pr.{num}.bid.{id} (draft, not published)
- Add attestation permissions for SLSA compliance
- No more deleting/recreating dev tag

Versioning strategy:
- Draft: +pr.{NUM}.bid.{ID} (testable, not published)
- Alpha: -alpha.{N} (canary channel)
- Beta: -beta (quality scored)
- RC: -rc.{N} (release candidate)
- Stable: no suffix

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

* fix(ci): use build@v3 and dot notation for versions

- Switch from host-uk/build@dev to host-uk/build@v3
- Use dots instead of + for build metadata (GitHub tag compatible)
- v0.0.4.pr.{num}.bid.{id} format for PR drafts

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

* ci(workflows): update all actions to latest versions

- actions/setup-go: v5 → v6 (Go 1.25+ support)
- actions/upload-artifact: v4 → v6 (immutable artifacts)
- actions/download-artifact: v4 → v7 (attestations support)
- actions/github-script: v7 → v8 (Node 20)
- actions/checkout: standardized on v6

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

* ci: temporarily use self-hosted runners

Testing build on local runners while GitHub hosted runners are backed up.

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

* ci: fix webkit dep for Ubuntu 20.04 runners

Fall back to libwebkit2gtk-4.0-dev on older Ubuntu.

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

* test: skip unwritable dir test when running as root

Docker self-hosted runners run as root, which can write anywhere.

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

* ci: revert to ubuntu-latest runners

Self-hosted runners need environment parity work (ARM64, root user, SDK tools).
Keep self-hosted for future local-llm integration tasks.

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 08:54:24 +00:00
dependabot[bot]
95d49eb453 deps(actions): bump actions/setup-go from 5 to 6 (#268)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Snider <snider@host.uk.com>
2026-02-04 01:29:43 +00:00
dependabot[bot]
2899347aed deps(actions): bump actions/download-artifact from 4 to 7 (#267)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Snider <snider@host.uk.com>
2026-02-04 01:00:11 +00:00
Snider
46c094242e fix(release): use PowerShell for Windows zip (#276)
Git Bash doesn't have zip command. Use PowerShell's Compress-Archive.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 05:17:48 +00:00
Snider
255705874c feat(release): package binaries in archives (#275)
- Build binary as `core` (or `core.exe` on Windows)
- Package in tar.gz (unix) or zip (windows)
- Archive names: core-{os}-{arch}.tar.gz/.zip

This prepares for dogfooding: host-uk/build can download and extract
the core CLI to replace complex GitHub Actions with simple commands.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 05:12:24 +00:00
Snider
23bedb999d fix(release): use bash shell for Windows build step (#274)
PowerShell interprets '.' differently than bash. Adding shell: bash
ensures consistent behavior across all platforms.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 05:00:57 +00:00
Snider
68704af131 fix(release): correct build path to root (main.go at root, not cmd/) (#273)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:56:11 +00:00
Snider
5f696fd252 fix(release): use direct Go build instead of build action (#272)
The build action only supports wails2/cpp stacks and defaults to wails2
for unknown projects. Core is a pure Go CLI with no frontend, so it
needs direct go build.

Changes:
- Replace host-uk/build@dev with direct go build steps
- Build separate darwin/amd64 and darwin/arm64 (no universal binary)
- Set CGO_ENABLED=0 for static binaries
- Inject version via -ldflags

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:51:04 +00:00
Snider
e497ddcaf5 feat: CI improvements and release channels (#266)
* feat(help): Add CLI help command

Fixes #136

* chore: remove binary

* feat(mcp): Add TCP transport

Fixes #126

* feat(io): Migrate pkg/mcp to use Medium abstraction

Fixes #103

* feat(io): batch implementation placeholder

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

* feat(errors): batch implementation placeholder

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

* feat(log): batch implementation placeholder

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

* chore(io): Migrate internal/cmd/docs/* to Medium abstraction

Fixes #113

* chore(io): Migrate internal/cmd/dev/* to Medium abstraction

Fixes #114

* chore(io): Migrate internal/cmd/setup/* to Medium abstraction

* chore(io): Complete migration of internal/cmd/dev/* to Medium abstraction

* 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>

* chore(io): Migrate internal/cmd/sdk, pkgcmd, and workspace to Medium abstraction

* 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>

* 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>

* 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>

* 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>

* 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>

* 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>

* 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>

* style: fix formatting in internal/variants

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

* style: fix formatting across migrated files

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

* refactor(io): simplify local Medium implementation

Rewrote to match the simpler TypeScript pattern:
- path() sanitizes and returns string directly
- Each method calls path() once
- No complex symlink validation
- Less code, less attack surface

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

* fix(io): remove duplicate method declarations

Clean up the client.go file that had duplicate method declarations
from a bad cherry-pick merge. Now has 127 lines of simple, clean code.

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

* test(io): fix traversal test to match sanitization behavior

The simplified path() sanitizes .. to . without returning errors.
Update test to verify sanitization works correctly.

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

* test(mcp): update sandboxing tests for simplified Medium

The simplified io/local.Medium implementation:
- Sanitizes .. to . (no error, path is cleaned)
- Allows absolute paths through (caller validates if needed)
- Follows symlinks (no traversal blocking)

Update tests to match this simplified behavior.

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

* fix: address CodeRabbit review issues

- Fix critical sandbox escape in local.Medium.path()
  - Absolute paths now constrained to sandbox root when root != "/"
  - Only allow absolute path passthrough when root is "/"
- Fix weak test assertion in TestMust_Ugly_Panics
  - Use assert.Contains instead of weak OR condition
- Remove unused issues.json file
- Add TestPath_RootFilesystem test for absolute path handling

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

* fix(io): sandbox absolute paths under root in Medium.path

* ci(workflows): use host-uk/build@dev for releases

- Replace manual Go bootstrap with host-uk/build@dev action
- Add matrix builds for linux/amd64, linux/arm64, darwin/universal, windows/amd64
- Update README URLs from Snider/Core to host-uk/core
- Simplify artifact handling with merge-multiple

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

* fix(io): sandbox absolute paths under root in Medium.path

Security fix: Remove Windows drive root bypass and properly strip
volume names before sandboxing. Paths like C:\Windows are now
correctly sandboxed under root instead of escaping.

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:52:09 +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
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
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
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
d25bd5c5ca Add GoReleaser configuration and update Go version to 1.25
Signed-off-by: Snider <snider@lt.hn>
2025-11-04 12:00:58 +00:00