Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,10 @@ jobs:
coverage=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | tr -d '%' | tail -1)
echo "Coverage: ${coverage}%"
echo "COVERAGE=${coverage}" >> "$GITHUB_ENV"
- name: Coverage threshold (minimum 60%)
- name: Coverage threshold (minimum 65%)
run: |
if (( $(echo "${COVERAGE} < 60" | bc -l) )); then
echo "::error::Coverage ${COVERAGE}% is below minimum 60%"
if (( $(echo "${COVERAGE} < 65" | bc -l) )); then
echo "::error::Coverage ${COVERAGE}% is below minimum 65%"
exit 1
fi
- name: Upload coverage
Expand Down Expand Up @@ -372,6 +372,30 @@ jobs:
npm install -g markdownlint-cli2
markdownlint-cli2 '**/*.md'

# -------------------------------------------------------------------------
# 9. API reference generation — build HTML docs from the OpenAPI spec.
# -------------------------------------------------------------------------
api-reference:
name: api reference
runs-on: ubuntu-latest
needs: [vet]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Validate OpenAPI spec
run: |
npm install -g @redocly/cli
redocly lint api/openapi.yaml
- name: Generate API reference (HTML)
run: |
npm install -g redoc-cli
redoc-cli bundle api/openapi.yaml -o api/reference.html
- name: Upload API reference artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: api-reference
path: api/reference.html
retention-days: 30

# -------------------------------------------------------------------------
# Dead code detection.
# -------------------------------------------------------------------------
Expand Down Expand Up @@ -406,6 +430,7 @@ jobs:
echo '```'
} >>"$GITHUB_STEP_SUMMARY"


# -------------------------------------------------------------------------
# Duplication detection — jscpd.
# -------------------------------------------------------------------------
Expand Down
62 changes: 62 additions & 0 deletions Dockerfile.daemon
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Dockerfile for the Hawk daemon (background HTTP server).
# The binary is identical to the CLI image — this Dockerfile just sets the
# daemon as the default entrypoint and exposes the daemon port.
#
# Build: docker build -f Dockerfile.daemon -t hawk-daemon .
# Run: docker run -p 4590:4590 -e HAWK_DAEMON_API_KEY=... hawk-daemon
FROM golang:1.26.5-alpine AS builder

RUN apk upgrade --no-cache && \
apk add --no-cache git ca-certificates tzdata

WORKDIR /build

ENV GOPRIVATE=github.com/GrayCodeAI/* \
GONOSUMDB=github.com/GrayCodeAI/* \
GONOSUMCHECK=1

ARG VERSION=dev
ARG COMMIT=none
ARG BUILD_DATE=unknown

COPY . .

RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
rm -f go.work go.work.sum && \
{ echo "go 1.26.5"; echo; echo "use ."; echo; echo "replace ("; \
for repo in hawk-core-contracts eyrie inspect sight tok trace yaad; do \
echo " github.com/GrayCodeAI/${repo} => ./external/${repo}"; \
done; echo ")"; } > go.work && \
CGO_ENABLED=0 GOOS=linux go build -trimpath \
-ldflags="-s -w \
-X main.Version=${VERSION} \
-X main.Commit=${COMMIT} \
-X main.BuildDate=${BUILD_DATE}" \
-o hawk ./cmd/hawk

FROM alpine:3.23.5

RUN apk upgrade --no-cache && \
apk add --no-cache ca-certificates git bash curl tini && \
adduser -D -u 1000 -h /home/hawk hawk

# Create state directory for daemon logs, API key, and audit log.
RUN mkdir -p /home/hawk/.hawk/state && \
chown -R hawk:hawk /home/hawk/.hawk

COPY --from=builder /build/hawk /usr/local/bin/hawk
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
COPY packaging/systemd/hawk-daemon.service /etc/systemd/system/hawk-daemon.service

USER hawk
WORKDIR /workspace

EXPOSE 4590

# Health check probes the daemon's health endpoint.
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -sf http://127.0.0.1:4590/v1/health || exit 1

ENTRYPOINT ["tini", "--", "hawk", "daemon", "start"]
CMD ["--host", "0.0.0.0", "--port", "4590"]
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ GORELEASER := $(GOBIN_DIR)/goreleaser
# Phony declarations (alphabetical).
# ---------------------------------------------------------------------------
.PHONY: all bench boundaries build check-replace ci clean contracts-guard ecosystem-guard eyrie-client-guard eyrie-engine-guard peer-guard internal-layers-guard package-boundaries-guard submodule-release-parity cover cover-new fmt help install lint lint-fix \
release security setup smoke path sync-external test test-10x test-live test-new test-race tidy version vet
release security setup smoke path sync-external test test-10x test-live test-new test-race tidy version vet api-docs api-validate

check-replace: ## Fail if go.mod has local replace directives (run before tagging)
@bash scripts/check-no-replace-directives.sh
Expand Down Expand Up @@ -83,6 +83,15 @@ cover: ## Generate a coverage report (coverage.out + coverage.html).
cover-new: ## Coverage report for Round 2 ecosystem packages only.
go test -cover -timeout=30s ./internal/safewrite/... ./internal/jsonc/... ./internal/providers/... ./internal/session/... ./internal/permissions/...

api-docs: ## Generate HTML API reference from OpenAPI spec.
@command -v redoc-cli >/dev/null 2>&1 || (echo "install: npm install -g redoc-cli" && exit 1)
redoc-cli bundle api/openapi.yaml -o api/reference.html
@echo "API reference generated: api/reference.html"

api-validate: ## Validate the OpenAPI spec.
@command -v @redocly/cli >/dev/null 2>&1 || (echo "install: npm install -g @redocly/cli" && exit 1)
@redocly lint api/openapi.yaml

bench: ## Run benchmarks.
go test ./... -bench=. -benchmem -count=3 -timeout=300s

Expand Down Expand Up @@ -143,7 +152,7 @@ tidy: ## Sync workspace modules and verify checksums.
# ---------------------------------------------------------------------------
# Composite gate used by CI and pre-push.
# ---------------------------------------------------------------------------
ci: tidy fmt vet boundaries lint test-race security ## Run everything CI runs.
ci: tidy fmt vet boundaries lint test-race security api-validate ## Run everything CI runs.
@echo "All CI checks passed."

smoke: ## Quick build + doctor + ecosystem verification.
Expand Down
25 changes: 25 additions & 0 deletions api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,31 @@ paths:
schema:
$ref: "#/components/schemas/Error"

/v1/metrics:
get:
tags: [stats]
summary: Daemon metrics in Prometheus exposition format
description: |
Returns daemon-level metrics (request counts, concurrency usage,
active sessions) as Prometheus text exposition format.
Use `?format=json` for JSON output.
responses:
"200":
description: Metrics output
content:
text/plain:
schema:
type: string
application/json:
schema:
type: object
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/Error"

/v1/review:
post:
tags: [review]
Expand Down
1 change: 1 addition & 0 deletions cmd/chat_tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func optionalTools() []tool.Tool {
tool.TaskGetTool{},
tool.TaskListTool{},
tool.TaskUpdateTool{},
tool.TaskRunTool{},
tool.SleepTool{},
tool.CronCreateTool{},
tool.CronDeleteTool{},
Expand Down
Loading
Loading