agent-runway 0.2.0 → 0.2.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +19 -5
- package/package.json +1 -1
- package/src/core.mjs +1 -1
- package/src/providers/index.mjs +5 -1
- package/src/providers/shared.mjs +13 -2
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"displayName": "Agent Runway",
|
|
12
12
|
"source": "./",
|
|
13
13
|
"description": "Quota and model discovery for the coding agents installed on this machine: how much runway each has left, and which model slugs each binary will actually accept.",
|
|
14
|
-
"version": "0.2.
|
|
14
|
+
"version": "0.2.1",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "jberdah",
|
|
17
17
|
"url": "https://github.com/jberdah"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-runway",
|
|
3
3
|
"displayName": "Agent Runway",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"description": "Quota and model discovery for the coding agents installed on this machine: how much runway each has left, and which model slugs each binary will actually accept.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "jberdah",
|
package/README.md
CHANGED
|
@@ -70,10 +70,17 @@ unless you pass `--force`.
|
|
|
70
70
|
### As a Claude Code plugin (skill + MCP tool)
|
|
71
71
|
|
|
72
72
|
```
|
|
73
|
-
/plugin marketplace add jberdah/agent-runway
|
|
73
|
+
/plugin marketplace add https://github.com/jberdah/agent-runway.git
|
|
74
74
|
/plugin install agent-runway@agent-runway
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
+
The full HTTPS URL rather than the `owner/repo` shorthand: the shorthand
|
|
78
|
+
resolves to SSH, which fails on any machine that has not accepted GitHub's host
|
|
79
|
+
key. If the clone then fails with *"self signed certificate in certificate
|
|
80
|
+
chain"*, a proxy is inspecting TLS; on Windows, `git config --global
|
|
81
|
+
http.sslBackend schannel` makes git trust the certificate store the rest of the
|
|
82
|
+
system already uses.
|
|
83
|
+
|
|
77
84
|
Claude then reads your usage whenever it is relevant — ask "how much quota do I
|
|
78
85
|
have left?" or let it check before a long task.
|
|
79
86
|
|
|
@@ -356,10 +363,17 @@ npm run smoke # drives the MCP server over stdio; needs network and a token
|
|
|
356
363
|
```
|
|
357
364
|
|
|
358
365
|
The runtime has **zero dependencies**. `src/mcp.mjs` speaks JSON-RPC directly
|
|
359
|
-
rather than importing the MCP SDK,
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
366
|
+
rather than importing the MCP SDK, and `scripts/smoke-mcp.mjs` connects the
|
|
367
|
+
official SDK client to it so the hand-rolled framing is checked against the real
|
|
368
|
+
implementation.
|
|
369
|
+
|
|
370
|
+
That choice was originally justified by a belief that a Claude Code plugin
|
|
371
|
+
installed from git is never `npm install`ed. **That is wrong**: installing this
|
|
372
|
+
plugin produced 91 packages in the plugin cache, devDependencies included. The
|
|
373
|
+
constraint is kept anyway, for reasons that survive the correction — nobody
|
|
374
|
+
installing a CLI that makes one HTTP request should wait on 91 packages, the
|
|
375
|
+
supply-chain surface stays at zero, and it keeps working where `npm install`
|
|
376
|
+
does not, which on a corporate network is not hypothetical.
|
|
363
377
|
|
|
364
378
|
```
|
|
365
379
|
src/core.mjs token resolution, HTTP, response normalization
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-runway",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Quota and model discovery for the coding agents installed on this machine: how much runway each has left, and which model slugs each binary will actually accept.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/core.mjs
CHANGED
package/src/providers/index.mjs
CHANGED
|
@@ -106,7 +106,7 @@ export function capacity(results, { threshold = 90 } = {}) {
|
|
|
106
106
|
if (r.allowed === false) {
|
|
107
107
|
return {
|
|
108
108
|
provider: r.provider, label: r.label, decision: "defer", reason: "provider_says_limit_reached",
|
|
109
|
-
binding, retryAt: binding.resetsAt, retryAtBasis: "reported_reset",
|
|
109
|
+
binding, windows: r.windows, retryAt: binding.resetsAt, retryAtBasis: "reported_reset",
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -117,6 +117,10 @@ export function capacity(results, { threshold = 90 } = {}) {
|
|
|
117
117
|
decision: over ? "defer" : "proceed",
|
|
118
118
|
reason: over ? "threshold_exceeded" : "within_threshold",
|
|
119
119
|
binding,
|
|
120
|
+
// The binding window decides, but hiding the rest loses information the
|
|
121
|
+
// read already paid for: a session at 0% next to a weekly at 89% is a
|
|
122
|
+
// different situation from a session at 0% alone.
|
|
123
|
+
windows: r.windows,
|
|
120
124
|
retryAt: over ? binding.resetsAt : null,
|
|
121
125
|
// The reset is when the window rolls over, not a promise that service
|
|
122
126
|
// resumes exactly then. Naming the basis keeps the two apart.
|
package/src/providers/shared.mjs
CHANGED
|
@@ -56,9 +56,20 @@ export function makeWindow({
|
|
|
56
56
|
model = null,
|
|
57
57
|
unit = "requests",
|
|
58
58
|
}) {
|
|
59
|
-
|
|
59
|
+
// A start can only be derived from a window that is actually running. When a
|
|
60
|
+
// provider has nothing to report it answers with the whole window ahead —
|
|
61
|
+
// Codex returns reset_at = now + 18000s at 0% consumption — and subtracting
|
|
62
|
+
// the duration then yields "now", which reads as a window that just began
|
|
63
|
+
// when none has. A start that lands on or after the present moment is not a
|
|
64
|
+
// measurement, so it is withheld rather than invented.
|
|
65
|
+
const derivedStart =
|
|
60
66
|
resetsAt && Number.isFinite(windowSeconds)
|
|
61
|
-
?
|
|
67
|
+
? Date.parse(resetsAt) - windowSeconds * 1000
|
|
68
|
+
: null;
|
|
69
|
+
const UNKNOWABLE_MS = 60_000;
|
|
70
|
+
const startsAt =
|
|
71
|
+
derivedStart != null && derivedStart < Date.now() - UNKNOWABLE_MS
|
|
72
|
+
? new Date(derivedStart).toISOString()
|
|
62
73
|
: null;
|
|
63
74
|
|
|
64
75
|
return {
|