@masculinecache/warp-axi 0.0.0-stage → 0.1.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 +21 -0
- package/README.md +45 -2
- package/dist/bin/warp-axi.d.ts +2 -0
- package/dist/bin/warp-axi.js +16 -0
- package/dist/src/args.d.ts +6 -0
- package/dist/src/args.js +56 -0
- package/dist/src/cli.d.ts +22 -0
- package/dist/src/cli.js +68 -0
- package/dist/src/commands/connect.d.ts +3 -0
- package/dist/src/commands/connect.js +50 -0
- package/dist/src/commands/debug.d.ts +2 -0
- package/dist/src/commands/debug.js +83 -0
- package/dist/src/commands/registration.d.ts +2 -0
- package/dist/src/commands/registration.js +111 -0
- package/dist/src/commands/settings.d.ts +2 -0
- package/dist/src/commands/settings.js +65 -0
- package/dist/src/commands/status.d.ts +2 -0
- package/dist/src/commands/status.js +89 -0
- package/dist/src/commands/target.d.ts +2 -0
- package/dist/src/commands/target.js +83 -0
- package/dist/src/commands/tunnel.d.ts +2 -0
- package/dist/src/commands/tunnel.js +112 -0
- package/dist/src/commands/vnet.d.ts +2 -0
- package/dist/src/commands/vnet.js +106 -0
- package/dist/src/errors.d.ts +2 -0
- package/dist/src/errors.js +2 -0
- package/dist/src/format.d.ts +8 -0
- package/dist/src/format.js +16 -0
- package/dist/src/list.d.ts +11 -0
- package/dist/src/list.js +17 -0
- package/dist/src/stdin.d.ts +2 -0
- package/dist/src/stdin.js +12 -0
- package/dist/src/toon.d.ts +24 -0
- package/dist/src/toon.js +140 -0
- package/dist/src/util.d.ts +2 -0
- package/dist/src/util.js +17 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +22 -0
- package/dist/src/warp.d.ts +19 -0
- package/dist/src/warp.js +131 -0
- package/package.json +54 -4
- package/skills/warp-axi/SKILL.md +74 -0
package/dist/src/warp.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { AxiError } from "axi-sdk-js";
|
|
3
|
+
const MAX_OUTPUT = 64 * 1024 * 1024;
|
|
4
|
+
export function realRunner(cwd) {
|
|
5
|
+
return {
|
|
6
|
+
async run(args, options) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const proc = spawn("warp-cli", args, {
|
|
9
|
+
cwd,
|
|
10
|
+
env: { ...process.env },
|
|
11
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
12
|
+
});
|
|
13
|
+
let stdout = "";
|
|
14
|
+
let stderr = "";
|
|
15
|
+
proc.stdout.on("data", (data) => {
|
|
16
|
+
if (stdout.length < MAX_OUTPUT) {
|
|
17
|
+
stdout += data.toString();
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
proc.stderr.on("data", (data) => {
|
|
21
|
+
if (stderr.length < MAX_OUTPUT) {
|
|
22
|
+
stderr += data.toString();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
if (options?.input) {
|
|
26
|
+
proc.stdin.write(options.input);
|
|
27
|
+
proc.stdin.end();
|
|
28
|
+
}
|
|
29
|
+
proc.on("error", (err) => {
|
|
30
|
+
if (err.code === "ENOENT") {
|
|
31
|
+
reject(new AxiError("WARP_NOT_INSTALLED", "warp-cli is not installed. Install cloudflare-warp package first.", ["Install: https://pkg.cloudflareclient.com/", "Or: brew install cloudflare-warp"]));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
reject(err);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
proc.on("close", (code) => {
|
|
38
|
+
resolve({
|
|
39
|
+
stdout: stdout.trim(),
|
|
40
|
+
stderr: stderr.trim(),
|
|
41
|
+
exitCode: code ?? 0,
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export async function callWarp(runner, args, options) {
|
|
49
|
+
const result = await runner.run(args, options);
|
|
50
|
+
if (result.exitCode !== 0) {
|
|
51
|
+
throw mapWarpError(result.stderr || result.stdout, result.exitCode);
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
export async function callWarpLenient(runner, args, options) {
|
|
56
|
+
return runner.run(args, options);
|
|
57
|
+
}
|
|
58
|
+
const ERROR_PATTERNS = [
|
|
59
|
+
{
|
|
60
|
+
pattern: /Registration\+failed|Unable to register/i,
|
|
61
|
+
code: "REGISTRATION_FAILED",
|
|
62
|
+
message: "WARP registration failed. The device could not enroll in the Zero Trust organization.",
|
|
63
|
+
suggestions: [
|
|
64
|
+
"Check that the MDM service token is valid and not expired",
|
|
65
|
+
"Verify the organization name in the MDM configuration",
|
|
66
|
+
"Ensure the device can reach api.cloudflareclient.com",
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
pattern: /not\s+registered|No\s+registration/i,
|
|
71
|
+
code: "NOT_REGISTERED",
|
|
72
|
+
message: "WARP is not registered with a Zero Trust organization.",
|
|
73
|
+
suggestions: [
|
|
74
|
+
"Run: warp-axi registration new --org <org-name>",
|
|
75
|
+
"Or: warp-cli registration new --organization <org>",
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
pattern: /already\s+registered/i,
|
|
80
|
+
code: "ALREADY_REGISTERED",
|
|
81
|
+
message: "WARP is already registered. Delete the existing registration first.",
|
|
82
|
+
suggestions: ["Run: warp-axi registration delete", "Then: warp-axi registration new --org <org>"],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
pattern: /connection\s+failed|Unable to connect/i,
|
|
86
|
+
code: "CONNECTION_FAILED",
|
|
87
|
+
message: "WARP could not establish a connection.",
|
|
88
|
+
suggestions: [
|
|
89
|
+
"Check network connectivity",
|
|
90
|
+
"Run: warp-axi debug connectivity-check",
|
|
91
|
+
"Check if another VPN is active",
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
pattern: /authentication\s+failed|auth\s+error/i,
|
|
96
|
+
code: "AUTH_FAILED",
|
|
97
|
+
message: "WARP authentication failed. The Zero Trust enrollment may have expired.",
|
|
98
|
+
suggestions: [
|
|
99
|
+
"Delete and re-register: warp-axi registration delete && warp-axi registration new --org <org>",
|
|
100
|
+
"Check that the MDM service token is still valid",
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
pattern: /daemon\s+not\s+running|warp-svc/i,
|
|
105
|
+
code: "DAEMON_NOT_RUNNING",
|
|
106
|
+
message: "The WARP daemon (warp-svc) is not running.",
|
|
107
|
+
suggestions: [
|
|
108
|
+
"Start the service: sudo systemctl start warp-svc",
|
|
109
|
+
"Check status: systemctl status warp-svc",
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
pattern: /permission\s+denied|Operation\s+not\s+permitted/i,
|
|
114
|
+
code: "PERMISSION_DENIED",
|
|
115
|
+
message: "Permission denied. This command requires elevated privileges.",
|
|
116
|
+
suggestions: ["Run with sudo or as root", "Check warp-svc daemon permissions"],
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
function stripAnsi(text) {
|
|
120
|
+
return text.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, "");
|
|
121
|
+
}
|
|
122
|
+
export function mapWarpError(stderr, _exitCode) {
|
|
123
|
+
const clean = stripAnsi(stderr);
|
|
124
|
+
for (const { pattern, code, message, suggestions } of ERROR_PATTERNS) {
|
|
125
|
+
if (pattern.test(clean)) {
|
|
126
|
+
return new AxiError(code, message, suggestions);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const firstLine = clean.split("\n").find((l) => l.trim()) ?? "Unknown error";
|
|
130
|
+
return new AxiError("UNKNOWN", firstLine.trim());
|
|
131
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masculinecache/warp-axi",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agent-ergonomic Cloudflare WARP CLI wrapper with TOON output — status, registration, connectivity, split tunnels, and debug diagnostics via warp-cli",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"warp-axi": "dist/bin/warp-axi.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"!dist/test",
|
|
12
|
+
"skills/warp-axi",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public",
|
|
21
|
+
"provenance": true
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"test": "vitest run --config vitest.config.mts",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"dev": "tsx bin/warp-axi.ts",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@toon-format/toon": "^4.1.1",
|
|
32
|
+
"axi-sdk-js": "^0.1.10"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^26.6.6",
|
|
36
|
+
"tsx": "^4.0.0",
|
|
37
|
+
"typescript": "^7.0.2",
|
|
38
|
+
"vitest": "^5.0.1"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"cloudflare",
|
|
42
|
+
"warp",
|
|
43
|
+
"warp-cli",
|
|
44
|
+
"axi",
|
|
45
|
+
"toon",
|
|
46
|
+
"agent-ergonomic",
|
|
47
|
+
"zero-trust",
|
|
48
|
+
"mesh"
|
|
49
|
+
],
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/masculinecache/warp-axi.git"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/masculinecache/warp-axi#readme"
|
|
56
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: warp-axi
|
|
3
|
+
description: Manage Cloudflare WARP client (warp-cli) through an agent-ergonomic TOON wrapper. Use when checking WARP connection status, registering/enrolling devices, managing split tunnel routes, virtual networks, infrastructure targets, or running network diagnostics on fleet nodes with WARP installed.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# warp-axi
|
|
7
|
+
|
|
8
|
+
Agent-ergonomic wrapper for the Cloudflare WARP CLI (`warp-cli`).
|
|
9
|
+
|
|
10
|
+
## Invocation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
warp-axi <area> [subcommand] [flags]
|
|
14
|
+
# or via npx:
|
|
15
|
+
npx @masculinecache/warp-axi <area> [subcommand] [flags]
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Areas
|
|
19
|
+
|
|
20
|
+
| Area | Subcommands | Description |
|
|
21
|
+
|------|-------------|-------------|
|
|
22
|
+
| `status` | (none), `--detail`, `--json` | Connection status and account info |
|
|
23
|
+
| `connect` | (none) | Connect to WARP |
|
|
24
|
+
| `disconnect` | (none) | Disconnect from WARP |
|
|
25
|
+
| `registration` | `show`, `new [--org <org>] [--token <token>]`, `delete` | Device registration management |
|
|
26
|
+
| `tunnel` | `dump`, `stats` | Split tunnel routes and tunnel statistics |
|
|
27
|
+
| `settings` | (none) | Client settings display |
|
|
28
|
+
| `debug` | `network`, `posture`, `connectivity-check` | Diagnostics |
|
|
29
|
+
| `vnet` | `list`, `add <name>`, `remove <name>` | Virtual network management |
|
|
30
|
+
| `target` | `list` | Infrastructure target listing |
|
|
31
|
+
|
|
32
|
+
## Global flags
|
|
33
|
+
|
|
34
|
+
- `--help`, `-h` — Show help
|
|
35
|
+
- `--version`, `-V` — Show version
|
|
36
|
+
|
|
37
|
+
## Exit codes
|
|
38
|
+
|
|
39
|
+
| Code | Meaning |
|
|
40
|
+
|------|---------|
|
|
41
|
+
| 0 | Success |
|
|
42
|
+
| 1 | General error |
|
|
43
|
+
| 2 | WARP not installed |
|
|
44
|
+
|
|
45
|
+
## Error codes
|
|
46
|
+
|
|
47
|
+
| Code | When |
|
|
48
|
+
|------|------|
|
|
49
|
+
| `WARP_NOT_INSTALLED` | `warp-cli` binary not found on PATH |
|
|
50
|
+
| `REGISTRATION_FAILED` | Registration attempt failed |
|
|
51
|
+
| `NOT_REGISTERED` | Device not registered with organization |
|
|
52
|
+
| `ALREADY_REGISTERED` | Device already registered |
|
|
53
|
+
| `CONNECTION_FAILED` | Could not establish WARP connection |
|
|
54
|
+
| `AUTH_FAILED` | Authentication failed |
|
|
55
|
+
| `DAEMON_NOT_RUNNING` | warp-svc daemon not running |
|
|
56
|
+
| `PERMISSION_DENIED` | Insufficient permissions |
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install -g @masculinecache/warp-axi
|
|
62
|
+
# or use without installing:
|
|
63
|
+
npx @masculinecache/warp-axi status
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## MDM headless enrollment
|
|
67
|
+
|
|
68
|
+
For zero-touch fleet enrollment, use the service token flow:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
warp-axi registration new --org <team-name> --token <service-token>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The service token is obtained from the Zero Trust dashboard under Settings → Devices → Service Tokens.
|