Skip to main content
Version: 0.3.x

LinaPro provides a cross-platform development command set. Long-term task orchestration lives in hack/tools/linactl, implemented as a Go program; the root Makefile and make.cmd are compatibility entries that forward to the underlying linactl. This means the same commands work on macOS, Linux, and Windows, without relying on GNU Make or POSIX Shell as the only entry point.

Platform Notesโ€‹

Cross-platform native commands: Every platform can use linactl directly:

cd hack/tools/linactl
go run . help
go run . status
go run . init confirm=init
go run . dev

macOS / Linux: The root make compatibility entry remains available:

make help
make db.init confirm=init
make dev

Windows cmd.exe: Use the make.cmd wrapper at the project root. In cmd.exe, executable extensions are resolved from the current directory, so the .cmd suffix can be omitted:

make dev
make build
make help

Windows PowerShell: A current-directory prefix is required. In a default Windows environment, .\make works; to avoid ambiguity with another installed make command, use .\make.cmd explicitly:

.\make help
.\make db.init confirm=init
.\make dev

Every make <command> example below can be replaced with cd hack/tools/linactl && go run . <command> with the same argument format. The make compatibility entry forwards common variables; for linactl-specific arguments, invoke go run . <command> directly.

Command Overviewโ€‹

CommandCategoryDescription
make env.checkEnvironmentCheck local development tools, project-local frontend tools, and the PostgreSQL version
make env.setupEnvironmentInstall frontend dependencies, the Playwright Chromium browser, and required system dependencies
make devDevelopment serverRestart the backend and frontend development servers
make stopDevelopment serverStop the backend and frontend development servers
make statusDevelopment serverShow backend/frontend running status and log paths
make buildBuildFully build the frontend, plugins, and backend binary
make pack.assetsBuildPrepare frontend static assets and manifest resources for core framework embedding
make wasmBuildBuild all or selected runtime WASM plugins
make tidyBuildTidy Go module dependencies for the core framework, tools, and plugins
make imageImageBuild a production Docker image
make image.buildImagePrepare image artifacts only, without running the Docker build
make testTestRun the full E2E test suite
make test.goTestRun Go unit tests
make test.hostTestRun only the core framework-owned E2E tests
make test.pluginsTestRun the official plugins' own E2E tests
make test.scriptsTestRun unit and smoke tests for tooling scripts
make i18n.checki18nScan runtime hardcoded text and validate language pack key coverage
make plugins.initPlugin workspaceConvert official plugin submodules into ordinary directories
make plugins.installPlugin workspaceInstall configured source plugins into apps/lina-plugins
make plugins.updatePlugin workspaceUpdate source plugins under apps/lina-plugins
make plugins.statusPlugin workspaceShow source plugin workspace status
make agentsAgent resourcesCreate or remove skill, prompt, and AGENTS.md symlinks for a single agent
make db.initDatabaseInitialize database schema and seed data
make db.upgradeDatabaseReplay host framework SQL files to upgrade database schema
make db.mockDatabaseLoad demo Mock data
make release.tag.checkRelease governanceVerify the release tag matches framework.version in metadata.yaml
make helpOtherShow all available commands

Environment Managementโ€‹

make env.checkโ€‹

Checks whether the local development environment satisfies the default development workflow requirements. This command only reads tool versions and database connection information; it does not modify the workspace. Vite and Playwright are checked from the project's local dependencies, while the PostgreSQL version is queried through the database.default.link connection configured in apps/lina-core/manifest/config/config.yaml.

make env.check

The current checks are:

CheckMinimum versionDescription
Go1.25.0Go toolchain used to build the backend, tooling, and WASM plugins
Node.js20.19.0Node.js runtime required for frontend development and builds
pnpm10.0.0Frontend dependency manager
Vite7.3.1Project-local frontend build tool; run make env.setup first if missing
Playwright1.58.2E2E test runner; run make env.setup first if missing
PostgreSQL14.0.0Server version detected through database.default.link

make env.setupโ€‹

Installs the frontend dependencies, the Playwright Chromium browser, and the system dependencies required by the browser for development and E2E testing. Run it once after the first clone or during CI environment initialization; it is usually not needed again.

make env.setup

Development Serversโ€‹

make devโ€‹

Restarts the backend and frontend development servers. Before starting, it checks that the command-line backend_port, backend server.address, and frontend Vite proxy target agree, so port mismatches fail early instead of surfacing later as health-check timeouts or API errors. The command then stops existing services, decides whether to build WASM plugins based on plugin mode, prepares frontend static assets, compiles the backend, and waits for both health checks to pass.

make dev

# Force core framework-only mode and skip official source plugins and WASM plugin builds
make dev plugins=0

# Force official source plugin mode
make dev plugins=1

plugins=auto is the default mode: if apps/lina-plugins/ contains usable plugin manifest files, official plugin mode is enabled automatically; otherwise core framework-only mode is used. When invoking linactl dev directly, you can also pass skip_wasm=true to skip only the WASM build step.

cd hack/tools/linactl
go run . dev skip_wasm=true

The backend listens on http://localhost:9120 by default, the frontend dev server listens on http://localhost:5666 by default, and the default admin workspace development entry is http://localhost:5666/admin. Logs are written to temp/lina-core.log and temp/lina-vben.log.

make stopโ€‹

Stops the backend and frontend development servers and cleans up stale PID files. Any remaining processes still occupying the ports are force-terminated.

make stop

make statusโ€‹

Prints the current backend/frontend running status and log file paths, making it easy to confirm whether both services started correctly.

make status

Sample output:

+----------+---------+------------------------+-------+------------------------+--------------------+
| Service | Status | URL | PID | PID File | Log File |
+----------+---------+------------------------+-------+------------------------+--------------------+
| Backend | running | http://127.0.0.1:9120/ | 87739 | temp/pids/backend.pid | temp/lina-core.log |
| Frontend | running | http://127.0.0.1:5666/ | 87740 | temp/pids/frontend.pid | temp/lina-vben.log |
+----------+---------+------------------------+-------+------------------------+--------------------+

Code Buildsโ€‹

make buildโ€‹

Runs the full build pipeline: frontend static asset build, static asset and manifest preparation for backend embedding, dynamic WASM plugin builds based on plugin mode, and finally compilation of the backend core framework binary. Build artifacts are written to temp/output/.

# Default build for the current platform
make build

# Force core framework-only mode without building official source plugins
make build plugins=0

# Target specific platforms through cross-compilation
make build platforms=linux/amd64,linux/arm64

# Override output directory and binary name
make build output_dir=temp/release binary_name=linapro

# Override the config file
make build config=hack/config.yaml

# Enable verbose logs
make build verbose=1
# or
make build v=1

Build defaults are managed centrally in the root hack/config.yaml. Command-line arguments override the corresponding fields.

build:
# Target platform list in goos/goarch format; make build platforms=... overrides this
platforms:
- "auto"
# Whether to enable CGO
cgoEnabled: false
# Build output path, relative to the repository root
outputDir: "temp/output"
# Filename of the compiled binary
binaryName: "lina"
FieldDefaultDescription
build.platforms["auto"]Target platform list in goos/goarch format; auto means linux/<current-arch>; override with make build platforms=...
build.cgoEnabledfalseWhether to enable CGO
build.outputDirtemp/outputBuild output path, relative to the repository root
build.binaryNamelinaCore framework binary filename

Plugin build mode is controlled by the plugins argument:

plugins valueDescription
auto (default)Enable official source plugin mode when apps/lina-plugins/ contains usable plugin manifest files
0Force core framework-only mode, remove official plugin build tags, and skip official plugin WASM builds
1Force official source plugin mode; fail fast if the plugin workspace is unavailable

make wasmโ€‹

Builds runtime WASM plugins separately. make wasm is a compatibility entry that writes artifacts to temp/output/ by default, supports p=<plugin-id> to build only one plugin, and supports dry_run=true to check the buildable plugin plan without writing artifacts. To build a single plugin directory at any path, invoke linactl wasm plugin_dir=<path> directly.

# Build all WASM plugins
make wasm

# Build only a specific plugin, where plugin-id is the plugin directory name
make wasm p=my-plugin

# Check the build plan only
make wasm dry_run=true

# Build a specific plugin directory directly
cd hack/tools/linactl
go run . wasm plugin_dir=../../apps/lina-plugins/my-plugin out=../../temp/output

make pack.assetsโ€‹

Prepares core framework manifest assets for Go embedding. This command refreshes config, sql, and i18n resources under apps/lina-core/internal/packed/manifest/. It is normally called automatically by make build or make dev, but can be run manually when you need to inspect or prepare embedded resources in isolation:

make pack.assets

make tidyโ€‹

Tidies Go module dependencies for the core framework, development tools, and plugins. Run it after dependency upgrades or after initializing full plugin mode:

make tidy

Image Buildsโ€‹

make imageโ€‹

Runs the full Docker image build pipeline: first performs the image build preflight, then runs make build to generate all build artifacts, and finally calls hack/tools/image-builder to package them into an image. Image name, tag, registry, base image, and plugin build mode are all configurable through arguments.

# Build with default configuration
make image

# Specify a tag and image registry
make image tag=v0.6.0 registry=ghcr.io/linaproai

# Build and push immediately
make image tag=v0.6.0 registry=ghcr.io/linaproai push=1

# Multi-platform build
make image platforms=linux/amd64,linux/arm64 tag=v0.6.0

# Override the runtime base image and use core framework-only mode
make image base_image=alpine:3.22 plugins=0

Image build defaults are also managed by hack/config.yaml; command-line arguments override values for the current invocation.

image:
# Image name; registry prefix is prepended at build time
name: "linapro"
# Default tag; leave empty to derive it from git metadata
tag: "dev"
# Remote registry prefix, for example ghcr.io/linaproai
registry: ""
# Whether to push by default; push=1 overrides this invocation
push: false
# Runtime base image
baseImage: "alpine:3.22"
# Dockerfile path, relative to the repository root
dockerfile: "hack/docker/Dockerfile"
FieldDefaultDescription
image.namelinaproImage name; the registry prefix is prepended during build
image.tagdevDefault tag; leave empty to derive it from git metadata
image.registryEmptyRemote registry prefix, for example ghcr.io/linaproai
image.pushfalseWhether to push by default; command-line push=1 overrides the current invocation
image.baseImagealpine:3.22Runtime base image
image.dockerfilehack/docker/DockerfileDockerfile path relative to the repository root

make image.buildโ€‹

Prepares all image build artifacts (equivalent to running make build and generating the image build context), but does not run the Docker build step. Use it when you need to inspect artifacts manually or customize the image build process.

make image.build

Test Managementโ€‹

make testโ€‹

Runs the full Playwright E2E test suite. Make sure the development services have been started with make dev first. Use the scope argument to narrow the test scope:

scope valueDescription
full (default)Run all E2E tests
hostRun only core framework-owned tests
pluginsRun all official plugin tests
plugin:<id>Run tests for a specific plugin
make test

# Run only core framework tests
make test scope=host

# Run only tests for a specific plugin
make test scope=plugin:multi-tenant

make test.goโ€‹

Runs unit tests for all maintained Go modules with race detection and verbose logs enabled by default. The command first discovers modules in the current Go workspace, runs real tests for packages that contain test files, performs compile smoke checks for packages without test files, and prints a per-module summary. Use plugins=0 to force core framework-only mode, or race=false to disable race detection.

make test.go
make test.go plugins=0
make test.go race=false
make test.go verbose=false

make test.hostโ€‹

Runs only the core framework-owned Playwright E2E tests and does not require official plugin submodules to be initialized.

make test.host

make test.pluginsโ€‹

Runs the official plugins' own Playwright E2E tests. Initialize the apps/lina-plugins/ submodules before running this command.

make test.plugins

make test.scriptsโ€‹

Runs unit and smoke checks for cross-platform repository tooling, validating the basic correctness of linactl, make.cmd, and other helper entries.

make test.scripts

Plugin Managementโ€‹

The apps/lina-plugins/ directory stores official plugins. It can be a Git submodule, or it can be managed as a source plugin workspace through the plugin workspace commands below.

make plugins.initโ€‹

Converts apps/lina-plugins from a Git submodule into an ordinary plugin directory while preserving the plugin code. After conversion, plugin code can be modified and committed freely without submodule constraints.

make plugins.init

make plugins.installโ€‹

Clones selected plugins from remote repositories into apps/lina-plugins/ according to plugins.sources in hack/config.yaml. Use p=<plugin-id> to install only one plugin, or source=<name> to process only one configured source.

# Install all configured source plugins
make plugins.install

# Install only one plugin
make plugins.install p=multi-tenant

# Force overwrite an existing plugin directory
make plugins.install force=1

make plugins.updateโ€‹

Updates configured source plugins under apps/lina-plugins/ by pulling the latest remote version. Plugins with uncommitted local changes are blocked from updating unless force=1 is passed.

make plugins.update
make plugins.update p=multi-tenant
make plugins.update force=1

make plugins.statusโ€‹

Shows the current official plugin workspace status, including configured plugin versions, local changes, and remote update state.

make plugins.status

i18nโ€‹

make i18n.checkโ€‹

Scans runtime-visible code paths for hardcoded text that has not been added to the internationalization system, and validates message key coverage across core framework and plugin runtime language packs. Run it before submitting new features to check i18n compliance.

make i18n.check

AI Tool Integrationโ€‹

The agents command family manages repository-local resource symlinks for different AI Coding Agent tools. LinaPro maintains project specifications, skills, and prompts at standard repository locations, then bridges them to each tool's own project paths through symlinks.

Canonical sourcePurposeTypical bridge examples
AGENTS.mdProject top-level specification entryCLAUDE.md, GEMINI.md, QWEN.md
.agents/skillsProject built-in AI skills.claude/skills, .goose/skills, .augment/skills
.agents/promptsProject commands and prompt directory.claude/commands, .codex/prompts, .cursor/commands

The goal is to let teams maintain one specification and one skill set while accommodating different developers' preferred AI Coding tools. Tools that natively support AGENTS.md or .agents/skills are recognized as such, and the commands only show status without creating unnecessary symlinks.

These commands manage only the symlinks they create. Unlink commands do not delete real directories or files, and they do not remove unmanaged symlinks that point elsewhere. If a symlink already exists but points to a different target, pass FORCE=1 to rebuild it.

make agentsโ€‹

Recommended aggregate entry. When called without arguments from an interactive terminal, it first lets you choose an agent with arrow keys, then choose the link or unlink action. In non-interactive environments, specify a single agent with agent=<name>. The aggregate entry applies the same action to every resource type supported by that agent; it does not support agent=all or comma-separated lists.

# Choose agent and action interactively
make agents

# Create every available resource symlink for one agent
make agents agent=claude-code

# Remove managed symlinks for one agent
make agents agent=claude-code action=unlink

# Rebuild managed symlinks that point to the wrong target
make agents agent=claude-code force=1

If an agent natively reads a resource type, such as AGENTS.md, the aggregate entry skips that resource and explains why in the summary.

Databaseโ€‹

Destructive Operations

Both init and mock perform destructive database operations. They require an explicit confirm argument to prevent accidental execution.

make db.initโ€‹

Initializes the database schema (DDL) and required system seed data. The command reads database.default.link from apps/lina-core/manifest/config/config.yaml; currently only the PostgreSQL 14+ dialect is supported. sqlite:, mysql:, or unknown links fail fast during dialect parsing without creating local database files or continuing to execute SQL.

# Initialize only, preserving existing data
make db.init confirm=init

# Rebuild the database after wiping it
make db.init confirm=init rebuild=true

If PostgreSQL cannot be reached, the command prompts you to start PostgreSQL and prints a local docker run example. rebuild=true first terminates connections to the target database, then runs DROP DATABASE IF EXISTS and CREATE DATABASE; use it only when the target database can be cleared.

make db.upgradeโ€‹

Replays host framework SQL files to upgrade the database schema to the latest state. The command reads all .sql files under apps/lina-core/manifest/sql/, executing them in filename order. All SQL statements use idempotent syntax such as CREATE TABLE IF NOT EXISTS and CREATE INDEX IF NOT EXISTS, so replaying them does not destroy existing dataโ€”it only adds any missing tables and indexes.

make db.upgrade confirm=upgrade

This command only processes host framework SQL files, not plugin-supplied SQL. To upgrade plugin schemas, refer to each plugin's documentation. If PostgreSQL cannot be reached, the command prompts you to start the database and prints a docker run example.

make db.mockโ€‹

After make db.init completes, loads optional Mock data for local demos and development validation.

make db.mock confirm=mock

Otherโ€‹

make helpโ€‹

Prints the default cross-platform development command list, sorted by command name. linactl also registers maintenance commands such as cli, cli.install, ctrl, and dao; default help does not show them. Run go run . help --all directly to list those commands.

make help