@openlimiter/connectors 0.2.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/dist/antigravity.d.ts +50 -1
- package/dist/antigravity.d.ts.map +1 -1
- package/dist/antigravity.js +150 -19
- package/dist/antigravity.js.map +1 -1
- package/dist/claude.d.ts +72 -6
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +467 -35
- package/dist/claude.js.map +1 -1
- package/dist/codex.d.ts +23 -1
- package/dist/codex.d.ts.map +1 -1
- package/dist/codex.js +112 -13
- package/dist/codex.js.map +1 -1
- package/dist/contract-gate.d.ts +56 -0
- package/dist/contract-gate.d.ts.map +1 -0
- package/dist/contract-gate.js +100 -0
- package/dist/contract-gate.js.map +1 -0
- package/dist/fixtures.d.ts +274 -2
- package/dist/fixtures.d.ts.map +1 -1
- package/dist/fixtures.js +947 -17
- package/dist/fixtures.js.map +1 -1
- package/dist/gemini-cli.d.ts +13 -0
- package/dist/gemini-cli.d.ts.map +1 -0
- package/dist/gemini-cli.js +86 -0
- package/dist/gemini-cli.js.map +1 -0
- package/dist/grok.d.ts +13 -0
- package/dist/grok.d.ts.map +1 -0
- package/dist/grok.js +143 -0
- package/dist/grok.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/kimi.d.ts +13 -0
- package/dist/kimi.d.ts.map +1 -0
- package/dist/kimi.js +141 -0
- package/dist/kimi.js.map +1 -0
- package/dist/manual.d.ts +3 -1
- package/dist/manual.d.ts.map +1 -1
- package/dist/manual.js +7 -3
- package/dist/manual.js.map +1 -1
- package/dist/opencode.d.ts +103 -1
- package/dist/opencode.d.ts.map +1 -1
- package/dist/opencode.js +428 -21
- package/dist/opencode.js.map +1 -1
- package/dist/openrouter.d.ts +3 -1
- package/dist/openrouter.d.ts.map +1 -1
- package/dist/openrouter.js +7 -3
- package/dist/openrouter.js.map +1 -1
- package/dist/shared.d.ts +105 -1
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +190 -0
- package/dist/shared.js.map +1 -1
- package/package.json +4 -3
package/dist/opencode.d.ts
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
|
-
import type { ConnectorContract, RawMeter } from "@openlimiter/core";
|
|
1
|
+
import type { ConnectionStatus, ConnectionTool, ConnectorContract, RawMeter } from "@openlimiter/core";
|
|
2
|
+
/**
|
|
3
|
+
* The OpenCode usage reader, and the least trustworthy one in the product.
|
|
4
|
+
*
|
|
5
|
+
* OpenCode publishes no usage interface at all. More than twenty candidate
|
|
6
|
+
* routes were probed on 2026-08-03 and the API key opens none of them: the plan
|
|
7
|
+
* percentages exist only inside the HTML of a logged in workspace page, server
|
|
8
|
+
* rendered. So this parser reads a PAGE, not a payload, and that is why its
|
|
9
|
+
* labels say browser-session, authenticated-scrape and automationRisk high, and
|
|
10
|
+
* why they do not improve when a capture lands. They describe the method, not
|
|
11
|
+
* the amount of evidence behind it.
|
|
12
|
+
*
|
|
13
|
+
* The reader used to parse `usage.percent` out of a JSON object, a shape from
|
|
14
|
+
* an early prototype that no OpenCode surface has ever produced.
|
|
15
|
+
*
|
|
16
|
+
* Two things make reading HTML survivable rather than reckless. Windows are
|
|
17
|
+
* matched by their LABEL and never by position, so a reordered page degrades to
|
|
18
|
+
* unknown instead of quietly reporting the monthly figure as the weekly one.
|
|
19
|
+
* And all three labels must be found: a page that has changed enough to lose
|
|
20
|
+
* one of them has changed enough not to be trusted for the other two.
|
|
21
|
+
*/
|
|
2
22
|
export declare const opencodeLabels: {
|
|
3
23
|
readonly credentialOrigin: "browser-session";
|
|
4
24
|
readonly dataInterfaceStatus: "authenticated-scrape";
|
|
@@ -6,12 +26,94 @@ export declare const opencodeLabels: {
|
|
|
6
26
|
readonly verification: "UNVERIFIED";
|
|
7
27
|
};
|
|
8
28
|
export declare const opencodeHonesty: "UNVERIFIED_AUTHENTICATED_SCRAPE_HIGH_RISK";
|
|
29
|
+
/**
|
|
30
|
+
* BETA, and stated rather than implied.
|
|
31
|
+
*
|
|
32
|
+
* Every other reader in this package reads an interface: documented, private,
|
|
33
|
+
* or declared in a vendor's own client source, but an interface. This one reads
|
|
34
|
+
* a page that was designed for a person's eyes, whose wording nobody promised
|
|
35
|
+
* and which has already been renamed once underneath it. That is a different
|
|
36
|
+
* class of thing, and a surface that shows it beside the others has to be able
|
|
37
|
+
* to say so.
|
|
38
|
+
*/
|
|
39
|
+
export declare const opencodeMaturity: "beta";
|
|
9
40
|
export declare const opencodeInput: {
|
|
10
41
|
readonly kind: "authenticated_page_payload";
|
|
11
42
|
readonly pathTemplate: "{browserSession}/usage";
|
|
12
43
|
readonly readMode: "read_only";
|
|
13
44
|
readonly honesty: "UNVERIFIED_AUTHENTICATED_SCRAPE_HIGH_RISK";
|
|
45
|
+
readonly maturity: "beta";
|
|
14
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* What this reader reads: text, not JSON.
|
|
49
|
+
*
|
|
50
|
+
* The collection pipeline keys on this. A body for this reader is handed over
|
|
51
|
+
* as the raw string it arrived as, because running it through a JSON parser
|
|
52
|
+
* first would turn every real response into a parse failure.
|
|
53
|
+
*/
|
|
54
|
+
export declare const opencodeEncoding: "text";
|
|
55
|
+
/**
|
|
56
|
+
* How far this reader will search for a window's own container, in characters.
|
|
57
|
+
*
|
|
58
|
+
* A bound on WORK, not a boundary. The boundary is structural: see
|
|
59
|
+
* `windowContainer`. A character count alone was tried and it does not close
|
|
60
|
+
* the hole, because "the first percentage within two thousand characters after
|
|
61
|
+
* the label" still reaches a footer when the window's own percentage is absent.
|
|
62
|
+
* That is the difference between bounding how far a reader wanders and
|
|
63
|
+
* bounding where it is allowed to look at all.
|
|
64
|
+
*/
|
|
65
|
+
export declare const OPENCODE_MAX_SEGMENT_CHARS = 2000;
|
|
66
|
+
/**
|
|
67
|
+
* Largest page this reader will look at, in characters.
|
|
68
|
+
*
|
|
69
|
+
* The transport already bounds the response at one mebibyte. This is the second
|
|
70
|
+
* bound, on the work done with it, so a page that is within the transport's
|
|
71
|
+
* limit still cannot make the label scan expensive.
|
|
72
|
+
*/
|
|
73
|
+
export declare const OPENCODE_MAX_PAGE_CHARS = 1048576;
|
|
74
|
+
export type OpencodeMeter = "FIVE_HOUR" | "SEVEN_DAY" | "MONTHLY";
|
|
75
|
+
/**
|
|
76
|
+
* The cadences the workspace page renders, and how each one is recognised.
|
|
77
|
+
*
|
|
78
|
+
* This used to be three exact phrases, all three required, and the page renamed
|
|
79
|
+
* them. Three exact strings is the most brittle possible way to read a document
|
|
80
|
+
* whose wording nobody promised us, and the failure was total: one renamed
|
|
81
|
+
* heading and the whole reader went dark on a page still rendering all three
|
|
82
|
+
* figures.
|
|
83
|
+
*
|
|
84
|
+
* So a cadence is now recognised by the WORD that names it, case insensitively,
|
|
85
|
+
* with the wordings seen so far and the obvious neighbours of each. Structure
|
|
86
|
+
* still does the real work: a match only produces a reading if it sits in a
|
|
87
|
+
* container that holds a percentage and names no other cadence, which is the
|
|
88
|
+
* guard that stops a heading from borrowing the figure beside it.
|
|
89
|
+
*/
|
|
90
|
+
export declare const OPENCODE_WINDOWS: readonly {
|
|
91
|
+
readonly meter: OpencodeMeter;
|
|
92
|
+
readonly seconds: number;
|
|
93
|
+
/** Every wording this cadence has been seen under, matched case blind. */
|
|
94
|
+
readonly pattern: RegExp;
|
|
95
|
+
}[];
|
|
96
|
+
/**
|
|
97
|
+
* Every provider window, including the monthly quota.
|
|
98
|
+
*
|
|
99
|
+
* The shared policy still derives the binding window by choosing the highest
|
|
100
|
+
* percentage. Keeping the three source windows lets every surface state which
|
|
101
|
+
* cadence a number belongs to instead of hiding the monthly value inside one
|
|
102
|
+
* synthetic primary meter.
|
|
103
|
+
*/
|
|
15
104
|
export declare function parseOpencodePayload(payload: unknown, now: string): RawMeter[] | null;
|
|
105
|
+
/** The local application that owns this browser session. */
|
|
106
|
+
export declare const OPENCODE_TOOL: ConnectionTool;
|
|
107
|
+
/**
|
|
108
|
+
* The connection this reader reports, which is not the generic one.
|
|
109
|
+
*
|
|
110
|
+
* A page it cannot read has two very different causes, and they need two
|
|
111
|
+
* different sentences. A logged out workspace renders a sign in form, and the
|
|
112
|
+
* fix is one click in a window the person already has open. Anything else is a
|
|
113
|
+
* layout this build no longer understands, which is ours to fix, and the honest
|
|
114
|
+
* instruction is to reconnect and tell us if it keeps happening. Neither one
|
|
115
|
+
* throws, and neither one is silence.
|
|
116
|
+
*/
|
|
117
|
+
export declare function opencodeConnection(parsed: boolean, payload: unknown): ConnectionStatus;
|
|
16
118
|
export declare const opencodeConnector: ConnectorContract;
|
|
17
119
|
//# sourceMappingURL=opencode.d.ts.map
|
package/dist/opencode.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../src/opencode.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../src/opencode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EAIjB,QAAQ,EACT,MAAM,mBAAmB,CAAC;AAQ3B;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,cAAc;;;;;CAKS,CAAC;AAErC,eAAO,MAAM,eAAe,EAAG,2CAAoD,CAAC;AAEpF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,QAA8C,CAAC;AAE5E,eAAO,MAAM,aAAa;;;;;;CAMhB,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAG,MAAe,CAAC;AAEhD;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,OAAQ,CAAC;AA6ChD;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,UAAY,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS;IACtC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,EAgBA,CAAC;AAqPF;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,IAAI,CAkCrF;AAED,4DAA4D;AAC5D,eAAO,MAAM,aAAa,EAAE,cAA2B,CAAC;AAExD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAmBtF;AAED,eAAO,MAAM,iBAAiB,EAAE,iBAgB/B,CAAC"}
|
package/dist/opencode.js
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
// This interface is UNOFFICIAL and may break.
|
|
2
|
+
import { connectionStatus } from "@openlimiter/core";
|
|
3
|
+
import { durationSecondsFromWords, instantAfter, rawMeter, shortExpiry } from "./shared.js";
|
|
4
|
+
/**
|
|
5
|
+
* The OpenCode usage reader, and the least trustworthy one in the product.
|
|
6
|
+
*
|
|
7
|
+
* OpenCode publishes no usage interface at all. More than twenty candidate
|
|
8
|
+
* routes were probed on 2026-08-03 and the API key opens none of them: the plan
|
|
9
|
+
* percentages exist only inside the HTML of a logged in workspace page, server
|
|
10
|
+
* rendered. So this parser reads a PAGE, not a payload, and that is why its
|
|
11
|
+
* labels say browser-session, authenticated-scrape and automationRisk high, and
|
|
12
|
+
* why they do not improve when a capture lands. They describe the method, not
|
|
13
|
+
* the amount of evidence behind it.
|
|
14
|
+
*
|
|
15
|
+
* The reader used to parse `usage.percent` out of a JSON object, a shape from
|
|
16
|
+
* an early prototype that no OpenCode surface has ever produced.
|
|
17
|
+
*
|
|
18
|
+
* Two things make reading HTML survivable rather than reckless. Windows are
|
|
19
|
+
* matched by their LABEL and never by position, so a reordered page degrades to
|
|
20
|
+
* unknown instead of quietly reporting the monthly figure as the weekly one.
|
|
21
|
+
* And all three labels must be found: a page that has changed enough to lose
|
|
22
|
+
* one of them has changed enough not to be trusted for the other two.
|
|
23
|
+
*/
|
|
2
24
|
export const opencodeLabels = {
|
|
3
25
|
credentialOrigin: "browser-session",
|
|
4
26
|
dataInterfaceStatus: "authenticated-scrape",
|
|
@@ -6,45 +28,430 @@ export const opencodeLabels = {
|
|
|
6
28
|
verification: "UNVERIFIED"
|
|
7
29
|
};
|
|
8
30
|
export const opencodeHonesty = "UNVERIFIED_AUTHENTICATED_SCRAPE_HIGH_RISK";
|
|
31
|
+
/**
|
|
32
|
+
* BETA, and stated rather than implied.
|
|
33
|
+
*
|
|
34
|
+
* Every other reader in this package reads an interface: documented, private,
|
|
35
|
+
* or declared in a vendor's own client source, but an interface. This one reads
|
|
36
|
+
* a page that was designed for a person's eyes, whose wording nobody promised
|
|
37
|
+
* and which has already been renamed once underneath it. That is a different
|
|
38
|
+
* class of thing, and a surface that shows it beside the others has to be able
|
|
39
|
+
* to say so.
|
|
40
|
+
*/
|
|
41
|
+
export const opencodeMaturity = "beta";
|
|
9
42
|
export const opencodeInput = {
|
|
10
43
|
kind: "authenticated_page_payload",
|
|
11
44
|
pathTemplate: "{browserSession}/usage",
|
|
12
45
|
readMode: "read_only",
|
|
13
|
-
honesty: opencodeHonesty
|
|
46
|
+
honesty: opencodeHonesty,
|
|
47
|
+
maturity: opencodeMaturity
|
|
14
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* What this reader reads: text, not JSON.
|
|
51
|
+
*
|
|
52
|
+
* The collection pipeline keys on this. A body for this reader is handed over
|
|
53
|
+
* as the raw string it arrived as, because running it through a JSON parser
|
|
54
|
+
* first would turn every real response into a parse failure.
|
|
55
|
+
*/
|
|
56
|
+
export const opencodeEncoding = "text";
|
|
57
|
+
/**
|
|
58
|
+
* How far this reader will search for a window's own container, in characters.
|
|
59
|
+
*
|
|
60
|
+
* A bound on WORK, not a boundary. The boundary is structural: see
|
|
61
|
+
* `windowContainer`. A character count alone was tried and it does not close
|
|
62
|
+
* the hole, because "the first percentage within two thousand characters after
|
|
63
|
+
* the label" still reaches a footer when the window's own percentage is absent.
|
|
64
|
+
* That is the difference between bounding how far a reader wanders and
|
|
65
|
+
* bounding where it is allowed to look at all.
|
|
66
|
+
*/
|
|
67
|
+
export const OPENCODE_MAX_SEGMENT_CHARS = 2_000;
|
|
68
|
+
/**
|
|
69
|
+
* Elements that never close, so a scan must not wait for a closing tag.
|
|
70
|
+
*
|
|
71
|
+
* Not exhaustive HTML: exhaustive for what a rendered page puts inside a meter
|
|
72
|
+
* block. An element outside this list that never closes makes the container
|
|
73
|
+
* scan run past its own end, and the scan answers null rather than guessing,
|
|
74
|
+
* which is the direction that costs a reading instead of inventing one.
|
|
75
|
+
*/
|
|
76
|
+
const VOID_ELEMENTS = new Set([
|
|
77
|
+
"area", "base", "br", "col", "embed", "hr", "img", "input",
|
|
78
|
+
"link", "meta", "param", "source", "track", "wbr"
|
|
79
|
+
]);
|
|
80
|
+
/** Every tag in a slice of text, in order. Comments are not tags. */
|
|
81
|
+
function tagsIn(html, from, to) {
|
|
82
|
+
const tags = [];
|
|
83
|
+
const pattern = /<!--[\s\S]*?-->|<\s*(\/?)\s*([a-zA-Z][a-zA-Z0-9-]*)([^>]*)>/gu;
|
|
84
|
+
const slice = html.slice(from, to);
|
|
85
|
+
for (const match of slice.matchAll(pattern)) {
|
|
86
|
+
/* A comment matched the first alternative and has no tag name. */
|
|
87
|
+
if (match[2] === undefined)
|
|
88
|
+
continue;
|
|
89
|
+
const name = match[2].toLowerCase();
|
|
90
|
+
const attributes = match[3] ?? "";
|
|
91
|
+
tags.push({
|
|
92
|
+
at: from + (match.index ?? 0),
|
|
93
|
+
end: from + (match.index ?? 0) + match[0].length,
|
|
94
|
+
name,
|
|
95
|
+
closing: match[1] === "/",
|
|
96
|
+
selfClosing: attributes.trimEnd().endsWith("/") || VOID_ELEMENTS.has(name)
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return tags;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Largest page this reader will look at, in characters.
|
|
103
|
+
*
|
|
104
|
+
* The transport already bounds the response at one mebibyte. This is the second
|
|
105
|
+
* bound, on the work done with it, so a page that is within the transport's
|
|
106
|
+
* limit still cannot make the label scan expensive.
|
|
107
|
+
*/
|
|
108
|
+
export const OPENCODE_MAX_PAGE_CHARS = 1_048_576;
|
|
109
|
+
/**
|
|
110
|
+
* The cadences the workspace page renders, and how each one is recognised.
|
|
111
|
+
*
|
|
112
|
+
* This used to be three exact phrases, all three required, and the page renamed
|
|
113
|
+
* them. Three exact strings is the most brittle possible way to read a document
|
|
114
|
+
* whose wording nobody promised us, and the failure was total: one renamed
|
|
115
|
+
* heading and the whole reader went dark on a page still rendering all three
|
|
116
|
+
* figures.
|
|
117
|
+
*
|
|
118
|
+
* So a cadence is now recognised by the WORD that names it, case insensitively,
|
|
119
|
+
* with the wordings seen so far and the obvious neighbours of each. Structure
|
|
120
|
+
* still does the real work: a match only produces a reading if it sits in a
|
|
121
|
+
* container that holds a percentage and names no other cadence, which is the
|
|
122
|
+
* guard that stops a heading from borrowing the figure beside it.
|
|
123
|
+
*/
|
|
124
|
+
export const OPENCODE_WINDOWS = [
|
|
125
|
+
{
|
|
126
|
+
meter: "FIVE_HOUR",
|
|
127
|
+
seconds: 18_000,
|
|
128
|
+
pattern: /\b(?:rolling|session|5[\s-]*hour|five[\s-]*hour)\b/giu
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
meter: "SEVEN_DAY",
|
|
132
|
+
seconds: 604_800,
|
|
133
|
+
pattern: /\b(?:weekly|week|7[\s-]*day|seven[\s-]*day)\b/giu
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
meter: "MONTHLY",
|
|
137
|
+
seconds: 2_592_000,
|
|
138
|
+
pattern: /\b(?:monthly|month|30[\s-]*day|thirty[\s-]*day)\b/giu
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
/**
|
|
142
|
+
* What a logged out workspace page says instead of a meter.
|
|
143
|
+
*
|
|
144
|
+
* Read only to tell a person WHICH thing went wrong. A page this reader cannot
|
|
145
|
+
* read is either a layout change or a session that ended, and those need
|
|
146
|
+
* different sentences: one is ours to fix and the other is one click.
|
|
147
|
+
*/
|
|
148
|
+
const SIGNED_OUT = /\b(?:sign[\s-]?in|sign[\s-]?up|log[\s-]?in|create an account)\b/iu;
|
|
149
|
+
/**
|
|
150
|
+
* Markup and hydration comments, removed so text can be matched.
|
|
151
|
+
*
|
|
152
|
+
* The page is server rendered by a framework that sprays hydration markers
|
|
153
|
+
* through the text, so it renders "Resets in<!--/--> <!--$-->5 days<!--/-->".
|
|
154
|
+
* Matching against raw HTML silently loses every reset time, which is a missing
|
|
155
|
+
* countdown rather than a wrong number, but missing for an invisible reason is
|
|
156
|
+
* still the worst kind of missing. Verified against the live page 2026-08-03.
|
|
157
|
+
*/
|
|
158
|
+
const MARKUP = /<!--[\s\S]*?-->|<[^>]*>/gu;
|
|
159
|
+
/**
|
|
160
|
+
* A percentage as the page prints it.
|
|
161
|
+
*
|
|
162
|
+
* The decimal part is optional because the page has printed both "92%" and
|
|
163
|
+
* "92.4%", and a reader that only knows whole numbers reads the second as 92
|
|
164
|
+
* or as nothing at all depending on where the match lands. The number pattern
|
|
165
|
+
* is what this reader trusts; the wording around it is not.
|
|
166
|
+
*/
|
|
167
|
+
const PERCENT = /(\d{1,3}(?:\.\d{1,2})?)\s*%/u;
|
|
168
|
+
/**
|
|
169
|
+
* A countdown as the page prints it.
|
|
170
|
+
*
|
|
171
|
+
* Anchored on the verb rather than one exact phrase, because "Resets in",
|
|
172
|
+
* "Renews in" and "Refreshes in" all name the same thing and the page has used
|
|
173
|
+
* more than one. It still consumes only consecutive number and unit pairs, so
|
|
174
|
+
* it cannot wander into the next window's duration if a boundary ever moves.
|
|
175
|
+
*/
|
|
176
|
+
const RESETS_IN = /\b(?:resets?|renews?|refreshes|refresh)\b(?:\s+in)?[:\s]\s*((?:\d{1,6}\s*(?:day|hour|minute|second)s?\s*)+)/iu;
|
|
177
|
+
function flatten(fragment) {
|
|
178
|
+
return fragment.replace(MARKUP, " ").split(/\s+/u).filter(Boolean).join(" ");
|
|
179
|
+
}
|
|
180
|
+
/** How many ancestors of a label this reader will consider. */
|
|
181
|
+
const MAX_CONTAINER_DEPTH = 6;
|
|
182
|
+
/**
|
|
183
|
+
* The element that encloses a position, as a half open range, or null.
|
|
184
|
+
*
|
|
185
|
+
* Found by walking backwards to the nearest element still open at that point,
|
|
186
|
+
* then forwards to its own closing tag. Both walks are bounded, and every
|
|
187
|
+
* failure answers null: an unbalanced page is one this reader declines rather
|
|
188
|
+
* than one it reads approximately.
|
|
189
|
+
*/
|
|
190
|
+
function enclosingElement(html, at) {
|
|
191
|
+
const searchFrom = Math.max(0, at - OPENCODE_MAX_SEGMENT_CHARS);
|
|
192
|
+
const before = tagsIn(html, searchFrom, at);
|
|
193
|
+
/* Backwards: a closing tag means a sibling element already finished, so the
|
|
194
|
+
next opening tag going left belongs to it and not to us. */
|
|
195
|
+
let pendingCloses = 0;
|
|
196
|
+
let container = null;
|
|
197
|
+
for (let index = before.length - 1; index >= 0; index -= 1) {
|
|
198
|
+
const tag = before[index];
|
|
199
|
+
if (tag.selfClosing)
|
|
200
|
+
continue;
|
|
201
|
+
if (tag.closing) {
|
|
202
|
+
pendingCloses += 1;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (pendingCloses > 0) {
|
|
206
|
+
pendingCloses -= 1;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
container = tag;
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
if (container === null)
|
|
213
|
+
return null;
|
|
214
|
+
/* Forwards from just inside the container to its own close, counting depth so
|
|
215
|
+
a nested element of the same name cannot end the region early. */
|
|
216
|
+
const searchTo = Math.min(html.length, container.end + OPENCODE_MAX_SEGMENT_CHARS);
|
|
217
|
+
let depth = 0;
|
|
218
|
+
for (const tag of tagsIn(html, container.end, searchTo)) {
|
|
219
|
+
if (tag.selfClosing)
|
|
220
|
+
continue;
|
|
221
|
+
if (!tag.closing) {
|
|
222
|
+
depth += 1;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (depth === 0) {
|
|
226
|
+
return tag.name === container.name
|
|
227
|
+
? { openedAt: container.at, from: container.end, to: tag.at }
|
|
228
|
+
/* A closing tag for something else pops above our container, which
|
|
229
|
+
means the page is unbalanced here. Decline it. */
|
|
230
|
+
: null;
|
|
231
|
+
}
|
|
232
|
+
depth -= 1;
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The region a window's reading may be read from, or null.
|
|
238
|
+
*
|
|
239
|
+
* This is the fix for the final segment attack, and the reason a character count
|
|
240
|
+
* could not be. A window's figure is not inside the heading that names it: it is
|
|
241
|
+
* a SIBLING of that heading, in a shared block. So the readable region is an
|
|
242
|
+
* ancestor of the label, and the right ancestor is the nearest one that holds a
|
|
243
|
+
* percentage while naming no other window.
|
|
244
|
+
*
|
|
245
|
+
* Both halves of that rule carry weight. Requiring a percentage is what walks
|
|
246
|
+
* past the bare heading element. Refusing a region that names another window is
|
|
247
|
+
* what stops the walk at the meter block instead of continuing up to the page
|
|
248
|
+
* body, which contains every window's figure and would let any of them stand in
|
|
249
|
+
* for any other. When no ancestor satisfies both, there is no region, and a
|
|
250
|
+
* window with no region is refused rather than approximated: that is the case
|
|
251
|
+
* the audit named, a monthly block that rendered no figure and a footer a few
|
|
252
|
+
* characters later that did.
|
|
253
|
+
*/
|
|
254
|
+
function windowRegion(html, labelAt, otherLabels) {
|
|
255
|
+
let position = labelAt;
|
|
256
|
+
for (let level = 0; level < MAX_CONTAINER_DEPTH; level += 1) {
|
|
257
|
+
const element = enclosingElement(html, position);
|
|
258
|
+
if (element === null)
|
|
259
|
+
return null;
|
|
260
|
+
const segment = flatten(html.slice(element.from, element.to));
|
|
261
|
+
if (otherLabels.some((pattern) => matches(pattern, segment)))
|
|
262
|
+
return null;
|
|
263
|
+
if (PERCENT.test(segment))
|
|
264
|
+
return segment;
|
|
265
|
+
/* No figure at this level, so try the block above it. */
|
|
266
|
+
position = element.openedAt;
|
|
267
|
+
}
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Whether a position sits inside a tag rather than in text a person reads.
|
|
272
|
+
*
|
|
273
|
+
* A cadence word in `class="monthly-card"` is markup, not a heading, and
|
|
274
|
+
* treating it as one would put a label in a place the reader then has to
|
|
275
|
+
* resolve a container for. Cheap and exact enough: the last angle bracket
|
|
276
|
+
* before the position decides.
|
|
277
|
+
*/
|
|
278
|
+
function insideTag(html, at) {
|
|
279
|
+
return html.lastIndexOf("<", at) > html.lastIndexOf(">", at);
|
|
280
|
+
}
|
|
281
|
+
/** Whether a pattern matches, without carrying lastIndex between calls. */
|
|
282
|
+
function matches(pattern, text) {
|
|
283
|
+
pattern.lastIndex = 0;
|
|
284
|
+
return pattern.test(text);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Where each cadence is named on the page, when it is named exactly once.
|
|
288
|
+
*
|
|
289
|
+
* A cadence named nowhere is a window this page is not rendering. A cadence
|
|
290
|
+
* named twice is two candidate containers and no way to know which one is the
|
|
291
|
+
* meter, so it is ambiguous. Both cost that cadence and nothing else: losing
|
|
292
|
+
* one bar is a smaller failure than drawing a bar with somebody else's number
|
|
293
|
+
* in it, and losing all three because one heading was renamed, which is what
|
|
294
|
+
* this reader used to do, is the largest failure of the three.
|
|
295
|
+
*/
|
|
296
|
+
function findLabels(html) {
|
|
297
|
+
const hits = [];
|
|
298
|
+
for (const window of OPENCODE_WINDOWS) {
|
|
299
|
+
window.pattern.lastIndex = 0;
|
|
300
|
+
const positions = [];
|
|
301
|
+
for (const match of html.matchAll(window.pattern)) {
|
|
302
|
+
const at = match.index ?? -1;
|
|
303
|
+
if (at < 0 || insideTag(html, at))
|
|
304
|
+
continue;
|
|
305
|
+
positions.push(at);
|
|
306
|
+
/* Two is already ambiguous, so there is no reason to scan a large page
|
|
307
|
+
looking for a third. */
|
|
308
|
+
if (positions.length > 1)
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
if (positions.length !== 1)
|
|
312
|
+
continue;
|
|
313
|
+
hits.push({
|
|
314
|
+
at: positions[0] ?? 0,
|
|
315
|
+
meter: window.meter,
|
|
316
|
+
seconds: window.seconds,
|
|
317
|
+
others: OPENCODE_WINDOWS
|
|
318
|
+
.filter((other) => other.meter !== window.meter)
|
|
319
|
+
.map((other) => other.pattern)
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
return hits.sort((left, right) => left.at - right.at);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Every window this page states, or null when it states none this reader can
|
|
326
|
+
* believe.
|
|
327
|
+
*
|
|
328
|
+
* Each window's figure is read out of its own CONTAINER and nowhere else, so a
|
|
329
|
+
* percentage can only ever be attributed to the block that rendered it. A
|
|
330
|
+
* window whose container cannot be resolved, or holds no percentage, or holds
|
|
331
|
+
* an impossible one, is dropped alone: the page is a rendered document rather
|
|
332
|
+
* than a contract, and one block changing shape is not a reason to discard the
|
|
333
|
+
* blocks that did not.
|
|
334
|
+
*/
|
|
335
|
+
function parseWindows(html, now) {
|
|
336
|
+
const windows = [];
|
|
337
|
+
for (const hit of findLabels(html)) {
|
|
338
|
+
const segment = windowRegion(html, hit.at, hit.others);
|
|
339
|
+
if (segment === null)
|
|
340
|
+
continue;
|
|
341
|
+
const percentMatch = PERCENT.exec(segment);
|
|
342
|
+
if (percentMatch === null)
|
|
343
|
+
continue;
|
|
344
|
+
const percent = Number.parseFloat(percentMatch[1] ?? "");
|
|
345
|
+
if (!Number.isFinite(percent) || percent < 0 || percent > 100)
|
|
346
|
+
continue;
|
|
347
|
+
/* The countdown is optional, because the page omits it on a window that has
|
|
348
|
+
no reset pending. A missing countdown costs the countdown and nothing
|
|
349
|
+
else: the percentage beside it was still rendered by the provider. */
|
|
350
|
+
const resetMatch = RESETS_IN.exec(segment);
|
|
351
|
+
const seconds = resetMatch === null ? null : durationSecondsFromWords(resetMatch[1] ?? "");
|
|
352
|
+
windows.push({
|
|
353
|
+
meter: hit.meter,
|
|
354
|
+
percent,
|
|
355
|
+
seconds: hit.seconds,
|
|
356
|
+
resetAt: seconds === null ? null : instantAfter(now, seconds)
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
return windows.length === 0 ? null : windows;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Every provider window, including the monthly quota.
|
|
363
|
+
*
|
|
364
|
+
* The shared policy still derives the binding window by choosing the highest
|
|
365
|
+
* percentage. Keeping the three source windows lets every surface state which
|
|
366
|
+
* cadence a number belongs to instead of hiding the monthly value inside one
|
|
367
|
+
* synthetic primary meter.
|
|
368
|
+
*/
|
|
15
369
|
export function parseOpencodePayload(payload, now) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
370
|
+
if (typeof payload !== "string")
|
|
371
|
+
return null;
|
|
372
|
+
if (payload.length === 0 || payload.length > OPENCODE_MAX_PAGE_CHARS)
|
|
373
|
+
return null;
|
|
374
|
+
/*
|
|
375
|
+
* Fail soft, and mean it. This is the only reader in the package pointed at a
|
|
376
|
+
* rendered document rather than an interface, so it is the only one where an
|
|
377
|
+
* unforeseen shape can reach code that was not written for it. A thrown error
|
|
378
|
+
* here would take down whatever was collecting, which would turn one changed
|
|
379
|
+
* page into a broken product, so the whole scan answers null instead and the
|
|
380
|
+
* connection below says what a person should do about it.
|
|
381
|
+
*/
|
|
382
|
+
let windows = null;
|
|
383
|
+
try {
|
|
384
|
+
windows = parseWindows(payload, now);
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
if (windows === null || windows.length === 0)
|
|
390
|
+
return null;
|
|
20
391
|
const expiresAt = shortExpiry(now);
|
|
21
|
-
if (
|
|
392
|
+
if (expiresAt === null)
|
|
22
393
|
return null;
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
394
|
+
return windows.map((window) => rawMeter({
|
|
395
|
+
provider: "OPENCODE",
|
|
396
|
+
meter: window.meter,
|
|
397
|
+
value: window.percent,
|
|
398
|
+
window: { kind: "rolling", durationSeconds: window.seconds },
|
|
399
|
+
resetAt: window.resetAt,
|
|
400
|
+
source: "authenticated_page",
|
|
401
|
+
precision: "estimated",
|
|
402
|
+
observedAt: now,
|
|
403
|
+
expiresAt,
|
|
404
|
+
labels: opencodeLabels
|
|
405
|
+
}));
|
|
406
|
+
}
|
|
407
|
+
/** The local application that owns this browser session. */
|
|
408
|
+
export const OPENCODE_TOOL = "OpenCode";
|
|
409
|
+
/**
|
|
410
|
+
* The connection this reader reports, which is not the generic one.
|
|
411
|
+
*
|
|
412
|
+
* A page it cannot read has two very different causes, and they need two
|
|
413
|
+
* different sentences. A logged out workspace renders a sign in form, and the
|
|
414
|
+
* fix is one click in a window the person already has open. Anything else is a
|
|
415
|
+
* layout this build no longer understands, which is ours to fix, and the honest
|
|
416
|
+
* instruction is to reconnect and tell us if it keeps happening. Neither one
|
|
417
|
+
* throws, and neither one is silence.
|
|
418
|
+
*/
|
|
419
|
+
export function opencodeConnection(parsed, payload) {
|
|
420
|
+
/*
|
|
421
|
+
* The signed out marker is read BEFORE the parse result, and the order is the
|
|
422
|
+
* whole point. A page asking somebody to sign in is a page whose numbers are
|
|
423
|
+
* leftovers, and this reader can still find a percentage in leftovers, so
|
|
424
|
+
* asking "did it parse" first reports a live looking meter behind an account
|
|
425
|
+
* nobody is signed into. That is the exact claim this product exists to stop.
|
|
426
|
+
*/
|
|
427
|
+
if (typeof payload === "string" && SIGNED_OUT.test(payload)) {
|
|
428
|
+
return connectionStatus("AUTH_EXPIRED", "token_expired", OPENCODE_TOOL);
|
|
429
|
+
}
|
|
430
|
+
if (parsed)
|
|
431
|
+
return connectionStatus("CONNECTED", null, OPENCODE_TOOL);
|
|
432
|
+
/* Nothing arrived at all, which is a session that has not been opened yet
|
|
433
|
+
rather than a fault. Anything that DID arrive and could not be read is a
|
|
434
|
+
fault, whatever type it turned out to be. */
|
|
435
|
+
if (payload === undefined || payload === null) {
|
|
436
|
+
return connectionStatus("DETECTED", "tool_not_running", OPENCODE_TOOL);
|
|
437
|
+
}
|
|
438
|
+
return connectionStatus("ERROR", "shape_mismatch", OPENCODE_TOOL);
|
|
35
439
|
}
|
|
36
440
|
export const opencodeConnector = {
|
|
37
441
|
id: "opencode",
|
|
38
442
|
displayName: "OpenCode",
|
|
443
|
+
encoding: "text",
|
|
444
|
+
maturity: opencodeMaturity,
|
|
39
445
|
labels: opencodeLabels,
|
|
40
446
|
detect(environment) {
|
|
41
447
|
return environment["OPENCODE_SESSION_PRESENT"] === "1";
|
|
42
448
|
},
|
|
43
449
|
async read(context) {
|
|
44
450
|
const meters = parseOpencodePayload(context.payload, context.now);
|
|
451
|
+
const connection = opencodeConnection(meters !== null, context.payload);
|
|
45
452
|
return meters === null
|
|
46
|
-
? { ok: false, reason: "unknown" }
|
|
47
|
-
: { ok: true, meters };
|
|
453
|
+
? { ok: false, reason: "unknown", connection }
|
|
454
|
+
: { ok: true, meters, connection };
|
|
48
455
|
}
|
|
49
456
|
};
|
|
50
457
|
//# sourceMappingURL=opencode.js.map
|
package/dist/opencode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../src/opencode.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../src/opencode.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAUrD,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,QAAQ,EACR,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,gBAAgB,EAAE,iBAAiB;IACnC,mBAAmB,EAAE,sBAAsB;IAC3C,cAAc,EAAE,MAAM;IACtB,YAAY,EAAE,YAAY;CACQ,CAAC;AAErC,MAAM,CAAC,MAAM,eAAe,GAAG,2CAAoD,CAAC;AAEpF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAA2C,CAAC;AAE5E,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,4BAA4B;IAClC,YAAY,EAAE,wBAAwB;IACtC,QAAQ,EAAE,WAAW;IACrB,OAAO,EAAE,eAAe;IACxB,QAAQ,EAAE,gBAAgB;CAClB,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAe,CAAC;AAEhD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAK,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO;IAC1D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK;CAClD,CAAC,CAAC;AAWH,qEAAqE;AACrE,SAAS,MAAM,CAAC,IAAY,EAAE,IAAY,EAAE,EAAU;IACpD,MAAM,IAAI,GAAU,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,+DAA+D,CAAC;IAChF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,kEAAkE;QAClE,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,SAAS;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;YAC7B,GAAG,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;YAChD,IAAI;YACJ,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;YACzB,WAAW,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;SAC3E,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,SAAS,CAAC;AAIjD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAKvB;IACJ;QACE,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,MAAM;QACf,OAAO,EAAE,uDAAuD;KACjE;IACD;QACE,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,kDAAkD;KAC5D;IACD;QACE,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,sDAAsD;KAChE;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,mEAAmE,CAAC;AAEvF;;;;;;;;GAQG;AACH,MAAM,MAAM,GAAG,2BAA2B,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,OAAO,GAAG,8BAA8B,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,SAAS,GACb,+GAA+G,CAAC;AAElH,SAAS,OAAO,CAAC,QAAgB;IAC/B,OAAO,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/E,CAAC;AAED,+DAA+D;AAC/D,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B;;;;;;;GAOG;AACH,SAAS,gBAAgB,CACvB,IAAY,EACZ,EAAU;IAEV,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,0BAA0B,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAC5C;kEAC8D;IAC9D,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,SAAS,GAAe,IAAI,CAAC;IACjC,KAAK,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,WAAW;YAAE,SAAS;QAC9B,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,aAAa,IAAI,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QACD,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACtB,aAAa,IAAI,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QACD,SAAS,GAAG,GAAG,CAAC;QAChB,MAAM;IACR,CAAC;IACD,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpC;wEACoE;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,GAAG,0BAA0B,CAAC,CAAC;IACnF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC;QACxD,IAAI,GAAG,CAAC,WAAW;YAAE,SAAS;QAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;gBAChC,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE;gBAC7D;oEACoD;gBACpD,CAAC,CAAC,IAAI,CAAC;QACX,CAAC;QACD,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,YAAY,CACnB,IAAY,EACZ,OAAe,EACf,WAA8B;IAE9B,IAAI,QAAQ,GAAG,OAAO,CAAC;IACvB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,mBAAmB,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACjD,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1E,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;QAC1C,yDAAyD;QACzD,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AASD;;;;;;;GAOG;AACH,SAAS,SAAS,CAAC,IAAY,EAAE,EAAU;IACzC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,2EAA2E;AAC3E,SAAS,OAAO,CAAC,OAAe,EAAE,IAAY;IAC5C,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;IACtB,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AASD;;;;;;;;;GASG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QAC7B,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;YAC7B,IAAI,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;gBAAE,SAAS;YAC5C,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnB;sCAC0B;YAC1B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM;QAClC,CAAC;QACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACrC,IAAI,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,gBAAgB;iBACrB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC;iBAC/C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,YAAY,CAAC,IAAY,EAAE,GAAW;IAC7C,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,OAAO,KAAK,IAAI;YAAE,SAAS;QAC/B,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,YAAY,KAAK,IAAI;YAAE,SAAS;QACpC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,GAAG;YAAE,SAAS;QACxE;;gFAEwE;QACxE,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,OAAO,GACX,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,OAAO;YACP,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC;SAC9D,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;AAC/C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAgB,EAAE,GAAW;IAChE,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,uBAAuB;QAAE,OAAO,IAAI,CAAC;IAClF;;;;;;;OAOG;IACH,IAAI,OAAO,GAA0B,IAAI,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAC5B,QAAQ,CAAC;QACP,QAAQ,EAAE,UAAU;QACpB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,OAAO;QACrB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,CAAC,OAAO,EAAE;QAC5D,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,oBAAoB;QAC5B,SAAS,EAAE,WAAW;QACtB,UAAU,EAAE,GAAG;QACf,SAAS;QACT,MAAM,EAAE,cAAc;KACvB,CAAC,CACH,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,MAAM,CAAC,MAAM,aAAa,GAAmB,UAAU,CAAC;AAExD;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAe,EAAE,OAAgB;IAClE;;;;;;OAMG;IACH,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,OAAO,gBAAgB,CAAC,cAAc,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,MAAM;QAAE,OAAO,gBAAgB,CAAC,WAAW,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;IACtE;;mDAE+C;IAC/C,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,EAAE,aAAa,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,EAAE,EAAE,UAAU;IACd,WAAW,EAAE,UAAU;IACvB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,gBAAgB;IAC1B,MAAM,EAAE,cAAc;IACtB,MAAM,CAAC,WAAW;QAChB,OAAO,WAAW,CAAC,0BAA0B,CAAC,KAAK,GAAG,CAAC;IACzD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,OAAO;QAChB,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAClE,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,KAAK,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACxE,OAAO,MAAM,KAAK,IAAI;YACpB,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE;YAC9C,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACvC,CAAC;CACF,CAAC"}
|
package/dist/openrouter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConnectorContract, RawMeter } from "@openlimiter/core";
|
|
1
|
+
import type { ConnectionTool, ConnectorContract, RawMeter } from "@openlimiter/core";
|
|
2
2
|
export declare const openrouterLabels: {
|
|
3
3
|
readonly credentialOrigin: "user-key";
|
|
4
4
|
readonly dataInterfaceStatus: "documented-api";
|
|
@@ -13,5 +13,7 @@ export declare const openrouterCredential: {
|
|
|
13
13
|
readonly readMode: "read_only";
|
|
14
14
|
};
|
|
15
15
|
export declare function parseOpenrouterPayload(payload: unknown, now: string): RawMeter[] | null;
|
|
16
|
+
/** No local application owns this key, so no instruction names one. */
|
|
17
|
+
export declare const OPENROUTER_TOOL: ConnectionTool;
|
|
16
18
|
export declare const openrouterConnector: ConnectorContract;
|
|
17
19
|
//# sourceMappingURL=openrouter.d.ts.map
|
package/dist/openrouter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../src/openrouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAGjB,QAAQ,EACT,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../src/openrouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAGjB,QAAQ,EACT,MAAM,mBAAmB,CAAC;AAS3B,eAAO,MAAM,gBAAgB;;;;;CAKO,CAAC;AAErC,eAAO,MAAM,oBAAoB;;;;;;CAMvB,CAAC;AAEX,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,IAAI,CAmCvF;AAED,uEAAuE;AACvE,eAAO,MAAM,eAAe,EAAE,cAAqB,CAAC;AAEpD,eAAO,MAAM,mBAAmB,EAAE,iBAmBjC,CAAC"}
|