-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathMakefile
More file actions
431 lines (330 loc) · 16 KB
/
Copy pathMakefile
File metadata and controls
431 lines (330 loc) · 16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# ==============================================================================
# Deck Monorepo Makefile
# ==============================================================================
# Variables
PNPM := pnpm
NODE := node
GO := go
DEPLOY_LOCAL := deploy/local
DAEMON_DIR := packages/daemon
SDK_GO_ROOT := packages/client-daemon-go
SDK_GO_OUT := $(SDK_GO_ROOT)/daemon
SWAGGER_JSON_PATH := $(DAEMON_DIR)/pkg/toolbox/docs/swagger.json
OPENAPI_GENERATOR_IMAGE := openapitools/openapi-generator-cli:v7.19.0
# Pilot environment files (override via `make target KEY=value`)
PILOT_LOCAL_ENV_FILE ?= .vscode/pilot.local.env
PILOT_LOCAL_ENV_EXAMPLE_FILE ?= .vscode/pilot.local.env.example
PILOT_BRIDGE_ENV_FILE ?= apps/pilot/bridge/.env
PILOT_BRIDGE_ENV_EXAMPLE_FILE ?= apps/pilot/bridge/.env.example
# Go Build Flags & Environment
# Default to host OS/Arch, but allow overrides (e.g., make build-go GOOS=linux)
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
CGO_ENABLED ?= 0
# Extract version from package.json
VERSION := $(shell node -p "require('./package.json').version")
# Build metadata
BUILD_TIME := $(shell date -u '+%Y-%m-%d_%H:%M:%S')
GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
# Output Directory Structure: dist/$(GOOS)_$(GOARCH)/
BIN_DIR := dist
OUTPUT_DIR := $(BIN_DIR)/$(GOOS)_$(GOARCH)
# Base linker flags (strip symbols and reduce binary size)
BASE_LDFLAGS := -s -w
# Application-specific linker flags with version injection
DAEMON_LDFLAGS := -ldflags="$(BASE_LDFLAGS) -X 'github.com/cofy-x/deck/packages/daemon/internal.Version=v$(VERSION)'"
CLI_LDFLAGS := -ldflags="$(BASE_LDFLAGS) -X 'github.com/cofy-x/deck/apps/cli/internal.Version=v$(VERSION)'"
# Go Application Entrypoints
DAEMON_MAIN := packages/daemon/cmd/daemon/main.go
CLI_MAIN := apps/cli/cmd/cli/main.go
# Binary names with optional platform suffix
PROXY_BIN := proxy
DAEMON_BIN := daemon
CLI_BIN := cli
.PHONY: all help install build test lint clean \
install-ts build-ts build-landing build-landing-image \
install-go download-xterm build-go build-linux build-darwin build-darwin-amd64 \
build-windows build-all-platforms fmt-go lint-go test-go \
docker-dev-up docker-dev-down \
run-api run-dashboard run-landing \
pilot-build pilot-build-host pilot-build-server pilot-build-bridge \
pilot-test pilot-test-host pilot-test-server pilot-test-bridge \
pilot-env-init pilot-bridge-env-init \
pilot-run-server pilot-run-bridge pilot-run-host-external pilot-status \
build-cli build-cli-linux build-cli-darwin-arm64 dev-cli-mcp \
runx-check-network runx-build-base-jdk21 runx-test-base-jdk21 runx-run-base-jdk21 runx-build-all
# ------------------------------------------------------------------------------
# Default Target & Help
# ------------------------------------------------------------------------------
help: ## Show this help message
@echo "Usage: make [target]"
@echo ""
@echo "Targets:"
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}'
all: install build ## Install dependencies and build everything
# ------------------------------------------------------------------------------
# Global Lifecycle
# ------------------------------------------------------------------------------
install: install-ts install-go ## Install all dependencies (Node.js & Go)
build: build-ts build-go ## Build all applications
test: test-ts test-go ## Run all tests
lint: lint-ts lint-go ## Run linters
clean: ## Clean up build artifacts
@echo "Cleaning up..."
@rm -rf $(BIN_DIR)
@rm -rf $(DAEMON_EMBED_DIR)
@rm -rf apps/*/dist
@rm -rf packages/*/dist
@rm -rf packages/*/tsconfig.tsbuildinfo
@echo "Clean complete."
# ------------------------------------------------------------------------------
# TypeScript / Node.js Tasks
# ------------------------------------------------------------------------------
install-ts: ## Install Node.js dependencies
@echo "Installing Node.js dependencies..."
@$(PNPM) install
build-ts: ## Build all TypeScript projects
@echo "Building TypeScript projects..."
@$(PNPM) run build
build-landing: ## Build landing web app
@$(PNPM) --filter @cofy-x/deck-landing run build
build-landing-image: ## Build landing Docker image
@docker build --platform linux/amd64 -t deck/landing:latest -f docker/landing/Dockerfile .
test-ts: ## Run Vitest
@$(PNPM) run test
lint-ts: ## Run ESLint
@$(PNPM) run lint
gen-daemon-swagger: ## Generate Swagger documentation for Daemon Toolbox API
@echo "Generating Daemon Toolbox API Swagger docs..."
@cd $(DAEMON_DIR) && swag fmt && swag init \
--parseDependency \
--parseInternal \
--parseDepth 10 \
--useStructName \
-g pkg/toolbox/toolbox.go \
-o pkg/toolbox/docs
@echo "Daemon Toolbox API Swagger docs generated."
gen-swagger: gen-daemon-swagger ## Generate all Swagger documentation
@echo "All Swagger docs generated."
gen-daemon-sdk-go: gen-daemon-swagger ## Generate Go SDK for Daemon via Docker
@echo "Generating Daemon Go SDK via Docker..."
@mkdir -p $(SDK_GO_OUT)
docker run --rm -v $(PWD):/local $(OPENAPI_GENERATOR_IMAGE) generate \
-i /local/$(SWAGGER_JSON_PATH) \
-g go \
-o /local/$(SDK_GO_OUT) \
-c /local/$(SDK_GO_ROOT)/openapi-config.yaml
@echo "Go SDK generated at $(SDK_GO_OUT)"
gen-client: ## Auto-generate TypeScript clients from Go APIs
@$(NODE) scripts/generate_client.js
gen-sdk: gen-client gen-daemon-sdk-go ## Generate all SDKs (TS and Go)
# ------------------------------------------------------------------------------
# Go Tasks
# ------------------------------------------------------------------------------
install-go: download-xterm ## Download Go module dependencies
@echo "Downloading Go modules..."
@go list -f '{{.Dir}}' -m | xargs -I {} sh -c 'cd {} && $(GO) mod download'
@echo "Go modules downloaded."
download-xterm: ## Download xterm.js dependencies for daemon terminal
@echo "Downloading xterm.js files..."
@GOOS= GOARCH= $(GO) run packages/daemon/tools/xterm.go
@echo "xterm.js dependencies downloaded."
# --- Core Build Targets ---
build-computer-use: ## Build the computer-use plugin binary (Linux/AMD64)
@bash docker/plugins/computer-use/build.sh
build-daemon: download-xterm ## Build Daemon binary for the current host (or specified GOOS)
@mkdir -p $(OUTPUT_DIR)
@echo "Building Daemon binary for $(GOOS)/$(GOARCH)..."
@CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO) build $(DAEMON_LDFLAGS) -o $(OUTPUT_DIR)/$(DAEMON_BIN) $(DAEMON_MAIN)
build-daemon-linux: ## Build Daemon for Linux/AMD64
@$(MAKE) build-daemon GOOS=linux GOARCH=amd64 CGO_ENABLED=0
build-cli: ## Build CLI binary
@mkdir -p $(OUTPUT_DIR)
@echo "Building CLI binary for $(GOOS)/$(GOARCH)..."
@CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO) build $(CLI_LDFLAGS) -o $(OUTPUT_DIR)/$(CLI_BIN) $(CLI_MAIN)
build-cli-linux: ## Build CLI for Linux/AMD64
@$(MAKE) build-cli GOOS=linux GOARCH=amd64 CGO_ENABLED=0
build-cli-darwin-arm64: ## Build CLI for macOS/ARM64 (Apple Silicon)
@$(MAKE) build-cli GOOS=darwin GOARCH=arm64
dev-cli-mcp: build-cli-darwin-arm64 ## Build and test CLI with MCP Inspector
@echo "Starting MCP Inspector..."
@pnpm dlx @modelcontextprotocol/inspector ./dist/darwin_arm64/cli mcp serve
build-go: build-cli ## Build all Go binaries
@echo "Build complete. Binaries in $(OUTPUT_DIR)/"
# --- Platform Specific Shortcuts ---
build-linux: ## Build Linux/AMD64 binaries (optimized for Docker)
@$(MAKE) build-go GOOS=linux GOARCH=amd64 CGO_ENABLED=0
@$(MAKE) build-computer-use
build-darwin: ## Build macOS/ARM64 binaries (for Apple Silicon)
@$(MAKE) build-go GOOS=darwin GOARCH=arm64
build-darwin-amd64: ## Build macOS/AMD64 binaries (for Intel Macs)
@$(MAKE) build-go GOOS=darwin GOARCH=amd64
build-windows: ## Build Windows/AMD64 binaries
@$(MAKE) build-go GOOS=windows GOARCH=amd64
build-all-platforms: ## Build binaries for all common platforms
@echo "Building for all platforms..."
@$(MAKE) build-linux
@$(MAKE) build-darwin
@$(MAKE) build-darwin-amd64
@$(MAKE) build-windows
@echo "All platform builds complete. Check $(BIN_DIR)/ for outputs."
test-go: ## Run Go tests
@echo "Running Go tests..."
@go list -f '{{.Dir}}' -m | xargs -I {} sh -c 'cd {} && $(GO) test ./...'
fmt-go: ## Format Go code
@echo "Formatting Go code..."
@go list -f '{{.Dir}}' -m | xargs -I {} sh -c 'cd {} && $(GO) fmt ./...'
lint-go: ## Run golangci-lint
@if command -v golangci-lint >/dev/null; then \
echo "Running golangci-lint..."; \
go list -f '{{.Dir}}' -m | xargs -I {} sh -c 'cd {} && golangci-lint run ./...'; \
else \
echo "golangci-lint not found. Skipping."; \
fi
# ------------------------------------------------------------------------------
# Docker Tasks
# ------------------------------------------------------------------------------
docker-dev-up: ## Start the dev environment
docker-compose -p deck -f $(DEPLOY_LOCAL)/docker-compose.yaml up -d
@echo "Waiting for Redis..."
@sleep 2
@echo "Dev Environment Started (Redis, DB)."
docker-dev-down: ## Stop the dev environment
docker-compose -p deck -f $(DEPLOY_LOCAL)/docker-compose.yaml down --remove-orphans
@echo "Proxy Dev Environment Stopped."
# --- Hack Docker Desktop Build ---
build-desktop-runtime-base: ## Build the desktop runtime base image
@cd docker/desktop/runtime-base && bash build.sh
run-desktop-runtime-base: build-desktop-runtime-base ## Run the desktop runtime base image
@cd docker/desktop/runtime-base && bash run.sh
build-desktop-runtime-dev: build-desktop-runtime-base ## Build the desktop runtime dev image
@cd docker/desktop/runtime-dev && bash build.sh
run-desktop-runtime-dev: build-desktop-runtime-dev ## Run the desktop runtime dev image
@cd docker/desktop/runtime-dev && bash run.sh
build-desktop-runtime-ai: build-desktop-runtime-dev ## Build the desktop runtime ai image
@cd docker/desktop/runtime-ai && bash build.sh
run-desktop-runtime-ai: build-desktop-runtime-ai ## Run the desktop runtime ai image
@cd docker/desktop/runtime-ai && bash run.sh
build-desktop-sandbox-ai: build-desktop-runtime-ai build-computer-use build-daemon-linux build-cli-linux ## Build the desktop sandbox ai image
@bash docker/desktop/sandbox-ai/build.sh
run-desktop-sandbox-ai: build-desktop-sandbox-ai ## Run the desktop sandbox ai image
@cd docker/desktop/sandbox-ai && bash run.sh
# --- Hack Docker CLI Build ---
build-cli-runtime-base: ## Build the cli runtime base image
@bash docker/cli/runtime-base/build.sh
build-cli-runtime-ai: build-cli-runtime-base ## Build the cli runtime ai image
@bash docker/cli/runtime-ai/build.sh
build-cli-sandbox-ai: build-cli-runtime-ai build-daemon-linux build-cli-linux ## Build the cli sandbox ai image
@bash docker/cli/sandbox-ai/build.sh
run-cli-sandbox-ai: build-cli-sandbox-ai ## Run the cli sandbox ai image
@cd docker/cli/sandbox-ai && bash run.sh
# --- Hack Docker Runx Build ---
runx-check-network: ## Check network connectivity and set proxy if needed
@echo "Checking network connectivity..."
@if curl -s --connect-timeout 3 https://hub.docker.com >/dev/null 2>&1; then \
echo "✓ Direct connection to Docker Hub available"; \
elif curl -s --connect-timeout 3 -x http://127.0.0.1:7890 https://hub.docker.com >/dev/null 2>&1; then \
echo "✓ Proxy connection available at 127.0.0.1:7890"; \
echo "Setting Docker proxy environment variables..."; \
export HTTP_PROXY=http://127.0.0.1:7890; \
export HTTPS_PROXY=http://127.0.0.1:7890; \
else \
echo "⚠ Warning: Network connectivity issues detected"; \
echo " - Direct connection failed"; \
echo " - Proxy at 127.0.0.1:7890 not available"; \
echo " - Build may be slow or fail"; \
fi
runx-build-base-jdk21: ## Build runx base-jdk21 image
@echo "Building runx base-jdk21..."
@if curl -s --connect-timeout 3 https://hub.docker.com >/dev/null 2>&1; then \
cd docker/runx/base-jdk21 && bash build.sh aliyun amd64; \
elif curl -s --connect-timeout 3 -x http://127.0.0.1:7890 https://hub.docker.com >/dev/null 2>&1; then \
echo "Using proxy at 127.0.0.1:7890..."; \
cd docker/runx/base-jdk21 && \
HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 \
bash build.sh aliyun amd64; \
else \
echo "Warning: No network connectivity, attempting build anyway..."; \
cd docker/runx/base-jdk21 && bash build.sh aliyun amd64; \
fi
runx-test-base-jdk21: ## Test runx base-jdk21 image
@echo "Testing runx base-jdk21..."
@cd docker/runx/base-jdk21 && bash test.sh
runx-run-base-jdk21: ## Run runx base-jdk21 container
@cd docker/runx/base-jdk21 && bash run.sh
runx-build-all: runx-build-base-jdk21 ## Build all runx images
@echo "All runx images built successfully"
# ------------------------------------------------------------------------------
# Run Tasks
# ------------------------------------------------------------------------------
pilot-build: pilot-build-host pilot-build-server pilot-build-bridge ## Build pilot host/server/bridge (TypeScript)
pilot-build-host: ## Build pilot-host only
@$(PNPM) --filter @cofy-x/deck-pilot-host run build:tsc
pilot-build-server: ## Build pilot-server only
@$(PNPM) --filter @cofy-x/deck-pilot-server run build:tsc
pilot-build-bridge: ## Build pilot-bridge only
@$(PNPM) --filter @cofy-x/deck-pilot-bridge run build:tsc
pilot-test: ## Run pilot host/server/bridge tests
@$(MAKE) pilot-test-host
@$(MAKE) pilot-test-server
@$(MAKE) pilot-test-bridge
pilot-test-host: ## Run pilot-host tests
@$(PNPM) --filter @cofy-x/deck-pilot-host run test
pilot-test-server: ## Run pilot-server tests
@$(PNPM) --filter @cofy-x/deck-pilot-server run test
pilot-test-bridge: ## Run pilot-bridge tests
@$(PNPM) --filter @cofy-x/deck-pilot-bridge run test
pilot-env-init: ## Ensure .vscode/pilot.local.env exists (copy from example if missing)
@if [ ! -f "$(PILOT_LOCAL_ENV_FILE)" ]; then \
if [ ! -f "$(PILOT_LOCAL_ENV_EXAMPLE_FILE)" ]; then \
echo "Missing $(PILOT_LOCAL_ENV_EXAMPLE_FILE)."; \
exit 1; \
fi; \
cp "$(PILOT_LOCAL_ENV_EXAMPLE_FILE)" "$(PILOT_LOCAL_ENV_FILE)"; \
echo "Created $(PILOT_LOCAL_ENV_FILE) from example."; \
fi
pilot-bridge-env-init: ## Ensure apps/pilot/bridge/.env exists (copy from example if missing)
@if [ ! -f "$(PILOT_BRIDGE_ENV_FILE)" ]; then \
if [ ! -f "$(PILOT_BRIDGE_ENV_EXAMPLE_FILE)" ]; then \
echo "Missing $(PILOT_BRIDGE_ENV_EXAMPLE_FILE)."; \
exit 1; \
fi; \
cp "$(PILOT_BRIDGE_ENV_EXAMPLE_FILE)" "$(PILOT_BRIDGE_ENV_FILE)"; \
echo "Created $(PILOT_BRIDGE_ENV_FILE) from example."; \
fi
pilot-run-server: pilot-build-server pilot-env-init ## Run pilot-server using .vscode/pilot.local.env
@set -a; \
. "$(PILOT_LOCAL_ENV_FILE)"; \
set +a; \
$(PNPM) --filter @cofy-x/deck-pilot-server run start
pilot-run-bridge: pilot-build-bridge pilot-bridge-env-init ## Run pilot-bridge using apps/pilot/bridge/.env
@$(PNPM) --filter @cofy-x/deck-pilot-bridge run start
pilot-run-host-external: pilot-build pilot-env-init ## Run pilot-host using .vscode/pilot.local.env
@set -a; \
. "$(PILOT_LOCAL_ENV_FILE)"; \
set +a; \
$(PNPM) --filter @cofy-x/deck-pilot-host run start -- start
pilot-status: pilot-build-host pilot-env-init ## Check health from .vscode/pilot.local.env
@set -a; \
. "$(PILOT_LOCAL_ENV_FILE)"; \
set +a; \
pilot_host="$${PILOT_HOST:-127.0.0.1}"; \
$(PNPM) --filter @cofy-x/deck-pilot-host run start -- \
status \
--pilot-url http://$${pilot_host}:$${PILOT_PORT:-8787} \
--opencode-url $${PILOT_OPENCODE_URL:-http://127.0.0.1:4096} \
--bridge-url http://$${pilot_host}:$${BRIDGE_HEALTH_PORT:-3005}
run-api: ## Run NestJS API in dev mode
@cp apps/api/.env.example apps/api/.env
@$(PNPM) --filter @cofy-x/deck-api run db:push
@$(PNPM) --filter @cofy-x/deck-api run start:dev
run-dashboard: ## Run React Dashboard in dev mode
@$(PNPM) --filter @cofy-x/deck-dashboard run dev
run-landing: ## Run React Landing in dev mode
@$(PNPM) --filter @cofy-x/deck-landing run dev
# ------------------------------------------------------------------------------
# Python Tasks
# ------------------------------------------------------------------------------
dev-py:
uv sync --all-packages
uv run --package server-py python apps/server-py/hello.py