@reumbra/forge 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 +165 -0
- package/bin/forge.js +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +225 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/activate.d.ts +1 -0
- package/dist/commands/activate.js +55 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/config.d.ts +1 -0
- package/dist/commands/config.js +35 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/dashboard.d.ts +1 -0
- package/dist/commands/dashboard.js +171 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/deactivate.d.ts +1 -0
- package/dist/commands/deactivate.js +33 -0
- package/dist/commands/deactivate.js.map +1 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.js +156 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +94 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.js +46 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +75 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.js +31 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.js +30 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/lib/api.d.ts +17 -0
- package/dist/lib/api.js +53 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/config.d.ts +4 -0
- package/dist/lib/config.js +40 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/logger.d.ts +11 -0
- package/dist/lib/logger.js +40 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/machine-id.d.ts +5 -0
- package/dist/lib/machine-id.js +11 -0
- package/dist/lib/machine-id.js.map +1 -0
- package/dist/lib/paths.d.ts +8 -0
- package/dist/lib/paths.js +13 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/styles.d.ts +32 -0
- package/dist/lib/styles.js +50 -0
- package/dist/lib/styles.js.map +1 -0
- package/dist/lib/ui.d.ts +22 -0
- package/dist/lib/ui.js +131 -0
- package/dist/lib/ui.js.map +1 -0
- package/dist/lib/zip.d.ts +6 -0
- package/dist/lib/zip.js +56 -0
- package/dist/lib/zip.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Forge DevKit CLI
|
|
2
|
+
|
|
3
|
+
**Package:** `@reumbra/forge`
|
|
4
|
+
**Role:** CLI tool for installing and managing Forge plugins for Claude Code
|
|
5
|
+
|
|
6
|
+
## Ecosystem
|
|
7
|
+
|
|
8
|
+
Forge DevKit is a commercial product by [Reumbra](https://reumbra.dev) — AI-powered project scaffolding tools for Claude Code.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
12
|
+
│ Forge DevKit Ecosystem │
|
|
13
|
+
├──────────────────────────────────────────────────────────────────┤
|
|
14
|
+
│ │
|
|
15
|
+
│ forge-devkit-cli (this repo) PUBLIC │
|
|
16
|
+
│ └─ npm @reumbra/forge │
|
|
17
|
+
│ └─ Commands: activate, install, update, list, status, doctor │
|
|
18
|
+
│ └─ User-facing tool, distributed via npm │
|
|
19
|
+
│ │
|
|
20
|
+
│ forge-devkit-api PRIVATE │
|
|
21
|
+
│ └─ License validation, plugin delivery, webhooks │
|
|
22
|
+
│ └─ Node.js (Fastify) + PostgreSQL (Supabase) + AWS S3 │
|
|
23
|
+
│ │
|
|
24
|
+
│ forge-devkit-landing PUBLIC │
|
|
25
|
+
│ └─ reumbra.dev/forge — website, pricing, docs │
|
|
26
|
+
│ └─ Astro + Tailwind, hosted on Cloudflare Pages │
|
|
27
|
+
│ │
|
|
28
|
+
│ forge-devkit-plugins PRIVATE (currently public) │
|
|
29
|
+
│ └─ Plugin source code, tests, design docs │
|
|
30
|
+
│ └─ Currently: github.com/maselious/ai-marketplace │
|
|
31
|
+
│ │
|
|
32
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Architecture
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
┌──────────────┐ ┌─────────────────┐
|
|
39
|
+
│ forge CLI │──────▶│ Forge API │
|
|
40
|
+
│ (this repo) │ │ (devkit-api) │
|
|
41
|
+
│ │ │ │
|
|
42
|
+
│ activate │ │ /auth/activate │
|
|
43
|
+
│ install │ │ /plugins/list │
|
|
44
|
+
│ update │ │ /plugins/down │
|
|
45
|
+
│ list │ │ /license/check │
|
|
46
|
+
└──────────────┘ └────────┬────────┘
|
|
47
|
+
│
|
|
48
|
+
┌────────┴─────────┐
|
|
49
|
+
│ Plugin Storage │
|
|
50
|
+
│ (AWS S3) │
|
|
51
|
+
└───────────────────┘
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Commands
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
forge activate <license-key> # Bind license to machine
|
|
58
|
+
forge deactivate # Unbind (for machine transfer)
|
|
59
|
+
forge install <plugin> [version] # Download and install plugin
|
|
60
|
+
forge update [plugin] # Update all or specific plugin
|
|
61
|
+
forge list # Show installed + available
|
|
62
|
+
forge status # License: expiry, binding, limits
|
|
63
|
+
forge doctor # Diagnostics: Claude Code found? Plugins intact?
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Config Storage
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
// ~/.forge/config.json
|
|
70
|
+
{
|
|
71
|
+
"license_key": "FRG-XXXX-XXXX-XXXX",
|
|
72
|
+
"machine_id": "a1b2c3...",
|
|
73
|
+
"api_url": "https://api.reumbra.com/velvet",
|
|
74
|
+
"installed_plugins": {
|
|
75
|
+
"forge-core": { "version": "1.5.0", "installed_at": "2026-02-19T..." },
|
|
76
|
+
"forge-product": { "version": "0.4.0", "installed_at": "2026-02-19T..." }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Install Flow
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
$ forge install core
|
|
85
|
+
|
|
86
|
+
1. Read config.json -> license_key, machine_id
|
|
87
|
+
2. POST /plugins/download {license_key, machine_id, plugin: "forge-core", version: "latest"}
|
|
88
|
+
3. API validates license, expiry, machine_id, plugin access
|
|
89
|
+
4. Returns signed download URL (R2 presigned, 5 min TTL)
|
|
90
|
+
5. CLI downloads .zip via signed URL
|
|
91
|
+
6. Unpacks to ~/.forge/cache/forge-core@1.5.0/
|
|
92
|
+
7. Links into Claude Code plugin directory
|
|
93
|
+
8. Updates config.json -> installed_plugins
|
|
94
|
+
9. "forge-core@1.5.0 installed. Run /forge:setup in your project"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Machine ID & Limits
|
|
98
|
+
|
|
99
|
+
License bound to N devices (default: 3). Machine ID = SHA256 hash of hostname + OS + username.
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
Activate flow:
|
|
103
|
+
CLI: POST /auth/activate {license_key, machine_id}
|
|
104
|
+
API: validate key -> check slots (3 max) -> register machine_id -> 200 OK
|
|
105
|
+
or 403 "All device slots used. Run forge deactivate on another machine"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Offline Behavior
|
|
109
|
+
|
|
110
|
+
- Already installed plugins: work forever (just .md files on disk)
|
|
111
|
+
- Install/update: requires API connection
|
|
112
|
+
- After license expiry: installed versions continue working, updates blocked
|
|
113
|
+
|
|
114
|
+
## Tech Stack
|
|
115
|
+
|
|
116
|
+
- **Runtime:** Node.js >=20
|
|
117
|
+
- **Package:** `@reumbra/forge` (public, scoped npm)
|
|
118
|
+
- **Dependencies:** Commander.js (routing), @clack/prompts (interactive UI)
|
|
119
|
+
- **Build:** TypeScript (strict), Biome (lint + format)
|
|
120
|
+
- **Tests:** Vitest (112 tests, 17 suites)
|
|
121
|
+
|
|
122
|
+
## Installation
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npm install -g @reumbra/forge
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Or run without installing:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx @reumbra/forge doctor
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Development
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pnpm install # Install dev dependencies
|
|
138
|
+
pnpm dev -- doctor # Run any command in dev mode (via tsx)
|
|
139
|
+
pnpm build # Compile TypeScript → dist/
|
|
140
|
+
pnpm check # Lint + format (Biome)
|
|
141
|
+
pnpm test # Run tests
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Project Structure
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
src/
|
|
148
|
+
├── cli.ts # Entry point, arg parser, command dispatch
|
|
149
|
+
├── types.ts # Shared types (config, API responses)
|
|
150
|
+
├── commands/
|
|
151
|
+
│ ├── activate.ts # forge activate <key>
|
|
152
|
+
│ ├── deactivate.ts # forge deactivate
|
|
153
|
+
│ ├── install.ts # forge install <plugin> [version]
|
|
154
|
+
│ ├── update.ts # forge update [plugin]
|
|
155
|
+
│ ├── list.ts # forge list
|
|
156
|
+
│ ├── status.ts # forge status
|
|
157
|
+
│ └── doctor.ts # forge doctor (local only)
|
|
158
|
+
└── lib/
|
|
159
|
+
├── api.ts # HTTP client (fetch), ApiError
|
|
160
|
+
├── config.ts # ~/.forge/config.json management
|
|
161
|
+
├── logger.ts # CLI output (colors, tables, icons)
|
|
162
|
+
├── machine-id.ts # SHA256-based device fingerprint
|
|
163
|
+
├── paths.ts # ~/.forge/ path constants
|
|
164
|
+
└── zip.ts # ZIP extraction (Node.js built-ins)
|
|
165
|
+
```
|
package/bin/forge.js
ADDED
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import { activate } from "./commands/activate.js";
|
|
7
|
+
import { showConfig } from "./commands/config.js";
|
|
8
|
+
import { dashboard } from "./commands/dashboard.js";
|
|
9
|
+
import { deactivate } from "./commands/deactivate.js";
|
|
10
|
+
import { doctor } from "./commands/doctor.js";
|
|
11
|
+
import { install } from "./commands/install.js";
|
|
12
|
+
import { list } from "./commands/list.js";
|
|
13
|
+
import { status } from "./commands/status.js";
|
|
14
|
+
import { uninstall } from "./commands/uninstall.js";
|
|
15
|
+
import { update } from "./commands/update.js";
|
|
16
|
+
import { loadConfig } from "./lib/config.js";
|
|
17
|
+
import { log } from "./lib/logger.js";
|
|
18
|
+
import { bold, dim, reset } from "./lib/styles.js";
|
|
19
|
+
import { banner } from "./lib/ui.js";
|
|
20
|
+
function getVersion() {
|
|
21
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
23
|
+
return pkg.version;
|
|
24
|
+
}
|
|
25
|
+
export function createProgram() {
|
|
26
|
+
const program = new Command();
|
|
27
|
+
program
|
|
28
|
+
.name("forge")
|
|
29
|
+
.version(`forge v${getVersion()}`, "-v, --version")
|
|
30
|
+
.addHelpText("before", `\n${banner()}\n`)
|
|
31
|
+
.addHelpText("after", `\n${bold}Examples:${reset}\n ${dim}$${reset} forge activate FRG-XXXX-XXXX-XXXX\n ${dim}$${reset} forge install core\n ${dim}$${reset} forge install forge-product@1.2.0\n ${dim}$${reset} forge list\n`)
|
|
32
|
+
.usage("[command] [options]")
|
|
33
|
+
.showHelpAfterError('Run "forge --help" for available commands.');
|
|
34
|
+
// Catch-all: no command → interactive dashboard (TTY) or help (non-TTY), unknown → error
|
|
35
|
+
program.argument("[command]").action(async (cmd) => {
|
|
36
|
+
if (!cmd) {
|
|
37
|
+
if (process.stdin.isTTY) {
|
|
38
|
+
await dashboard();
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
program.help();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
log.error(`Unknown command: ${cmd}`);
|
|
46
|
+
log.info('Run "forge --help" for available commands.');
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
program
|
|
51
|
+
.command("activate")
|
|
52
|
+
.description("Bind license to this machine")
|
|
53
|
+
.argument("[license-key]", "Forge license key (FRG-XXXX-XXXX-XXXX)")
|
|
54
|
+
.action(async (key) => {
|
|
55
|
+
if (!key) {
|
|
56
|
+
if (!process.stdin.isTTY) {
|
|
57
|
+
log.error("Usage: forge activate <license-key>");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const input = await p.text({
|
|
61
|
+
message: "Enter your license key:",
|
|
62
|
+
placeholder: "FRG-XXXX-XXXX-XXXX",
|
|
63
|
+
validate: (v) => {
|
|
64
|
+
if (!v || !/^FRG-[A-Z2-9]{4}-[A-Z2-9]{4}-[A-Z2-9]{4}$/.test(v)) {
|
|
65
|
+
return "Invalid format. Expected: FRG-XXXX-XXXX-XXXX";
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
if (p.isCancel(input)) {
|
|
70
|
+
p.cancel("Activation cancelled.");
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
key = input;
|
|
74
|
+
}
|
|
75
|
+
await activate(key);
|
|
76
|
+
});
|
|
77
|
+
program
|
|
78
|
+
.command("deactivate")
|
|
79
|
+
.description("Unbind this machine (free a slot)")
|
|
80
|
+
.action(async () => {
|
|
81
|
+
if (process.stdin.isTTY) {
|
|
82
|
+
const confirmed = await p.confirm({
|
|
83
|
+
message: "Deactivate this machine? This will free up a machine slot.",
|
|
84
|
+
});
|
|
85
|
+
if (p.isCancel(confirmed) || !confirmed) {
|
|
86
|
+
p.cancel("Deactivation cancelled.");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
await deactivate();
|
|
91
|
+
});
|
|
92
|
+
program
|
|
93
|
+
.command("install")
|
|
94
|
+
.description("Download and install a plugin")
|
|
95
|
+
.argument("[plugin]", "Plugin name (e.g. core, forge-product@1.2.0)")
|
|
96
|
+
.argument("[version]", "Specific version")
|
|
97
|
+
.action(async (plugin, version) => {
|
|
98
|
+
if (!plugin) {
|
|
99
|
+
if (!process.stdin.isTTY) {
|
|
100
|
+
log.error("Usage: forge install <plugin> [version]");
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
const input = await p.text({
|
|
104
|
+
message: "Plugin name to install:",
|
|
105
|
+
placeholder: "e.g. core, forge-product@1.2.0",
|
|
106
|
+
validate: (v) => {
|
|
107
|
+
if (!v?.trim())
|
|
108
|
+
return "Plugin name is required";
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
if (p.isCancel(input)) {
|
|
112
|
+
p.cancel("Installation cancelled.");
|
|
113
|
+
process.exit(0);
|
|
114
|
+
}
|
|
115
|
+
plugin = input.trim();
|
|
116
|
+
}
|
|
117
|
+
if (plugin.includes("@")) {
|
|
118
|
+
const [name, ver] = plugin.split("@");
|
|
119
|
+
await install(name, ver);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
await install(plugin, version);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
program
|
|
126
|
+
.command("uninstall")
|
|
127
|
+
.alias("remove")
|
|
128
|
+
.description("Remove an installed plugin")
|
|
129
|
+
.argument("[plugin]", "Plugin name to remove")
|
|
130
|
+
.action(async (plugin) => {
|
|
131
|
+
if (!plugin) {
|
|
132
|
+
if (!process.stdin.isTTY) {
|
|
133
|
+
log.error("Usage: forge uninstall <plugin>");
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
const config = loadConfig();
|
|
137
|
+
const installed = Object.keys(config.installed_plugins);
|
|
138
|
+
if (installed.length === 0) {
|
|
139
|
+
log.warn("No plugins installed.");
|
|
140
|
+
process.exit(0);
|
|
141
|
+
}
|
|
142
|
+
const selected = await p.select({
|
|
143
|
+
message: "Select plugin to uninstall:",
|
|
144
|
+
options: installed.map((name) => ({
|
|
145
|
+
value: name,
|
|
146
|
+
label: name,
|
|
147
|
+
hint: `v${config.installed_plugins[name].version}`,
|
|
148
|
+
})),
|
|
149
|
+
});
|
|
150
|
+
if (p.isCancel(selected)) {
|
|
151
|
+
p.cancel("Uninstall cancelled.");
|
|
152
|
+
process.exit(0);
|
|
153
|
+
}
|
|
154
|
+
plugin = selected;
|
|
155
|
+
}
|
|
156
|
+
if (process.stdin.isTTY) {
|
|
157
|
+
const confirmed = await p.confirm({
|
|
158
|
+
message: `Uninstall ${bold}${plugin}${reset}?`,
|
|
159
|
+
});
|
|
160
|
+
if (p.isCancel(confirmed) || !confirmed) {
|
|
161
|
+
p.cancel("Uninstall cancelled.");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
uninstall(plugin);
|
|
166
|
+
});
|
|
167
|
+
program
|
|
168
|
+
.command("update")
|
|
169
|
+
.description("Update all or specific plugin")
|
|
170
|
+
.argument("[plugin]", "Plugin to update (omit for all)")
|
|
171
|
+
.action(async (plugin) => {
|
|
172
|
+
await update(plugin);
|
|
173
|
+
});
|
|
174
|
+
program
|
|
175
|
+
.command("list")
|
|
176
|
+
.alias("ls")
|
|
177
|
+
.description("Show available plugins")
|
|
178
|
+
.action(async () => {
|
|
179
|
+
await list();
|
|
180
|
+
});
|
|
181
|
+
program
|
|
182
|
+
.command("status")
|
|
183
|
+
.description("License info: plan, expiry, devices")
|
|
184
|
+
.action(async () => {
|
|
185
|
+
await status();
|
|
186
|
+
});
|
|
187
|
+
program
|
|
188
|
+
.command("config")
|
|
189
|
+
.description("Show current configuration")
|
|
190
|
+
.action(() => {
|
|
191
|
+
showConfig();
|
|
192
|
+
});
|
|
193
|
+
program
|
|
194
|
+
.command("doctor")
|
|
195
|
+
.description("Run diagnostics")
|
|
196
|
+
.action(async () => {
|
|
197
|
+
const result = await doctor();
|
|
198
|
+
if (result.issues > 0)
|
|
199
|
+
process.exit(1);
|
|
200
|
+
});
|
|
201
|
+
return program;
|
|
202
|
+
}
|
|
203
|
+
async function main() {
|
|
204
|
+
const program = createProgram();
|
|
205
|
+
try {
|
|
206
|
+
await program.parseAsync();
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
if (err instanceof Error) {
|
|
210
|
+
if (err.message.includes("fetch failed") || err.message.includes("ECONNREFUSED")) {
|
|
211
|
+
log.error("Could not connect to Forge API.");
|
|
212
|
+
log.info("Check your internet connection or try again later.");
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
log.error(err.message);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
log.error("An unexpected error occurred.");
|
|
220
|
+
}
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
main();
|
|
225
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function activate(licenseKey: string): Promise<void>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ApiError, apiRequest } from "../lib/api.js";
|
|
2
|
+
import { loadConfig, saveConfig } from "../lib/config.js";
|
|
3
|
+
import { log } from "../lib/logger.js";
|
|
4
|
+
import { bold, dim, green, reset } from "../lib/styles.js";
|
|
5
|
+
import { box, createSpinner, statusBadge } from "../lib/ui.js";
|
|
6
|
+
export async function activate(licenseKey) {
|
|
7
|
+
if (!/^FRG-[A-Z2-9]{4}-[A-Z2-9]{4}-[A-Z2-9]{4}$/.test(licenseKey)) {
|
|
8
|
+
log.error("Invalid license key format. Expected: FRG-XXXX-XXXX-XXXX");
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
config.license_key = licenseKey;
|
|
13
|
+
const spinner = createSpinner("Activating license...");
|
|
14
|
+
try {
|
|
15
|
+
const result = await apiRequest(config, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
path: "/auth/activate",
|
|
18
|
+
body: {
|
|
19
|
+
license_key: licenseKey,
|
|
20
|
+
machine_id: config.machine_id,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
saveConfig(config);
|
|
24
|
+
const expires = new Date(result.license.expires_at);
|
|
25
|
+
spinner.stop(`${green}✓${reset} License activated!`);
|
|
26
|
+
console.log(box([
|
|
27
|
+
`${bold}Plan:${reset} ${result.license.plan}`,
|
|
28
|
+
`${bold}Expires:${reset} ${expires.toLocaleDateString()}`,
|
|
29
|
+
`${bold}Machines:${reset} ${result.license.machines_used}/${result.license.max_machines}`,
|
|
30
|
+
`${bold}Status:${reset} ${statusBadge("active")}`,
|
|
31
|
+
], { title: "License", borderColor: dim }));
|
|
32
|
+
log.info(`${dim}Run \`forge install <plugin>\` to get started.${reset}`);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
spinner.stop();
|
|
36
|
+
if (err instanceof ApiError) {
|
|
37
|
+
if (err.code === "MACHINE_LIMIT") {
|
|
38
|
+
log.error("All device slots are used.");
|
|
39
|
+
log.info("Run `forge deactivate` on another machine first.");
|
|
40
|
+
}
|
|
41
|
+
else if (err.code === "INVALID_LICENSE") {
|
|
42
|
+
log.error("Invalid license key. Double-check your key and try again.");
|
|
43
|
+
}
|
|
44
|
+
else if (err.code === "LICENSE_EXPIRED") {
|
|
45
|
+
log.error("This license has expired. Renew at https://reumbra.dev/forge");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
log.error(err.message);
|
|
49
|
+
}
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=activate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activate.js","sourceRoot":"","sources":["../../src/commands/activate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function showConfig(): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { loadConfig } from "../lib/config.js";
|
|
3
|
+
import { log } from "../lib/logger.js";
|
|
4
|
+
import { CONFIG_PATH } from "../lib/paths.js";
|
|
5
|
+
import { bold, dim, reset } from "../lib/styles.js";
|
|
6
|
+
import { box, table } from "../lib/ui.js";
|
|
7
|
+
export function showConfig() {
|
|
8
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
9
|
+
log.warn("No config file found. Run `forge activate <key>` to create one.");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
const maskedKey = config.license_key
|
|
14
|
+
? `${config.license_key.slice(0, 8)}..${config.license_key.slice(-4)}`
|
|
15
|
+
: "(not set)";
|
|
16
|
+
console.log(box([
|
|
17
|
+
`${bold}License:${reset} ${maskedKey}`,
|
|
18
|
+
`${bold}Machine ID:${reset} ${config.machine_id}`,
|
|
19
|
+
`${bold}API URL:${reset} ${config.api_url}`,
|
|
20
|
+
`${bold}Config:${reset} ${dim}${CONFIG_PATH}${reset}`,
|
|
21
|
+
], { title: "Forge Config", borderColor: dim }));
|
|
22
|
+
const plugins = Object.entries(config.installed_plugins);
|
|
23
|
+
if (plugins.length > 0) {
|
|
24
|
+
const rows = plugins.map(([name, info]) => [
|
|
25
|
+
name,
|
|
26
|
+
`v${info.version}`,
|
|
27
|
+
dim + new Date(info.installed_at).toLocaleDateString() + reset,
|
|
28
|
+
]);
|
|
29
|
+
console.log(table(rows, { header: ["Plugin", "Version", "Installed"] }));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
log.info("No plugins installed.");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,GAAG,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW;QAClC,CAAC,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;QACtE,CAAC,CAAC,WAAW,CAAC;IAEhB,OAAO,CAAC,GAAG,CACT,GAAG,CACD;QACE,GAAG,IAAI,WAAW,KAAK,OAAO,SAAS,EAAE;QACzC,GAAG,IAAI,cAAc,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE;QACjD,GAAG,IAAI,WAAW,KAAK,OAAO,MAAM,CAAC,OAAO,EAAE;QAC9C,GAAG,IAAI,UAAU,KAAK,QAAQ,GAAG,GAAG,WAAW,GAAG,KAAK,EAAE;KAC1D,EACD,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,EAAE,CAC5C,CACF,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI;YACJ,IAAI,IAAI,CAAC,OAAO,EAAE;YAClB,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,kBAAkB,EAAE,GAAG,KAAK;SAC/D,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACpC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function dashboard(): Promise<void>;
|