pi-clinepass 0.1.5 → 0.1.6

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 CHANGED
@@ -2,9 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## 0.1.5 - 2026-09-12
5
+ ## 0.1.6 - 2026-09-25
6
6
 
7
- - New paid model: `cline-pass/deepseek-v4.1-flash` (measured rates pending calibration)
7
+ - 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`
8
+ - New paid model: `cline-pass/muse-spark-1.3-contributor` ($0.10/$0.20/$0.01)
9
+ - Retired models removed from catalog
10
+ - Error classification refined: upstream provider errors, 402 (insufficient credits), 404 (model not found), and 5xx gateway errors no longer misclassified as expired auth
11
+ - Free-route client headers updated to latest CLI convention
8
12
 
9
13
  ## 0.1.4 - 2026-09-09
10
14
 
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
- - **22 Models**: 16 ClinePass models on a dollar-based limit system plus 6 free tier models
28
+ - **17 Models**: 12 ClinePass models on a dollar-based limit system plus 5 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.5",
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.6",
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
@@ -102,6 +102,17 @@ const XHIGH_MEDIUM_LOW: ThinkingLevelMap = {
102
102
  max: null,
103
103
  };
104
104
 
105
+ /** Only low/medium/high, mandatory (no off). Used for gemini-3.8-flash. */
106
+ const LOW_MEDIUM_HIGH_MANDATORY: ThinkingLevelMap = {
107
+ off: null,
108
+ minimal: null,
109
+ low: "low",
110
+ medium: "medium",
111
+ high: "high",
112
+ xhigh: null,
113
+ max: null,
114
+ };
115
+
105
116
  /** Only off/medium/high. Used for solar-pro4. */
106
117
  const OFF_MEDIUM_HIGH: ThinkingLevelMap = {
107
118
  off: "none",
@@ -164,28 +175,24 @@ function model(
164
175
  /** Measured prices ($/1M tokens: input/output/cacheRead) — latest verified. */
165
176
  export const MODELS: readonly ClinePassModel[] = [
166
177
  // ── Free models (Cline free tier, cost 0) ──────────────────────────────
167
- model("cline-free/longcat-2.0", "LongCat 2.0", [0, 0, 0], 921_600, 131_072, ["text"], ALL_THINKING),
168
- model("z-ai/glm-5.3-flash", "GLM-5.3 Flash", [0, 0, 0], 921_600, 131_072, ["text", "image"], MAX_HIGH_LOW_MANDATORY),
169
- model("deepseek/deepseek-v4-flash", "DeepSeek V4 Flash", [0, 0, 0], 921_600, 131_072, ["text"], MAX_HIGH_LOW),
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),
178
+ model("cline-free/gemini-3.8-flash", "Gemini 3.8 Flash", [0, 0, 0], 921_600, 65_536, ["text", "image"], LOW_MEDIUM_HIGH_MANDATORY),
179
+ model("stealth/space-bunny-alpha", "Space Bunny Alpha", [0, 0, 0], 921_600, 131_072, ["text", "image"], ALL_THINKING),
180
+ model("cline-free/mimo-v2.6-flash", "MiMo-V2.6-Flash", [0, 0, 0], 921_600, 131_072, ["text", "image"], ALL_THINKING),
181
+ model("cline-free/deepseek-v4.1-flash", "DeepSeek V4.1 Flash", [0, 0, 0], 921_600, 131_072, ["text", "image"], MAX_HIGH_LOW),
172
182
  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
183
  // ── 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
184
  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.2", "GLM-5.2", [1.4, 4.4, 0.26], 921_600, 131_072, ["text"], XHIGH_HIGH),
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),
185
+ 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
186
  model("cline-pass/kimi-k3", "Kimi K3", [6.0, 30.0, 0.6], 921_600, 131_072, ["text", "image"], MAX_HIGH_LOW),
180
187
  model("cline-pass/deepseek-v4-pro", "DeepSeek V4 Pro", [1.65, 4.95, 0.06], 921_600, 131_072, ["text"], MAX_HIGH_LOW),
181
188
  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
189
  model("cline-pass/mimo-v2.5", "MiMo-V2.5", [0.14, 0.28, 0.0028], 921_600, 131_072, ["text", "image"], ALL_THINKING),
184
190
  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
191
  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/qwen3.7-plus", "Qwen3.7 Plus", [0.67, 2.67, 0.07], 921_600, 131_072, ["text", "image"], ALL_THINKING),
187
- model("cline-pass/qwen3.7-max", "Qwen3.7 Max", [4.17, 12.5, 0.83], 921_600, 131_072, ["text"], ALL_THINKING),
192
+ 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
193
  model("cline-pass/qwen3.8-max", "Qwen3.8 Max", [2.75, 8.25, 0.34], 921_600, 131_072, ["text", "image"], XHIGH_MEDIUM_LOW),
194
+ model("cline-pass/qwen3.7-max", "Qwen3.7 Max", [4.17, 12.5, 0.83], 921_600, 131_072, ["text"], ALL_THINKING),
195
+ model("cline-pass/qwen3.7-plus", "Qwen3.7 Plus", [0.67, 2.67, 0.07], 921_600, 131_072, ["text", "image"], ALL_THINKING),
189
196
  ];
190
197
 
191
198
  export function modelIds(): string[] {
@@ -195,5 +202,6 @@ export function modelIds(): string[] {
195
202
  /** True for the Cline free-tier models — derived from the catalog itself
196
203
  * (cost 0), so adding a free model never needs a second edit here. */
197
204
  export function isFreeModel(id: string): boolean {
198
- return MODELS.some((m) => m.id === id && m.cost.input === 0);
205
+ const normalized = id.startsWith("clinepass/") ? id.slice(10) : id;
206
+ return MODELS.some((m) => m.id === normalized && m.cost.input === 0);
199
207
  }
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
- unknown: "ClinePass request failed. Check your subscription at app.cline.bot or run `pi /login`.",
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
- if (matchesAny(lower, ["401", "unauthorized", "invalid api key", "invalid_api_key"])) {
56
- return { type: "auth_expired", message: CLINEPASS_ERROR_MESSAGES.auth_expired };
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
- if (matchesAny(lower, ["429", "rate limit", "too many requests", "rate_limit"])) {
59
- return { type: "rate_limited", message: CLINEPASS_ERROR_MESSAGES.rate_limited };
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.61";
14
+ const FALLBACK_CLINE_VERSION = "3.0.65";
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
- "x-client-type": "cli",
77
- "x-client-version": version,
78
- "x-core-version": version,
79
- "x-platform": process.platform,
80
- "x-platform-version": release(),
81
- "user-agent": `Cline/${version}`,
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,8 +1,8 @@
1
1
  /**
2
2
  * pi-clinepass — ClinePass for pi.
3
3
  *
4
- * Registers the `clinepass` provider (14 paid models with measured billing
5
- * prices + 4 free models) and wires the hooks that keep pi's numbers real:
4
+ * Registers the `clinepass` provider (12 paid models with measured billing
5
+ * prices + 5 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
8
8
  * - model_select / session_start → immediate meter + default model sync