@dominusnode/pi-extension 1.1.0 → 1.2.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 +29 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +332 -1
- package/dist/toolkit.d.ts +32 -1
- package/dist/toolkit.js +483 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @dominusnode/pi-extension
|
|
2
2
|
|
|
3
|
-
[Pi](https://github.com/badlogic/pi-mono) extension providing **
|
|
3
|
+
[Pi](https://github.com/badlogic/pi-mono) extension providing **53 tools** for the [Dominus Node](https://dominusnode.com) rotating proxy and management platform.
|
|
4
4
|
|
|
5
5
|
## What is Pi?
|
|
6
6
|
|
|
@@ -39,7 +39,7 @@ export DOMINUSNODE_API_KEY="dn_live_your_key_here"
|
|
|
39
39
|
|
|
40
40
|
Get your API key at [dominusnode.com](https://dominusnode.com) → Dashboard → API Keys.
|
|
41
41
|
|
|
42
|
-
## Available Tools (
|
|
42
|
+
## Available Tools (53 total)
|
|
43
43
|
|
|
44
44
|
| Tool | Description |
|
|
45
45
|
|------|-------------|
|
|
@@ -69,6 +69,33 @@ Get your API key at [dominusnode.com](https://dominusnode.com) → Dashboard →
|
|
|
69
69
|
| `dominusnode_topup_crypto` | Top up via crypto (BTC/ETH/USDC/...) |
|
|
70
70
|
| `dominusnode_x402_info` | x402 micropayment config |
|
|
71
71
|
| `dominusnode_update_wallet_policy` | Set spending limits/domain restrictions |
|
|
72
|
+
| `dominusnode_get_proxy_status` | Proxy gateway status and pool health |
|
|
73
|
+
| `dominusnode_get_transactions` | Wallet transaction history |
|
|
74
|
+
| `dominusnode_get_forecast` | Spending forecast and projected costs |
|
|
75
|
+
| `dominusnode_check_payment` | Check crypto payment status by invoice ID |
|
|
76
|
+
| `dominusnode_get_daily_usage` | Daily bandwidth usage breakdown |
|
|
77
|
+
| `dominusnode_get_top_hosts` | Top hosts by bandwidth usage |
|
|
78
|
+
| `dominusnode_register` | Register a new account |
|
|
79
|
+
| `dominusnode_login` | Log in to an existing account |
|
|
80
|
+
| `dominusnode_get_account_info` | Get account profile information |
|
|
81
|
+
| `dominusnode_verify_email` | Verify email with token |
|
|
82
|
+
| `dominusnode_resend_verification` | Resend email verification link |
|
|
83
|
+
| `dominusnode_update_password` | Change account password |
|
|
84
|
+
| `dominusnode_list_keys` | List personal API keys |
|
|
85
|
+
| `dominusnode_create_key` | Create a new personal API key |
|
|
86
|
+
| `dominusnode_revoke_key` | Revoke a personal API key |
|
|
87
|
+
| `dominusnode_get_plan` | Get current subscription plan |
|
|
88
|
+
| `dominusnode_list_plans` | List available plans |
|
|
89
|
+
| `dominusnode_change_plan` | Change subscription plan |
|
|
90
|
+
| `dominusnode_team_delete` | Delete a team |
|
|
91
|
+
| `dominusnode_team_revoke_key` | Revoke a team API key |
|
|
92
|
+
| `dominusnode_team_list_keys` | List team API keys |
|
|
93
|
+
| `dominusnode_team_list_members` | List team members |
|
|
94
|
+
| `dominusnode_team_add_member` | Add a member to a team |
|
|
95
|
+
| `dominusnode_team_remove_member` | Remove a member from a team |
|
|
96
|
+
| `dominusnode_team_invite_member` | Invite a user to a team by email |
|
|
97
|
+
| `dominusnode_team_list_invites` | List pending team invitations |
|
|
98
|
+
| `dominusnode_team_cancel_invite` | Cancel a pending team invitation |
|
|
72
99
|
|
|
73
100
|
## Proxy Usage
|
|
74
101
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Dominus Node — Pi Extension
|
|
3
3
|
*
|
|
4
|
-
* Pi-mono extension providing
|
|
4
|
+
* Pi-mono extension providing 53 tools for the Dominus Node rotating proxy
|
|
5
5
|
* and management platform. Loaded by the pi coding agent from:
|
|
6
6
|
* ~/.pi/agent/extensions/dominusnode/ (global)
|
|
7
7
|
* .pi/extensions/dominusnode/ (project-local)
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Dominus Node — Pi Extension
|
|
4
4
|
*
|
|
5
|
-
* Pi-mono extension providing
|
|
5
|
+
* Pi-mono extension providing 53 tools for the Dominus Node rotating proxy
|
|
6
6
|
* and management platform. Loaded by the pi coding agent from:
|
|
7
7
|
* ~/.pi/agent/extensions/dominusnode/ (global)
|
|
8
8
|
* .pi/extensions/dominusnode/ (project-local)
|
|
@@ -370,4 +370,335 @@ function dominusNodeExtension(pi) {
|
|
|
370
370
|
return toolkit.updateWalletPolicy(String(params.walletId ?? ""), params.dailyLimitCents !== undefined ? Number(params.dailyLimitCents) : undefined, params.allowedDomains !== undefined ? params.allowedDomains : undefined);
|
|
371
371
|
},
|
|
372
372
|
});
|
|
373
|
+
// ── Tool 27: get_proxy_status ───────────────────────────────────────────
|
|
374
|
+
pi.registerTool({
|
|
375
|
+
name: "dominusnode_get_proxy_status",
|
|
376
|
+
label: "DominusNode: Get Proxy Status",
|
|
377
|
+
description: "Get the current status of the proxy gateway including uptime, active connections, and pool health.",
|
|
378
|
+
parameters: typebox_1.Type.Object({}),
|
|
379
|
+
async execute(_id, _params, _signal, _onUpdate, _ctx) {
|
|
380
|
+
return toolkit.getProxyStatus();
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
// ── Tool 28: get_transactions ───────────────────────────────────────────
|
|
384
|
+
pi.registerTool({
|
|
385
|
+
name: "dominusnode_get_transactions",
|
|
386
|
+
label: "DominusNode: Get Wallet Transactions",
|
|
387
|
+
description: "Get wallet transaction history showing top-ups, charges, and refunds.",
|
|
388
|
+
parameters: typebox_1.Type.Object({
|
|
389
|
+
limit: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Number of transactions to return (default: 20, max: 100)", minimum: 1, maximum: 100 })),
|
|
390
|
+
}),
|
|
391
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
392
|
+
return toolkit.getTransactions(params.limit !== undefined ? Number(params.limit) : 20);
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
// ── Tool 29: get_forecast ──────────────────────────────────────────────
|
|
396
|
+
pi.registerTool({
|
|
397
|
+
name: "dominusnode_get_forecast",
|
|
398
|
+
label: "DominusNode: Get Spending Forecast",
|
|
399
|
+
description: "Get a spending forecast based on recent usage patterns. " +
|
|
400
|
+
"Shows estimated days until balance runs out and projected monthly cost.",
|
|
401
|
+
parameters: typebox_1.Type.Object({}),
|
|
402
|
+
async execute(_id, _params, _signal, _onUpdate, _ctx) {
|
|
403
|
+
return toolkit.getForecast();
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
// ── Tool 30: check_payment ─────────────────────────────────────────────
|
|
407
|
+
pi.registerTool({
|
|
408
|
+
name: "dominusnode_check_payment",
|
|
409
|
+
label: "DominusNode: Check Crypto Payment Status",
|
|
410
|
+
description: "Check the status of a crypto top-up payment by invoice ID. " +
|
|
411
|
+
"Returns payment status (pending, confirming, completed, expired).",
|
|
412
|
+
parameters: typebox_1.Type.Object({
|
|
413
|
+
invoiceId: typebox_1.Type.String({ description: "Crypto invoice ID (UUID) returned from topup_crypto" }),
|
|
414
|
+
}),
|
|
415
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
416
|
+
return toolkit.checkPayment(String(params.invoiceId ?? ""));
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
// ── Tool 31: get_daily_usage ───────────────────────────────────────────
|
|
420
|
+
pi.registerTool({
|
|
421
|
+
name: "dominusnode_get_daily_usage",
|
|
422
|
+
label: "DominusNode: Get Daily Usage Breakdown",
|
|
423
|
+
description: "Get daily bandwidth usage breakdown for the specified number of days. " +
|
|
424
|
+
"Returns per-day bytes transferred and cost.",
|
|
425
|
+
parameters: typebox_1.Type.Object({
|
|
426
|
+
days: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Number of days to look back (default: 7, max: 365)", minimum: 1, maximum: 365 })),
|
|
427
|
+
}),
|
|
428
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
429
|
+
return toolkit.getDailyUsage(params.days !== undefined ? Number(params.days) : 7);
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
// ── Tool 32: get_top_hosts ─────────────────────────────────────────────
|
|
433
|
+
pi.registerTool({
|
|
434
|
+
name: "dominusnode_get_top_hosts",
|
|
435
|
+
label: "DominusNode: Get Top Hosts by Usage",
|
|
436
|
+
description: "Get the top hosts by bandwidth usage. Shows which domains consume the most proxy traffic.",
|
|
437
|
+
parameters: typebox_1.Type.Object({
|
|
438
|
+
limit: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Number of top hosts to return (default: 10, max: 100)", minimum: 1, maximum: 100 })),
|
|
439
|
+
}),
|
|
440
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
441
|
+
return toolkit.getTopHosts(params.limit !== undefined ? Number(params.limit) : 10);
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
// ── Tool 33: register ──────────────────────────────────────────────────
|
|
445
|
+
pi.registerTool({
|
|
446
|
+
name: "dominusnode_register",
|
|
447
|
+
label: "DominusNode: Register Account",
|
|
448
|
+
description: "Register a new Dominus Node account. Does not require authentication. " +
|
|
449
|
+
"Returns user info and initial API key.",
|
|
450
|
+
parameters: typebox_1.Type.Object({
|
|
451
|
+
email: typebox_1.Type.String({ description: "Email address for the new account" }),
|
|
452
|
+
password: typebox_1.Type.String({ description: "Password (8-128 characters)" }),
|
|
453
|
+
}),
|
|
454
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
455
|
+
return toolkit.register(String(params.email ?? ""), String(params.password ?? ""));
|
|
456
|
+
},
|
|
457
|
+
});
|
|
458
|
+
// ── Tool 34: login ─────────────────────────────────────────────────────
|
|
459
|
+
pi.registerTool({
|
|
460
|
+
name: "dominusnode_login",
|
|
461
|
+
label: "DominusNode: Login",
|
|
462
|
+
description: "Log in to an existing Dominus Node account. Does not require authentication. " +
|
|
463
|
+
"Returns JWT access and refresh tokens.",
|
|
464
|
+
parameters: typebox_1.Type.Object({
|
|
465
|
+
email: typebox_1.Type.String({ description: "Account email address" }),
|
|
466
|
+
password: typebox_1.Type.String({ description: "Account password" }),
|
|
467
|
+
}),
|
|
468
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
469
|
+
return toolkit.login(String(params.email ?? ""), String(params.password ?? ""));
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
// ── Tool 35: get_account_info ──────────────────────────────────────────
|
|
473
|
+
pi.registerTool({
|
|
474
|
+
name: "dominusnode_get_account_info",
|
|
475
|
+
label: "DominusNode: Get Account Info",
|
|
476
|
+
description: "Get your account profile information including email, plan, verification status, and creation date.",
|
|
477
|
+
parameters: typebox_1.Type.Object({}),
|
|
478
|
+
async execute(_id, _params, _signal, _onUpdate, _ctx) {
|
|
479
|
+
return toolkit.getAccountInfo();
|
|
480
|
+
},
|
|
481
|
+
});
|
|
482
|
+
// ── Tool 36: verify_email ──────────────────────────────────────────────
|
|
483
|
+
pi.registerTool({
|
|
484
|
+
name: "dominusnode_verify_email",
|
|
485
|
+
label: "DominusNode: Verify Email",
|
|
486
|
+
description: "Verify an email address using the verification token sent to the user's email. " +
|
|
487
|
+
"Does not require authentication.",
|
|
488
|
+
parameters: typebox_1.Type.Object({
|
|
489
|
+
token: typebox_1.Type.String({ description: "Email verification token from the verification email" }),
|
|
490
|
+
}),
|
|
491
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
492
|
+
return toolkit.verifyEmail(String(params.token ?? ""));
|
|
493
|
+
},
|
|
494
|
+
});
|
|
495
|
+
// ── Tool 37: resend_verification ───────────────────────────────────────
|
|
496
|
+
pi.registerTool({
|
|
497
|
+
name: "dominusnode_resend_verification",
|
|
498
|
+
label: "DominusNode: Resend Verification Email",
|
|
499
|
+
description: "Resend the email verification link. Requires authentication.",
|
|
500
|
+
parameters: typebox_1.Type.Object({}),
|
|
501
|
+
async execute(_id, _params, _signal, _onUpdate, _ctx) {
|
|
502
|
+
return toolkit.resendVerification();
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
// ── Tool 38: update_password ───────────────────────────────────────────
|
|
506
|
+
pi.registerTool({
|
|
507
|
+
name: "dominusnode_update_password",
|
|
508
|
+
label: "DominusNode: Update Password",
|
|
509
|
+
description: "Change your account password. Requires current password for verification.",
|
|
510
|
+
parameters: typebox_1.Type.Object({
|
|
511
|
+
currentPassword: typebox_1.Type.String({ description: "Current account password" }),
|
|
512
|
+
newPassword: typebox_1.Type.String({ description: "New password (8-128 characters)" }),
|
|
513
|
+
}),
|
|
514
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
515
|
+
return toolkit.updatePassword(String(params.currentPassword ?? ""), String(params.newPassword ?? ""));
|
|
516
|
+
},
|
|
517
|
+
});
|
|
518
|
+
// ── Tool 39: list_keys ─────────────────────────────────────────────────
|
|
519
|
+
pi.registerTool({
|
|
520
|
+
name: "dominusnode_list_keys",
|
|
521
|
+
label: "DominusNode: List API Keys",
|
|
522
|
+
description: "List all your personal API keys with their labels, creation dates, and last-used timestamps.",
|
|
523
|
+
parameters: typebox_1.Type.Object({}),
|
|
524
|
+
async execute(_id, _params, _signal, _onUpdate, _ctx) {
|
|
525
|
+
return toolkit.listKeys();
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
// ── Tool 40: create_key ────────────────────────────────────────────────
|
|
529
|
+
pi.registerTool({
|
|
530
|
+
name: "dominusnode_create_key",
|
|
531
|
+
label: "DominusNode: Create API Key",
|
|
532
|
+
description: "Create a new personal API key. The key is shown only once -- save it immediately. " +
|
|
533
|
+
"Usage is billed against your personal wallet.",
|
|
534
|
+
parameters: typebox_1.Type.Object({
|
|
535
|
+
label: typebox_1.Type.String({ description: "Label for the API key (e.g. 'production', 'dev-testing')" }),
|
|
536
|
+
}),
|
|
537
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
538
|
+
return toolkit.createKey(String(params.label ?? ""));
|
|
539
|
+
},
|
|
540
|
+
});
|
|
541
|
+
// ── Tool 41: revoke_key ────────────────────────────────────────────────
|
|
542
|
+
pi.registerTool({
|
|
543
|
+
name: "dominusnode_revoke_key",
|
|
544
|
+
label: "DominusNode: Revoke API Key",
|
|
545
|
+
description: "Revoke (delete) a personal API key. This action is irreversible -- " +
|
|
546
|
+
"any applications using this key will lose access immediately.",
|
|
547
|
+
parameters: typebox_1.Type.Object({
|
|
548
|
+
keyId: typebox_1.Type.String({ description: "API key ID (UUID) to revoke" }),
|
|
549
|
+
}),
|
|
550
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
551
|
+
return toolkit.revokeKey(String(params.keyId ?? ""));
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
// ── Tool 42: get_plan ──────────────────────────────────────────────────
|
|
555
|
+
pi.registerTool({
|
|
556
|
+
name: "dominusnode_get_plan",
|
|
557
|
+
label: "DominusNode: Get Current Plan",
|
|
558
|
+
description: "Get your current subscription plan including tier, bandwidth limits, and pricing.",
|
|
559
|
+
parameters: typebox_1.Type.Object({}),
|
|
560
|
+
async execute(_id, _params, _signal, _onUpdate, _ctx) {
|
|
561
|
+
return toolkit.getPlan();
|
|
562
|
+
},
|
|
563
|
+
});
|
|
564
|
+
// ── Tool 43: list_plans ────────────────────────────────────────────────
|
|
565
|
+
pi.registerTool({
|
|
566
|
+
name: "dominusnode_list_plans",
|
|
567
|
+
label: "DominusNode: List Available Plans",
|
|
568
|
+
description: "List all available subscription plans with features, pricing, and bandwidth limits.",
|
|
569
|
+
parameters: typebox_1.Type.Object({}),
|
|
570
|
+
async execute(_id, _params, _signal, _onUpdate, _ctx) {
|
|
571
|
+
return toolkit.listPlans();
|
|
572
|
+
},
|
|
573
|
+
});
|
|
574
|
+
// ── Tool 44: change_plan ───────────────────────────────────────────────
|
|
575
|
+
pi.registerTool({
|
|
576
|
+
name: "dominusnode_change_plan",
|
|
577
|
+
label: "DominusNode: Change Subscription Plan",
|
|
578
|
+
description: "Change your subscription plan. Takes effect immediately. " +
|
|
579
|
+
"Use list_plans to see available options.",
|
|
580
|
+
parameters: typebox_1.Type.Object({
|
|
581
|
+
planId: typebox_1.Type.String({ description: "Plan ID (UUID) to switch to" }),
|
|
582
|
+
}),
|
|
583
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
584
|
+
return toolkit.changePlan(String(params.planId ?? ""));
|
|
585
|
+
},
|
|
586
|
+
});
|
|
587
|
+
// ── Tool 45: team_delete ───────────────────────────────────────────────
|
|
588
|
+
pi.registerTool({
|
|
589
|
+
name: "dominusnode_team_delete",
|
|
590
|
+
label: "DominusNode: Delete Team",
|
|
591
|
+
description: "Delete a team. Only the team owner can delete. " +
|
|
592
|
+
"All team keys are revoked and remaining balance is refunded.",
|
|
593
|
+
parameters: typebox_1.Type.Object({
|
|
594
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID) to delete" }),
|
|
595
|
+
}),
|
|
596
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
597
|
+
return toolkit.teamDelete(String(params.teamId ?? ""));
|
|
598
|
+
},
|
|
599
|
+
});
|
|
600
|
+
// ── Tool 46: team_revoke_key ───────────────────────────────────────────
|
|
601
|
+
pi.registerTool({
|
|
602
|
+
name: "dominusnode_team_revoke_key",
|
|
603
|
+
label: "DominusNode: Revoke Team API Key",
|
|
604
|
+
description: "Revoke a team API key. Only owners and admins can revoke keys. " +
|
|
605
|
+
"Applications using this key will lose access immediately.",
|
|
606
|
+
parameters: typebox_1.Type.Object({
|
|
607
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID)" }),
|
|
608
|
+
keyId: typebox_1.Type.String({ description: "API key ID (UUID) to revoke" }),
|
|
609
|
+
}),
|
|
610
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
611
|
+
return toolkit.teamRevokeKey(String(params.teamId ?? ""), String(params.keyId ?? ""));
|
|
612
|
+
},
|
|
613
|
+
});
|
|
614
|
+
// ── Tool 47: team_list_keys ────────────────────────────────────────────
|
|
615
|
+
pi.registerTool({
|
|
616
|
+
name: "dominusnode_team_list_keys",
|
|
617
|
+
label: "DominusNode: List Team API Keys",
|
|
618
|
+
description: "List all API keys for a team with labels, creation dates, and last-used timestamps.",
|
|
619
|
+
parameters: typebox_1.Type.Object({
|
|
620
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID)" }),
|
|
621
|
+
}),
|
|
622
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
623
|
+
return toolkit.teamListKeys(String(params.teamId ?? ""));
|
|
624
|
+
},
|
|
625
|
+
});
|
|
626
|
+
// ── Tool 48: team_list_members ─────────────────────────────────────────
|
|
627
|
+
pi.registerTool({
|
|
628
|
+
name: "dominusnode_team_list_members",
|
|
629
|
+
label: "DominusNode: List Team Members",
|
|
630
|
+
description: "List all members of a team with their roles and join dates.",
|
|
631
|
+
parameters: typebox_1.Type.Object({
|
|
632
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID)" }),
|
|
633
|
+
}),
|
|
634
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
635
|
+
return toolkit.teamListMembers(String(params.teamId ?? ""));
|
|
636
|
+
},
|
|
637
|
+
});
|
|
638
|
+
// ── Tool 49: team_add_member ───────────────────────────────────────────
|
|
639
|
+
pi.registerTool({
|
|
640
|
+
name: "dominusnode_team_add_member",
|
|
641
|
+
label: "DominusNode: Add Team Member",
|
|
642
|
+
description: "Add a user directly to a team by user ID. Only owners and admins can add members.",
|
|
643
|
+
parameters: typebox_1.Type.Object({
|
|
644
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID)" }),
|
|
645
|
+
userId: typebox_1.Type.String({ description: "User ID (UUID) of the user to add" }),
|
|
646
|
+
role: typebox_1.Type.Optional(typebox_1.Type.Union([typebox_1.Type.Literal("member"), typebox_1.Type.Literal("admin")], { description: "Role for the new member (default: 'member')" })),
|
|
647
|
+
}),
|
|
648
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
649
|
+
return toolkit.teamAddMember(String(params.teamId ?? ""), String(params.userId ?? ""), params.role !== undefined ? String(params.role) : "member");
|
|
650
|
+
},
|
|
651
|
+
});
|
|
652
|
+
// ── Tool 50: team_remove_member ────────────────────────────────────────
|
|
653
|
+
pi.registerTool({
|
|
654
|
+
name: "dominusnode_team_remove_member",
|
|
655
|
+
label: "DominusNode: Remove Team Member",
|
|
656
|
+
description: "Remove a member from a team. Only owners and admins can remove members.",
|
|
657
|
+
parameters: typebox_1.Type.Object({
|
|
658
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID)" }),
|
|
659
|
+
userId: typebox_1.Type.String({ description: "User ID (UUID) of the member to remove" }),
|
|
660
|
+
}),
|
|
661
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
662
|
+
return toolkit.teamRemoveMember(String(params.teamId ?? ""), String(params.userId ?? ""));
|
|
663
|
+
},
|
|
664
|
+
});
|
|
665
|
+
// ── Tool 51: team_invite_member ────────────────────────────────────────
|
|
666
|
+
pi.registerTool({
|
|
667
|
+
name: "dominusnode_team_invite_member",
|
|
668
|
+
label: "DominusNode: Invite Team Member",
|
|
669
|
+
description: "Invite a user to join a team by email address. The user will receive an invitation email.",
|
|
670
|
+
parameters: typebox_1.Type.Object({
|
|
671
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID)" }),
|
|
672
|
+
email: typebox_1.Type.String({ description: "Email address of the user to invite" }),
|
|
673
|
+
role: typebox_1.Type.Optional(typebox_1.Type.Union([typebox_1.Type.Literal("member"), typebox_1.Type.Literal("admin")], { description: "Role for the invited member (default: 'member')" })),
|
|
674
|
+
}),
|
|
675
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
676
|
+
return toolkit.teamInviteMember(String(params.teamId ?? ""), String(params.email ?? ""), params.role !== undefined ? String(params.role) : "member");
|
|
677
|
+
},
|
|
678
|
+
});
|
|
679
|
+
// ── Tool 52: team_list_invites ─────────────────────────────────────────
|
|
680
|
+
pi.registerTool({
|
|
681
|
+
name: "dominusnode_team_list_invites",
|
|
682
|
+
label: "DominusNode: List Team Invites",
|
|
683
|
+
description: "List all pending invitations for a team.",
|
|
684
|
+
parameters: typebox_1.Type.Object({
|
|
685
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID)" }),
|
|
686
|
+
}),
|
|
687
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
688
|
+
return toolkit.teamListInvites(String(params.teamId ?? ""));
|
|
689
|
+
},
|
|
690
|
+
});
|
|
691
|
+
// ── Tool 53: team_cancel_invite ────────────────────────────────────────
|
|
692
|
+
pi.registerTool({
|
|
693
|
+
name: "dominusnode_team_cancel_invite",
|
|
694
|
+
label: "DominusNode: Cancel Team Invite",
|
|
695
|
+
description: "Cancel a pending team invitation. Only owners and admins can cancel invites.",
|
|
696
|
+
parameters: typebox_1.Type.Object({
|
|
697
|
+
teamId: typebox_1.Type.String({ description: "Team ID (UUID)" }),
|
|
698
|
+
inviteId: typebox_1.Type.String({ description: "Invite ID (UUID) to cancel" }),
|
|
699
|
+
}),
|
|
700
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
701
|
+
return toolkit.teamCancelInvite(String(params.teamId ?? ""), String(params.inviteId ?? ""));
|
|
702
|
+
},
|
|
703
|
+
});
|
|
373
704
|
}
|
package/dist/toolkit.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Dominus Node Pi Extension Toolkit
|
|
3
3
|
*
|
|
4
|
-
* Provides
|
|
4
|
+
* Provides 53 tools for the pi-mono agent framework (github.com/badlogic/pi-mono).
|
|
5
5
|
* Covers proxied fetching, wallet management, agentic wallets, teams,
|
|
6
6
|
* Stripe/PayPal/crypto top-up, and x402 micropayment info.
|
|
7
7
|
*
|
|
@@ -94,4 +94,35 @@ export declare class DominusNodeToolkit {
|
|
|
94
94
|
topupCrypto(amountUsd: number, currency: string): Promise<PiToolResult>;
|
|
95
95
|
x402Info(): Promise<PiToolResult>;
|
|
96
96
|
updateWalletPolicy(walletId: string, dailyLimitCents?: number, allowedDomains?: string[]): Promise<PiToolResult>;
|
|
97
|
+
private _rawRequest;
|
|
98
|
+
private static readonly EMAIL_RE;
|
|
99
|
+
private static validateEmail;
|
|
100
|
+
private static validatePassword;
|
|
101
|
+
getProxyStatus(): Promise<PiToolResult>;
|
|
102
|
+
getTransactions(limit?: number): Promise<PiToolResult>;
|
|
103
|
+
getForecast(): Promise<PiToolResult>;
|
|
104
|
+
checkPayment(invoiceId: string): Promise<PiToolResult>;
|
|
105
|
+
getDailyUsage(days?: number): Promise<PiToolResult>;
|
|
106
|
+
getTopHosts(limit?: number): Promise<PiToolResult>;
|
|
107
|
+
register(email: string, password: string): Promise<PiToolResult>;
|
|
108
|
+
login(email: string, password: string): Promise<PiToolResult>;
|
|
109
|
+
getAccountInfo(): Promise<PiToolResult>;
|
|
110
|
+
verifyEmail(token: string): Promise<PiToolResult>;
|
|
111
|
+
resendVerification(): Promise<PiToolResult>;
|
|
112
|
+
updatePassword(currentPassword: string, newPassword: string): Promise<PiToolResult>;
|
|
113
|
+
listKeys(): Promise<PiToolResult>;
|
|
114
|
+
createKey(label: string): Promise<PiToolResult>;
|
|
115
|
+
revokeKey(keyId: string): Promise<PiToolResult>;
|
|
116
|
+
getPlan(): Promise<PiToolResult>;
|
|
117
|
+
listPlans(): Promise<PiToolResult>;
|
|
118
|
+
changePlan(planId: string): Promise<PiToolResult>;
|
|
119
|
+
teamDelete(teamId: string): Promise<PiToolResult>;
|
|
120
|
+
teamRevokeKey(teamId: string, keyId: string): Promise<PiToolResult>;
|
|
121
|
+
teamListKeys(teamId: string): Promise<PiToolResult>;
|
|
122
|
+
teamListMembers(teamId: string): Promise<PiToolResult>;
|
|
123
|
+
teamAddMember(teamId: string, userId: string, role?: string): Promise<PiToolResult>;
|
|
124
|
+
teamRemoveMember(teamId: string, userId: string): Promise<PiToolResult>;
|
|
125
|
+
teamInviteMember(teamId: string, email: string, role?: string): Promise<PiToolResult>;
|
|
126
|
+
teamListInvites(teamId: string): Promise<PiToolResult>;
|
|
127
|
+
teamCancelInvite(teamId: string, inviteId: string): Promise<PiToolResult>;
|
|
97
128
|
}
|
package/dist/toolkit.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Dominus Node Pi Extension Toolkit
|
|
4
4
|
*
|
|
5
|
-
* Provides
|
|
5
|
+
* Provides 53 tools for the pi-mono agent framework (github.com/badlogic/pi-mono).
|
|
6
6
|
* Covers proxied fetching, wallet management, agentic wallets, teams,
|
|
7
7
|
* Stripe/PayPal/crypto top-up, and x402 micropayment info.
|
|
8
8
|
*
|
|
@@ -789,7 +789,7 @@ class DominusNodeToolkit {
|
|
|
789
789
|
const amount = Math.floor(Number(amountCents));
|
|
790
790
|
if (isNaN(amount) || amount < 1 || amount > 1000000)
|
|
791
791
|
return err("amountCents must be between 1 and 1,000,000");
|
|
792
|
-
const data = await this._req("POST", `/api/agent-wallet/${id}/fund`, { amountCents: amount });
|
|
792
|
+
const data = await this._req("POST", `/api/agent-wallet/${encodeURIComponent(id)}/fund`, { amountCents: amount });
|
|
793
793
|
return ok(JSON.stringify(data, null, 2));
|
|
794
794
|
}
|
|
795
795
|
catch (e) {
|
|
@@ -802,7 +802,7 @@ class DominusNodeToolkit {
|
|
|
802
802
|
async checkAgenticBalance(walletId) {
|
|
803
803
|
try {
|
|
804
804
|
const id = validateUuid(walletId, "walletId");
|
|
805
|
-
const data = await this._req("GET", `/api/agent-wallet/${id}`);
|
|
805
|
+
const data = await this._req("GET", `/api/agent-wallet/${encodeURIComponent(id)}`);
|
|
806
806
|
return ok(JSON.stringify(data, null, 2));
|
|
807
807
|
}
|
|
808
808
|
catch (e) {
|
|
@@ -831,7 +831,7 @@ class DominusNodeToolkit {
|
|
|
831
831
|
if (!Number.isFinite(rawLim))
|
|
832
832
|
return err("limit must be a finite number");
|
|
833
833
|
const lim = Math.max(1, Math.min(100, Math.floor(rawLim)));
|
|
834
|
-
const data = await this._req("GET", `/api/agent-wallet/${id}/transactions?limit=${lim}`);
|
|
834
|
+
const data = await this._req("GET", `/api/agent-wallet/${encodeURIComponent(id)}/transactions?limit=${lim}`);
|
|
835
835
|
return ok(JSON.stringify(data, null, 2));
|
|
836
836
|
}
|
|
837
837
|
catch (e) {
|
|
@@ -844,7 +844,7 @@ class DominusNodeToolkit {
|
|
|
844
844
|
async freezeAgenticWallet(walletId) {
|
|
845
845
|
try {
|
|
846
846
|
const id = validateUuid(walletId, "walletId");
|
|
847
|
-
const data = await this._req("POST", `/api/agent-wallet/${id}/freeze`);
|
|
847
|
+
const data = await this._req("POST", `/api/agent-wallet/${encodeURIComponent(id)}/freeze`);
|
|
848
848
|
return ok(JSON.stringify(data, null, 2));
|
|
849
849
|
}
|
|
850
850
|
catch (e) {
|
|
@@ -857,7 +857,7 @@ class DominusNodeToolkit {
|
|
|
857
857
|
async unfreezeAgenticWallet(walletId) {
|
|
858
858
|
try {
|
|
859
859
|
const id = validateUuid(walletId, "walletId");
|
|
860
|
-
const data = await this._req("POST", `/api/agent-wallet/${id}/unfreeze`);
|
|
860
|
+
const data = await this._req("POST", `/api/agent-wallet/${encodeURIComponent(id)}/unfreeze`);
|
|
861
861
|
return ok(JSON.stringify(data, null, 2));
|
|
862
862
|
}
|
|
863
863
|
catch (e) {
|
|
@@ -870,7 +870,7 @@ class DominusNodeToolkit {
|
|
|
870
870
|
async deleteAgenticWallet(walletId) {
|
|
871
871
|
try {
|
|
872
872
|
const id = validateUuid(walletId, "walletId");
|
|
873
|
-
const data = await this._req("DELETE", `/api/agent-wallet/${id}`);
|
|
873
|
+
const data = await this._req("DELETE", `/api/agent-wallet/${encodeURIComponent(id)}`);
|
|
874
874
|
return ok(JSON.stringify(data, null, 2));
|
|
875
875
|
}
|
|
876
876
|
catch (e) {
|
|
@@ -917,7 +917,7 @@ class DominusNodeToolkit {
|
|
|
917
917
|
async teamDetails(teamId) {
|
|
918
918
|
try {
|
|
919
919
|
const id = validateUuid(teamId, "teamId");
|
|
920
|
-
const data = await this._req("GET", `/api/teams/${id}`);
|
|
920
|
+
const data = await this._req("GET", `/api/teams/${encodeURIComponent(id)}`);
|
|
921
921
|
return ok(JSON.stringify(data, null, 2));
|
|
922
922
|
}
|
|
923
923
|
catch (e) {
|
|
@@ -933,7 +933,7 @@ class DominusNodeToolkit {
|
|
|
933
933
|
const amount = Math.floor(Number(amountCents));
|
|
934
934
|
if (isNaN(amount) || amount < 1 || amount > 1000000)
|
|
935
935
|
return err("amountCents must be between 1 and 1,000,000");
|
|
936
|
-
const data = await this._req("POST", `/api/teams/${id}/wallet/fund`, { amountCents: amount });
|
|
936
|
+
const data = await this._req("POST", `/api/teams/${encodeURIComponent(id)}/wallet/fund`, { amountCents: amount });
|
|
937
937
|
return ok(JSON.stringify(data, null, 2));
|
|
938
938
|
}
|
|
939
939
|
catch (e) {
|
|
@@ -949,7 +949,7 @@ class DominusNodeToolkit {
|
|
|
949
949
|
const labelErr = validateLabel(label);
|
|
950
950
|
if (labelErr)
|
|
951
951
|
return err(labelErr);
|
|
952
|
-
const data = await this._req("POST", `/api/teams/${id}/keys`, { label: label.trim() });
|
|
952
|
+
const data = await this._req("POST", `/api/teams/${encodeURIComponent(id)}/keys`, { label: label.trim() });
|
|
953
953
|
return ok(JSON.stringify(data, null, 2) + "\n\nIMPORTANT: Store this API key securely — it will not be shown again.");
|
|
954
954
|
}
|
|
955
955
|
catch (e) {
|
|
@@ -968,7 +968,7 @@ class DominusNodeToolkit {
|
|
|
968
968
|
const d = Math.max(1, Math.min(365, Math.floor(rawDays)));
|
|
969
969
|
const until = new Date().toISOString();
|
|
970
970
|
const since = new Date(Date.now() - d * 86400000).toISOString();
|
|
971
|
-
const data = await this._req("GET", `/api/teams/${id}/usage?since=${encodeURIComponent(since)}&until=${encodeURIComponent(until)}`);
|
|
971
|
+
const data = await this._req("GET", `/api/teams/${encodeURIComponent(id)}/usage?since=${encodeURIComponent(since)}&until=${encodeURIComponent(until)}`);
|
|
972
972
|
return ok(JSON.stringify(data, null, 2));
|
|
973
973
|
}
|
|
974
974
|
catch (e) {
|
|
@@ -996,7 +996,7 @@ class DominusNodeToolkit {
|
|
|
996
996
|
}
|
|
997
997
|
if (!Object.keys(body).length)
|
|
998
998
|
return err("At least one of name or maxMembers must be provided");
|
|
999
|
-
const data = await this._req("PATCH", `/api/teams/${id}`, body);
|
|
999
|
+
const data = await this._req("PATCH", `/api/teams/${encodeURIComponent(id)}`, body);
|
|
1000
1000
|
return ok(JSON.stringify(data, null, 2));
|
|
1001
1001
|
}
|
|
1002
1002
|
catch (e) {
|
|
@@ -1112,7 +1112,477 @@ class DominusNodeToolkit {
|
|
|
1112
1112
|
}
|
|
1113
1113
|
if (!Object.keys(body).length)
|
|
1114
1114
|
return err("At least one of dailyLimitCents or allowedDomains must be provided");
|
|
1115
|
-
const data = await this._req("PATCH", `/api/agent-wallet/${id}/policy`, body);
|
|
1115
|
+
const data = await this._req("PATCH", `/api/agent-wallet/${encodeURIComponent(id)}/policy`, body);
|
|
1116
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1117
|
+
}
|
|
1118
|
+
catch (e) {
|
|
1119
|
+
return err(e);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
// -----------------------------------------------------------------------
|
|
1123
|
+
// Unauthenticated request helper (register, login, verify-email)
|
|
1124
|
+
// -----------------------------------------------------------------------
|
|
1125
|
+
async _rawRequest(method, path, body) {
|
|
1126
|
+
const url = `${this.baseUrl}${path}`;
|
|
1127
|
+
const headers = {
|
|
1128
|
+
Accept: "application/json",
|
|
1129
|
+
"User-Agent": "dominusnode-pi/1.0.0",
|
|
1130
|
+
};
|
|
1131
|
+
if (this.agentSecret) {
|
|
1132
|
+
headers["X-DominusNode-Agent"] = "mcp";
|
|
1133
|
+
headers["X-DominusNode-Agent-Secret"] = this.agentSecret;
|
|
1134
|
+
}
|
|
1135
|
+
const init = { method, headers, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), redirect: "error" };
|
|
1136
|
+
if (body && ["POST", "PUT", "PATCH", "DELETE"].includes(method)) {
|
|
1137
|
+
headers["Content-Type"] = "application/json";
|
|
1138
|
+
init.body = JSON.stringify(body);
|
|
1139
|
+
}
|
|
1140
|
+
let res;
|
|
1141
|
+
try {
|
|
1142
|
+
res = await fetch(url, init);
|
|
1143
|
+
}
|
|
1144
|
+
catch (e) {
|
|
1145
|
+
throw new Error(`API request failed: ${safeError(e)}`);
|
|
1146
|
+
}
|
|
1147
|
+
let rawText = "";
|
|
1148
|
+
if (res.body) {
|
|
1149
|
+
const reader = res.body.getReader();
|
|
1150
|
+
const chunks = [];
|
|
1151
|
+
let totalBytes = 0;
|
|
1152
|
+
try {
|
|
1153
|
+
while (true) {
|
|
1154
|
+
const { done, value } = await reader.read();
|
|
1155
|
+
if (done)
|
|
1156
|
+
break;
|
|
1157
|
+
totalBytes += value.length;
|
|
1158
|
+
if (totalBytes > MAX_RESPONSE_BYTES) {
|
|
1159
|
+
reader.cancel().catch(() => { });
|
|
1160
|
+
throw new Error("API response too large");
|
|
1161
|
+
}
|
|
1162
|
+
chunks.push(value);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
catch (e) {
|
|
1166
|
+
reader.cancel().catch(() => { });
|
|
1167
|
+
throw e;
|
|
1168
|
+
}
|
|
1169
|
+
rawText = Buffer.concat(chunks).toString("utf-8");
|
|
1170
|
+
}
|
|
1171
|
+
if (!res.ok) {
|
|
1172
|
+
let msg = `API error ${res.status}`;
|
|
1173
|
+
try {
|
|
1174
|
+
const parsed = JSON.parse(rawText);
|
|
1175
|
+
stripDangerousKeys(parsed);
|
|
1176
|
+
const detail = parsed.error ?? parsed.message;
|
|
1177
|
+
if (detail)
|
|
1178
|
+
msg = `API error ${res.status}: ${scrubCredentials(String(detail))}`;
|
|
1179
|
+
}
|
|
1180
|
+
catch {
|
|
1181
|
+
if (rawText)
|
|
1182
|
+
msg = `API error ${res.status}: ${scrubCredentials(rawText.slice(0, 200))}`;
|
|
1183
|
+
}
|
|
1184
|
+
throw new Error(msg);
|
|
1185
|
+
}
|
|
1186
|
+
if (!rawText || !rawText.trim())
|
|
1187
|
+
return {};
|
|
1188
|
+
try {
|
|
1189
|
+
const parsed = JSON.parse(rawText);
|
|
1190
|
+
stripDangerousKeys(parsed);
|
|
1191
|
+
return parsed;
|
|
1192
|
+
}
|
|
1193
|
+
catch {
|
|
1194
|
+
throw new Error("Failed to parse API response as JSON");
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
// -----------------------------------------------------------------------
|
|
1198
|
+
// Validation helpers for account tools
|
|
1199
|
+
// -----------------------------------------------------------------------
|
|
1200
|
+
static EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1201
|
+
static validateEmail(email) {
|
|
1202
|
+
const trimmed = email.trim();
|
|
1203
|
+
if (!trimmed || !DominusNodeToolkit.EMAIL_RE.test(trimmed)) {
|
|
1204
|
+
throw new Error("Invalid email address.");
|
|
1205
|
+
}
|
|
1206
|
+
if (trimmed.length > 254) {
|
|
1207
|
+
throw new Error("Email address too long (max 254 characters).");
|
|
1208
|
+
}
|
|
1209
|
+
return trimmed;
|
|
1210
|
+
}
|
|
1211
|
+
static validatePassword(password) {
|
|
1212
|
+
if (!password || password.length < 8) {
|
|
1213
|
+
throw new Error("Password must be at least 8 characters.");
|
|
1214
|
+
}
|
|
1215
|
+
if (password.length > 128) {
|
|
1216
|
+
throw new Error("Password must be at most 128 characters.");
|
|
1217
|
+
}
|
|
1218
|
+
return password;
|
|
1219
|
+
}
|
|
1220
|
+
// -----------------------------------------------------------------------
|
|
1221
|
+
// Tool 27: getProxyStatus
|
|
1222
|
+
// -----------------------------------------------------------------------
|
|
1223
|
+
async getProxyStatus() {
|
|
1224
|
+
try {
|
|
1225
|
+
const data = await this._req("GET", "/api/proxy/status");
|
|
1226
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1227
|
+
}
|
|
1228
|
+
catch (e) {
|
|
1229
|
+
return err(e);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
// -----------------------------------------------------------------------
|
|
1233
|
+
// Tool 28: getTransactions
|
|
1234
|
+
// -----------------------------------------------------------------------
|
|
1235
|
+
async getTransactions(limit = 20) {
|
|
1236
|
+
try {
|
|
1237
|
+
const rawLim = Number(limit);
|
|
1238
|
+
if (!Number.isFinite(rawLim))
|
|
1239
|
+
return err("limit must be a finite number");
|
|
1240
|
+
const lim = Math.max(1, Math.min(100, Math.floor(rawLim)));
|
|
1241
|
+
const data = await this._req("GET", `/api/wallet/transactions?limit=${lim}`);
|
|
1242
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1243
|
+
}
|
|
1244
|
+
catch (e) {
|
|
1245
|
+
return err(e);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
// -----------------------------------------------------------------------
|
|
1249
|
+
// Tool 29: getForecast
|
|
1250
|
+
// -----------------------------------------------------------------------
|
|
1251
|
+
async getForecast() {
|
|
1252
|
+
try {
|
|
1253
|
+
const data = await this._req("GET", "/api/wallet/forecast");
|
|
1254
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1255
|
+
}
|
|
1256
|
+
catch (e) {
|
|
1257
|
+
return err(e);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
// -----------------------------------------------------------------------
|
|
1261
|
+
// Tool 30: checkPayment
|
|
1262
|
+
// -----------------------------------------------------------------------
|
|
1263
|
+
async checkPayment(invoiceId) {
|
|
1264
|
+
try {
|
|
1265
|
+
const id = validateUuid(invoiceId, "invoiceId");
|
|
1266
|
+
const data = await this._req("GET", `/api/wallet/topup/crypto/${encodeURIComponent(id)}/status`);
|
|
1267
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1268
|
+
}
|
|
1269
|
+
catch (e) {
|
|
1270
|
+
return err(e);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
// -----------------------------------------------------------------------
|
|
1274
|
+
// Tool 31: getDailyUsage
|
|
1275
|
+
// -----------------------------------------------------------------------
|
|
1276
|
+
async getDailyUsage(days = 7) {
|
|
1277
|
+
try {
|
|
1278
|
+
const rawDays = Number(days);
|
|
1279
|
+
if (!Number.isFinite(rawDays))
|
|
1280
|
+
return err("days must be a finite number between 1 and 365");
|
|
1281
|
+
const d = Math.max(1, Math.min(365, Math.floor(rawDays)));
|
|
1282
|
+
const data = await this._req("GET", `/api/usage/daily?days=${d}`);
|
|
1283
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1284
|
+
}
|
|
1285
|
+
catch (e) {
|
|
1286
|
+
return err(e);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
// -----------------------------------------------------------------------
|
|
1290
|
+
// Tool 32: getTopHosts
|
|
1291
|
+
// -----------------------------------------------------------------------
|
|
1292
|
+
async getTopHosts(limit = 10) {
|
|
1293
|
+
try {
|
|
1294
|
+
const rawLim = Number(limit);
|
|
1295
|
+
if (!Number.isFinite(rawLim))
|
|
1296
|
+
return err("limit must be a finite number");
|
|
1297
|
+
const lim = Math.max(1, Math.min(100, Math.floor(rawLim)));
|
|
1298
|
+
const data = await this._req("GET", `/api/usage/top-hosts?limit=${lim}`);
|
|
1299
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1300
|
+
}
|
|
1301
|
+
catch (e) {
|
|
1302
|
+
return err(e);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
// -----------------------------------------------------------------------
|
|
1306
|
+
// Tool 33: register
|
|
1307
|
+
// -----------------------------------------------------------------------
|
|
1308
|
+
async register(email, password) {
|
|
1309
|
+
try {
|
|
1310
|
+
const safeEmail = DominusNodeToolkit.validateEmail(email);
|
|
1311
|
+
const safePassword = DominusNodeToolkit.validatePassword(password);
|
|
1312
|
+
const data = await this._rawRequest("POST", "/api/auth/register", { email: safeEmail, password: safePassword });
|
|
1313
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1314
|
+
}
|
|
1315
|
+
catch (e) {
|
|
1316
|
+
return err(e);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
// -----------------------------------------------------------------------
|
|
1320
|
+
// Tool 34: login
|
|
1321
|
+
// -----------------------------------------------------------------------
|
|
1322
|
+
async login(email, password) {
|
|
1323
|
+
try {
|
|
1324
|
+
const safeEmail = DominusNodeToolkit.validateEmail(email);
|
|
1325
|
+
const safePassword = DominusNodeToolkit.validatePassword(password);
|
|
1326
|
+
const data = await this._rawRequest("POST", "/api/auth/login", { email: safeEmail, password: safePassword });
|
|
1327
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1328
|
+
}
|
|
1329
|
+
catch (e) {
|
|
1330
|
+
return err(e);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
// -----------------------------------------------------------------------
|
|
1334
|
+
// Tool 35: getAccountInfo
|
|
1335
|
+
// -----------------------------------------------------------------------
|
|
1336
|
+
async getAccountInfo() {
|
|
1337
|
+
try {
|
|
1338
|
+
const data = await this._req("GET", "/api/auth/me");
|
|
1339
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1340
|
+
}
|
|
1341
|
+
catch (e) {
|
|
1342
|
+
return err(e);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
// -----------------------------------------------------------------------
|
|
1346
|
+
// Tool 36: verifyEmail
|
|
1347
|
+
// -----------------------------------------------------------------------
|
|
1348
|
+
async verifyEmail(token) {
|
|
1349
|
+
try {
|
|
1350
|
+
if (!token || typeof token !== "string" || token.trim().length === 0) {
|
|
1351
|
+
return err("Verification token is required.");
|
|
1352
|
+
}
|
|
1353
|
+
if (/[\x00-\x1f\x7f]/.test(token)) {
|
|
1354
|
+
return err("Token contains invalid control characters.");
|
|
1355
|
+
}
|
|
1356
|
+
const data = await this._rawRequest("POST", "/api/auth/verify-email", { token: token.trim() });
|
|
1357
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1358
|
+
}
|
|
1359
|
+
catch (e) {
|
|
1360
|
+
return err(e);
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
// -----------------------------------------------------------------------
|
|
1364
|
+
// Tool 37: resendVerification
|
|
1365
|
+
// -----------------------------------------------------------------------
|
|
1366
|
+
async resendVerification() {
|
|
1367
|
+
try {
|
|
1368
|
+
const data = await this._req("POST", "/api/auth/resend-verification");
|
|
1369
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1370
|
+
}
|
|
1371
|
+
catch (e) {
|
|
1372
|
+
return err(e);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
// -----------------------------------------------------------------------
|
|
1376
|
+
// Tool 38: updatePassword
|
|
1377
|
+
// -----------------------------------------------------------------------
|
|
1378
|
+
async updatePassword(currentPassword, newPassword) {
|
|
1379
|
+
try {
|
|
1380
|
+
DominusNodeToolkit.validatePassword(currentPassword);
|
|
1381
|
+
DominusNodeToolkit.validatePassword(newPassword);
|
|
1382
|
+
const data = await this._req("POST", "/api/auth/change-password", { currentPassword, newPassword });
|
|
1383
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1384
|
+
}
|
|
1385
|
+
catch (e) {
|
|
1386
|
+
return err(e);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
// -----------------------------------------------------------------------
|
|
1390
|
+
// Tool 39: listKeys
|
|
1391
|
+
// -----------------------------------------------------------------------
|
|
1392
|
+
async listKeys() {
|
|
1393
|
+
try {
|
|
1394
|
+
const data = await this._req("GET", "/api/keys");
|
|
1395
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1396
|
+
}
|
|
1397
|
+
catch (e) {
|
|
1398
|
+
return err(e);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
// -----------------------------------------------------------------------
|
|
1402
|
+
// Tool 40: createKey
|
|
1403
|
+
// -----------------------------------------------------------------------
|
|
1404
|
+
async createKey(label) {
|
|
1405
|
+
try {
|
|
1406
|
+
const labelErr = validateLabel(label);
|
|
1407
|
+
if (labelErr)
|
|
1408
|
+
return err(labelErr);
|
|
1409
|
+
const data = await this._req("POST", "/api/keys", { label: label.trim() });
|
|
1410
|
+
return ok(JSON.stringify(data, null, 2) + "\n\nIMPORTANT: Store this API key securely — it will not be shown again.");
|
|
1411
|
+
}
|
|
1412
|
+
catch (e) {
|
|
1413
|
+
return err(e);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
// -----------------------------------------------------------------------
|
|
1417
|
+
// Tool 41: revokeKey
|
|
1418
|
+
// -----------------------------------------------------------------------
|
|
1419
|
+
async revokeKey(keyId) {
|
|
1420
|
+
try {
|
|
1421
|
+
const id = validateUuid(keyId, "keyId");
|
|
1422
|
+
const data = await this._req("DELETE", `/api/keys/${encodeURIComponent(id)}`);
|
|
1423
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1424
|
+
}
|
|
1425
|
+
catch (e) {
|
|
1426
|
+
return err(e);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
// -----------------------------------------------------------------------
|
|
1430
|
+
// Tool 42: getPlan
|
|
1431
|
+
// -----------------------------------------------------------------------
|
|
1432
|
+
async getPlan() {
|
|
1433
|
+
try {
|
|
1434
|
+
const data = await this._req("GET", "/api/plans/user/plan");
|
|
1435
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1436
|
+
}
|
|
1437
|
+
catch (e) {
|
|
1438
|
+
return err(e);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
// -----------------------------------------------------------------------
|
|
1442
|
+
// Tool 43: listPlans
|
|
1443
|
+
// -----------------------------------------------------------------------
|
|
1444
|
+
async listPlans() {
|
|
1445
|
+
try {
|
|
1446
|
+
const data = await this._req("GET", "/api/plans");
|
|
1447
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1448
|
+
}
|
|
1449
|
+
catch (e) {
|
|
1450
|
+
return err(e);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
// -----------------------------------------------------------------------
|
|
1454
|
+
// Tool 44: changePlan
|
|
1455
|
+
// -----------------------------------------------------------------------
|
|
1456
|
+
async changePlan(planId) {
|
|
1457
|
+
try {
|
|
1458
|
+
const id = validateUuid(planId, "planId");
|
|
1459
|
+
const data = await this._req("PUT", "/api/plans/user/plan", { planId: id });
|
|
1460
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1461
|
+
}
|
|
1462
|
+
catch (e) {
|
|
1463
|
+
return err(e);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
// -----------------------------------------------------------------------
|
|
1467
|
+
// Tool 45: teamDelete
|
|
1468
|
+
// -----------------------------------------------------------------------
|
|
1469
|
+
async teamDelete(teamId) {
|
|
1470
|
+
try {
|
|
1471
|
+
const id = validateUuid(teamId, "teamId");
|
|
1472
|
+
const data = await this._req("DELETE", `/api/teams/${encodeURIComponent(id)}`);
|
|
1473
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1474
|
+
}
|
|
1475
|
+
catch (e) {
|
|
1476
|
+
return err(e);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
// -----------------------------------------------------------------------
|
|
1480
|
+
// Tool 46: teamRevokeKey
|
|
1481
|
+
// -----------------------------------------------------------------------
|
|
1482
|
+
async teamRevokeKey(teamId, keyId) {
|
|
1483
|
+
try {
|
|
1484
|
+
const tid = validateUuid(teamId, "teamId");
|
|
1485
|
+
const kid = validateUuid(keyId, "keyId");
|
|
1486
|
+
const data = await this._req("DELETE", `/api/teams/${encodeURIComponent(tid)}/keys/${encodeURIComponent(kid)}`);
|
|
1487
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1488
|
+
}
|
|
1489
|
+
catch (e) {
|
|
1490
|
+
return err(e);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
// -----------------------------------------------------------------------
|
|
1494
|
+
// Tool 47: teamListKeys
|
|
1495
|
+
// -----------------------------------------------------------------------
|
|
1496
|
+
async teamListKeys(teamId) {
|
|
1497
|
+
try {
|
|
1498
|
+
const id = validateUuid(teamId, "teamId");
|
|
1499
|
+
const data = await this._req("GET", `/api/teams/${encodeURIComponent(id)}/keys`);
|
|
1500
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1501
|
+
}
|
|
1502
|
+
catch (e) {
|
|
1503
|
+
return err(e);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
// -----------------------------------------------------------------------
|
|
1507
|
+
// Tool 48: teamListMembers
|
|
1508
|
+
// -----------------------------------------------------------------------
|
|
1509
|
+
async teamListMembers(teamId) {
|
|
1510
|
+
try {
|
|
1511
|
+
const id = validateUuid(teamId, "teamId");
|
|
1512
|
+
const data = await this._req("GET", `/api/teams/${encodeURIComponent(id)}/members`);
|
|
1513
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1514
|
+
}
|
|
1515
|
+
catch (e) {
|
|
1516
|
+
return err(e);
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
// -----------------------------------------------------------------------
|
|
1520
|
+
// Tool 49: teamAddMember
|
|
1521
|
+
// -----------------------------------------------------------------------
|
|
1522
|
+
async teamAddMember(teamId, userId, role = "member") {
|
|
1523
|
+
try {
|
|
1524
|
+
const tid = validateUuid(teamId, "teamId");
|
|
1525
|
+
const uid = validateUuid(userId, "userId");
|
|
1526
|
+
if (role !== "member" && role !== "admin")
|
|
1527
|
+
return err("role must be 'member' or 'admin'");
|
|
1528
|
+
const data = await this._req("POST", `/api/teams/${encodeURIComponent(tid)}/members`, { userId: uid, role });
|
|
1529
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1530
|
+
}
|
|
1531
|
+
catch (e) {
|
|
1532
|
+
return err(e);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
// -----------------------------------------------------------------------
|
|
1536
|
+
// Tool 50: teamRemoveMember
|
|
1537
|
+
// -----------------------------------------------------------------------
|
|
1538
|
+
async teamRemoveMember(teamId, userId) {
|
|
1539
|
+
try {
|
|
1540
|
+
const tid = validateUuid(teamId, "teamId");
|
|
1541
|
+
const uid = validateUuid(userId, "userId");
|
|
1542
|
+
const data = await this._req("DELETE", `/api/teams/${encodeURIComponent(tid)}/members/${encodeURIComponent(uid)}`);
|
|
1543
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1544
|
+
}
|
|
1545
|
+
catch (e) {
|
|
1546
|
+
return err(e);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
// -----------------------------------------------------------------------
|
|
1550
|
+
// Tool 51: teamInviteMember
|
|
1551
|
+
// -----------------------------------------------------------------------
|
|
1552
|
+
async teamInviteMember(teamId, email, role = "member") {
|
|
1553
|
+
try {
|
|
1554
|
+
const id = validateUuid(teamId, "teamId");
|
|
1555
|
+
const safeEmail = DominusNodeToolkit.validateEmail(email);
|
|
1556
|
+
if (role !== "member" && role !== "admin")
|
|
1557
|
+
return err("role must be 'member' or 'admin'");
|
|
1558
|
+
const data = await this._req("POST", `/api/teams/${encodeURIComponent(id)}/invites`, { email: safeEmail, role });
|
|
1559
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1560
|
+
}
|
|
1561
|
+
catch (e) {
|
|
1562
|
+
return err(e);
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
// -----------------------------------------------------------------------
|
|
1566
|
+
// Tool 52: teamListInvites
|
|
1567
|
+
// -----------------------------------------------------------------------
|
|
1568
|
+
async teamListInvites(teamId) {
|
|
1569
|
+
try {
|
|
1570
|
+
const id = validateUuid(teamId, "teamId");
|
|
1571
|
+
const data = await this._req("GET", `/api/teams/${encodeURIComponent(id)}/invites`);
|
|
1572
|
+
return ok(JSON.stringify(data, null, 2));
|
|
1573
|
+
}
|
|
1574
|
+
catch (e) {
|
|
1575
|
+
return err(e);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
// -----------------------------------------------------------------------
|
|
1579
|
+
// Tool 53: teamCancelInvite
|
|
1580
|
+
// -----------------------------------------------------------------------
|
|
1581
|
+
async teamCancelInvite(teamId, inviteId) {
|
|
1582
|
+
try {
|
|
1583
|
+
const tid = validateUuid(teamId, "teamId");
|
|
1584
|
+
const iid = validateUuid(inviteId, "inviteId");
|
|
1585
|
+
const data = await this._req("DELETE", `/api/teams/${encodeURIComponent(tid)}/invites/${encodeURIComponent(iid)}`);
|
|
1116
1586
|
return ok(JSON.stringify(data, null, 2));
|
|
1117
1587
|
}
|
|
1118
1588
|
catch (e) {
|
package/package.json
CHANGED