@true-and-useful/janee 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 +324 -0
- package/dist/cli/commands/add.d.ts +6 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +191 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +140 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +2 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +54 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +6 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +55 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/remove.d.ts +2 -0
- package/dist/cli/commands/remove.d.ts.map +1 -0
- package/dist/cli/commands/remove.js +92 -0
- package/dist/cli/commands/remove.js.map +1 -0
- package/dist/cli/commands/revoke.d.ts +2 -0
- package/dist/cli/commands/revoke.d.ts.map +1 -0
- package/dist/cli/commands/revoke.js +55 -0
- package/dist/cli/commands/revoke.js.map +1 -0
- package/dist/cli/commands/serve-mcp.d.ts +2 -0
- package/dist/cli/commands/serve-mcp.d.ts.map +1 -0
- package/dist/cli/commands/serve-mcp.js +83 -0
- package/dist/cli/commands/serve-mcp.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +6 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +12 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/sessions.d.ts +2 -0
- package/dist/cli/commands/sessions.d.ts.map +1 -0
- package/dist/cli/commands/sessions.js +71 -0
- package/dist/cli/commands/sessions.js.map +1 -0
- package/dist/cli/config-yaml.d.ts +73 -0
- package/dist/cli/config-yaml.d.ts.map +1 -0
- package/dist/cli/config-yaml.js +213 -0
- package/dist/cli/config-yaml.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +61 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/audit.d.ts +63 -0
- package/dist/core/audit.d.ts.map +1 -0
- package/dist/core/audit.js +165 -0
- package/dist/core/audit.js.map +1 -0
- package/dist/core/crypto.d.ts +26 -0
- package/dist/core/crypto.d.ts.map +1 -0
- package/dist/core/crypto.js +89 -0
- package/dist/core/crypto.js.map +1 -0
- package/dist/core/mcp-server.d.ts +59 -0
- package/dist/core/mcp-server.d.ts.map +1 -0
- package/dist/core/mcp-server.js +220 -0
- package/dist/core/mcp-server.js.map +1 -0
- package/dist/core/rules.d.ts +43 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +149 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/sessions.d.ts +51 -0
- package/dist/core/sessions.d.ts.map +1 -0
- package/dist/core/sessions.js +143 -0
- package/dist/core/sessions.js.map +1 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ross Douglas and David Wilson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# Janee 🔐
|
|
2
|
+
|
|
3
|
+
**Secrets management for AI agents via MCP**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The Problem
|
|
8
|
+
|
|
9
|
+
AI agents need API access to be useful. The current approach is to give them your keys and hope they behave.
|
|
10
|
+
|
|
11
|
+
- 🔓 Agents have full access to Stripe, Gmail, databases
|
|
12
|
+
- 📊 No audit trail of what was accessed or why
|
|
13
|
+
- 🚫 No kill switch when things go wrong
|
|
14
|
+
- 💉 One prompt injection away from disaster
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## The Solution
|
|
19
|
+
|
|
20
|
+
Janee is an [MCP](https://modelcontextprotocol.io) server that manages API secrets for AI agents:
|
|
21
|
+
|
|
22
|
+
1. **Store your API keys** — encrypted locally in `~/.janee/`
|
|
23
|
+
2. **Run `janee serve`** — starts MCP server
|
|
24
|
+
3. **Agent requests access** — via `execute` MCP tool
|
|
25
|
+
4. **Janee injects the real key** — agent never sees it
|
|
26
|
+
5. **Everything is logged** — full audit trail
|
|
27
|
+
|
|
28
|
+
**Your keys stay on your machine. Agents never see them. You stay in control.**
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
### Install
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install -g @true-and-useful/janee
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Initialize
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
janee init
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This creates `~/.janee/config.yaml` with example services.
|
|
47
|
+
|
|
48
|
+
### Add Services
|
|
49
|
+
|
|
50
|
+
**Option 1: Interactive (recommended for first-time users)**
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
janee add
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Janee will guide you through adding a service:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Service name: stripe
|
|
60
|
+
Base URL: https://api.stripe.com
|
|
61
|
+
Auth type (bearer/hmac/headers): bearer
|
|
62
|
+
API key: sk_live_xxx
|
|
63
|
+
|
|
64
|
+
✓ Added service "stripe"
|
|
65
|
+
|
|
66
|
+
Create a capability for this service? (Y/n): y
|
|
67
|
+
Capability name (default: stripe):
|
|
68
|
+
TTL (e.g., 1h, 30m): 1h
|
|
69
|
+
Auto-approve? (Y/n): y
|
|
70
|
+
|
|
71
|
+
✓ Added capability "stripe"
|
|
72
|
+
|
|
73
|
+
Done! Run 'janee serve' to start.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Option 2: Edit config directly**
|
|
77
|
+
|
|
78
|
+
Edit `~/.janee/config.yaml`:
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
services:
|
|
82
|
+
stripe:
|
|
83
|
+
baseUrl: https://api.stripe.com
|
|
84
|
+
auth:
|
|
85
|
+
type: bearer
|
|
86
|
+
key: sk_live_xxx
|
|
87
|
+
|
|
88
|
+
capabilities:
|
|
89
|
+
stripe:
|
|
90
|
+
service: stripe
|
|
91
|
+
ttl: 1h
|
|
92
|
+
autoApprove: true
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Start the MCP server
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
janee serve
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Use with your agent
|
|
102
|
+
|
|
103
|
+
Agents that support MCP (Claude Desktop, Cursor, OpenClaw) can now call the `execute` tool to make API requests through Janee:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// Agent calls the execute tool
|
|
107
|
+
execute({
|
|
108
|
+
service: "stripe",
|
|
109
|
+
method: "GET",
|
|
110
|
+
path: "/v1/balance",
|
|
111
|
+
reason: "User asked for account balance"
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Janee decrypts the key, makes the request, logs everything, and returns the response.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## OpenClaw Integration
|
|
120
|
+
|
|
121
|
+
If you're using [OpenClaw](https://openclaw.ai), install the plugin for native tool support:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm install -g @true-and-useful/janee
|
|
125
|
+
janee init
|
|
126
|
+
# Edit ~/.janee/config.yaml with your services
|
|
127
|
+
|
|
128
|
+
# Install the OpenClaw plugin
|
|
129
|
+
openclaw plugins install @true-and-useful/janee-openclaw
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Enable in your agent config:
|
|
133
|
+
|
|
134
|
+
```json5
|
|
135
|
+
{
|
|
136
|
+
agents: {
|
|
137
|
+
list: [{
|
|
138
|
+
id: "main",
|
|
139
|
+
tools: { allow: ["janee"] }
|
|
140
|
+
}]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Your agent now has these tools:
|
|
146
|
+
|
|
147
|
+
- `janee_list_services` — Discover available APIs
|
|
148
|
+
- `janee_execute` — Make API requests through Janee
|
|
149
|
+
|
|
150
|
+
The plugin spawns `janee serve` automatically. All requests are logged to `~/.janee/logs/`.
|
|
151
|
+
|
|
152
|
+
**See [docs/OPENCLAW.md](docs/OPENCLAW.md) for full integration guide.**
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## MCP Tools
|
|
157
|
+
|
|
158
|
+
Janee exposes two MCP tools:
|
|
159
|
+
|
|
160
|
+
| Tool | Description |
|
|
161
|
+
|------|-------------|
|
|
162
|
+
| `list_services` | Discover available APIs and their policies |
|
|
163
|
+
| `execute` | Make an API request through Janee |
|
|
164
|
+
|
|
165
|
+
Agents discover what's available, then call APIs through Janee. Same audit trail, same protection.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Configuration
|
|
170
|
+
|
|
171
|
+
Config lives in `~/.janee/config.yaml`:
|
|
172
|
+
|
|
173
|
+
```yaml
|
|
174
|
+
server:
|
|
175
|
+
host: localhost
|
|
176
|
+
|
|
177
|
+
services:
|
|
178
|
+
stripe:
|
|
179
|
+
baseUrl: https://api.stripe.com
|
|
180
|
+
auth:
|
|
181
|
+
type: bearer
|
|
182
|
+
key: sk_live_xxx # encrypted at rest
|
|
183
|
+
|
|
184
|
+
github:
|
|
185
|
+
baseUrl: https://api.github.com
|
|
186
|
+
auth:
|
|
187
|
+
type: bearer
|
|
188
|
+
key: ghp_xxx
|
|
189
|
+
|
|
190
|
+
capabilities:
|
|
191
|
+
stripe:
|
|
192
|
+
service: stripe
|
|
193
|
+
ttl: 1h
|
|
194
|
+
autoApprove: true
|
|
195
|
+
|
|
196
|
+
stripe_sensitive:
|
|
197
|
+
service: stripe
|
|
198
|
+
ttl: 5m
|
|
199
|
+
requiresReason: true
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Services** = Real APIs with real keys
|
|
203
|
+
**Capabilities** = What agents can request, with policies
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Request Policies
|
|
208
|
+
|
|
209
|
+
Control exactly what requests each capability can make using `rules`:
|
|
210
|
+
|
|
211
|
+
```yaml
|
|
212
|
+
capabilities:
|
|
213
|
+
stripe_readonly:
|
|
214
|
+
service: stripe
|
|
215
|
+
ttl: 1h
|
|
216
|
+
rules:
|
|
217
|
+
allow:
|
|
218
|
+
- GET *
|
|
219
|
+
deny:
|
|
220
|
+
- POST *
|
|
221
|
+
- PUT *
|
|
222
|
+
- DELETE *
|
|
223
|
+
|
|
224
|
+
stripe_billing:
|
|
225
|
+
service: stripe
|
|
226
|
+
ttl: 15m
|
|
227
|
+
requiresReason: true
|
|
228
|
+
rules:
|
|
229
|
+
allow:
|
|
230
|
+
- GET *
|
|
231
|
+
- POST /v1/refunds/*
|
|
232
|
+
- POST /v1/invoices/*
|
|
233
|
+
deny:
|
|
234
|
+
- POST /v1/charges/* # Can't charge cards
|
|
235
|
+
- DELETE *
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**How rules work:**
|
|
239
|
+
|
|
240
|
+
1. **`deny` patterns are checked first** — explicit deny always wins
|
|
241
|
+
2. **Then `allow` patterns are checked** — must match to proceed
|
|
242
|
+
3. **No rules defined** → allow all (backward compatible)
|
|
243
|
+
4. **Rules defined but no match** → denied by default
|
|
244
|
+
|
|
245
|
+
**Pattern format:** `METHOD PATH`
|
|
246
|
+
|
|
247
|
+
- `GET *` → any GET request
|
|
248
|
+
- `POST /v1/charges/*` → POST to /v1/charges/ and subpaths
|
|
249
|
+
- `* /v1/customers` → any method to /v1/customers
|
|
250
|
+
- `DELETE /v1/customers/*` → DELETE any customer
|
|
251
|
+
|
|
252
|
+
**This makes security real:** Even if an agent lies about its "reason", it can only access the endpoints the policy allows. Enforcement happens server-side.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## CLI Reference
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
janee init # Set up ~/.janee/ with example config
|
|
260
|
+
janee add # Add a service (interactive)
|
|
261
|
+
janee add stripe -u https://api.stripe.com -k sk_xxx # Add with args
|
|
262
|
+
janee remove <service> # Remove a service
|
|
263
|
+
janee list # List configured services
|
|
264
|
+
janee serve # Start MCP server
|
|
265
|
+
janee logs # View audit log
|
|
266
|
+
janee logs -f # Tail audit log
|
|
267
|
+
janee sessions # List active sessions
|
|
268
|
+
janee revoke <id> # Kill a session
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
You can also edit `~/.janee/config.yaml` directly if you prefer.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## How It Works
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
┌─────────────┐ ┌──────────┐ ┌─────────┐
|
|
279
|
+
│ AI Agent │─────▶│ Janee │─────▶│ Stripe │
|
|
280
|
+
│ │ MCP │ MCP │ HTTP │ API │
|
|
281
|
+
└─────────────┘ └──────────┘ └─────────┘
|
|
282
|
+
│ │
|
|
283
|
+
No key Injects key
|
|
284
|
+
+ logs request
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
1. Agent calls `execute` MCP tool with service, method, path
|
|
288
|
+
2. Janee looks up service config, decrypts the real key
|
|
289
|
+
3. Makes HTTP request to real API with key
|
|
290
|
+
4. Logs: timestamp, service, method, path, status
|
|
291
|
+
5. Returns response to agent
|
|
292
|
+
|
|
293
|
+
Agent never touches the real key.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Security
|
|
298
|
+
|
|
299
|
+
- **Encryption**: Keys stored with AES-256-GCM
|
|
300
|
+
- **Local only**: MCP server over stdio (no network exposure)
|
|
301
|
+
- **Audit log**: Every request logged to `~/.janee/logs/`
|
|
302
|
+
- **Sessions**: Time-limited, revocable
|
|
303
|
+
- **Kill switch**: `janee revoke` or delete config
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Integrations
|
|
308
|
+
|
|
309
|
+
Works with any agent that speaks MCP:
|
|
310
|
+
|
|
311
|
+
- **OpenClaw** — Native plugin (`@true-and-useful/janee-openclaw`)
|
|
312
|
+
- **Claude Desktop** — MCP client
|
|
313
|
+
- **Cursor** — MCP client
|
|
314
|
+
- **Any MCP client** — just point at `janee serve`
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## License
|
|
319
|
+
|
|
320
|
+
MIT
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
**Stop giving AI agents your keys. Start controlling access.** 🔐
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"AAKA,wBAAsB,UAAU,CAC9B,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACjE,OAAO,CAAC,IAAI,CAAC,CAoLf"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.addCommand = addCommand;
|
|
37
|
+
const readline = __importStar(require("readline/promises"));
|
|
38
|
+
const process_1 = require("process");
|
|
39
|
+
const config_yaml_1 = require("../config-yaml");
|
|
40
|
+
async function addCommand(serviceName, options = {}) {
|
|
41
|
+
try {
|
|
42
|
+
// Check for YAML config
|
|
43
|
+
if (!(0, config_yaml_1.hasYAMLConfig)()) {
|
|
44
|
+
console.error('❌ No config found. Run `janee init` first.');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const rl = readline.createInterface({ input: process_1.stdin, output: process_1.stdout });
|
|
48
|
+
// Service name
|
|
49
|
+
if (!serviceName) {
|
|
50
|
+
serviceName = await rl.question('Service name: ');
|
|
51
|
+
serviceName = serviceName.trim();
|
|
52
|
+
}
|
|
53
|
+
if (!serviceName) {
|
|
54
|
+
console.error('❌ Service name is required');
|
|
55
|
+
rl.close();
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const config = (0, config_yaml_1.loadYAMLConfig)();
|
|
59
|
+
// Check if service already exists
|
|
60
|
+
if (config.services[serviceName]) {
|
|
61
|
+
console.error(`❌ Service "${serviceName}" already exists`);
|
|
62
|
+
rl.close();
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
// Base URL
|
|
66
|
+
let baseUrl = options.url;
|
|
67
|
+
if (!baseUrl) {
|
|
68
|
+
baseUrl = await rl.question('Base URL: ');
|
|
69
|
+
baseUrl = baseUrl.trim();
|
|
70
|
+
}
|
|
71
|
+
if (!baseUrl || !baseUrl.startsWith('http')) {
|
|
72
|
+
console.error('❌ Invalid base URL. Must start with http:// or https://');
|
|
73
|
+
rl.close();
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
// Auth type
|
|
77
|
+
const authTypeInput = await rl.question('Auth type (bearer/hmac/headers): ');
|
|
78
|
+
const authType = authTypeInput.trim().toLowerCase();
|
|
79
|
+
if (!['bearer', 'hmac', 'headers'].includes(authType)) {
|
|
80
|
+
console.error('❌ Invalid auth type. Must be bearer, hmac, or headers');
|
|
81
|
+
rl.close();
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
// Build auth config
|
|
85
|
+
let auth;
|
|
86
|
+
if (authType === 'bearer') {
|
|
87
|
+
let apiKey = options.key;
|
|
88
|
+
if (!apiKey) {
|
|
89
|
+
apiKey = await rl.question('API key: ');
|
|
90
|
+
apiKey = apiKey.trim();
|
|
91
|
+
}
|
|
92
|
+
if (!apiKey) {
|
|
93
|
+
console.error('❌ API key is required');
|
|
94
|
+
rl.close();
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
auth = {
|
|
98
|
+
type: 'bearer',
|
|
99
|
+
key: apiKey
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
else if (authType === 'hmac') {
|
|
103
|
+
const apiKey = await rl.question('API key: ');
|
|
104
|
+
const apiSecret = await rl.question('API secret: ');
|
|
105
|
+
if (!apiKey || !apiSecret) {
|
|
106
|
+
console.error('❌ API key and secret are required for HMAC');
|
|
107
|
+
rl.close();
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
auth = {
|
|
111
|
+
type: 'hmac',
|
|
112
|
+
apiKey: apiKey.trim(),
|
|
113
|
+
apiSecret: apiSecret.trim()
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// headers
|
|
118
|
+
console.log('Enter headers as key:value pairs (empty line to finish):');
|
|
119
|
+
const headers = {};
|
|
120
|
+
while (true) {
|
|
121
|
+
const line = await rl.question(' ');
|
|
122
|
+
if (!line.trim())
|
|
123
|
+
break;
|
|
124
|
+
const [key, ...valueParts] = line.split(':');
|
|
125
|
+
const value = valueParts.join(':').trim();
|
|
126
|
+
if (key && value) {
|
|
127
|
+
headers[key.trim()] = value;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (Object.keys(headers).length === 0) {
|
|
131
|
+
console.error('❌ At least one header is required');
|
|
132
|
+
rl.close();
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
auth = {
|
|
136
|
+
type: 'headers',
|
|
137
|
+
headers
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// Add service to config
|
|
141
|
+
config.services[serviceName] = {
|
|
142
|
+
baseUrl,
|
|
143
|
+
auth
|
|
144
|
+
};
|
|
145
|
+
(0, config_yaml_1.saveYAMLConfig)(config);
|
|
146
|
+
console.log(`✅ Added service "${serviceName}"`);
|
|
147
|
+
console.log();
|
|
148
|
+
// Ask about capability
|
|
149
|
+
const createCapAnswer = await rl.question('Create a capability for this service? (Y/n): ');
|
|
150
|
+
const createCap = !createCapAnswer || createCapAnswer.toLowerCase() === 'y' || createCapAnswer.toLowerCase() === 'yes';
|
|
151
|
+
if (createCap) {
|
|
152
|
+
const capNameDefault = serviceName;
|
|
153
|
+
const capNameInput = await rl.question(`Capability name (default: ${capNameDefault}): `);
|
|
154
|
+
const capName = capNameInput.trim() || capNameDefault;
|
|
155
|
+
// Check if capability already exists
|
|
156
|
+
if (config.capabilities[capName]) {
|
|
157
|
+
console.error(`❌ Capability "${capName}" already exists`);
|
|
158
|
+
rl.close();
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
const ttlInput = await rl.question('TTL (e.g., 1h, 30m): ');
|
|
162
|
+
const ttl = ttlInput.trim() || '1h';
|
|
163
|
+
const autoApproveInput = await rl.question('Auto-approve? (Y/n): ');
|
|
164
|
+
const autoApprove = !autoApproveInput || autoApproveInput.toLowerCase() === 'y' || autoApproveInput.toLowerCase() === 'yes';
|
|
165
|
+
const requiresReasonInput = await rl.question('Requires reason? (y/N): ');
|
|
166
|
+
const requiresReason = requiresReasonInput.toLowerCase() === 'y' || requiresReasonInput.toLowerCase() === 'yes';
|
|
167
|
+
// Add capability
|
|
168
|
+
config.capabilities[capName] = {
|
|
169
|
+
service: serviceName,
|
|
170
|
+
ttl,
|
|
171
|
+
autoApprove,
|
|
172
|
+
requiresReason
|
|
173
|
+
};
|
|
174
|
+
(0, config_yaml_1.saveYAMLConfig)(config);
|
|
175
|
+
console.log(`✅ Added capability "${capName}"`);
|
|
176
|
+
console.log();
|
|
177
|
+
}
|
|
178
|
+
rl.close();
|
|
179
|
+
console.log("Done! Run 'janee serve' to start.");
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
if (error instanceof Error) {
|
|
183
|
+
console.error('❌ Error:', error.message);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
console.error('❌ Unknown error occurred');
|
|
187
|
+
}
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AA0FA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAkDjD"}
|