@eve-horizon/cli 0.0.1 → 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/README.md +19 -8
- package/dist/commands/admin.js +84 -0
- package/dist/commands/auth.js +468 -41
- package/dist/commands/db.js +2 -70
- package/dist/commands/env.js +28 -16
- package/dist/commands/job.js +200 -2
- package/dist/commands/pipeline.js +21 -2
- package/dist/commands/profile.js +5 -0
- package/dist/commands/skills.js +390 -0
- package/dist/index.js +8 -0
- package/dist/lib/context.js +29 -1
- package/dist/lib/help.js +145 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ Profiles store API URL, default org/project IDs, default harness, and Supabase a
|
|
|
19
19
|
```bash
|
|
20
20
|
# Create or update a profile
|
|
21
21
|
eve profile set local \
|
|
22
|
-
--api-url http://localhost:
|
|
22
|
+
--api-url http://localhost:4801 \
|
|
23
23
|
--org org_defaulttestorg \
|
|
24
24
|
--project proj_xxx
|
|
25
25
|
|
|
@@ -51,16 +51,19 @@ eve profile set prod \
|
|
|
51
51
|
|
|
52
52
|
## Auth
|
|
53
53
|
|
|
54
|
-
Auth is **
|
|
55
|
-
|
|
56
|
-
`EVE_SUPABASE_ANON_KEY`.
|
|
54
|
+
Auth is **required** for cloud stacks. The default flow uses GitHub SSH keys; Supabase remains an
|
|
55
|
+
optional adapter for legacy deployments.
|
|
57
56
|
|
|
58
|
-
The CLI will refresh access tokens automatically if a refresh token is available.
|
|
57
|
+
The CLI will refresh Supabase access tokens automatically if a refresh token is available.
|
|
59
58
|
|
|
60
59
|
```bash
|
|
61
|
-
#
|
|
60
|
+
# SSH login (default)
|
|
61
|
+
eve auth login --email you@example.com --ssh-key ~/.ssh/id_ed25519
|
|
62
|
+
|
|
63
|
+
# Supabase login (optional)
|
|
62
64
|
eve auth login --email you@example.com --password '...' \
|
|
63
|
-
--
|
|
65
|
+
--supabase-url https://your-project.supabase.co \
|
|
66
|
+
--supabase-anon-key <anon-key>
|
|
64
67
|
|
|
65
68
|
# Status / whoami
|
|
66
69
|
eve auth status
|
|
@@ -100,6 +103,15 @@ Jobs created without a `--phase` flag default to `ready`, making them immediatel
|
|
|
100
103
|
eve job create --description "Fix the login bug in auth.ts"
|
|
101
104
|
eve job create --description "Add dark mode" --priority 1 --harness mclaude
|
|
102
105
|
|
|
106
|
+
# Create a job with git controls
|
|
107
|
+
eve job create \
|
|
108
|
+
--description "Fix checkout" \
|
|
109
|
+
--git-ref main \
|
|
110
|
+
--git-branch job/fix-checkout \
|
|
111
|
+
--git-create-branch if_missing \
|
|
112
|
+
--git-commit auto \
|
|
113
|
+
--git-push on_success
|
|
114
|
+
|
|
103
115
|
# List and filter jobs
|
|
104
116
|
eve job list --phase ready
|
|
105
117
|
eve job ready # Schedulable jobs (ready, not blocked)
|
|
@@ -271,5 +283,4 @@ Local dev/ops tooling:
|
|
|
271
283
|
./bin/eh dev start
|
|
272
284
|
./bin/eh k8s start # Default runtime
|
|
273
285
|
./bin/eh docker start # Quick dev loop
|
|
274
|
-
./bin/eh db migrate
|
|
275
286
|
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleAdmin = handleAdmin;
|
|
4
|
+
const args_1 = require("../lib/args");
|
|
5
|
+
const client_1 = require("../lib/client");
|
|
6
|
+
const output_1 = require("../lib/output");
|
|
7
|
+
async function handleAdmin(subcommand, positionals, flags, context) {
|
|
8
|
+
const json = Boolean(flags.json);
|
|
9
|
+
switch (subcommand) {
|
|
10
|
+
case 'invite': {
|
|
11
|
+
const githubUsername = (0, args_1.getStringFlag)(flags, ['github']);
|
|
12
|
+
const email = (0, args_1.getStringFlag)(flags, ['email']);
|
|
13
|
+
const role = (0, args_1.getStringFlag)(flags, ['role']) ?? 'member';
|
|
14
|
+
const orgId = (0, args_1.getStringFlag)(flags, ['org']) ?? context.orgId;
|
|
15
|
+
if (!email) {
|
|
16
|
+
throw new Error('Usage: eve admin invite --email <email> [--github <username>] [--role <role>] [--org <org_id>]');
|
|
17
|
+
}
|
|
18
|
+
if (!['owner', 'admin', 'member'].includes(role)) {
|
|
19
|
+
throw new Error(`Invalid role: ${role}. Must be one of: owner, admin, member`);
|
|
20
|
+
}
|
|
21
|
+
const results = {
|
|
22
|
+
keys_registered: 0,
|
|
23
|
+
identities: [],
|
|
24
|
+
};
|
|
25
|
+
// Fetch and register GitHub SSH keys if username provided
|
|
26
|
+
if (githubUsername) {
|
|
27
|
+
const keys = await fetchGitHubKeys(githubUsername);
|
|
28
|
+
if (keys.length === 0) {
|
|
29
|
+
throw new Error(`No SSH keys found for GitHub user: ${githubUsername}`);
|
|
30
|
+
}
|
|
31
|
+
for (const publicKey of keys) {
|
|
32
|
+
const identity = await (0, client_1.requestJson)(context, '/auth/identities', {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
body: {
|
|
35
|
+
email,
|
|
36
|
+
public_key: publicKey,
|
|
37
|
+
label: `github-${githubUsername}`,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
results.identities.push(identity);
|
|
41
|
+
results.keys_registered += 1;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Add user to org if org_id provided
|
|
45
|
+
if (orgId) {
|
|
46
|
+
// Get user_id from the first registered identity, or look up by email
|
|
47
|
+
let userId;
|
|
48
|
+
if (results.identities.length > 0) {
|
|
49
|
+
userId = results.identities[0].user_id;
|
|
50
|
+
}
|
|
51
|
+
if (userId) {
|
|
52
|
+
const membership = await (0, client_1.requestJson)(context, `/orgs/${orgId}/members`, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
body: {
|
|
55
|
+
user_id: userId,
|
|
56
|
+
role,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
results.membership = membership;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const summary = [
|
|
63
|
+
`Invited ${email}`,
|
|
64
|
+
results.keys_registered > 0 ? `${results.keys_registered} SSH key(s) registered` : null,
|
|
65
|
+
results.membership ? `Added to ${orgId} as ${role}` : null,
|
|
66
|
+
].filter(Boolean).join(', ');
|
|
67
|
+
(0, output_1.outputJson)(results, json, `+ ${summary}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
default:
|
|
71
|
+
throw new Error('Usage: eve admin <invite>');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function fetchGitHubKeys(username) {
|
|
75
|
+
const response = await fetch(`https://github.com/${username}.keys`);
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
if (response.status === 404) {
|
|
78
|
+
throw new Error(`GitHub user not found: ${username}`);
|
|
79
|
+
}
|
|
80
|
+
throw new Error(`Failed to fetch GitHub keys: HTTP ${response.status}`);
|
|
81
|
+
}
|
|
82
|
+
const text = await response.text();
|
|
83
|
+
return text.trim().split('\n').filter(k => k.length > 0);
|
|
84
|
+
}
|