@fonderie/cli 0.6.0 → 0.8.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/bin/fonderie.mjs +22 -0
- package/bin/fonderie.test.mjs +7 -0
- package/package.json +1 -1
package/bin/fonderie.mjs
CHANGED
|
@@ -331,6 +331,8 @@ const ADMIN_PAGES = {
|
|
|
331
331
|
user: { path: '/users', about: 'look up a user: admin user <email|id> [sessions|history|revoke-sessions|suspend|unsuspend]' },
|
|
332
332
|
catalog: { path: '/catalog', about: 'plans as configured and as stored' },
|
|
333
333
|
subscriber:{ path: '/subscriptions', about: 'admin subscriber <user|workspace> <id> [subscription|wallet|ledger]' },
|
|
334
|
+
audit: { path: '/audit', about: 'events across every workspace (--workspace, --type, --actor, --from, --to, --limit, --cursor)' },
|
|
335
|
+
token: { path: '/access/tokens', about: 'admin token issue <name> --scopes read[,write[,secrets]] [--days <n>] · admin token revoke <id> (root token only)' },
|
|
334
336
|
};
|
|
335
337
|
async function adminCmd() {
|
|
336
338
|
const pageName = argv[1];
|
|
@@ -355,6 +357,19 @@ async function adminCmd() {
|
|
|
355
357
|
const qs = q.toString();
|
|
356
358
|
return adminFetch(sub[0], base + sub[1] + (qs ? `?${qs}` : ''));
|
|
357
359
|
}
|
|
360
|
+
if (pageName === 'token') {
|
|
361
|
+
const verb = argv[2];
|
|
362
|
+
if (verb === 'issue') {
|
|
363
|
+
const name = argv[3]; const scopes = (arg('--scopes', '') || '').split(',').map((x) => x.trim()).filter(Boolean); const days = arg('--days', undefined);
|
|
364
|
+
if (!name || scopes.length === 0) { console.error('fonderie admin token issue <name> --scopes read[,write[,secrets]] [--days <n>]'); process.exit(2); }
|
|
365
|
+
return adminFetch('POST', `${prefix}/access/tokens`, { name, scopes, ...(days ? { expiresInDays: Number(days) } : {}) });
|
|
366
|
+
}
|
|
367
|
+
if (verb === 'revoke') {
|
|
368
|
+
const id = argv[3]; if (!id) { console.error('fonderie admin token revoke <id>'); process.exit(2); }
|
|
369
|
+
return adminFetch('DELETE', `${prefix}/access/tokens/${encodeURIComponent(id)}`);
|
|
370
|
+
}
|
|
371
|
+
console.error('fonderie admin token <issue|revoke> …'); process.exit(2);
|
|
372
|
+
}
|
|
358
373
|
if (pageName === 'subscriber') {
|
|
359
374
|
const type = argv[2]; const id = argv[3]; const verb = argv[4] ?? 'subscription';
|
|
360
375
|
if ((type !== 'user' && type !== 'workspace') || !id) { console.error('fonderie admin subscriber <user|workspace> <id> [subscription|wallet|ledger] [--currency <c>] [--limit <n>]'); process.exit(2); }
|
|
@@ -372,6 +387,11 @@ async function adminCmd() {
|
|
|
372
387
|
const before = arg('--before', undefined);
|
|
373
388
|
if (pageName === 'log' && limit) q.set('limit', limit);
|
|
374
389
|
if (pageName === 'log' && before) q.set('before', before);
|
|
390
|
+
if (pageName === 'audit') {
|
|
391
|
+
for (const [flag, param] of [['--workspace', 'workspaceId'], ['--type', 'type'], ['--actor', 'actorId'], ['--from', 'from'], ['--to', 'to'], ['--limit', 'limit'], ['--cursor', 'cursor']]) {
|
|
392
|
+
const v = arg(flag, undefined); if (v) q.set(param, v);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
375
395
|
const qs = q.toString();
|
|
376
396
|
return adminFetch('GET', prefix + page.path + (qs ? `?${qs}` : ''));
|
|
377
397
|
}
|
|
@@ -474,6 +494,8 @@ else {
|
|
|
474
494
|
fonderie admin <attention|manifest|doctor|config|routes|tokens|log> [--limit <n>] [--before <cursor>]
|
|
475
495
|
fonderie admin user <email|id> [sessions|history|revoke-sessions|suspend|unsuspend]
|
|
476
496
|
fonderie admin catalog · admin subscriber <user|workspace> <id> [subscription|wallet|ledger] [--currency <c>]
|
|
497
|
+
fonderie admin audit [--workspace <id>] [--type <t>] [--actor <id>] [--from <iso>] [--to <iso>] [--limit <n>]
|
|
498
|
+
fonderie admin token issue <name> --scopes read[,write[,secrets]] [--days <n>] · admin token revoke <id> (root token only)
|
|
477
499
|
read a deployment's operator surface (@fonderie/admin) — same env; FONDERIE_ADMIN_PREFIX if moved
|
|
478
500
|
|
|
479
501
|
Zero deps. No MCP server. A binary + markdown that runs in any agent harness.`);
|
package/bin/fonderie.test.mjs
CHANGED
|
@@ -153,6 +153,13 @@ await (async () => {
|
|
|
153
153
|
if (!find('GET', '/_admin/catalog')) fail('admin catalog: wrong path');
|
|
154
154
|
if (!find('GET', '/_admin/subscriptions/workspace/w1')) fail('admin subscriber: wrong path');
|
|
155
155
|
if (!find('GET', '/_admin/wallet/user/u1/ledger?currency=eur&limit=7')) fail('admin subscriber ledger: flags not forwarded');
|
|
156
|
+
await cli(['admin', 'audit', '--workspace', 'w1', '--type', 'user.login', '--limit', '9']);
|
|
157
|
+
if (!find('GET', '/_admin/audit?workspaceId=w1&type=user.login&limit=9')) fail('admin audit: flags not forwarded');
|
|
158
|
+
await cli(['admin', 'token', 'issue', 'dashboard', '--scopes', 'read,write', '--days', '30']);
|
|
159
|
+
await cli(['admin', 'token', 'revoke', 't1']);
|
|
160
|
+
const iss = find('POST', '/_admin/access/tokens');
|
|
161
|
+
if (!iss || iss.body?.name !== 'dashboard' || iss.body?.scopes?.join() !== 'read,write' || iss.body?.expiresInDays !== 30) fail('admin token issue: wrong body');
|
|
162
|
+
if (!find('DELETE', '/_admin/access/tokens/t1')) fail('admin token revoke: wrong path');
|
|
156
163
|
let badType = 0;
|
|
157
164
|
try { await cli(['admin', 'subscriber', 'team', 'x']); } catch (e) { badType = e.code; }
|
|
158
165
|
if (badType !== 2) fail(`admin subscriber <bad type> should exit 2, got ${badType}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonderie/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "The Fonderie CLI — teaches any coding agent the SDK without loading it eagerly. `fonderie skill` writes a lazy skill (a small router + per-package bodies read on demand); `fonderie query` answers what to install for a capability. Zero deps, runs anywhere.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fonderiejs",
|