pi-clinepass 0.1.5 → 0.1.7
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/CHANGELOG.md +11 -2
- package/README.md +1 -1
- package/package.json +54 -54
- package/src/catalog.ts +9 -13
- package/src/errors.ts +69 -8
- package/src/headers.ts +10 -7
- package/src/index.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## 0.1.
|
|
5
|
+
## 0.1.7 - 2026-10-01
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- Retired model removed: `cline-free/gemini-3.8-flash` (dropped from the gateway's free tier)
|
|
8
|
+
- Free-route client headers track the latest CLI release
|
|
9
|
+
|
|
10
|
+
## 0.1.6 - 2026-09-25
|
|
11
|
+
|
|
12
|
+
- New free models: `cline-free/gemini-3.8-flash` (mandatory low/medium/high reasoning), `stealth/space-bunny-alpha`, `cline-free/mimo-v2.6-flash`, and `cline-free/deepseek-v4.1-flash`
|
|
13
|
+
- New paid model: `cline-pass/muse-spark-1.3-contributor` ($0.10/$0.20/$0.01)
|
|
14
|
+
- Retired models removed from catalog
|
|
15
|
+
- Error classification refined: upstream provider errors, 402 (insufficient credits), 404 (model not found), and 5xx gateway errors no longer misclassified as expired auth
|
|
16
|
+
- Free-route client headers updated to latest CLI convention
|
|
8
17
|
|
|
9
18
|
## 0.1.4 - 2026-09-09
|
|
10
19
|
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Dollar-based limits, live cost tracking, and plan cap reporting.
|
|
|
25
25
|
|
|
26
26
|
## Highlights
|
|
27
27
|
|
|
28
|
-
- **
|
|
28
|
+
- **16 Models**: 12 ClinePass models on a dollar-based limit system plus 4 free tier models
|
|
29
29
|
- **Live Status Meter**: Per-turn and session cost directly in the pi footer
|
|
30
30
|
- **Plan Utilization**: 5-hour, weekly, and monthly caps tracked via `/clinepass`
|
|
31
31
|
- **Price Calibration**: measure real gateway billing from `/clinepass` to keep displayed prices honest
|
package/package.json
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "pi-clinepass",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "ClinePass for pi — static measured-price catalog, server-truth billing meter, free models",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"ai",
|
|
7
|
-
"cline",
|
|
8
|
-
"cline-pass",
|
|
9
|
-
"clinepass",
|
|
10
|
-
"pi",
|
|
11
|
-
"pi-coding-agent",
|
|
12
|
-
"pi-package",
|
|
13
|
-
"pi-extension"
|
|
14
|
-
],
|
|
15
|
-
"license": "MIT",
|
|
16
|
-
"author": "fifidayone",
|
|
17
|
-
"repository": {
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/fifidayone/pi-clinepass.git"
|
|
20
|
-
},
|
|
21
|
-
"type": "module",
|
|
22
|
-
"main": "src/index.ts",
|
|
23
|
-
"types": "src/index.ts",
|
|
24
|
-
"files": [
|
|
25
|
-
"src",
|
|
26
|
-
"CHANGELOG.md",
|
|
27
|
-
"README.md",
|
|
28
|
-
"LICENSE"
|
|
29
|
-
],
|
|
30
|
-
"engines": {
|
|
31
|
-
"node": ">=22"
|
|
32
|
-
},
|
|
33
|
-
"scripts": {
|
|
34
|
-
"test": "vitest run",
|
|
35
|
-
"test:watch": "vitest",
|
|
36
|
-
"typecheck": "tsc --noEmit"
|
|
37
|
-
},
|
|
38
|
-
"peerDependencies": {
|
|
39
|
-
"@earendil-works/pi-ai": "*",
|
|
40
|
-
"@earendil-works/pi-coding-agent": "*",
|
|
41
|
-
"@earendil-works/pi-tui": "*"
|
|
42
|
-
},
|
|
43
|
-
"devDependencies": {
|
|
44
|
-
"@types/node": "^26.3.0",
|
|
45
|
-
"typescript": "^7.0.2",
|
|
46
|
-
"vitest": "^4.1.11"
|
|
47
|
-
},
|
|
48
|
-
"pi": {
|
|
49
|
-
"extensions": [
|
|
50
|
-
"./src/index.ts"
|
|
51
|
-
],
|
|
52
|
-
"image": "https://raw.githubusercontent.com/fifidayone/pi-clinepass/main/assets/report.png"
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-clinepass",
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "ClinePass for pi — static measured-price catalog, server-truth billing meter, free models",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"cline",
|
|
8
|
+
"cline-pass",
|
|
9
|
+
"clinepass",
|
|
10
|
+
"pi",
|
|
11
|
+
"pi-coding-agent",
|
|
12
|
+
"pi-package",
|
|
13
|
+
"pi-extension"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "fifidayone",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/fifidayone/pi-clinepass.git"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "src/index.ts",
|
|
23
|
+
"types": "src/index.ts",
|
|
24
|
+
"files": [
|
|
25
|
+
"src",
|
|
26
|
+
"CHANGELOG.md",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=22"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"test:watch": "vitest",
|
|
36
|
+
"typecheck": "tsc --noEmit"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@earendil-works/pi-ai": "*",
|
|
40
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
41
|
+
"@earendil-works/pi-tui": "*"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^26.3.0",
|
|
45
|
+
"typescript": "^7.0.2",
|
|
46
|
+
"vitest": "^4.1.11"
|
|
47
|
+
},
|
|
48
|
+
"pi": {
|
|
49
|
+
"extensions": [
|
|
50
|
+
"./src/index.ts"
|
|
51
|
+
],
|
|
52
|
+
"image": "https://raw.githubusercontent.com/fifidayone/pi-clinepass/main/assets/report.png"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/catalog.ts
CHANGED
|
@@ -164,28 +164,23 @@ function model(
|
|
|
164
164
|
/** Measured prices ($/1M tokens: input/output/cacheRead) — latest verified. */
|
|
165
165
|
export const MODELS: readonly ClinePassModel[] = [
|
|
166
166
|
// ── Free models (Cline free tier, cost 0) ──────────────────────────────
|
|
167
|
-
model("
|
|
168
|
-
model("
|
|
169
|
-
model("
|
|
170
|
-
model("poolside/laguna-s-2.1:free", "Laguna S-2.1", [0, 0, 0], 262_144, 131_072, ["text"], ALL_THINKING),
|
|
171
|
-
model("cline-free/solar-pro4", "Solar Pro 4", [0, 0, 0], 524_288, 131_072, ["text"], OFF_MEDIUM_HIGH),
|
|
167
|
+
model("stealth/space-bunny-alpha", "Space Bunny Alpha", [0, 0, 0], 921_600, 131_072, ["text", "image"], ALL_THINKING),
|
|
168
|
+
model("cline-free/mimo-v2.6-flash", "MiMo-V2.6-Flash", [0, 0, 0], 921_600, 131_072, ["text", "image"], ALL_THINKING),
|
|
169
|
+
model("cline-free/deepseek-v4.1-flash", "DeepSeek V4.1 Flash", [0, 0, 0], 921_600, 131_072, ["text", "image"], MAX_HIGH_LOW),
|
|
172
170
|
model("cline-free/muse-spark-1.3-contributor", "Muse Spark 1.3 Contributor", [0, 0, 0], 921_600, 131_072, ["text", "image"], MANDATORY_NO_MAX),
|
|
173
171
|
// ── ClinePass models (measured billing prices) ─────────────────────────
|
|
174
|
-
model("cline-pass/glm-5.3-flash", "GLM-5.3 Flash", [0.15, 0.5, 0.03], 921_600, 131_072, ["text", "image"], MAX_HIGH_LOW_MANDATORY),
|
|
175
172
|
model("cline-pass/glm-5.3", "GLM-5.3", [1.4, 4.4, 0.26], 921_600, 131_072, ["text"], MAX_HIGH_LOW_MANDATORY),
|
|
176
|
-
model("cline-pass/glm-5.
|
|
177
|
-
model("cline-pass/kimi-k2.7-code", "Kimi K2.7 Code", [1.58, 6.67, 0.32], 262_144, 131_072, ["text", "image"], ALL_MANDATORY),
|
|
178
|
-
model("cline-pass/kimi-k2.6", "Kimi K2.6", [1.58, 6.67, 0.27], 262_144, 131_072, ["text", "image"], ALL_THINKING),
|
|
173
|
+
model("cline-pass/glm-5.3-flash", "GLM-5.3 Flash", [0.15, 0.5, 0.03], 921_600, 131_072, ["text", "image"], MAX_HIGH_LOW_MANDATORY),
|
|
179
174
|
model("cline-pass/kimi-k3", "Kimi K3", [6.0, 30.0, 0.6], 921_600, 131_072, ["text", "image"], MAX_HIGH_LOW),
|
|
180
175
|
model("cline-pass/deepseek-v4-pro", "DeepSeek V4 Pro", [1.65, 4.95, 0.06], 921_600, 131_072, ["text"], MAX_HIGH_LOW),
|
|
181
176
|
model("cline-pass/deepseek-v4.1-flash", "DeepSeek V4.1 Flash", [0.3, 1.2, 0.006], 921_600, 131_072, ["text", "image"], MAX_HIGH_LOW),
|
|
182
|
-
model("cline-pass/deepseek-v4-flash", "DeepSeek V4 Flash", [0.44, 1.32, 0.014], 921_600, 131_072, ["text"], MAX_HIGH_LOW),
|
|
183
177
|
model("cline-pass/mimo-v2.5", "MiMo-V2.5", [0.14, 0.28, 0.0028], 921_600, 131_072, ["text", "image"], ALL_THINKING),
|
|
184
178
|
model("cline-pass/mimo-v2.5-pro", "MiMo-V2.5-Pro", [0.435, 0.87, 0.0036], 921_600, 131_072, ["text"], ALL_THINKING),
|
|
185
179
|
model("cline-pass/minimax-m3", "MiniMax M3", [0.5, 2.0, 0.1], 921_600, 131_072, ["text", "image"], ALL_THINKING),
|
|
186
|
-
model("cline-pass/
|
|
187
|
-
model("cline-pass/qwen3.7-max", "Qwen3.7 Max", [4.17, 12.5, 0.83], 921_600, 131_072, ["text"], ALL_THINKING),
|
|
180
|
+
model("cline-pass/muse-spark-1.3-contributor", "Muse Spark 1.3 Contributor", [0.10, 0.20, 0.01], 921_600, 131_072, ["text", "image"], MANDATORY_NO_MAX),
|
|
188
181
|
model("cline-pass/qwen3.8-max", "Qwen3.8 Max", [2.75, 8.25, 0.34], 921_600, 131_072, ["text", "image"], XHIGH_MEDIUM_LOW),
|
|
182
|
+
model("cline-pass/qwen3.7-max", "Qwen3.7 Max", [4.17, 12.5, 0.83], 921_600, 131_072, ["text"], ALL_THINKING),
|
|
183
|
+
model("cline-pass/qwen3.7-plus", "Qwen3.7 Plus", [0.67, 2.67, 0.07], 921_600, 131_072, ["text", "image"], ALL_THINKING),
|
|
189
184
|
];
|
|
190
185
|
|
|
191
186
|
export function modelIds(): string[] {
|
|
@@ -195,5 +190,6 @@ export function modelIds(): string[] {
|
|
|
195
190
|
/** True for the Cline free-tier models — derived from the catalog itself
|
|
196
191
|
* (cost 0), so adding a free model never needs a second edit here. */
|
|
197
192
|
export function isFreeModel(id: string): boolean {
|
|
198
|
-
|
|
193
|
+
const normalized = id.startsWith("clinepass/") ? id.slice(10) : id;
|
|
194
|
+
return MODELS.some((m) => m.id === normalized && m.cost.input === 0);
|
|
199
195
|
}
|
package/src/errors.ts
CHANGED
|
@@ -16,6 +16,10 @@ export type ClinePassErrorType =
|
|
|
16
16
|
| "rate_limited"
|
|
17
17
|
| "free_limit_reached"
|
|
18
18
|
| "free_route_forbidden"
|
|
19
|
+
| "insufficient_credits"
|
|
20
|
+
| "model_not_found"
|
|
21
|
+
| "upstream_error"
|
|
22
|
+
| "server_error"
|
|
19
23
|
| "unknown";
|
|
20
24
|
|
|
21
25
|
function matchesAny(text: string, patterns: string[]): boolean {
|
|
@@ -35,7 +39,15 @@ export const CLINEPASS_ERROR_MESSAGES: Record<ClinePassErrorType, string> = {
|
|
|
35
39
|
free_route_forbidden:
|
|
36
40
|
"Free model route unavailable (HTTP 403). The free route is gated to Cline product " +
|
|
37
41
|
"surfaces — retry in a moment, or switch to a ClinePass model.",
|
|
38
|
-
|
|
42
|
+
insufficient_credits:
|
|
43
|
+
"Insufficient Cline credits. Top up your balance at app.cline.bot/credits or switch to a free/subscription model.",
|
|
44
|
+
model_not_found:
|
|
45
|
+
"Model not found on Cline gateway (HTTP 404). Run `/model` to select an available model.",
|
|
46
|
+
upstream_error:
|
|
47
|
+
"Upstream model provider error. The model host returned an error — retry in a moment, or switch to another model.",
|
|
48
|
+
server_error:
|
|
49
|
+
"Cline gateway server error. The service is temporarily unavailable — please retry in a moment.",
|
|
50
|
+
unknown: "ClinePass request failed. Please check app.cline.bot or try again later.",
|
|
39
51
|
};
|
|
40
52
|
|
|
41
53
|
/**
|
|
@@ -52,23 +64,50 @@ export function classifyClinePassError(
|
|
|
52
64
|
} {
|
|
53
65
|
const lower = errorMessage.toLowerCase();
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
|
|
67
|
+
// 1. Upstream Provider / Inference host errors:
|
|
68
|
+
// Must precede auth checks because upstream errors (e.g. OpenRouter/Meta/DeepSeek)
|
|
69
|
+
// often forward payloads containing "401" or "invalid_api_key" from the host,
|
|
70
|
+
// which does not mean the user's ClinePass authentication has expired.
|
|
71
|
+
if (
|
|
72
|
+
matchesAny(lower, [
|
|
73
|
+
"provider returned error",
|
|
74
|
+
"failed to generate stream from openrouter",
|
|
75
|
+
"openrouter",
|
|
76
|
+
"inference request failed",
|
|
77
|
+
"failed to invoke model",
|
|
78
|
+
"provider_error_code",
|
|
79
|
+
])
|
|
80
|
+
) {
|
|
81
|
+
return { type: "upstream_error", message: CLINEPASS_ERROR_MESSAGES.upstream_error };
|
|
57
82
|
}
|
|
58
|
-
|
|
59
|
-
|
|
83
|
+
|
|
84
|
+
// 2. Insufficient Credits (HTTP 402)
|
|
85
|
+
if (matchesAny(lower, ["insufficient_credits", "insufficient balance", "buy_credits_url", "402"])) {
|
|
86
|
+
return { type: "insufficient_credits", message: CLINEPASS_ERROR_MESSAGES.insufficient_credits };
|
|
60
87
|
}
|
|
88
|
+
|
|
89
|
+
// 3. Model Not Found (HTTP 404)
|
|
90
|
+
if (matchesAny(lower, ["model not found", "model_not_found"]) || /\b404\b/.test(lower)) {
|
|
91
|
+
return { type: "model_not_found", message: CLINEPASS_ERROR_MESSAGES.model_not_found };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 4. Rate Limits & Free limits
|
|
61
95
|
if (matchesAny(lower, ["free limit reached", "free limit", "try again in"])) {
|
|
62
96
|
return { type: "free_limit_reached", message: CLINEPASS_ERROR_MESSAGES.free_limit_reached };
|
|
63
97
|
}
|
|
98
|
+
if (matchesAny(lower, ["rate limit", "too many requests", "rate_limit"]) || /\b429\b/.test(lower)) {
|
|
99
|
+
return { type: "rate_limited", message: CLINEPASS_ERROR_MESSAGES.rate_limited };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 5. Subscription & Route Access (HTTP 403)
|
|
64
103
|
if (
|
|
65
104
|
matchesAny(lower, [
|
|
66
|
-
"403",
|
|
67
|
-
"forbidden",
|
|
68
105
|
"subscription required",
|
|
69
106
|
"not subscribed",
|
|
70
107
|
"organization accounts cannot use",
|
|
71
|
-
|
|
108
|
+
"forbidden",
|
|
109
|
+
]) ||
|
|
110
|
+
/\b403\b/.test(lower)
|
|
72
111
|
) {
|
|
73
112
|
// Every free-tier route is gated to Cline product surfaces — a 403 on a
|
|
74
113
|
// free model is a route-gate rejection, not a subscription problem.
|
|
@@ -77,6 +116,28 @@ export function classifyClinePassError(
|
|
|
77
116
|
}
|
|
78
117
|
return { type: "not_subscribed", message: CLINEPASS_ERROR_MESSAGES.not_subscribed };
|
|
79
118
|
}
|
|
119
|
+
|
|
120
|
+
// 6. Gateway / Server 5xx Errors
|
|
121
|
+
if (
|
|
122
|
+
matchesAny(lower, [
|
|
123
|
+
"bad gateway",
|
|
124
|
+
"service unavailable",
|
|
125
|
+
"gateway timeout",
|
|
126
|
+
"internal server error",
|
|
127
|
+
]) ||
|
|
128
|
+
/\b(500|502|503|504)\b/.test(lower)
|
|
129
|
+
) {
|
|
130
|
+
return { type: "server_error", message: CLINEPASS_ERROR_MESSAGES.server_error };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 7. Client Authentication (genuine 401 / unauthorized from Cline gateway)
|
|
134
|
+
if (
|
|
135
|
+
matchesAny(lower, ["unauthorized", "invalid api key", "invalid_api_key"]) ||
|
|
136
|
+
/\b401\b/.test(lower)
|
|
137
|
+
) {
|
|
138
|
+
return { type: "auth_expired", message: CLINEPASS_ERROR_MESSAGES.auth_expired };
|
|
139
|
+
}
|
|
140
|
+
|
|
80
141
|
return { type: "unknown", message: CLINEPASS_ERROR_MESSAGES.unknown };
|
|
81
142
|
}
|
|
82
143
|
|
package/src/headers.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { release } from "node:os";
|
|
12
12
|
import { isFreeModel } from "./catalog.js";
|
|
13
13
|
|
|
14
|
-
const FALLBACK_CLINE_VERSION = "3.0.
|
|
14
|
+
const FALLBACK_CLINE_VERSION = "3.0.67";
|
|
15
15
|
const VERSION_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
16
16
|
const NPM_REGISTRY_URL = "https://registry.npmjs.org/cline/latest";
|
|
17
17
|
|
|
@@ -73,11 +73,14 @@ export function needsFreeModelHeaders(modelId: string): boolean {
|
|
|
73
73
|
export function buildFreeModelHeadersSync(): Record<string, string> {
|
|
74
74
|
const version = cachedVersion ?? FALLBACK_CLINE_VERSION;
|
|
75
75
|
return {
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
76
|
+
"HTTP-Referer": "https://cline.bot",
|
|
77
|
+
"X-Title": "Cline",
|
|
78
|
+
"X-IS-MULTIROOT": "false",
|
|
79
|
+
"X-CLIENT-TYPE": "cline-cli",
|
|
80
|
+
"X-CLIENT-VERSION": version,
|
|
81
|
+
"X-CORE-VERSION": version,
|
|
82
|
+
"X-PLATFORM": process.platform,
|
|
83
|
+
"X-PLATFORM-VERSION": release(),
|
|
84
|
+
"User-Agent": `Cline/${version}`,
|
|
82
85
|
};
|
|
83
86
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* pi-clinepass — ClinePass for pi.
|
|
3
3
|
*
|
|
4
|
-
* Registers the `clinepass` provider (
|
|
4
|
+
* Registers the `clinepass` provider (12 paid models with measured billing
|
|
5
5
|
* prices + 4 free models) and wires the hooks that keep pi's numbers real:
|
|
6
6
|
* - message_end → server-truth cost meter + session total + error surface + thinking repair
|
|
7
7
|
* - before_provider_headers → free-route Cline-CLI headers
|