linkshell-cli 0.10.96 → 0.10.98
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 +1 -1
- package/dist/cli/src/commands/host.js +1 -1
- package/dist/cli/src/commands/host.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/dist/client-core/src/pro-membership.d.ts +31 -2
- package/dist/client-core/src/pro-membership.js +28 -2
- package/dist/client-core/src/pro-membership.js.map +1 -1
- package/dist/gateway/src/subscription.d.ts +1 -1
- package/dist/gateway/src/subscription.js +2 -1
- package/dist/gateway/src/subscription.js.map +1 -1
- package/dist/host/src/drivers/codex/driver.d.ts +5 -1
- package/dist/host/src/drivers/codex/driver.js +66 -26
- package/dist/host/src/drivers/codex/driver.js.map +1 -1
- package/dist/host/src/machine-metrics.d.ts +9 -1
- package/dist/host/src/machine-metrics.js +46 -3
- package/dist/host/src/machine-metrics.js.map +1 -1
- package/dist/wire/src/model.d.ts +21 -0
- package/dist/wire/src/model.js +10 -0
- package/dist/wire/src/model.js.map +1 -1
- package/dist/wire/src/rpc.d.ts +14 -0
- package/package.json +4 -4
- package/src/commands/host.ts +1 -1
|
@@ -24,9 +24,38 @@ export interface ProMembershipOptions {
|
|
|
24
24
|
signal?: AbortSignal;
|
|
25
25
|
}
|
|
26
26
|
export declare const LINKSHELL_PRODUCT = "linkshell";
|
|
27
|
-
/**
|
|
28
|
-
|
|
27
|
+
/**
|
|
28
|
+
* The only place a membership is bought. Phones must not link to it (App Store rules).
|
|
29
|
+
* www and a locale up front: the bare domain costs two redirects (308 to www, 307 to a locale).
|
|
30
|
+
* Chinese, like the rest of the computer UI. The entitlement API below stays on the bare domain:
|
|
31
|
+
* it is exempt from those redirects, and a cross-host redirect would drop the bearer token.
|
|
32
|
+
*/
|
|
33
|
+
export declare const ITOOL_MEMBERSHIP_URL = "https://www.itool.tech/zh/pro?from=linkshell";
|
|
29
34
|
export declare const ITOOL_ENTITLEMENT_URL = "https://itool.tech/api/membership/entitlement?product=linkshell";
|
|
35
|
+
/**
|
|
36
|
+
* iTool products a membership can unlock: yearly unlocks all of them, monthly the iTool site and LinkShell.
|
|
37
|
+
* Mirrors itool-tech src/lib/membership.ts MEMBERSHIP_PRODUCTS: change them when it changes.
|
|
38
|
+
*/
|
|
39
|
+
export declare const MEMBERSHIP_PRODUCT_TOTAL = 7;
|
|
40
|
+
export declare const MONTHLY_PRODUCT_COUNT = 2;
|
|
41
|
+
/**
|
|
42
|
+
* For monthly members: with `checkout=yearly`, itool.tech opens the yearly checkout once the
|
|
43
|
+
* person is signed in. Like the buy page, phones must not link to it (App Store rules).
|
|
44
|
+
* apps/mac mirrors this and the counts in `DesktopModel.swift` (`ITool`).
|
|
45
|
+
*/
|
|
46
|
+
export declare const ITOOL_YEARLY_UPGRADE_URL = "https://www.itool.tech/zh/pro?from=linkshell&checkout=yearly";
|
|
47
|
+
/** The upgrade row monthly members see on the computer: what they have, and the way to the rest. */
|
|
48
|
+
export declare const MONTHLY_UPGRADE_COPY: {
|
|
49
|
+
readonly zh: {
|
|
50
|
+
readonly unlocked: "已解锁 2/7 款产品";
|
|
51
|
+
readonly action: "升级年度";
|
|
52
|
+
};
|
|
53
|
+
readonly en: {
|
|
54
|
+
readonly unlocked: "2 of 7 products unlocked";
|
|
55
|
+
readonly action: "Go yearly";
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export declare function monthlyUpgradeLabel(lang?: keyof typeof MONTHLY_UPGRADE_COPY): string;
|
|
30
59
|
/**
|
|
31
60
|
* Why a lookup failed. `login` means the token is no good; `unavailable` and `network` say
|
|
32
61
|
* nothing about the account, so callers keep what they last knew.
|
|
@@ -4,9 +4,35 @@
|
|
|
4
4
|
* clients just read the entitlement and send people to the buy page.
|
|
5
5
|
*/
|
|
6
6
|
export const LINKSHELL_PRODUCT = "linkshell";
|
|
7
|
-
/**
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The only place a membership is bought. Phones must not link to it (App Store rules).
|
|
9
|
+
* www and a locale up front: the bare domain costs two redirects (308 to www, 307 to a locale).
|
|
10
|
+
* Chinese, like the rest of the computer UI. The entitlement API below stays on the bare domain:
|
|
11
|
+
* it is exempt from those redirects, and a cross-host redirect would drop the bearer token.
|
|
12
|
+
*/
|
|
13
|
+
export const ITOOL_MEMBERSHIP_URL = "https://www.itool.tech/zh/pro?from=linkshell";
|
|
9
14
|
export const ITOOL_ENTITLEMENT_URL = `https://itool.tech/api/membership/entitlement?product=${LINKSHELL_PRODUCT}`;
|
|
15
|
+
/**
|
|
16
|
+
* iTool products a membership can unlock: yearly unlocks all of them, monthly the iTool site and LinkShell.
|
|
17
|
+
* Mirrors itool-tech src/lib/membership.ts MEMBERSHIP_PRODUCTS: change them when it changes.
|
|
18
|
+
*/
|
|
19
|
+
export const MEMBERSHIP_PRODUCT_TOTAL = 7;
|
|
20
|
+
export const MONTHLY_PRODUCT_COUNT = 2;
|
|
21
|
+
/**
|
|
22
|
+
* For monthly members: with `checkout=yearly`, itool.tech opens the yearly checkout once the
|
|
23
|
+
* person is signed in. Like the buy page, phones must not link to it (App Store rules).
|
|
24
|
+
* apps/mac mirrors this and the counts in `DesktopModel.swift` (`ITool`).
|
|
25
|
+
*/
|
|
26
|
+
export const ITOOL_YEARLY_UPGRADE_URL = `${ITOOL_MEMBERSHIP_URL}&checkout=yearly`;
|
|
27
|
+
/** The upgrade row monthly members see on the computer: what they have, and the way to the rest. */
|
|
28
|
+
export const MONTHLY_UPGRADE_COPY = {
|
|
29
|
+
zh: { unlocked: `已解锁 ${MONTHLY_PRODUCT_COUNT}/${MEMBERSHIP_PRODUCT_TOTAL} 款产品`, action: "升级年度" },
|
|
30
|
+
en: { unlocked: `${MONTHLY_PRODUCT_COUNT} of ${MEMBERSHIP_PRODUCT_TOTAL} products unlocked`, action: "Go yearly" },
|
|
31
|
+
};
|
|
32
|
+
export function monthlyUpgradeLabel(lang = "zh") {
|
|
33
|
+
const copy = MONTHLY_UPGRADE_COPY[lang];
|
|
34
|
+
return `${copy.unlocked} · ${copy.action}`;
|
|
35
|
+
}
|
|
10
36
|
const REQUEST_TIMEOUT_MS = 15_000;
|
|
11
37
|
const LOGIN_REQUIRED = "登录已失效,请重新登录后再试";
|
|
12
38
|
const MALFORMED = "会员状态返回异常,请稍后重试";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pro-membership.js","sourceRoot":"","sources":["../../../../client-core/src/pro-membership.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAC;AAC7C
|
|
1
|
+
{"version":3,"file":"pro-membership.js","sourceRoot":"","sources":["../../../../client-core/src/pro-membership.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { GatewayOptions } from "./relay.js";
|
|
2
|
-
export declare const MEMBERSHIP_URL = "https://itool.tech/pro?from=linkshell";
|
|
2
|
+
export declare const MEMBERSHIP_URL = "https://www.itool.tech/zh/pro?from=linkshell";
|
|
3
3
|
export interface SubscriptionCheck {
|
|
4
4
|
/** "unknown": the lookup itself failed, which says nothing about the account. */
|
|
5
5
|
status: "active" | "inactive" | "unknown";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// The official gateway is part of the iTool membership: any active member (monthly or yearly)
|
|
2
2
|
// has LinkShell. The gateway asks iTool's `itool_entitlement_for(uid, 'linkshell')` with the
|
|
3
3
|
// service-role key, on its own behalf, not with the user's token.
|
|
4
|
-
|
|
4
|
+
// www and a locale up front: the bare domain costs two redirects. Chinese, like the message it ends.
|
|
5
|
+
export const MEMBERSHIP_URL = "https://www.itool.tech/zh/pro?from=linkshell";
|
|
5
6
|
/** The RPC's jsonb answer, as the gateway reads it. */
|
|
6
7
|
export function subscriptionFromEntitlement(value) {
|
|
7
8
|
const body = value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../../gateway/src/subscription.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,6FAA6F;AAC7F,kEAAkE;AAElE,MAAM,CAAC,MAAM,cAAc,GAAG,
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../../gateway/src/subscription.ts"],"names":[],"mappings":"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"}
|
|
@@ -95,6 +95,8 @@ export declare class CodexDriver implements AgentDriver {
|
|
|
95
95
|
private readonly goalRevision;
|
|
96
96
|
private skillsRevision;
|
|
97
97
|
private models?;
|
|
98
|
+
private modelsLoadedAt?;
|
|
99
|
+
private lastModels;
|
|
98
100
|
private restartTimer?;
|
|
99
101
|
private restartDelay;
|
|
100
102
|
private stopped;
|
|
@@ -268,12 +270,14 @@ export declare class CodexDriver implements AgentDriver {
|
|
|
268
270
|
private sideUpdate;
|
|
269
271
|
private markFullAccess;
|
|
270
272
|
private approvePending;
|
|
271
|
-
/**
|
|
273
|
+
/** Refresh when a client opens the picker; a long-running host must pick up models added since its first session. */
|
|
272
274
|
listModels(cwd?: string, model?: string): Promise<import("@linkshell/wire").MethodResult<"agents.models">>;
|
|
273
275
|
/** The model config.toml (with the project's own layers, for `cwd`) gives a new thread; undefined: Codex's default. */
|
|
274
276
|
private configuredSettings;
|
|
275
277
|
private loadModels;
|
|
276
278
|
private announceConfig;
|
|
279
|
+
private clearModels;
|
|
280
|
+
private publishConfig;
|
|
277
281
|
private isNews;
|
|
278
282
|
private loadSkills;
|
|
279
283
|
/** What `/` offers on a device: the commands above, then the skills this project can use. */
|
|
@@ -172,6 +172,8 @@ export class CodexDriver {
|
|
|
172
172
|
goalRevision = new Map();
|
|
173
173
|
skillsRevision = 0;
|
|
174
174
|
models;
|
|
175
|
+
modelsLoadedAt;
|
|
176
|
+
lastModels = [];
|
|
175
177
|
restartTimer;
|
|
176
178
|
restartDelay;
|
|
177
179
|
stopped = false;
|
|
@@ -257,6 +259,7 @@ export class CodexDriver {
|
|
|
257
259
|
clearTimeout(timer);
|
|
258
260
|
this.taskPolls.clear();
|
|
259
261
|
this.stopped = true;
|
|
262
|
+
this.clearModels();
|
|
260
263
|
if (this.restartTimer)
|
|
261
264
|
clearTimeout(this.restartTimer);
|
|
262
265
|
for (const timer of this.followRetries.values())
|
|
@@ -888,6 +891,10 @@ export class CodexDriver {
|
|
|
888
891
|
watched(nativeId, open) {
|
|
889
892
|
if (open) {
|
|
890
893
|
this.watching.add(nativeId);
|
|
894
|
+
// The hub can keep a session attached after its last viewer leaves.
|
|
895
|
+
// Reopening it must also refresh the choices sent in ls_config.
|
|
896
|
+
if (this.attached.has(nativeId) || this.observed.has(nativeId))
|
|
897
|
+
void this.announceConfig(nativeId);
|
|
891
898
|
void this.syncTasks(nativeId);
|
|
892
899
|
this.cancelRelease(nativeId);
|
|
893
900
|
}
|
|
@@ -1601,9 +1608,9 @@ export class CodexDriver {
|
|
|
1601
1608
|
this.host?.update(this.id, threadId, { sessionUpdate: "ls_permission_resolved", requestId, optionId });
|
|
1602
1609
|
}
|
|
1603
1610
|
}
|
|
1604
|
-
/**
|
|
1611
|
+
/** Refresh when a client opens the picker; a long-running host must pick up models added since its first session. */
|
|
1605
1612
|
async listModels(cwd, model) {
|
|
1606
|
-
const [models, configured] = await Promise.all([this.loadModels(true), this.configuredSettings(cwd)]);
|
|
1613
|
+
const [models, configured] = await Promise.all([this.loadModels(true, true), this.configuredSettings(cwd)]);
|
|
1607
1614
|
const listed = newThreadModels(models, configured.model);
|
|
1608
1615
|
const selected = model && listed.models.some((entry) => entry.value === model) ? model : undefined;
|
|
1609
1616
|
return { ...listed, config: configOptions(configured, selected ? { model: selected } : {}, models).filter((option) => option.category === "mode" || option.category === "effort") };
|
|
@@ -1620,33 +1627,66 @@ export class CodexDriver {
|
|
|
1620
1627
|
return {};
|
|
1621
1628
|
}
|
|
1622
1629
|
}
|
|
1623
|
-
loadModels(strict = false) {
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
let cursor;
|
|
1628
|
-
do {
|
|
1629
|
-
const result = await this.rpc("model/list", { includeHidden: false, ...(cursor ? { cursor } : {}) });
|
|
1630
|
-
models.push(...result.data);
|
|
1631
|
-
cursor = result.nextCursor ?? undefined;
|
|
1632
|
-
if (cursor && cursors.has(cursor))
|
|
1633
|
-
throw new Error("Codex 返回了重复的模型分页,请重试");
|
|
1634
|
-
if (cursor)
|
|
1635
|
-
cursors.add(cursor);
|
|
1636
|
-
} while (cursor);
|
|
1637
|
-
return models;
|
|
1638
|
-
})()
|
|
1639
|
-
.catch((error) => {
|
|
1630
|
+
loadModels(strict = false, refresh = false) {
|
|
1631
|
+
// Concurrent pickers share the same request. Internal configuration updates can
|
|
1632
|
+
// reuse its result, while the next explicit listing reads the agent again.
|
|
1633
|
+
if (this.modelsLoadedAt !== undefined && (refresh || Date.now() - this.modelsLoadedAt >= 60_000))
|
|
1640
1634
|
this.models = undefined;
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1635
|
+
if (!this.models) {
|
|
1636
|
+
this.modelsLoadedAt = undefined;
|
|
1637
|
+
const loading = (async () => {
|
|
1638
|
+
const models = [];
|
|
1639
|
+
const cursors = new Set();
|
|
1640
|
+
let cursor;
|
|
1641
|
+
do {
|
|
1642
|
+
const result = await this.rpc("model/list", { includeHidden: false, ...(cursor ? { cursor } : {}) });
|
|
1643
|
+
models.push(...result.data);
|
|
1644
|
+
cursor = result.nextCursor ?? undefined;
|
|
1645
|
+
if (cursor && cursors.has(cursor))
|
|
1646
|
+
throw new Error("Codex 返回了重复的模型分页,请重试");
|
|
1647
|
+
if (cursor)
|
|
1648
|
+
cursors.add(cursor);
|
|
1649
|
+
} while (cursor);
|
|
1650
|
+
return models;
|
|
1651
|
+
})()
|
|
1652
|
+
.then((models) => {
|
|
1653
|
+
if (this.models === loading) {
|
|
1654
|
+
this.modelsLoadedAt = Date.now();
|
|
1655
|
+
this.lastModels = models;
|
|
1656
|
+
// An existing composer reads ls_config, not agents.models. Keep its
|
|
1657
|
+
// current selection while publishing newly discovered choices.
|
|
1658
|
+
for (const nativeId of this.watching) {
|
|
1659
|
+
if (this.attached.has(nativeId) || this.observed.has(nativeId))
|
|
1660
|
+
this.publishConfig(nativeId, models);
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
return models;
|
|
1664
|
+
})
|
|
1665
|
+
.catch((error) => {
|
|
1666
|
+
if (this.models === loading)
|
|
1667
|
+
this.models = undefined;
|
|
1668
|
+
this.host?.log(`[codex] model/list failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1669
|
+
if (error instanceof RpcError && error.code === RPC_METHOD_NOT_FOUND)
|
|
1670
|
+
return [];
|
|
1671
|
+
throw error;
|
|
1672
|
+
});
|
|
1673
|
+
this.models = loading;
|
|
1674
|
+
}
|
|
1675
|
+
return strict ? this.models : this.models.catch(() => this.lastModels);
|
|
1647
1676
|
}
|
|
1648
1677
|
async announceConfig(nativeId) {
|
|
1678
|
+
// Permissions and Plan still come from this session when the catalogue
|
|
1679
|
+
// is unavailable; keep its last model choices while publishing new settings.
|
|
1649
1680
|
const models = await this.loadModels();
|
|
1681
|
+
if (!this.stopped)
|
|
1682
|
+
this.publishConfig(nativeId, models);
|
|
1683
|
+
}
|
|
1684
|
+
clearModels() {
|
|
1685
|
+
this.models = undefined;
|
|
1686
|
+
this.modelsLoadedAt = undefined;
|
|
1687
|
+
this.lastModels = [];
|
|
1688
|
+
}
|
|
1689
|
+
publishConfig(nativeId, models) {
|
|
1650
1690
|
const options = configOptions(this.settings.get(nativeId) ?? {}, this.overridesOf(nativeId), models);
|
|
1651
1691
|
if (options.length > 0 && this.isNews(`config:${nativeId}`, options))
|
|
1652
1692
|
this.host?.update(this.id, nativeId, { sessionUpdate: "ls_config", options });
|
|
@@ -1849,7 +1889,7 @@ export class CodexDriver {
|
|
|
1849
1889
|
});
|
|
1850
1890
|
}
|
|
1851
1891
|
onDown(reason) {
|
|
1852
|
-
this.
|
|
1892
|
+
this.clearModels();
|
|
1853
1893
|
this.skills.clear();
|
|
1854
1894
|
if (this.stopped)
|
|
1855
1895
|
return;
|