@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 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:4701 \
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 **optional** per stack. When the server has `EVE_AUTH_ENABLED=false`, login is not required.
55
- Supabase settings can be stored in a profile or provided via `EVE_SUPABASE_URL` and
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
- # Login (cloud)
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
- --profile prod
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
+ }