@hlix/cli 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +130 -0
- package/THIRD_PARTY_NOTICES +51 -0
- package/dist/chunk-FYS2JH42.js +31 -0
- package/dist/index.js +4701 -0
- package/dist/package-WT5SD5LO.js +88 -0
- package/package.json +49 -0
- package/skills/hlix/SKILL.md +194 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "./chunk-FYS2JH42.js";
|
|
3
|
+
|
|
4
|
+
// package.json
|
|
5
|
+
var name = "@hlix/cli";
|
|
6
|
+
var version = "0.2.0";
|
|
7
|
+
var license = "Apache-2.0";
|
|
8
|
+
var description = "Command-line interface for the hlix control plane, built on @hlix/sdk.";
|
|
9
|
+
var keywords = [
|
|
10
|
+
"hlix",
|
|
11
|
+
"cli",
|
|
12
|
+
"agents"
|
|
13
|
+
];
|
|
14
|
+
var homepage = "https://github.com/hlix-ai/hlix#readme";
|
|
15
|
+
var repository = {
|
|
16
|
+
type: "git",
|
|
17
|
+
url: "git+https://github.com/hlix-ai/hlix.git",
|
|
18
|
+
directory: "packages/cli"
|
|
19
|
+
};
|
|
20
|
+
var bugs = {
|
|
21
|
+
url: "https://github.com/hlix-ai/hlix/issues"
|
|
22
|
+
};
|
|
23
|
+
var type = "module";
|
|
24
|
+
var main = "./dist/index.js";
|
|
25
|
+
var bin = {
|
|
26
|
+
hlix: "./dist/index.js"
|
|
27
|
+
};
|
|
28
|
+
var files = [
|
|
29
|
+
"dist",
|
|
30
|
+
"skills",
|
|
31
|
+
"THIRD_PARTY_NOTICES"
|
|
32
|
+
];
|
|
33
|
+
var engines = {
|
|
34
|
+
node: ">=20"
|
|
35
|
+
};
|
|
36
|
+
var publishConfig = {
|
|
37
|
+
access: "public"
|
|
38
|
+
};
|
|
39
|
+
var scripts = {
|
|
40
|
+
build: "tsup",
|
|
41
|
+
test: "bun test --isolate --timeout 20000",
|
|
42
|
+
typecheck: "tsc --noEmit",
|
|
43
|
+
prepublishOnly: "bun run typecheck && bun run build && bun test src/boundary.test.ts src/skill.test.ts src/binary.test.ts src/readme.test.ts"
|
|
44
|
+
};
|
|
45
|
+
var devDependencies = {
|
|
46
|
+
"@hlix/sdk": "^0.2.0",
|
|
47
|
+
ignore: "7.0.5",
|
|
48
|
+
tsup: "^8.5.0",
|
|
49
|
+
typescript: "^5.7.2",
|
|
50
|
+
"@types/bun": "latest"
|
|
51
|
+
};
|
|
52
|
+
var package_default = {
|
|
53
|
+
name,
|
|
54
|
+
version,
|
|
55
|
+
license,
|
|
56
|
+
description,
|
|
57
|
+
keywords,
|
|
58
|
+
homepage,
|
|
59
|
+
repository,
|
|
60
|
+
bugs,
|
|
61
|
+
type,
|
|
62
|
+
main,
|
|
63
|
+
bin,
|
|
64
|
+
files,
|
|
65
|
+
engines,
|
|
66
|
+
publishConfig,
|
|
67
|
+
scripts,
|
|
68
|
+
devDependencies
|
|
69
|
+
};
|
|
70
|
+
export {
|
|
71
|
+
bin,
|
|
72
|
+
bugs,
|
|
73
|
+
package_default as default,
|
|
74
|
+
description,
|
|
75
|
+
devDependencies,
|
|
76
|
+
engines,
|
|
77
|
+
files,
|
|
78
|
+
homepage,
|
|
79
|
+
keywords,
|
|
80
|
+
license,
|
|
81
|
+
main,
|
|
82
|
+
name,
|
|
83
|
+
publishConfig,
|
|
84
|
+
repository,
|
|
85
|
+
scripts,
|
|
86
|
+
type,
|
|
87
|
+
version
|
|
88
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hlix/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"description": "Command-line interface for the hlix control plane, built on @hlix/sdk.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"hlix",
|
|
8
|
+
"cli",
|
|
9
|
+
"agents"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/hlix-ai/hlix#readme",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/hlix-ai/hlix.git",
|
|
15
|
+
"directory": "packages/cli"
|
|
16
|
+
},
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/hlix-ai/hlix/issues"
|
|
19
|
+
},
|
|
20
|
+
"type": "module",
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"bin": {
|
|
23
|
+
"hlix": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"skills",
|
|
28
|
+
"THIRD_PARTY_NOTICES"
|
|
29
|
+
],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=20"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup",
|
|
38
|
+
"test": "bun test --isolate --timeout 20000",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"prepublishOnly": "bun run typecheck && bun run build && bun test src/boundary.test.ts src/skill.test.ts src/binary.test.ts src/readme.test.ts"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@hlix/sdk": "^0.2.0",
|
|
44
|
+
"ignore": "7.0.5",
|
|
45
|
+
"tsup": "^8.5.0",
|
|
46
|
+
"typescript": "^5.7.2",
|
|
47
|
+
"@types/bun": "latest"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hlix
|
|
3
|
+
description: Import and configure local projects, then inspect Hlix projects and tasks from the terminal. Use when asked to scan or import a folder, initialize it, list projects, look up a task, read review evidence, or watch task status.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# hlix CLI
|
|
7
|
+
|
|
8
|
+
Project setup and inspection for a Hlix workspace. Every command below is registered in
|
|
9
|
+
the CLI — `skill.test.ts` compares this list against the command table and fails
|
|
10
|
+
if they disagree, so this file cannot advertise something that does not exist.
|
|
11
|
+
|
|
12
|
+
## Authentication
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
hlix auth login --workspace <id> [--base-url <url>]
|
|
16
|
+
hlix auth status [--json] # which credential, from where, does it work
|
|
17
|
+
hlix auth logout [--yes] [--json] # remove the stored credential file
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Reads the key from a hidden terminal prompt, verifies it against the API
|
|
21
|
+
**before** storing it, then writes it atomically to
|
|
22
|
+
`~/.config/hlix/credentials.json` with mode 0600. The key is never printed back.
|
|
23
|
+
|
|
24
|
+
`HLIX_API_KEY` overrides the stored file; `HLIX_BASE_URL` and
|
|
25
|
+
`HLIX_WORKSPACE_ID` set the target and workspace. Use those in CI rather than
|
|
26
|
+
running a login step.
|
|
27
|
+
|
|
28
|
+
`--workspace` is required at login: an API key authenticates a user but names
|
|
29
|
+
no workspace, so the caller states one. `hlix auth login` verifies the key
|
|
30
|
+
against a real call **before** writing it, so a key that does not work is never
|
|
31
|
+
stored.
|
|
32
|
+
|
|
33
|
+
`auth status` names the credential's **source** — the environment or the stored
|
|
34
|
+
file — and probes it against the API. It never prints the key, not even a
|
|
35
|
+
prefix. `auth logout` removes the credential **file** only; a key supplied
|
|
36
|
+
through `HLIX_API_KEY` is reported and left alone, because it belongs to the
|
|
37
|
+
shell that set it. Removal asks for confirmation unless `--yes` is given, and
|
|
38
|
+
refuses any path that is not a credential document this CLI wrote.
|
|
39
|
+
|
|
40
|
+
## Where a command points
|
|
41
|
+
|
|
42
|
+
Every command resolves its workspace and API through one chain, highest first:
|
|
43
|
+
|
|
44
|
+
1. an explicit flag (`--workspace`, `--base-url`)
|
|
45
|
+
2. the `HLIX_*` environment
|
|
46
|
+
3. the nearest `.hlix/config.json`, walking up from the working directory
|
|
47
|
+
4. the stored credential
|
|
48
|
+
5. the built-in default (`https://server.hlix.ai`)
|
|
49
|
+
|
|
50
|
+
The folder's binding therefore outranks the machine-wide credential: a folder
|
|
51
|
+
bound to workspace A is queried against workspace A even when the last login
|
|
52
|
+
named workspace B. A flag or environment variable that **contradicts** the
|
|
53
|
+
folder's binding is not resolved by precedence — it exits `workspace_mismatch`
|
|
54
|
+
naming both, because guessing which one was meant is how a push reaches the
|
|
55
|
+
wrong tenant. `hlix auth login` is deliberately outside the chain, so signing in
|
|
56
|
+
to a second workspace from inside a bound folder still works.
|
|
57
|
+
|
|
58
|
+
`--cwd <dir>` makes any command operate on another directory, including the
|
|
59
|
+
binding lookup. `hlix status` prints the resolved answer and the source that
|
|
60
|
+
decided it.
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
hlix status [--json] # workspace, binding, local and cloud drift
|
|
66
|
+
hlix projects list [--json] # projects in the workspace
|
|
67
|
+
hlix projects get [project-id] [--json]
|
|
68
|
+
hlix init [folder] [--json] # create committed project configuration
|
|
69
|
+
hlix import [folder] [--dry-run] [--env-file <path>] [--history preserve] [--yes] [--json]
|
|
70
|
+
hlix sync [--dry-run] [--json] # push or pull when only one side changed
|
|
71
|
+
hlix pull [--force] [--yes] [--dry-run] [--json]
|
|
72
|
+
hlix push [--dry-run] [--json] # compare-and-swap a new immutable revision
|
|
73
|
+
hlix skill import <SKILL.md|folder> [--name <slug>] [--json]
|
|
74
|
+
hlix agent import <markdown-file> [--name <name>] [--runtime <runtime>] [--profile <profile>] [--json]
|
|
75
|
+
hlix mcp import <.mcp.json> [--server <name>] [--allow-stdio] [--json]
|
|
76
|
+
hlix tasks list [--project <id>] [--status <status>] [--json]
|
|
77
|
+
hlix tasks get <task-id> [--json] # one task
|
|
78
|
+
hlix tasks review <task-id> [--json] # the verified review evidence for a task
|
|
79
|
+
hlix tasks watch <task-id> [--json] # stream status changes until the task ends
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`hlix --help` lists them; `hlix <command> --help` shows its usage. Every command
|
|
83
|
+
also accepts `--cwd <dir>`.
|
|
84
|
+
|
|
85
|
+
`hlix status` answers "where am I" in one screen: the resolved workspace and API
|
|
86
|
+
with the source that decided each, the folder's binding and local revision, and
|
|
87
|
+
whether the working tree or the cloud head has moved since the last sync. It
|
|
88
|
+
reports rather than judges: a missing credential, an unreadable project file, a
|
|
89
|
+
contradicting override and an unreachable API are all lines in the output, and
|
|
90
|
+
the command itself always exits 0. An argument error — an unknown flag, a stray
|
|
91
|
+
positional, a `--cwd` that is not a directory — is still exit 2, because it is
|
|
92
|
+
rejected before `status` runs at all.
|
|
93
|
+
|
|
94
|
+
`tasks list` and `projects get` default to the project this folder is bound to,
|
|
95
|
+
so both are usable with no arguments inside an imported project.
|
|
96
|
+
|
|
97
|
+
Run `hlix import --dry-run` first. The report names secret **keys**, quarantined
|
|
98
|
+
agent/skill/MCP resources, and Git-history findings, but never secret values.
|
|
99
|
+
Hlix collects every project-local dotenv and credential file. It applies the
|
|
100
|
+
standard development dotenv precedence automatically and preserves every other
|
|
101
|
+
profile encrypted; `--env-file` is an explicit override.
|
|
102
|
+
The default history policy aborts on possible historical secrets. Explicit
|
|
103
|
+
`--history preserve` keeps the full Git history after showing the risk.
|
|
104
|
+
Current environment values are sent only in the authenticated finalization
|
|
105
|
+
request and stored encrypted; they are never placed in the Git bundle.
|
|
106
|
+
|
|
107
|
+
When the scan finds cloud setup commands, protected files, or quarantined
|
|
108
|
+
resources, interactive imports ask for one explicit trust decision before any
|
|
109
|
+
project is created or uploaded. Non-interactive and `--json` callers must first
|
|
110
|
+
review `--dry-run`, then pass `--yes`; it never bypasses a scan blocker. A
|
|
111
|
+
declined prompt exits as `cancelled`, while a caller that cannot prompt exits
|
|
112
|
+
as `approval_required`.
|
|
113
|
+
|
|
114
|
+
Agent, skill, and MCP files found during a project scan stay quarantined until
|
|
115
|
+
one of the explicit import commands above is run. Skill content and agents are
|
|
116
|
+
scoped to the bound project. MCP imports send environment key names only;
|
|
117
|
+
values remain in encrypted project secrets and the generated cloud config uses
|
|
118
|
+
`${KEY}` placeholders, including remote authentication headers such as
|
|
119
|
+
`Authorization: Bearer ${TOKEN}`. Literal-only headers are refused. Remote MCP URLs must use public HTTPS. Stdio servers
|
|
120
|
+
require `--allow-stdio` and run only through a validated direct executable,
|
|
121
|
+
never a shell.
|
|
122
|
+
|
|
123
|
+
`sync` never guesses through a two-sided conflict. If only local changed it
|
|
124
|
+
pushes; if only cloud changed it pulls; if both changed it exits with
|
|
125
|
+
`conflict`.
|
|
126
|
+
|
|
127
|
+
`push`, `pull` and `sync` accept `--dry-run`: it prints the divergence — each
|
|
128
|
+
side's generation, and how many files are local-only, cloud-only or differing —
|
|
129
|
+
takes no action, and reports the verdict the real command would reach. A dry run
|
|
130
|
+
that would end in `conflict` exits 1, as `import --dry-run` does for a blocker.
|
|
131
|
+
|
|
132
|
+
`pull --force` is the destructive override, and it now asks before replacing
|
|
133
|
+
local files: `--force` states "replace my changes", `--yes` states "do not ask".
|
|
134
|
+
A `--json` or non-interactive caller cannot answer, so it exits
|
|
135
|
+
`approval_required` pointing at `--dry-run`; a declined prompt exits `cancelled`.
|
|
136
|
+
`--force` without local changes replaces nothing and does not prompt.
|
|
137
|
+
|
|
138
|
+
## Machine output
|
|
139
|
+
|
|
140
|
+
`--json` is a stable contract. Human output is not — do not parse it.
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"schemaVersion": 1,
|
|
145
|
+
"command": "projects list",
|
|
146
|
+
"data": [ /* documented command result */ ]
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Failures use the same envelope with `error` instead of `data`:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"schemaVersion": 1,
|
|
155
|
+
"command": "tasks get",
|
|
156
|
+
"error": { "code": "not_found", "message": "Task not found", "status": 404 }
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Branch on `error.code`, never on `error.message`. Codes: `unauthenticated`,
|
|
161
|
+
`forbidden`, `not_found`, `conflict`, `invalid_request`, `bad_request`,
|
|
162
|
+
`rate_limited`, `not_implemented`, `server_error`, `unreachable`,
|
|
163
|
+
`missing_argument`, `invalid_usage`, `approval_required`, `cancelled`, `unknown_command`,
|
|
164
|
+
`workspace_mismatch`, `not_initialized`, `scan_blocked`, `already_imported`,
|
|
165
|
+
`workspace_required`, `invalid_base_url`, `missing_credential`, `unknown`.
|
|
166
|
+
|
|
167
|
+
That list is the complete set — `skill.test.ts` compares it against every code
|
|
168
|
+
the sources can emit in BOTH directions, so a code the CLI can return cannot go
|
|
169
|
+
undocumented and a documented code cannot be one the CLI never returns.
|
|
170
|
+
|
|
171
|
+
Transport-only inspection commands pass the API response through unchanged.
|
|
172
|
+
Local project commands such as `import`, `push`, `pull`, and `sync` return the
|
|
173
|
+
documented local result shape. The CLI selects columns for the human table only.
|
|
174
|
+
|
|
175
|
+
`tasks watch --json` is the one exception to "one document": it emits **one
|
|
176
|
+
envelope per line** (JSONL), because a live stream cannot be a single JSON
|
|
177
|
+
document. Read it line by line.
|
|
178
|
+
|
|
179
|
+
## Exit codes
|
|
180
|
+
|
|
181
|
+
| Code | Meaning |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| 0 | Success |
|
|
184
|
+
| 1 | The command ran and failed |
|
|
185
|
+
| 2 | Usage error — unknown command, bad flags, missing argument |
|
|
186
|
+
| 3 | Authentication or permission failure |
|
|
187
|
+
|
|
188
|
+
## Not available
|
|
189
|
+
|
|
190
|
+
- **No execution commands.** There is deliberately no way to start a run,
|
|
191
|
+
execute a cycle or dispatch a task from this CLI.
|
|
192
|
+
- **No `tasks logs`.** The log endpoint is not part of the published API
|
|
193
|
+
contract, and there is no log stream to follow. `tasks watch` streams task
|
|
194
|
+
*status*, which is a different thing and is named accordingly.
|