relic 0.4.4 → 0.6.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
@@ -1,11 +1,36 @@
1
- # Relic CLI
1
+ # Relic
2
2
 
3
- Zero-knowledge secret layer CLI. Fetches encrypted secrets from the server, decrypts them locally, and injects them into the process environment.
3
+ Zero-knowledge secret layer for your projects. Encrypted on your device, never exposed to anyone else. Not even us.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- bun install
8
+ # npm
9
+ npm install -g relic
10
+
11
+ # Homebrew
12
+ brew install heycupola/tap/relic
13
+
14
+ # Download binary
15
+ curl -fsSL https://github.com/heycupola/relic/releases/latest/download/relic-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m).tar.gz | tar -xz -C /usr/local/bin
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ```bash
21
+ # Launch the TUI
22
+ relic
23
+
24
+ # Authenticate
25
+ relic login
26
+
27
+ # Initialize a project
28
+ relic init
29
+
30
+ # Run a command with secrets injected
31
+ relic run -e production -- npm run deploy
32
+ relic run -e staging -f database -- ./migrate.sh
33
+ relic run -e production -s client -- npm run build
9
34
  ```
10
35
 
11
36
  ## Commands
@@ -14,20 +39,14 @@ bun install
14
39
  |---------|-------------|
15
40
  | `relic` | Launch the TUI (default) |
16
41
  | `relic login` | Authenticate via device code flow |
17
- | `relic logout` | Clear session, cached keys, and password |
18
- | `relic whoami` | Show current user (name, email, plan) |
42
+ | `relic logout` | Clear session and cached data |
43
+ | `relic whoami` | Show current user |
19
44
  | `relic projects` | List projects with environments and folders |
20
- | `relic init` | Create `relic.toml` and `.relic/` directory |
45
+ | `relic init` | Create `relic.toml` for the current project |
21
46
  | `relic run` | Run a command with secrets injected |
22
- | `relic telemetry status` | Show telemetry status |
23
- | `relic telemetry enable` | Enable telemetry |
24
- | `relic telemetry disable` | Disable telemetry |
47
+ | `relic telemetry` | Manage anonymous usage data collection |
25
48
 
26
- ### `relic run`
27
-
28
- ```bash
29
- relic run -e <environment> [options] -- <command>
30
- ```
49
+ ### `relic run` options
31
50
 
32
51
  | Flag | Description |
33
52
  |------|-------------|
@@ -36,94 +55,36 @@ relic run -e <environment> [options] -- <command>
36
55
  | `-s, --scope` | `client`, `server`, or `shared` |
37
56
  | `-p, --project` | Project ID (overrides `relic.toml`) |
38
57
 
39
- ```bash
40
- relic run -e production -- npm run deploy
41
- relic run -e staging -f database -- ./migrate.sh
42
- relic run -e production -s client -- npm run build
43
- ```
44
-
45
- ## Configuration
46
-
47
- `relic.toml` in project root:
48
-
49
- ```toml
50
- project_id = "<uuid>"
51
- ```
52
-
53
- Created by `relic init`. The CLI walks up from the current directory to find it.
54
-
55
- ## Runner (FFI)
56
-
57
- Secret injection uses a Rust binary (`packages/runner`) loaded via Bun FFI (`dlopen`). The runner:
58
-
59
- - Spawns the child process with a clean environment (`env_clear()`)
60
- - Injects only the decrypted secrets
61
- - Forwards signals (SIGTERM, SIGINT)
62
- - Uses `Zeroizing` for secret memory and disables core dumps
63
-
64
- Prebuilt binaries in `prebuilds/` for: `darwin-arm64`, `darwin-x64`, `linux-x64`, `win32-x64`.
65
-
66
- ## Caching
67
-
68
- Local SQLite cache at `.relic/cache.db` (relative to `relic.toml` location). Used in session mode only; API key mode always fetches fresh data.
69
-
70
- **Cached data:** environment/folder ID mappings, encrypted secrets, encrypted project key.
71
-
72
- **Invalidation:** on each `relic run`, the CLI compares local `lastCachedAt` against the backend `updatedAt`. Stale cache triggers a fresh fetch. Key rotation invalidates all caches.
73
-
74
- Scope filtering (`--scope`) is applied locally against cached data.
75
-
76
58
  ## CI/CD
77
59
 
78
- Use API keys instead of interactive login:
79
-
80
- | Variable | Description |
81
- |----------|-------------|
82
- | `RELIC_API_KEY` | API key for authentication |
83
- | `RELIC_PASSWORD` | Master password for decryption |
84
- | `RELIC_PROJECT_ID` | Project ID (optional if `relic.toml` exists) |
85
- | `CONVEX_SITE_URL` | Convex HTTP actions URL |
86
-
87
- ### GitHub Actions
60
+ Use API keys for non-interactive environments:
88
61
 
89
62
  ```yaml
63
+ # GitHub Actions
90
64
  - name: Deploy with secrets
91
65
  env:
92
66
  RELIC_API_KEY: ${{ secrets.RELIC_API_KEY }}
93
67
  RELIC_PASSWORD: ${{ secrets.RELIC_PASSWORD }}
94
- RELIC_PROJECT_ID: ${{ secrets.RELIC_PROJECT_ID }}
95
- CONVEX_URL: ${{ secrets.CONVEX_URL }}
96
- CONVEX_SITE_URL: ${{ secrets.CONVEX_SITE_URL }}
97
- run: bunx relic run -e production -- npm run deploy
68
+ run: npx relic run -e production -- npm run deploy
98
69
  ```
99
70
 
100
- ## Structure
71
+ | Variable | Description |
72
+ |----------|-------------|
73
+ | `RELIC_API_KEY` | API key for authentication |
74
+ | `RELIC_PASSWORD` | Master password for decryption |
75
+ | `RELIC_PROJECT_ID` | Project ID (optional if `relic.toml` exists) |
101
76
 
102
- ```
103
- ├── index.ts # Entry point (commander setup)
104
- ├── commands/
105
- │ ├── init.ts # relic init
106
- │ ├── login.ts # relic login
107
- │ ├── logout.ts # relic logout
108
- │ ├── whoami.ts # relic whoami
109
- │ ├── projects.ts # relic projects
110
- │ ├── run.ts # relic run
111
- │ └── telemetry.ts # relic telemetry
112
- ├── lib/
113
- │ ├── api.ts # Convex API client, secret export
114
- │ ├── config.ts # relic.toml loading/saving
115
- │ ├── crypto.ts # Secret decryption helpers
116
- │ └── types.ts # SecretScope type
117
- ├── ffi/
118
- │ ├── bridge.ts # RunnerBridge FFI wrapper
119
- │ ├── helper.ts # Library loading (dlopen)
120
- │ └── constants.ts # URLs
121
- └── helpers/
122
- └── cache.ts # SQLite cache
123
- ```
77
+ ## Supported Platforms
78
+
79
+ | Platform | Architecture |
80
+ |----------|-------------|
81
+ | macOS | ARM64 (Apple Silicon) |
82
+ | macOS | x64 (Intel) |
83
+ | Linux | x64 |
84
+ | Windows | x64 |
124
85
 
125
- ## Development
86
+ ## Links
126
87
 
127
- ```bash
128
- bun run index.ts
129
- ```
88
+ - [Website](https://heyrelic.com)
89
+ - [Documentation](https://docs.heyrelic.com)
90
+ - [GitHub](https://github.com/heycupola/relic)
package/bin/relic ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFileSync } from "node:child_process";
4
+ import { existsSync } from "node:fs";
5
+ import { join, dirname } from "node:path";
6
+ import { createRequire } from "node:module";
7
+ import { platform, arch } from "node:os";
8
+
9
+ const PLATFORM_MAP = {
10
+ "darwin-arm64": "relic-cli-darwin-arm64",
11
+ "darwin-x64": "relic-cli-darwin-x64",
12
+ "linux-x64": "relic-cli-linux-x64",
13
+ "win32-x64": "relic-cli-windows-x64",
14
+ };
15
+
16
+ const currentPlatform = `${platform()}-${arch()}`;
17
+ const pkg = PLATFORM_MAP[currentPlatform];
18
+
19
+ if (!pkg) {
20
+ console.error(
21
+ `relic: Unsupported platform ${currentPlatform}.\n` +
22
+ `Supported: ${Object.keys(PLATFORM_MAP).join(", ")}\n` +
23
+ `Download manually from: https://github.com/heycupola/relic/releases`
24
+ );
25
+ process.exit(1);
26
+ }
27
+
28
+ const require = createRequire(import.meta.url);
29
+ const isWindows = platform() === "win32";
30
+ const binaryName = isWindows ? "relic.exe" : "relic";
31
+
32
+ let binary;
33
+ try {
34
+ const pkgJson = require.resolve(`${pkg}/package.json`);
35
+ binary = join(dirname(pkgJson), "bin", binaryName);
36
+ } catch {
37
+ console.error(
38
+ `relic: Platform package ${pkg} is not installed.\n` +
39
+ `Try reinstalling: npm install -g relic\n\n` +
40
+ `If the problem persists, download from:\n` +
41
+ ` https://github.com/heycupola/relic/releases`
42
+ );
43
+ process.exit(1);
44
+ }
45
+
46
+ if (!existsSync(binary)) {
47
+ console.error(
48
+ `relic: Binary not found at ${binary}\n` +
49
+ `Try reinstalling: npm install -g relic`
50
+ );
51
+ process.exit(1);
52
+ }
53
+
54
+ try {
55
+ execFileSync(binary, process.argv.slice(2), {
56
+ stdio: "inherit",
57
+ env: process.env,
58
+ });
59
+ } catch (err) {
60
+ if (err.status !== null && err.status !== undefined) {
61
+ process.exit(err.status);
62
+ }
63
+ if (err.signal) {
64
+ process.kill(process.pid, err.signal);
65
+ }
66
+ throw err;
67
+ }
package/package.json CHANGED
@@ -1,69 +1,34 @@
1
1
  {
2
2
  "name": "relic",
3
- "version": "0.4.4",
3
+ "version": "0.6.0",
4
4
  "description": "The Relic CLI for managing and sharing secrets. Encrypted on your device, never exposed to anyone else. Not even us.",
5
- "keywords": [
6
- "cli",
7
- "tui"
8
- ],
5
+ "license": "MIT",
6
+ "type": "module",
9
7
  "repository": {
10
8
  "type": "git",
11
- "url": "https://github.com/heycupola/relic.git",
12
- "directory": "apps/cli"
9
+ "url": "https://github.com/heycupola/relic.git"
13
10
  },
11
+ "keywords": [
12
+ "cli",
13
+ "secrets",
14
+ "encryption",
15
+ "security"
16
+ ],
14
17
  "author": "Can Vardar",
15
- "license": "MIT",
16
- "module": "index.ts",
17
- "type": "module",
18
18
  "bin": {
19
- "relic": "dist/cli.js"
20
- },
21
- "scripts": {
22
- "build": "bun run scripts/build.ts",
23
- "build:runner": "cd ../../packages/runner && cargo build --release",
24
- "prepublishOnly": "bun run build",
25
- "dev:cli": "DEV=true bun run build:runner && bun run index.ts",
26
- "log:watch": "bun run ../../packages/logger/scripts/watch.ts",
27
- "lint": "biome check --write .",
28
- "format": "biome format --write .",
29
- "check-types": "tsc --noEmit",
30
- "test": "bun test"
19
+ "relic": "bin/relic"
31
20
  },
32
21
  "files": [
33
- "dist/**",
34
- "prebuilds/**",
22
+ "bin/",
35
23
  "README.md"
36
24
  ],
37
- "dependencies": {
38
- "argon2": "^0.41.1"
39
- },
40
25
  "optionalDependencies": {
41
- "@opentui/core-darwin-arm64": "0.1.65",
42
- "@opentui/core-darwin-x64": "0.1.65",
43
- "@opentui/core-linux-x64": "0.1.65",
44
- "@opentui/core-win32-x64": "0.1.65"
45
- },
46
- "devDependencies": {
47
- "@clack/prompts": "^0.11.0",
48
- "@repo/auth": "*",
49
- "@repo/backend": "*",
50
- "@repo/crypto": "*",
51
- "@repo/logger": "*",
52
- "@repo/tui": "*",
53
- "@repo/typescript-config": "*",
54
- "@types/bun": "latest",
55
- "bun-types": "^1.3.1",
56
- "commander": "^13.1.0",
57
- "convex": "catalog:",
58
- "open": "^11.0.0",
59
- "ora": "^8.2.0",
60
- "picocolors": "^1.1.1",
61
- "smol-toml": "^1.6.0"
62
- },
63
- "peerDependencies": {
64
- "typescript": "^5"
26
+ "relic-cli-darwin-arm64": "0.6.0",
27
+ "relic-cli-darwin-x64": "0.6.0",
28
+ "relic-cli-linux-x64": "0.6.0",
29
+ "relic-cli-windows-x64": "0.6.0"
65
30
  },
66
31
  "engines": {
67
32
  "node": ">=18"
68
33
  }
69
- }
34
+ }