@aliou/pi-neuralwatt 0.0.1 → 0.1.1
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 +137 -0
- package/package.json +68 -5
- package/schema.json +24 -0
- package/src/config.ts +154 -0
- package/src/extensions/command-quotas/command.ts +83 -0
- package/src/extensions/command-quotas/components/quota-tabs.ts +251 -0
- package/src/extensions/command-quotas/components/quotas-display.ts +192 -0
- package/src/extensions/command-quotas/index.ts +23 -0
- package/src/extensions/provider/index.ts +146 -0
- package/src/extensions/provider/models.test.ts +120 -0
- package/src/extensions/provider/models.ts +285 -0
- package/src/extensions/quota-warnings/index.ts +75 -0
- package/src/extensions/quota-warnings/notifier.ts +98 -0
- package/src/extensions/sub-bar-integration/index.ts +142 -0
- package/src/extensions/sub-bar-integration/snapshot.ts +47 -0
- package/src/lib/env.ts +18 -0
- package/src/types/quota-api.ts +55 -0
- package/src/types/quota-events.ts +72 -0
- package/src/utils/quota-bar.ts +61 -0
- package/src/utils/quota-format.ts +25 -0
- package/src/utils/quotas.ts +73 -0
- package/index.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# Pi Neuralwatt Extension
|
|
4
|
+
|
|
5
|
+
A Pi extension that adds [Neuralwatt](https://portal.neuralwatt.com/auth/register?ref=NW-ALIOU-Q7MF) as a model provider, giving you access to open-source models through an OpenAI-compatible API with energy transparency.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### Get API Key
|
|
10
|
+
|
|
11
|
+
Sign up at [neuralwatt.com](https://portal.neuralwatt.com/auth/register?ref=NW-ALIOU-Q7MF) to get an API key.
|
|
12
|
+
|
|
13
|
+
### Configure Credentials
|
|
14
|
+
|
|
15
|
+
The extension uses Pi's credential storage. Add your API key to `~/.pi/agent/auth.json` (recommended):
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"neuralwatt": { "type": "api_key", "key": "your-api-key-here" }
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or set environment variable:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
export NEURALWATT_API_KEY="your-api-key-here"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Install Extension
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# From npm
|
|
33
|
+
pi install npm:@aliou/pi-neuralwatt
|
|
34
|
+
|
|
35
|
+
# From git
|
|
36
|
+
pi install git:github.com/aliou/pi-neuralwatt
|
|
37
|
+
|
|
38
|
+
# Local development
|
|
39
|
+
pi -e ./src/extensions/provider/index.ts
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
Once installed, select `neuralwatt` as your provider and choose from available models:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
/model neuralwatt meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Quota Command
|
|
51
|
+
|
|
52
|
+
Check your API usage at a glance:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
/neuralwatt:quota
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The quota command shows three tabs:
|
|
59
|
+
- **Subscription** (when subscribed) — plan details, energy quota with progress bar, billing period
|
|
60
|
+
- **Credits** — credit balance with progress bar, accounting method
|
|
61
|
+
- **Usage & Key** — monthly usage (cost, requests, tokens, energy), API key info, key allowance, rate limits
|
|
62
|
+
|
|
63
|
+
https://github.com/user-attachments/assets/a8994940-c467-4744-a0f2-833cb63923ff
|
|
64
|
+
|
|
65
|
+
### Quota Warnings
|
|
66
|
+
|
|
67
|
+
When enabled, the extension notifies you when credits or energy are running low. When you have an active subscription, only energy warnings fire (credits are on-demand top-up only). Warnings use escalation on severity transitions and have a cooldown for `warning` level.
|
|
68
|
+
|
|
69
|
+
### Sub-bar Integration
|
|
70
|
+
|
|
71
|
+
When a Neuralwatt model is active, the footer status bar shows live quota usage (credits and energy). The status updates after each response and on session start.
|
|
72
|
+
|
|
73
|
+
## Settings
|
|
74
|
+
|
|
75
|
+
Configure features with `/neuralwatt:settings`:
|
|
76
|
+
|
|
77
|
+
- **Quota command** — Show/hide `/neuralwatt:quota`
|
|
78
|
+
- **Quota warnings** — Enable/disable low quota notifications
|
|
79
|
+
- **Sub-bar integration** — Show/hide usage in status bar
|
|
80
|
+
|
|
81
|
+
The provider itself cannot be disabled — it is always loaded.
|
|
82
|
+
|
|
83
|
+
## Adding or Updating Models
|
|
84
|
+
|
|
85
|
+
Models are hardcoded in `src/extensions/provider/models.ts` and validated against the live API. To update:
|
|
86
|
+
|
|
87
|
+
1. Run `pnpm test` — it fetches `/v1/models` and compares against hardcoded definitions
|
|
88
|
+
2. Fix any discrepancies (missing models, changed context windows)
|
|
89
|
+
3. Re-run `pnpm test` to confirm
|
|
90
|
+
|
|
91
|
+
## Development
|
|
92
|
+
|
|
93
|
+
### Setup
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
git clone https://github.com/aliou/pi-neuralwatt.git
|
|
97
|
+
cd pi-neuralwatt
|
|
98
|
+
|
|
99
|
+
# Install dependencies (sets up pre-commit hooks)
|
|
100
|
+
pnpm install && pnpm prepare
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Pre-commit hooks run on every commit:
|
|
104
|
+
- TypeScript type checking
|
|
105
|
+
- Biome linting
|
|
106
|
+
- Biome formatting with auto-fix
|
|
107
|
+
|
|
108
|
+
### Commands
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Type check
|
|
112
|
+
pnpm run typecheck
|
|
113
|
+
|
|
114
|
+
# Lint
|
|
115
|
+
pnpm run lint
|
|
116
|
+
|
|
117
|
+
# Format
|
|
118
|
+
pnpm run format
|
|
119
|
+
|
|
120
|
+
# Test
|
|
121
|
+
pnpm run test
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Release
|
|
125
|
+
|
|
126
|
+
This repository uses [Changesets](https://github.com/changesets/changesets) for versioning.
|
|
127
|
+
|
|
128
|
+
## Requirements
|
|
129
|
+
|
|
130
|
+
- Pi coding agent v0.67.68+
|
|
131
|
+
- Neuralwatt API key (configured in `~/.pi/agent/auth.json` or via `NEURALWATT_API_KEY`)
|
|
132
|
+
|
|
133
|
+
## Links
|
|
134
|
+
|
|
135
|
+
- [Neuralwatt](https://portal.neuralwatt.com/auth/register?ref=NW-ALIOU-Q7MF)
|
|
136
|
+
- [Neuralwatt API Docs](https://neuralwatt.com/docs)
|
|
137
|
+
- [Pi Documentation](https://buildwithpi.ai/)
|
package/package.json
CHANGED
|
@@ -1,15 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aliou/pi-neuralwatt",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"private": false,
|
|
7
|
+
"keywords": [
|
|
8
|
+
"pi-package",
|
|
9
|
+
"pi-extension",
|
|
10
|
+
"pi"
|
|
11
|
+
],
|
|
6
12
|
"repository": {
|
|
7
13
|
"type": "git",
|
|
8
14
|
"url": "https://github.com/aliou/pi-neuralwatt"
|
|
9
15
|
},
|
|
10
|
-
"
|
|
11
|
-
|
|
16
|
+
"pi": {
|
|
17
|
+
"extensions": [
|
|
18
|
+
"./src/extensions/provider/index.ts",
|
|
19
|
+
"./src/extensions/command-quotas/index.ts",
|
|
20
|
+
"./src/extensions/quota-warnings/index.ts",
|
|
21
|
+
"./src/extensions/sub-bar-integration/index.ts"
|
|
22
|
+
],
|
|
23
|
+
"video": "https://assets.aliou.me/pi-extensions/demos/pi-neuralwatt.mp4"
|
|
24
|
+
},
|
|
12
25
|
"publishConfig": {
|
|
13
26
|
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"src",
|
|
30
|
+
"schema.json",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@aliou/pi-utils-settings": "^0.9.0",
|
|
35
|
+
"@aliou/pi-utils-ui": "^0.1.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@mariozechner/pi-coding-agent": ">=0.67.68",
|
|
39
|
+
"@mariozechner/pi-tui": ">=0.67.68",
|
|
40
|
+
"@sinclair/typebox": ">=0.34.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@aliou/biome-plugins": "^0.8.1",
|
|
44
|
+
"@biomejs/biome": "^2.4.12",
|
|
45
|
+
"@changesets/cli": "^2.27.11",
|
|
46
|
+
"@mariozechner/pi-coding-agent": "0.67.68",
|
|
47
|
+
"@mariozechner/pi-tui": "0.67.68",
|
|
48
|
+
"@types/node": "^25.0.10",
|
|
49
|
+
"husky": "^9.1.7",
|
|
50
|
+
"ts-json-schema-generator": "^2.4.0",
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"vitest": "^4.0.18"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"@mariozechner/pi-coding-agent": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"@mariozechner/pi-tui": {
|
|
59
|
+
"optional": true
|
|
60
|
+
},
|
|
61
|
+
"@sinclair/typebox": {
|
|
62
|
+
"optional": true
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"typecheck": "tsc --noEmit",
|
|
67
|
+
"lint": "biome check",
|
|
68
|
+
"format": "biome check --write",
|
|
69
|
+
"test": "vitest run",
|
|
70
|
+
"test:watch": "vitest",
|
|
71
|
+
"gen:schema": "ts-json-schema-generator --path src/config.ts --type NeuralwattConfig --no-type-check -o schema.json",
|
|
72
|
+
"check:schema": "ts-json-schema-generator --path src/config.ts --type NeuralwattConfig --no-type-check -o /tmp/schema-check.json && diff -q schema.json /tmp/schema-check.json",
|
|
73
|
+
"check:lockfile": "pnpm install --frozen-lockfile --ignore-scripts",
|
|
74
|
+
"changeset": "changeset",
|
|
75
|
+
"version": "changeset version",
|
|
76
|
+
"release": "pnpm changeset publish"
|
|
14
77
|
}
|
|
15
|
-
}
|
|
78
|
+
}
|
package/schema.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$ref": "#/definitions/NeuralwattConfig",
|
|
3
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
|
+
"definitions": {
|
|
5
|
+
"NeuralwattConfig": {
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"properties": {
|
|
8
|
+
"quotaCommand": {
|
|
9
|
+
"description": "Show the quota command (/neuralwatt:quota).",
|
|
10
|
+
"type": "boolean"
|
|
11
|
+
},
|
|
12
|
+
"quotaWarnings": {
|
|
13
|
+
"description": "Show quota warnings when credits or energy are low.",
|
|
14
|
+
"type": "boolean"
|
|
15
|
+
},
|
|
16
|
+
"subBarIntegration": {
|
|
17
|
+
"description": "Show usage in the sub-bar / status bar.",
|
|
18
|
+
"type": "boolean"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"type": "object"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConfigLoader,
|
|
3
|
+
registerSettingsCommand,
|
|
4
|
+
type SettingsSection,
|
|
5
|
+
} from "@aliou/pi-utils-settings";
|
|
6
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
7
|
+
import type { SettingItem } from "@mariozechner/pi-tui";
|
|
8
|
+
|
|
9
|
+
export type NeuralwattFeatureId =
|
|
10
|
+
| "quotaCommand"
|
|
11
|
+
| "quotaWarnings"
|
|
12
|
+
| "subBarIntegration";
|
|
13
|
+
|
|
14
|
+
export const NEURALWATT_EXTENSIONS_REQUEST_EVENT =
|
|
15
|
+
"neuralwatt:extensions:request" as const;
|
|
16
|
+
|
|
17
|
+
export const NEURALWATT_EXTENSIONS_REGISTER_EVENT =
|
|
18
|
+
"neuralwatt:extensions:register" as const;
|
|
19
|
+
|
|
20
|
+
export interface NeuralwattExtensionsRegisterPayload {
|
|
21
|
+
feature: NeuralwattFeatureId;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface NeuralwattConfig {
|
|
25
|
+
/** Show the quota command (/neuralwatt:quota). */
|
|
26
|
+
quotaCommand?: boolean;
|
|
27
|
+
/** Show quota warnings when credits or energy are low. */
|
|
28
|
+
quotaWarnings?: boolean;
|
|
29
|
+
/** Show usage in the sub-bar / status bar. */
|
|
30
|
+
subBarIntegration?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ResolvedNeuralwattConfig {
|
|
34
|
+
quotaCommand: boolean;
|
|
35
|
+
quotaWarnings: boolean;
|
|
36
|
+
subBarIntegration: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const DEFAULTS: ResolvedNeuralwattConfig = {
|
|
40
|
+
quotaCommand: true,
|
|
41
|
+
quotaWarnings: true,
|
|
42
|
+
subBarIntegration: true,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const configLoader = new ConfigLoader<
|
|
46
|
+
NeuralwattConfig,
|
|
47
|
+
ResolvedNeuralwattConfig
|
|
48
|
+
>("neuralwatt", DEFAULTS);
|
|
49
|
+
|
|
50
|
+
export const NEURALWATT_CONFIG_UPDATED_EVENT =
|
|
51
|
+
"neuralwatt:config:updated" as const;
|
|
52
|
+
|
|
53
|
+
export interface NeuralwattConfigUpdatedPayload {
|
|
54
|
+
config: ResolvedNeuralwattConfig;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function emitConfigUpdated(pi: ExtensionAPI): void {
|
|
58
|
+
pi.events.emit(NEURALWATT_CONFIG_UPDATED_EVENT, {
|
|
59
|
+
config: configLoader.getConfig(),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface RegisterNeuralwattSettingsOptions {
|
|
64
|
+
getLoadedFeatures: () => Set<NeuralwattFeatureId>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function featureRow(
|
|
68
|
+
id: NeuralwattFeatureId,
|
|
69
|
+
label: string,
|
|
70
|
+
description: string,
|
|
71
|
+
configValue: boolean,
|
|
72
|
+
isLoaded: boolean,
|
|
73
|
+
): SettingItem {
|
|
74
|
+
if (isLoaded) {
|
|
75
|
+
return {
|
|
76
|
+
id,
|
|
77
|
+
label,
|
|
78
|
+
description,
|
|
79
|
+
currentValue: configValue ? "enabled" : "disabled",
|
|
80
|
+
values: ["enabled", "disabled"],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
id,
|
|
85
|
+
label,
|
|
86
|
+
description: `${description} (Not loaded by Pi)`,
|
|
87
|
+
currentValue: "unavailable",
|
|
88
|
+
values: [],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function registerNeuralwattSettings(
|
|
93
|
+
pi: ExtensionAPI,
|
|
94
|
+
options: RegisterNeuralwattSettingsOptions,
|
|
95
|
+
): void {
|
|
96
|
+
const { getLoadedFeatures } = options;
|
|
97
|
+
|
|
98
|
+
registerSettingsCommand<NeuralwattConfig, ResolvedNeuralwattConfig>(pi, {
|
|
99
|
+
commandName: "neuralwatt:settings",
|
|
100
|
+
title: "Neuralwatt Settings",
|
|
101
|
+
configStore: configLoader,
|
|
102
|
+
buildSections: (tabConfig, resolved): SettingsSection[] => {
|
|
103
|
+
const loaded = getLoadedFeatures();
|
|
104
|
+
return [
|
|
105
|
+
{
|
|
106
|
+
label: "Features",
|
|
107
|
+
items: [
|
|
108
|
+
featureRow(
|
|
109
|
+
"quotaCommand",
|
|
110
|
+
"Quota command",
|
|
111
|
+
"Toggle the /neuralwatt:quota command, showing your API usage at a glance",
|
|
112
|
+
tabConfig?.quotaCommand ?? resolved.quotaCommand,
|
|
113
|
+
loaded.has("quotaCommand"),
|
|
114
|
+
),
|
|
115
|
+
featureRow(
|
|
116
|
+
"quotaWarnings",
|
|
117
|
+
"Quota warnings",
|
|
118
|
+
"Toggle notifications when credits or energy are running low",
|
|
119
|
+
tabConfig?.quotaWarnings ?? resolved.quotaWarnings,
|
|
120
|
+
loaded.has("quotaWarnings"),
|
|
121
|
+
),
|
|
122
|
+
featureRow(
|
|
123
|
+
"subBarIntegration",
|
|
124
|
+
"Sub-bar integration",
|
|
125
|
+
"Toggle integration with the status bar and sub-core",
|
|
126
|
+
tabConfig?.subBarIntegration ?? resolved.subBarIntegration,
|
|
127
|
+
loaded.has("subBarIntegration"),
|
|
128
|
+
),
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
},
|
|
133
|
+
onSettingChange: (id, newValue, config) => {
|
|
134
|
+
if (!getLoadedFeatures().has(id as NeuralwattFeatureId)) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const enabled = newValue === "enabled";
|
|
139
|
+
switch (id) {
|
|
140
|
+
case "quotaCommand":
|
|
141
|
+
return { ...config, quotaCommand: enabled };
|
|
142
|
+
case "quotaWarnings":
|
|
143
|
+
return { ...config, quotaWarnings: enabled };
|
|
144
|
+
case "subBarIntegration":
|
|
145
|
+
return { ...config, subBarIntegration: enabled };
|
|
146
|
+
default:
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
onSave: async () => {
|
|
151
|
+
emitConfigUpdated(pi);
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { type ExtensionAPI, getAgentDir } from "@mariozechner/pi-coding-agent";
|
|
3
|
+
import { getNeuralwattApiKey } from "../../lib/env";
|
|
4
|
+
import { fetchQuotas } from "../../utils/quotas";
|
|
5
|
+
import { QuotasComponent } from "./components/quotas-display";
|
|
6
|
+
|
|
7
|
+
function missingAuthMessage(): string {
|
|
8
|
+
const authPath = join(getAgentDir(), "auth.json");
|
|
9
|
+
return `Neuralwatt quota requires an API key. Add credentials to ${authPath} or set the NEURALWATT_API_KEY environment variable.`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function registerQuotasCommand(pi: ExtensionAPI): void {
|
|
13
|
+
pi.registerCommand("neuralwatt:quota", {
|
|
14
|
+
description: "Display Neuralwatt API usage and quota",
|
|
15
|
+
handler: async (_args, ctx) => {
|
|
16
|
+
const apiKey = await getNeuralwattApiKey(ctx.modelRegistry.authStorage);
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
ctx.ui.notify(missingAuthMessage(), "warning");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const key: string = apiKey;
|
|
22
|
+
|
|
23
|
+
const result = await ctx.ui.custom<null>((tui, theme, _kb, done) => {
|
|
24
|
+
const controller = new AbortController();
|
|
25
|
+
const component = new QuotasComponent(
|
|
26
|
+
theme,
|
|
27
|
+
tui,
|
|
28
|
+
() => {
|
|
29
|
+
controller.abort();
|
|
30
|
+
done(null);
|
|
31
|
+
},
|
|
32
|
+
() => {
|
|
33
|
+
component.setState({ type: "loading" });
|
|
34
|
+
tui.requestRender();
|
|
35
|
+
void loadQuotas();
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
async function loadQuotas(): Promise<void> {
|
|
40
|
+
const fetchResult = await fetchQuotas(key, controller.signal);
|
|
41
|
+
if (controller.signal.aborted) return;
|
|
42
|
+
if (fetchResult.success) {
|
|
43
|
+
component.setState({
|
|
44
|
+
type: "loaded",
|
|
45
|
+
quotas: fetchResult.data.quotas,
|
|
46
|
+
});
|
|
47
|
+
} else {
|
|
48
|
+
component.setState({
|
|
49
|
+
type: "error",
|
|
50
|
+
message: fetchResult.error.message,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
tui.requestRender();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void loadQuotas();
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
render: (width: number) => component.render(width),
|
|
60
|
+
invalidate: () => component.invalidate(),
|
|
61
|
+
handleInput: (data: string) => component.handleInput(data),
|
|
62
|
+
dispose: () => {
|
|
63
|
+
controller.abort();
|
|
64
|
+
component.destroy();
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Non-interactive fallback (RPC, print, JSON modes)
|
|
70
|
+
if (result === undefined) {
|
|
71
|
+
const fetchResult = await fetchQuotas(key);
|
|
72
|
+
if (!fetchResult.success) {
|
|
73
|
+
ctx.ui.notify(
|
|
74
|
+
JSON.stringify({ error: fetchResult.error.message }),
|
|
75
|
+
"error",
|
|
76
|
+
);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
ctx.ui.notify(JSON.stringify(fetchResult.data.quotas), "info");
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|