@camerontaylor/paseo-plugin 0.10.2-fork.1 → 0.11.0-beta.3.fork.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/dist/client/contracts.d.ts +50 -2
- package/dist/client/index.d.ts +1 -1
- package/dist/client/ui.d.ts +23 -0
- package/dist/server/acp-internal/connection.js +14 -3
- package/dist/server/acp.js +1 -0
- package/dist/server/contracts.d.ts +2 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/provider.d.ts +24 -1
- package/dist/server/provider.js +14 -1
- package/dist/server/usage.d.ts +106 -0
- package/dist/server/usage.js +60 -0
- package/package.json +10 -5
|
@@ -35,8 +35,39 @@ interface PluginNavigableHostProps extends PluginHostProps {
|
|
|
35
35
|
}) => void;
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
+
/** String keys and values: params travel in the screen's URL. */
|
|
39
|
+
export type PluginScreenParams = Record<string, string>;
|
|
40
|
+
export interface PluginOpenScreenInput {
|
|
41
|
+
screenId: string;
|
|
42
|
+
params?: PluginScreenParams;
|
|
43
|
+
}
|
|
44
|
+
export interface PluginScreenLocation {
|
|
45
|
+
screenId: string;
|
|
46
|
+
params: PluginScreenParams;
|
|
47
|
+
}
|
|
38
48
|
export interface PluginSurfaceProps extends PluginNavigableHostProps {
|
|
39
49
|
}
|
|
50
|
+
export interface PluginScreenProps extends PluginSurfaceProps {
|
|
51
|
+
/** The params the screen was opened with; `{}` when none. */
|
|
52
|
+
params: PluginScreenParams;
|
|
53
|
+
}
|
|
54
|
+
export interface PluginPopoverProps extends PluginHostProps {
|
|
55
|
+
close(): void;
|
|
56
|
+
openScreen(input: PluginOpenScreenInput): void;
|
|
57
|
+
}
|
|
58
|
+
export interface PluginSidebarItemProps extends PluginHostProps {
|
|
59
|
+
/** This plugin's screen open on this item's host, with its params, else null. */
|
|
60
|
+
currentScreen: PluginScreenLocation | null;
|
|
61
|
+
openScreen(input: PluginOpenScreenInput): void;
|
|
62
|
+
/** Anchored to the item on wide layouts; a bottom sheet on compact layouts. */
|
|
63
|
+
openPopover(Content: ComponentType<PluginPopoverProps>): void;
|
|
64
|
+
}
|
|
65
|
+
export interface PluginSidebarItemContribution {
|
|
66
|
+
id: string;
|
|
67
|
+
/** Settings row label, accessibility label, and default label for SidebarRow. */
|
|
68
|
+
title: string;
|
|
69
|
+
Component: ComponentType<PluginSidebarItemProps>;
|
|
70
|
+
}
|
|
40
71
|
export interface PluginIconProps {
|
|
41
72
|
name: string;
|
|
42
73
|
size?: number;
|
|
@@ -65,10 +96,17 @@ export interface PluginClientOpenPanelOptions extends PluginOpenPanelOptions {
|
|
|
65
96
|
workspaceId: string;
|
|
66
97
|
agentId?: string;
|
|
67
98
|
}
|
|
68
|
-
|
|
69
|
-
|
|
99
|
+
interface PluginClientContextAliases {
|
|
100
|
+
/** @deprecated Use `addScreen`. */
|
|
70
101
|
addSurface(id: string, Component: ComponentType<PluginSurfaceProps>): PluginCleanup;
|
|
102
|
+
/** @deprecated Use `addSidebarHeaderItem`. */
|
|
71
103
|
addSidebarItem(contribution: PluginSidebarContribution): PluginCleanup;
|
|
104
|
+
}
|
|
105
|
+
export interface PluginClientContext extends PluginCommandCapabilities, PluginClientContextAliases {
|
|
106
|
+
addSettingsScreen(contribution: PluginSettingsScreenContribution): PluginCleanup;
|
|
107
|
+
addScreen(contribution: PluginScreenContribution): PluginCleanup;
|
|
108
|
+
addSidebarHeaderItem(contribution: PluginSidebarItemContribution): PluginCleanup;
|
|
109
|
+
addSidebarFooterItem(contribution: PluginSidebarItemContribution): PluginCleanup;
|
|
72
110
|
addWorkspacePanel(contribution: PluginWorkspacePanelContribution): PluginCleanup;
|
|
73
111
|
addCommandCenterItem(contribution: PluginCommandCenterItemContribution): PluginCleanup;
|
|
74
112
|
addSlashCommand(contribution: PluginClientSlashCommandContribution): PluginCleanup;
|
|
@@ -94,10 +132,18 @@ export interface PluginSettingsScreenContribution {
|
|
|
94
132
|
icon: string;
|
|
95
133
|
Component: ComponentType<PluginSurfaceProps>;
|
|
96
134
|
}
|
|
135
|
+
/** The screen header's title: fixed, or derived from the params the screen was opened with. */
|
|
136
|
+
export type PluginScreenTitle = string | ((params: PluginScreenParams) => string);
|
|
137
|
+
export interface PluginScreenContribution {
|
|
138
|
+
id: string;
|
|
139
|
+
title: PluginScreenTitle;
|
|
140
|
+
Component: ComponentType<PluginScreenProps>;
|
|
141
|
+
}
|
|
97
142
|
export interface PluginSurfaceContribution {
|
|
98
143
|
id: string;
|
|
99
144
|
Component: ComponentType<PluginSurfaceProps>;
|
|
100
145
|
}
|
|
146
|
+
/** @deprecated Use `PluginSidebarItemContribution` with `addSidebarHeaderItem`. */
|
|
101
147
|
export interface PluginSidebarContribution {
|
|
102
148
|
id: string;
|
|
103
149
|
title: string;
|
|
@@ -135,6 +181,8 @@ export interface PluginTimelineRendererContribution<Schema extends ZodType = Zod
|
|
|
135
181
|
export interface PluginCommandCapabilities {
|
|
136
182
|
paseo: PaseoApi;
|
|
137
183
|
rpc<InputSchema extends ZodType, OutputSchema extends ZodType>(contract: PluginRpcContract<InputSchema, OutputSchema>, input: ZodInput<InputSchema>): Promise<ZodOutput<OutputSchema>>;
|
|
184
|
+
openScreen(input: PluginOpenScreenInput): void;
|
|
185
|
+
/** @deprecated Use `openScreen`. */
|
|
138
186
|
openSurface(id: string): void;
|
|
139
187
|
openSettings(id: string): void;
|
|
140
188
|
}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { PluginHostProps, PluginSurfaceProps, PluginIconProps, PluginPanelLocation, PluginOpenPanelOptions, PluginWorkspacePanelProps, PluginAgentPanelProps, PluginClientOpenPanelOptions, PluginClientContext, PluginClientContribution, PluginWorkspacePanelContribution, PluginSettingsScreenContribution, PluginSurfaceContribution, PluginSidebarContribution, PluginTimelineTransformerContribution, PluginTimelineItemProps, PluginTimelineRendererContribution, PluginCommandCapabilities, PluginGlobalCommandContext, PluginWorkspaceCommandContext, PluginAgentCommandContext, PluginCommandCenterItemContribution, PluginClientSlashCommandContribution, SettingsState, } from "./contracts.js";
|
|
1
|
+
export type { PluginHostProps, PluginSurfaceProps, PluginScreenProps, PluginPopoverProps, PluginScreenParams, PluginOpenScreenInput, PluginScreenLocation, PluginSidebarItemProps, PluginSidebarItemContribution, PluginIconProps, PluginPanelLocation, PluginOpenPanelOptions, PluginWorkspacePanelProps, PluginAgentPanelProps, PluginClientOpenPanelOptions, PluginClientContext, PluginClientContribution, PluginWorkspacePanelContribution, PluginSettingsScreenContribution, PluginSurfaceContribution, PluginScreenContribution, PluginScreenTitle, PluginSidebarContribution, PluginTimelineTransformerContribution, PluginTimelineItemProps, PluginTimelineRendererContribution, PluginCommandCapabilities, PluginGlobalCommandContext, PluginWorkspaceCommandContext, PluginAgentCommandContext, PluginCommandCenterItemContribution, PluginClientSlashCommandContribution, SettingsState, } from "./contracts.js";
|
|
2
2
|
export type { PluginButton, PluginButtonBehavior, PluginButtonContentProps, PluginButtonContext, PluginButtonIcon, PluginButtonIconProps, PluginButtonMenuEntry, PluginButtonRegistration, PluginComposerPillContribution, PluginHeaderButtonContribution, } from "./buttons.js";
|
|
3
3
|
export { usePaseo } from "./paseo-context.js";
|
|
4
4
|
export { useAgent, useWorkspace } from "./client-state.js";
|
package/dist/client/ui.d.ts
CHANGED
|
@@ -65,4 +65,27 @@ export interface ExternalLinkProps {
|
|
|
65
65
|
onError?: (error: unknown) => void;
|
|
66
66
|
}
|
|
67
67
|
export declare const ExternalLink: ComponentType<ExternalLinkProps>;
|
|
68
|
+
export type SidebarIcon = string | ComponentType<{
|
|
69
|
+
size: number;
|
|
70
|
+
color: string;
|
|
71
|
+
}>;
|
|
72
|
+
export interface SidebarRowProps {
|
|
73
|
+
/**
|
|
74
|
+
* Tells rows of one item apart when the item renders several: "bot-2". Unique within the item.
|
|
75
|
+
* Omit it when the item renders one row.
|
|
76
|
+
*/
|
|
77
|
+
id?: string;
|
|
78
|
+
/** A Lucide icon name or a component. */
|
|
79
|
+
icon?: SidebarIcon;
|
|
80
|
+
/** Defaults to the item's registered title. */
|
|
81
|
+
label?: string;
|
|
82
|
+
onPress(): void;
|
|
83
|
+
active?: boolean;
|
|
84
|
+
/** Right slot. Renders beside the row's pressable, so a button here presses on its own. */
|
|
85
|
+
trailing?: ReactNode;
|
|
86
|
+
}
|
|
87
|
+
/** A sidebar navigation row. Render it from a sidebar item's `Component`. */
|
|
88
|
+
export declare const SidebarRow: ComponentType<SidebarRowProps>;
|
|
89
|
+
/** A line between groups of rows. Render it from a sidebar item's `Component`. */
|
|
90
|
+
export declare const SidebarSeparator: ComponentType;
|
|
68
91
|
//# sourceMappingURL=ui.d.ts.map
|
|
@@ -15,6 +15,7 @@ export async function createAcpProviderConnection(options, request) {
|
|
|
15
15
|
}
|
|
16
16
|
const probe = await AcpRuntime.start({
|
|
17
17
|
options,
|
|
18
|
+
launch: request.launch,
|
|
18
19
|
boundarySessionId: "capability-probe",
|
|
19
20
|
env: {},
|
|
20
21
|
emit: () => undefined,
|
|
@@ -45,6 +46,7 @@ export async function createAcpProviderConnection(options, request) {
|
|
|
45
46
|
};
|
|
46
47
|
const state = {
|
|
47
48
|
options,
|
|
49
|
+
launch: request.launch,
|
|
48
50
|
capabilities,
|
|
49
51
|
sessions,
|
|
50
52
|
emit,
|
|
@@ -170,6 +172,7 @@ async function dispatch(input, state) {
|
|
|
170
172
|
async function discover(input, state) {
|
|
171
173
|
const runtime = await AcpRuntime.start({
|
|
172
174
|
options: state.options,
|
|
175
|
+
launch: state.launch,
|
|
173
176
|
boundarySessionId: "catalog",
|
|
174
177
|
env: {},
|
|
175
178
|
emit: state.emit,
|
|
@@ -191,6 +194,7 @@ async function discover(input, state) {
|
|
|
191
194
|
async function listSessions(input, state) {
|
|
192
195
|
const runtime = await AcpRuntime.start({
|
|
193
196
|
options: state.options,
|
|
197
|
+
launch: state.launch,
|
|
194
198
|
boundarySessionId: "sessions",
|
|
195
199
|
env: {},
|
|
196
200
|
emit: state.emit,
|
|
@@ -218,6 +222,7 @@ async function openSession(input, state) {
|
|
|
218
222
|
throw new Error(`Session already exists: ${input.sessionId}`);
|
|
219
223
|
const runtime = await AcpRuntime.start({
|
|
220
224
|
options: state.options,
|
|
225
|
+
launch: state.launch,
|
|
221
226
|
boundarySessionId: input.sessionId,
|
|
222
227
|
env: input.config.env,
|
|
223
228
|
emit: state.emit,
|
|
@@ -257,9 +262,15 @@ class AcpRuntime {
|
|
|
257
262
|
let stream;
|
|
258
263
|
let closeConnector = async () => { };
|
|
259
264
|
if (options.options.command) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
265
|
+
// COMPAT(pluginProviderLaunch): added in v0.10.0, remove after 2027-03-29 once plugin host floor >= v0.10.0.
|
|
266
|
+
// Standalone callers and older hosts do not send a daemon-resolved launch.
|
|
267
|
+
const launch = options.launch ?? {
|
|
268
|
+
command: options.options.command[0],
|
|
269
|
+
args: options.options.command.slice(1),
|
|
270
|
+
env: process.env,
|
|
271
|
+
};
|
|
272
|
+
child = spawn(launch.command, launch.args, {
|
|
273
|
+
env: { ...launch.env, ...options.env },
|
|
263
274
|
stdio: ["pipe", "pipe", "pipe"],
|
|
264
275
|
});
|
|
265
276
|
spawnFailure = new Promise((_resolve, reject) => child.once("error", reject));
|
package/dist/server/acp.js
CHANGED
|
@@ -3,6 +3,7 @@ import type { ZodType, input as ZodInput, output as ZodOutput } from "zod";
|
|
|
3
3
|
import type { PluginRpcContract } from "../rpc.js";
|
|
4
4
|
import type { PluginCleanup } from "../contracts.js";
|
|
5
5
|
import type { ProviderRegistration } from "./provider.js";
|
|
6
|
+
import type { UsageSourceRegistration } from "./usage.js";
|
|
6
7
|
import type { PluginLifecycleRegistration } from "./lifecycle.js";
|
|
7
8
|
export interface PluginHandlerContext {
|
|
8
9
|
paseo: PaseoApi;
|
|
@@ -24,6 +25,7 @@ export interface PluginServerContext extends PluginLifecycleRegistration {
|
|
|
24
25
|
registerSettings<Schema extends ZodType>(definition: import("../settings.js").SettingsDefinition<Schema>): PluginSettings<Schema>;
|
|
25
26
|
handle<InputSchema extends ZodType, OutputSchema extends ZodType>(contract: PluginRpcContract<InputSchema, OutputSchema>, handler: (input: ZodOutput<InputSchema>, context: PluginHandlerContext) => ZodInput<OutputSchema> | Promise<ZodInput<OutputSchema>>): void;
|
|
26
27
|
registerProvider(provider: ProviderRegistration): void;
|
|
28
|
+
registerUsageSource(source: UsageSourceRegistration): void;
|
|
27
29
|
}
|
|
28
30
|
export type PluginServerContribution = (server: PluginServerContext) => PluginCleanup;
|
|
29
31
|
//# sourceMappingURL=contracts.d.ts.map
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type { UsageSourceRegistration, UsageReport, UsageWindow, UsageBalance, UsageDetail, } from "./usage.js";
|
|
1
2
|
export type { PluginHandlerContext, PluginServerContext, PluginServerContribution, PluginSettings, PluginSettingsState, } from "./contracts.js";
|
|
2
3
|
export type { PluginHookContext, PluginHookWorkspace, PluginHookAgent, PluginSessionOpenRequest, PluginTurnOutcome, PluginLifecycleEvents, PluginBeforeRequests, PluginLifecycleRegistration, } from "./lifecycle.js";
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -6,6 +6,9 @@ export type ProviderCapability = (typeof PROVIDER_CAPABILITIES)[number];
|
|
|
6
6
|
export interface ProviderRegistration {
|
|
7
7
|
/** Equal keys share discovery within this provider. Include effective configuration and execution environment. */
|
|
8
8
|
getCatalogCacheKey?(options: ProviderCatalogOptions): Promise<string | undefined>;
|
|
9
|
+
/** Default executable and arguments; the daemon resolves overrides before status/connect. */
|
|
10
|
+
command?: readonly [string, ...string[]];
|
|
11
|
+
status?(request: ProviderStatusRequest): Promise<ProviderStatus>;
|
|
9
12
|
id: string;
|
|
10
13
|
label: string;
|
|
11
14
|
description?: string;
|
|
@@ -16,12 +19,32 @@ export interface ProviderRegistration {
|
|
|
16
19
|
export type ProviderCatalogOptions = {
|
|
17
20
|
scope: "global";
|
|
18
21
|
force?: boolean;
|
|
22
|
+
launch?: ProviderLaunch;
|
|
19
23
|
} | {
|
|
20
24
|
scope: "workspace";
|
|
21
25
|
cwd: string;
|
|
22
26
|
force?: boolean;
|
|
27
|
+
launch?: ProviderLaunch;
|
|
23
28
|
};
|
|
29
|
+
export declare const ProviderLaunchSchema: z.ZodObject<{
|
|
30
|
+
command: z.ZodString;
|
|
31
|
+
args: z.ZodArray<z.ZodString>;
|
|
32
|
+
env: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
export type ProviderLaunch = z.infer<typeof ProviderLaunchSchema>;
|
|
35
|
+
export interface ProviderStatusRequest {
|
|
36
|
+
launch?: ProviderLaunch;
|
|
37
|
+
}
|
|
38
|
+
export declare const ProviderStatusSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
39
|
+
available: z.ZodLiteral<true>;
|
|
40
|
+
diagnostic: z.ZodOptional<z.ZodString>;
|
|
41
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
42
|
+
available: z.ZodLiteral<false>;
|
|
43
|
+
diagnostic: z.ZodString;
|
|
44
|
+
}, z.core.$strip>], "available">;
|
|
45
|
+
export type ProviderStatus = z.infer<typeof ProviderStatusSchema>;
|
|
24
46
|
export interface ProviderConnectRequest {
|
|
47
|
+
launch?: ProviderLaunch;
|
|
25
48
|
versions: readonly number[];
|
|
26
49
|
capabilities: readonly string[];
|
|
27
50
|
}
|
|
@@ -65,7 +88,7 @@ export interface ProviderSessionConfig {
|
|
|
65
88
|
mode?: string;
|
|
66
89
|
thinkingOption?: string;
|
|
67
90
|
settings: Readonly<Record<string, JsonValue>>;
|
|
68
|
-
providerOptions?: Readonly<Record<string,
|
|
91
|
+
providerOptions?: Readonly<Record<string, unknown>>;
|
|
69
92
|
title?: string;
|
|
70
93
|
persist: boolean;
|
|
71
94
|
}
|
package/dist/server/provider.js
CHANGED
|
@@ -19,6 +19,19 @@ export const PROVIDER_CAPABILITIES = [
|
|
|
19
19
|
"permission.tool_policy",
|
|
20
20
|
"timeline.plugin",
|
|
21
21
|
];
|
|
22
|
+
export const ProviderLaunchSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
/** Resolved executable path. */
|
|
25
|
+
command: z.string().min(1),
|
|
26
|
+
args: z.array(z.string()),
|
|
27
|
+
/** Complete daemon-owned environment, including overrides and parent-session stripping. */
|
|
28
|
+
env: z.record(z.string(), z.string()),
|
|
29
|
+
})
|
|
30
|
+
.strip();
|
|
31
|
+
export const ProviderStatusSchema = z.discriminatedUnion("available", [
|
|
32
|
+
z.object({ available: z.literal(true), diagnostic: z.string().optional() }).strip(),
|
|
33
|
+
z.object({ available: z.literal(false), diagnostic: z.string().min(1) }).strip(),
|
|
34
|
+
]);
|
|
22
35
|
export function negotiateProviderCapabilities(offered, supported) {
|
|
23
36
|
const known = new Set(PROVIDER_CAPABILITIES);
|
|
24
37
|
const supportedCapabilities = new Set(supported.filter((capability) => known.has(capability)));
|
|
@@ -151,7 +164,7 @@ const sessionConfigSchema = z
|
|
|
151
164
|
mode: z.string().optional(),
|
|
152
165
|
thinkingOption: z.string().optional(),
|
|
153
166
|
settings: jsonObjectSchema,
|
|
154
|
-
providerOptions:
|
|
167
|
+
providerOptions: z.record(z.string(), z.unknown()).optional(),
|
|
155
168
|
title: z.string().optional(),
|
|
156
169
|
persist: z.boolean(),
|
|
157
170
|
})
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
import type { JsonValue } from "@camerontaylor/paseo-protocol/agent-types";
|
|
3
|
+
export interface UsageWindow {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
/**
|
|
7
|
+
* A few characters naming the window where space is tight, e.g. "5h" or "wk". An empty string
|
|
8
|
+
* shows the percent alone; leaving it out shows `label`.
|
|
9
|
+
*/
|
|
10
|
+
shortLabel?: string;
|
|
11
|
+
/** Shown in the usage summary until the user pins windows of their own. */
|
|
12
|
+
summary?: boolean;
|
|
13
|
+
usedPct?: number | null;
|
|
14
|
+
remainingPct?: number | null;
|
|
15
|
+
resetsAt?: string | null;
|
|
16
|
+
runsOutAt?: string | null;
|
|
17
|
+
shortfallPct?: number | null;
|
|
18
|
+
tone?: "default" | "ok" | "warning" | "danger";
|
|
19
|
+
}
|
|
20
|
+
export interface UsageBalance {
|
|
21
|
+
id: string;
|
|
22
|
+
label: string;
|
|
23
|
+
used?: number | null;
|
|
24
|
+
remaining?: number | null;
|
|
25
|
+
limit?: number | null;
|
|
26
|
+
unit: "usd" | "credits" | "requests" | "tokens";
|
|
27
|
+
resetsAt?: string | null;
|
|
28
|
+
tone?: UsageWindow["tone"];
|
|
29
|
+
}
|
|
30
|
+
export interface UsageDetail {
|
|
31
|
+
id: string;
|
|
32
|
+
label: string;
|
|
33
|
+
value: string;
|
|
34
|
+
tone?: UsageWindow["tone"];
|
|
35
|
+
}
|
|
36
|
+
export type UsageProblem = {
|
|
37
|
+
kind: "expired";
|
|
38
|
+
expiresAt: string;
|
|
39
|
+
refreshedBy?: string;
|
|
40
|
+
} | {
|
|
41
|
+
kind: "rejected";
|
|
42
|
+
status: number;
|
|
43
|
+
refreshedBy?: string;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "no_quota";
|
|
46
|
+
detail: string;
|
|
47
|
+
};
|
|
48
|
+
export type UsageReport = {
|
|
49
|
+
status: "available";
|
|
50
|
+
planLabel?: string;
|
|
51
|
+
windows: UsageWindow[];
|
|
52
|
+
balances?: UsageBalance[];
|
|
53
|
+
details?: UsageDetail[];
|
|
54
|
+
} | {
|
|
55
|
+
status: "unavailable";
|
|
56
|
+
problem: UsageProblem;
|
|
57
|
+
} | {
|
|
58
|
+
status: "error";
|
|
59
|
+
error: string;
|
|
60
|
+
};
|
|
61
|
+
export interface UsageAccount {
|
|
62
|
+
/** Stable across token rotation; [A-Za-z0-9._-]{1,128}. Never a credential or raw email. */
|
|
63
|
+
key: string;
|
|
64
|
+
label?: string;
|
|
65
|
+
/** Store locator, opaque to the daemon. */
|
|
66
|
+
input: JsonValue;
|
|
67
|
+
}
|
|
68
|
+
export interface UsageSourceRegistration {
|
|
69
|
+
id: string;
|
|
70
|
+
label: string;
|
|
71
|
+
icon?: string;
|
|
72
|
+
input: ZodType;
|
|
73
|
+
/** Every account whose login exists on this machine. Empty when none. */
|
|
74
|
+
discover(): Promise<UsageAccount[]>;
|
|
75
|
+
/** Re-reads the login store; never writes it. */
|
|
76
|
+
fetch(input: unknown): Promise<UsageReport>;
|
|
77
|
+
}
|
|
78
|
+
export declare function windowFromUsedPct(input: {
|
|
79
|
+
id: string;
|
|
80
|
+
label: string;
|
|
81
|
+
shortLabel?: string;
|
|
82
|
+
summary?: boolean;
|
|
83
|
+
utilizationPct: number | null | undefined;
|
|
84
|
+
resetsAt?: string | null;
|
|
85
|
+
tone?: UsageWindow["tone"];
|
|
86
|
+
}): UsageWindow;
|
|
87
|
+
/**
|
|
88
|
+
* The tone scale for anything measured against a known limit, windows and balances alike.
|
|
89
|
+
*
|
|
90
|
+
* Thresholds match `deriveTone` in the app's provider-usage/tone.ts, which is what the
|
|
91
|
+
* client falls back to when a window arrives without a tone. Healthy is "ok" rather than
|
|
92
|
+
* "default" because that is what every provider setting a tone has always sent, and it is
|
|
93
|
+
* what the bars render today below their thresholds.
|
|
94
|
+
*/
|
|
95
|
+
export declare function toneFromUsedPct(usedPct: number | null | undefined): UsageWindow["tone"];
|
|
96
|
+
/**
|
|
97
|
+
* Tone for a balance with no known limit, where a percentage cannot be computed and the
|
|
98
|
+
* only signal is whether anything is left. Prefer `toneFromUsedPct` when a limit exists:
|
|
99
|
+
* this one stays "ok" until the balance is completely spent.
|
|
100
|
+
*/
|
|
101
|
+
export declare function balanceToneFromRemaining(remaining: number | null | undefined): UsageBalance["tone"];
|
|
102
|
+
/** Percentage of a limit consumed, or null when either side is unknown. */
|
|
103
|
+
export declare function usedPctOf(used: number | null | undefined, limit: number | null | undefined): number | null;
|
|
104
|
+
export declare function hashAccountKey(value: string): string;
|
|
105
|
+
export declare function unavailable(problem: UsageProblem): UsageReport;
|
|
106
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export function windowFromUsedPct(input) {
|
|
3
|
+
const usedPct = typeof input.utilizationPct === "number" ? input.utilizationPct : null;
|
|
4
|
+
const window = {
|
|
5
|
+
id: input.id,
|
|
6
|
+
label: input.label,
|
|
7
|
+
usedPct,
|
|
8
|
+
remainingPct: usedPct === null ? null : Math.max(0, 100 - usedPct),
|
|
9
|
+
resetsAt: input.resetsAt ?? null,
|
|
10
|
+
};
|
|
11
|
+
if (input.shortLabel !== undefined)
|
|
12
|
+
window.shortLabel = input.shortLabel;
|
|
13
|
+
if (input.summary)
|
|
14
|
+
window.summary = true;
|
|
15
|
+
if (input.tone)
|
|
16
|
+
window.tone = input.tone;
|
|
17
|
+
return window;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The tone scale for anything measured against a known limit, windows and balances alike.
|
|
21
|
+
*
|
|
22
|
+
* Thresholds match `deriveTone` in the app's provider-usage/tone.ts, which is what the
|
|
23
|
+
* client falls back to when a window arrives without a tone. Healthy is "ok" rather than
|
|
24
|
+
* "default" because that is what every provider setting a tone has always sent, and it is
|
|
25
|
+
* what the bars render today below their thresholds.
|
|
26
|
+
*/
|
|
27
|
+
export function toneFromUsedPct(usedPct) {
|
|
28
|
+
if (typeof usedPct !== "number")
|
|
29
|
+
return "default";
|
|
30
|
+
if (usedPct > 90)
|
|
31
|
+
return "danger";
|
|
32
|
+
if (usedPct >= 70)
|
|
33
|
+
return "warning";
|
|
34
|
+
return "ok";
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Tone for a balance with no known limit, where a percentage cannot be computed and the
|
|
38
|
+
* only signal is whether anything is left. Prefer `toneFromUsedPct` when a limit exists:
|
|
39
|
+
* this one stays "ok" until the balance is completely spent.
|
|
40
|
+
*/
|
|
41
|
+
export function balanceToneFromRemaining(remaining) {
|
|
42
|
+
if (typeof remaining !== "number")
|
|
43
|
+
return "default";
|
|
44
|
+
if (remaining <= 0)
|
|
45
|
+
return "danger";
|
|
46
|
+
return "ok";
|
|
47
|
+
}
|
|
48
|
+
/** Percentage of a limit consumed, or null when either side is unknown. */
|
|
49
|
+
export function usedPctOf(used, limit) {
|
|
50
|
+
if (typeof used !== "number" || typeof limit !== "number" || limit <= 0)
|
|
51
|
+
return null;
|
|
52
|
+
return (used / limit) * 100;
|
|
53
|
+
}
|
|
54
|
+
export function hashAccountKey(value) {
|
|
55
|
+
return createHash("sha256").update(value).digest("hex");
|
|
56
|
+
}
|
|
57
|
+
export function unavailable(problem) {
|
|
58
|
+
return { status: "unavailable", problem };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=usage.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camerontaylor/paseo-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-beta.3.fork.1",
|
|
4
4
|
"description": "Paseo plugin SDK package",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"source": "./src/server/provider.ts",
|
|
24
24
|
"default": "./dist/server/provider.js"
|
|
25
25
|
},
|
|
26
|
+
"./server/usage": {
|
|
27
|
+
"types": "./dist/server/usage.d.ts",
|
|
28
|
+
"source": "./src/server/usage.ts",
|
|
29
|
+
"default": "./dist/server/usage.js"
|
|
30
|
+
},
|
|
26
31
|
"./server/acp": {
|
|
27
32
|
"types": "./dist/server/acp.d.ts",
|
|
28
33
|
"source": "./src/server/acp.ts",
|
|
@@ -65,8 +70,8 @@
|
|
|
65
70
|
"use-sync-external-store": "^1.6.0"
|
|
66
71
|
},
|
|
67
72
|
"devDependencies": {
|
|
68
|
-
"@camerontaylor/paseo-client": "0.
|
|
69
|
-
"@camerontaylor/paseo-protocol": "0.
|
|
73
|
+
"@camerontaylor/paseo-client": "0.11.0-beta.3.fork.1",
|
|
74
|
+
"@camerontaylor/paseo-protocol": "0.11.0-beta.3.fork.1",
|
|
70
75
|
"@types/node": "^20.9.0",
|
|
71
76
|
"@types/react": "~19.2.0",
|
|
72
77
|
"react": "19.1.0",
|
|
@@ -76,8 +81,8 @@
|
|
|
76
81
|
"zod": "^4.4.3"
|
|
77
82
|
},
|
|
78
83
|
"peerDependencies": {
|
|
79
|
-
"@camerontaylor/paseo-client": "0.
|
|
80
|
-
"@camerontaylor/paseo-protocol": "0.
|
|
84
|
+
"@camerontaylor/paseo-client": "0.11.0-beta.3.fork.1",
|
|
85
|
+
"@camerontaylor/paseo-protocol": "0.11.0-beta.3.fork.1",
|
|
81
86
|
"react": "~19.1.0",
|
|
82
87
|
"react-native": ">=0.81.5",
|
|
83
88
|
"zod": "^4.4.3"
|