linkshell-cli 0.10.44 → 0.10.46
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/README.md +2 -0
- package/dist/cli/src/auth.js +4 -0
- package/dist/cli/src/auth.js.map +1 -1
- package/dist/cli/src/commands/desktop.d.ts +5 -5
- package/dist/cli/src/commands/desktop.js +67 -5
- package/dist/cli/src/commands/desktop.js.map +1 -1
- package/dist/cli/src/commands/login.js +10 -17
- package/dist/cli/src/commands/login.js.map +1 -1
- package/dist/cli/src/pro-membership.d.ts +16 -0
- package/dist/cli/src/pro-membership.js +91 -0
- package/dist/cli/src/pro-membership.js.map +1 -0
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/dist/client-core/src/pro-membership.d.ts +17 -0
- package/dist/client-core/src/pro-membership.js +107 -0
- package/dist/client-core/src/pro-membership.js.map +1 -0
- package/dist/host/src/drivers/acp/antigravity.js +9 -15
- package/dist/host/src/drivers/acp/antigravity.js.map +1 -1
- package/dist/host/src/drivers/acp/driver.d.ts +2 -0
- package/dist/host/src/drivers/acp/driver.js +18 -6
- package/dist/host/src/drivers/acp/driver.js.map +1 -1
- package/dist/host/src/drivers/claude/transcript.d.ts +6 -0
- package/dist/host/src/host.js +1 -1
- package/dist/host/src/host.js.map +1 -1
- package/dist/host/src/store.d.ts +4 -0
- package/dist/host/src/store.js +10 -0
- package/dist/host/src/store.js.map +1 -1
- package/dist/host/src/usage.d.ts +20 -5
- package/dist/host/src/usage.js +55 -3
- package/dist/host/src/usage.js.map +1 -1
- package/dist/wire/src/rpc.d.ts +190 -3
- package/dist/wire/src/updates.d.ts +68 -0
- package/dist/wire/src/updates.js +2 -0
- package/dist/wire/src/updates.js.map +1 -1
- package/dist/wire/src/usage.d.ts +46 -3
- package/dist/wire/src/usage.js +5 -1
- package/dist/wire/src/usage.js.map +1 -1
- package/package.json +4 -4
- package/src/auth.ts +3 -0
- package/src/commands/desktop.ts +60 -6
- package/src/commands/login.ts +7 -25
- package/src/pro-membership.ts +82 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ProMembership {
|
|
2
|
+
plan: "free" | "pro";
|
|
3
|
+
expiresAt?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ProMembershipOptions {
|
|
6
|
+
supabaseUrl: string;
|
|
7
|
+
anonKey: string;
|
|
8
|
+
accessToken: string;
|
|
9
|
+
userId: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const PRO_CODE_SHOP_URL = "https://pay.ldxp.cn/item/7lgv1s";
|
|
12
|
+
/** The profile is read with the user's token; only the server can grant Pro. */
|
|
13
|
+
export declare function fetchProMembership(options: ProMembershipOptions): Promise<ProMembership>;
|
|
14
|
+
export declare function redeemProCode(accessToken: string, code: string): Promise<{
|
|
15
|
+
expiresAt: string;
|
|
16
|
+
idempotent: boolean;
|
|
17
|
+
}>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export const PRO_CODE_SHOP_URL = "https://pay.ldxp.cn/item/7lgv1s";
|
|
2
|
+
const REDEEM_URL = "https://itool.tech/api/pro/redeem";
|
|
3
|
+
const REQUEST_TIMEOUT_MS = 15_000;
|
|
4
|
+
const LOGIN_REQUIRED = "登录已失效,请重新登录后再试";
|
|
5
|
+
function record(value) {
|
|
6
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
7
|
+
}
|
|
8
|
+
function timestamp(value) {
|
|
9
|
+
return typeof value === "string" ? Date.parse(value) : NaN;
|
|
10
|
+
}
|
|
11
|
+
async function request(url, init) {
|
|
12
|
+
const controller = new AbortController();
|
|
13
|
+
const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
14
|
+
try {
|
|
15
|
+
const response = await fetch(url, { ...init, credentials: "omit", signal: controller.signal });
|
|
16
|
+
let body;
|
|
17
|
+
try {
|
|
18
|
+
body = await response.json();
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
if (controller.signal.aborted || !(error instanceof SyntaxError))
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
return { response, body };
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new Error(controller.signal.aborted ? "请求超时,请稍后重试" : "网络连接失败,请检查网络后重试");
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
clearTimeout(timer);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** The profile is read with the user's token; only the server can grant Pro. */
|
|
34
|
+
export async function fetchProMembership(options) {
|
|
35
|
+
if (!options.accessToken.trim() || !options.userId.trim())
|
|
36
|
+
throw new Error(LOGIN_REQUIRED);
|
|
37
|
+
const url = `${options.supabaseUrl.replace(/\/$/, "")}/rest/v1/profiles?select=plan,plan_expires_at&id=eq.${encodeURIComponent(options.userId)}&limit=1`;
|
|
38
|
+
const { response, body } = await request(url, {
|
|
39
|
+
headers: { apikey: options.anonKey, Authorization: `Bearer ${options.accessToken}` },
|
|
40
|
+
});
|
|
41
|
+
if (response.status === 401 || response.status === 403)
|
|
42
|
+
throw new Error(LOGIN_REQUIRED);
|
|
43
|
+
if (!response.ok)
|
|
44
|
+
throw new Error("暂时无法获取会员状态,请稍后重试");
|
|
45
|
+
if (!Array.isArray(body))
|
|
46
|
+
throw new Error("会员状态返回异常,请稍后重试");
|
|
47
|
+
if (body.length === 0)
|
|
48
|
+
return { plan: "free" };
|
|
49
|
+
const profile = record(body[0]);
|
|
50
|
+
if (!profile || typeof profile.plan !== "string")
|
|
51
|
+
throw new Error("会员状态返回异常,请稍后重试");
|
|
52
|
+
const expiresAt = profile.plan_expires_at;
|
|
53
|
+
const expires = timestamp(expiresAt);
|
|
54
|
+
const serverTime = timestamp(response.headers.get("date"));
|
|
55
|
+
const now = Number.isFinite(serverTime) ? serverTime : Date.now();
|
|
56
|
+
return profile.plan === "pro" && Number.isFinite(expires) && expires > now
|
|
57
|
+
? { plan: "pro", expiresAt: expiresAt }
|
|
58
|
+
: { plan: "free" };
|
|
59
|
+
}
|
|
60
|
+
const redeemErrors = {
|
|
61
|
+
malformed_request: "激活码格式不正确,请检查后重试",
|
|
62
|
+
login_required: LOGIN_REQUIRED,
|
|
63
|
+
request_too_large: "激活码内容过长,请检查后重试",
|
|
64
|
+
invalid_or_unavailable: "激活码无效或已不可用,请检查后重试",
|
|
65
|
+
rate_limited: "操作太频繁,请稍后重试",
|
|
66
|
+
temporarily_unavailable: "兑换服务暂时不可用,请稍后重试",
|
|
67
|
+
};
|
|
68
|
+
const redeemStatusCodes = {
|
|
69
|
+
400: "malformed_request",
|
|
70
|
+
401: "login_required",
|
|
71
|
+
413: "request_too_large",
|
|
72
|
+
422: "invalid_or_unavailable",
|
|
73
|
+
429: "rate_limited",
|
|
74
|
+
503: "temporarily_unavailable",
|
|
75
|
+
};
|
|
76
|
+
export async function redeemProCode(accessToken, code) {
|
|
77
|
+
if (!accessToken.trim())
|
|
78
|
+
throw new Error(LOGIN_REQUIRED);
|
|
79
|
+
const normalizedCode = code.trim();
|
|
80
|
+
if (!normalizedCode)
|
|
81
|
+
throw new Error("请输入激活码");
|
|
82
|
+
const { response, body: responseBody } = await request(REDEEM_URL, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" },
|
|
85
|
+
body: JSON.stringify({ code: normalizedCode }),
|
|
86
|
+
});
|
|
87
|
+
const body = record(responseBody);
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
const code = body?.code ?? record(body?.error)?.code;
|
|
90
|
+
const knownCode = typeof code === "string" && Object.hasOwn(redeemErrors, code) ? code : redeemStatusCodes[response.status];
|
|
91
|
+
throw new Error(knownCode ? redeemErrors[knownCode] : "兑换失败,请稍后重试");
|
|
92
|
+
}
|
|
93
|
+
const expires = timestamp(body?.plan_expires_at);
|
|
94
|
+
const serverTime = timestamp(body?.server_time);
|
|
95
|
+
if (body?.ok !== true || body.valid !== true || typeof body.idempotent !== "boolean" ||
|
|
96
|
+
typeof body.months !== "number" || !Number.isFinite(body.months) || body.months < 0 ||
|
|
97
|
+
!Number.isFinite(expires) || !Number.isFinite(serverTime)) {
|
|
98
|
+
throw new Error("兑换结果尚未确认,请刷新会员状态后重试");
|
|
99
|
+
}
|
|
100
|
+
if (expires <= serverTime) {
|
|
101
|
+
throw new Error(body.idempotent
|
|
102
|
+
? "此激活码已兑换且权益已到期,请使用新的激活码"
|
|
103
|
+
: "兑换结果尚未确认,请刷新会员状态后重试");
|
|
104
|
+
}
|
|
105
|
+
return { expiresAt: body.plan_expires_at, idempotent: body.idempotent };
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=pro-membership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pro-membership.js","sourceRoot":"","sources":["../../../../client-core/src/pro-membership.ts"],"names":[],"mappings":"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"}
|
|
@@ -827,21 +827,15 @@ export function parseTranscriptSteps(parsed, state) {
|
|
|
827
827
|
updates.push({ sessionUpdate: "ls_goal", goal: state.goal });
|
|
828
828
|
}
|
|
829
829
|
}
|
|
830
|
-
//
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
inputTokens: step.input_tokens ?? 0,
|
|
840
|
-
outputTokens: step.output_tokens ?? 0,
|
|
841
|
-
cachedReadTokens: step.cache_read_tokens ?? 0,
|
|
842
|
-
},
|
|
843
|
-
});
|
|
844
|
-
}
|
|
830
|
+
// Each step is a distinct usage record; only the latest supplies context occupancy.
|
|
831
|
+
const input = (step.input_tokens ?? 0) + (step.cache_read_tokens ?? 0);
|
|
832
|
+
if (input > 0 || (step.output_tokens ?? 0) > 0) {
|
|
833
|
+
const timestamp = Date.parse(step.created_at ?? "");
|
|
834
|
+
updates.push({ sessionUpdate: "usage_update",
|
|
835
|
+
usedTokens: i === lastPlanner || (lastPlanner >= 0 && parsed[lastPlanner].index === stepIndex) ? input : undefined,
|
|
836
|
+
...(Number.isFinite(timestamp) ? { accounting: { id: `agy:step:${stepIndex}`, scope: "turn", timestamp, model: state.lastModelLabel } } : {}),
|
|
837
|
+
tokens: { totalTokens: input + (step.output_tokens ?? 0), inputTokens: step.input_tokens ?? 0,
|
|
838
|
+
outputTokens: step.output_tokens ?? 0, cachedReadTokens: step.cache_read_tokens ?? 0 }, });
|
|
845
839
|
}
|
|
846
840
|
if (updates.length > 0)
|
|
847
841
|
items.push({ itemId: `agy:step:${stepIndex}`, updates });
|