@cjhyy/code-shell-server 0.9.30 → 0.9.31
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/dist/links/http.js
CHANGED
|
@@ -113,6 +113,7 @@ export function createLinkHttp(options) {
|
|
|
113
113
|
"connectionId",
|
|
114
114
|
"expectedRevision",
|
|
115
115
|
"authModeId",
|
|
116
|
+
"resourceUrl",
|
|
116
117
|
]);
|
|
117
118
|
result = await service.startAuthorization(owner, input, input.authModeId);
|
|
118
119
|
}
|
|
@@ -170,6 +171,7 @@ export function createLinkHttp(options) {
|
|
|
170
171
|
"connectionId",
|
|
171
172
|
"expectedRevision",
|
|
172
173
|
...(token ? ["token"] : []),
|
|
174
|
+
...(url.pathname.endsWith("/remote") ? ["resourceUrl"] : []),
|
|
173
175
|
]);
|
|
174
176
|
result = token
|
|
175
177
|
? await service.connectToken(owner, input)
|
package/dist/links/service.js
CHANGED
|
@@ -186,6 +186,14 @@ export function createLinkService(options = {}) {
|
|
|
186
186
|
id: meta.linkAccountId,
|
|
187
187
|
label: meta.linkAccountLabel,
|
|
188
188
|
resources: meta.linkResourceLabels?.slice(0, 100) ?? [],
|
|
189
|
+
...(remote && meta.linkResourceGroups
|
|
190
|
+
? {
|
|
191
|
+
resourceGroups: meta.linkResourceGroups.map((group) => ({
|
|
192
|
+
id: group.id,
|
|
193
|
+
items: group.items.map((item) => ({ id: item.id, label: item.label })),
|
|
194
|
+
})),
|
|
195
|
+
}
|
|
196
|
+
: {}),
|
|
189
197
|
},
|
|
190
198
|
capabilityIds: meta.linkCapabilityIds ?? [],
|
|
191
199
|
verifiedAt: meta.linkLastVerifiedAt,
|
|
@@ -664,6 +672,8 @@ export function createLinkService(options = {}) {
|
|
|
664
672
|
async function startAuthorization(context, input, rawAuthModeId) {
|
|
665
673
|
await authorize(context);
|
|
666
674
|
const authModeId = string(rawAuthModeId, 80);
|
|
675
|
+
if (input?.resourceUrl !== undefined && authModeId !== "remote-link")
|
|
676
|
+
throw new LinkServiceError(400, "invalid_request");
|
|
667
677
|
if (authModeId === "remote-link")
|
|
668
678
|
await refreshRemoteCatalog(context);
|
|
669
679
|
const provider = snapshot().providers.find((candidate) => candidate.id === input?.providerId);
|
|
@@ -1029,7 +1039,12 @@ export function createLinkService(options = {}) {
|
|
|
1029
1039
|
checkCapacity();
|
|
1030
1040
|
if (!input ||
|
|
1031
1041
|
input.methodId !== "remote-link" ||
|
|
1032
|
-
!REMOTE_LINK_ADAPTERS.some((adapter) => adapter.id === input.providerId)
|
|
1042
|
+
!REMOTE_LINK_ADAPTERS.some((adapter) => adapter.id === input.providerId) ||
|
|
1043
|
+
(input.resourceUrl !== undefined &&
|
|
1044
|
+
(input.providerId !== "figma" ||
|
|
1045
|
+
!input.connectionId ||
|
|
1046
|
+
typeof input.resourceUrl !== "string" ||
|
|
1047
|
+
!input.resourceUrl)))
|
|
1033
1048
|
throw new LinkServiceError(400, "invalid_request");
|
|
1034
1049
|
const config = options.remoteLink?.();
|
|
1035
1050
|
if (!config)
|
|
@@ -1055,11 +1070,24 @@ export function createLinkService(options = {}) {
|
|
|
1055
1070
|
throw new LinkServiceError(409, "conflict");
|
|
1056
1071
|
}
|
|
1057
1072
|
const prepared = { id, expected, input: { ...input, label: string(input.label) } };
|
|
1073
|
+
if (input.resourceUrl !== undefined && !expected)
|
|
1074
|
+
throw new LinkServiceError(400, "invalid_request");
|
|
1058
1075
|
let attempt;
|
|
1059
1076
|
try {
|
|
1077
|
+
let resourceFiles;
|
|
1078
|
+
if (input.providerId === "figma") {
|
|
1079
|
+
// Recover the old whitelist from Host custody. Browser input can only suggest one new file.
|
|
1080
|
+
const groups = expected?.meta?.linkResourceGroups;
|
|
1081
|
+
if (expected && (!groups || groups.length !== 1 || groups[0]?.id !== "files"))
|
|
1082
|
+
throw new Error("Invalid saved Figma resources");
|
|
1083
|
+
resourceFiles = groups?.[0]?.items.map((item) => item.id) ?? [];
|
|
1084
|
+
if (input.resourceUrl !== undefined)
|
|
1085
|
+
resourceFiles.push(input.resourceUrl);
|
|
1086
|
+
}
|
|
1060
1087
|
attempt = beginRemoteLinkAuthorization(config, now(), {
|
|
1061
1088
|
providerId: input.providerId,
|
|
1062
1089
|
actions: capabilities.actions,
|
|
1090
|
+
...(resourceFiles !== undefined ? { resourceFiles } : {}),
|
|
1063
1091
|
});
|
|
1064
1092
|
}
|
|
1065
1093
|
catch {
|
|
@@ -1123,6 +1151,10 @@ export function createLinkService(options = {}) {
|
|
|
1123
1151
|
},
|
|
1124
1152
|
});
|
|
1125
1153
|
await check();
|
|
1154
|
+
if (job.attempt.providerId === "figma" &&
|
|
1155
|
+
job.prepared.expected &&
|
|
1156
|
+
credential.meta?.linkAccountId !== job.prepared.expected.meta?.linkAccountId)
|
|
1157
|
+
throw new LinkServiceError(409, "conflict");
|
|
1126
1158
|
const guarded = {
|
|
1127
1159
|
ownerId: context.ownerId,
|
|
1128
1160
|
authorize: async () => {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type PanelAppPreview, type PanelAppSourceInput } from "@cjhyy/code-shell-core";
|
|
2
|
-
import { getRefCommit } from "@cjhyy/code-shell-core/internal/skills";
|
|
3
2
|
import type { PanelCompatibility, PanelDiscovery, PanelOperationContext, PanelReview, PanelProjectReview, PanelSnapshot, PanelPackageHistory, PanelPackageRestoreReview } from "./types.js";
|
|
4
3
|
export declare class PanelManagementError extends Error {
|
|
5
4
|
readonly status: number;
|
|
@@ -23,7 +22,10 @@ export interface PanelManagementOptions {
|
|
|
23
22
|
compatibility?: (app: Pick<PanelAppPreview, "permissions" | "agent">) => PanelCompatibility;
|
|
24
23
|
now?: () => number;
|
|
25
24
|
/** Network seam only; production still uses the reviewed Core installer. */
|
|
26
|
-
resolveCommit?:
|
|
25
|
+
resolveCommit?: (info: {
|
|
26
|
+
owner: string;
|
|
27
|
+
repo: string;
|
|
28
|
+
}, ref: string) => Promise<string>;
|
|
27
29
|
}
|
|
28
30
|
export declare function createPanelManagement(options: PanelManagementOptions): {
|
|
29
31
|
snapshot: (appId?: string) => Promise<PanelSnapshot>;
|
|
@@ -3,9 +3,9 @@ import { panelPackageMutationMatches } from "./package-mutation.js";
|
|
|
3
3
|
import { createHash, randomBytes } from "node:crypto";
|
|
4
4
|
import { lstatSync, mkdirSync, statSync } from "node:fs";
|
|
5
5
|
import { basename, extname, isAbsolute, join, resolve } from "node:path";
|
|
6
|
-
import { SettingsManager, PanelAppAlreadyInstalledError, PanelAppInstallError, PanelAppReviewChangedError, assertSafePanelAppId, discoverGitPanelApps, installReviewedLocalPanelApp, invalidateSkillCache, listInstalledPanelApps, inspectProjectPanelApps, listRetainedPanelAppPackages, resolvePanelAppPackage, parsePanelAppPackagePins, retainInstalledPanelApp, userHome, panelAppsRoot, previewLocalPanelApp, resolvePanelAppBindingPolicy, uninstallPanelApp, } from "@cjhyy/code-shell-core";
|
|
6
|
+
import { SettingsManager, PanelAppAlreadyInstalledError, PanelAppInstallError, PanelAppReviewChangedError, assertSafePanelAppId, discoverGitPanelApps, installReviewedLocalPanelApp, invalidateSkillCache, listInstalledPanelApps, inspectProjectPanelApps, listRetainedPanelAppPackages, resolvePanelAppPackage, parsePanelAppPackagePins, retainInstalledPanelApp, userHome, panelAppsRoot, previewLocalPanelApp, resolveGitHubPanelAppCommit, resolvePanelAppBindingPolicy, uninstallPanelApp, } from "@cjhyy/code-shell-core";
|
|
7
7
|
import { mutateJsonFile } from "@cjhyy/code-shell-core/internal";
|
|
8
|
-
import {
|
|
8
|
+
import { parseGithubUrl } from "@cjhyy/code-shell-core/internal/skills";
|
|
9
9
|
const REVIEW_TTL = 8 * 60_000;
|
|
10
10
|
const MAX_REVIEWS = 8;
|
|
11
11
|
const MAX_NETWORK = 2;
|
|
@@ -47,7 +47,7 @@ export function publicPanelError(error) {
|
|
|
47
47
|
return new PanelManagementError(503, "github_unavailable", "GitHub 暂时不可用,请稍后重试。");
|
|
48
48
|
if (/(?:ENOTFOUND|EAI_AGAIN|ECONNRESET|ECONNREFUSED|UND_ERR_SOCKET)/.test(code) ||
|
|
49
49
|
/^(?:fetch failed|Failed to fetch)$/i.test(message) ||
|
|
50
|
-
/GitHub source download failed/i.test(message))
|
|
50
|
+
/GitHub source (?:download|ref lookup) failed/i.test(message))
|
|
51
51
|
return new PanelManagementError(502, "github_network", "服务端无法连接 GitHub,请检查网络、DNS 或代理设置后重试。");
|
|
52
52
|
if (error instanceof PanelAppInstallError)
|
|
53
53
|
return new PanelManagementError(400, "invalid_source", error.message);
|
|
@@ -352,7 +352,9 @@ export function createPanelManagement(options) {
|
|
|
352
352
|
const ref = parsed.source.ref ?? "HEAD";
|
|
353
353
|
const commit = SHA.test(ref)
|
|
354
354
|
? ref.toLowerCase()
|
|
355
|
-
:
|
|
355
|
+
: options.resolveCommit
|
|
356
|
+
? await options.resolveCommit({ owner: parsed.owner, repo: parsed.repo }, ref)
|
|
357
|
+
: await resolveGitHubPanelAppCommit(parsed.source);
|
|
356
358
|
await guard();
|
|
357
359
|
if (!SHA.test(commit))
|
|
358
360
|
throw new PanelManagementError(502, "invalid_source", "GitHub 没有返回有效的提交版本。");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cjhyy/code-shell-server",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.31",
|
|
4
4
|
"description": "CodeShell server transport layer — mobile remote HTTP/WS host, pairing, passcode gate, tunnel, rooms, uploads, and session/attachment services. Electron-free; precursor of the auth gateway.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -60,13 +60,13 @@
|
|
|
60
60
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@cjhyy/code-shell-capability-coding": "0.9.
|
|
64
|
-
"@cjhyy/code-shell-core": "0.9.
|
|
65
|
-
"@cjhyy/code-shell-web": "0.9.
|
|
63
|
+
"@cjhyy/code-shell-capability-coding": "0.9.31",
|
|
64
|
+
"@cjhyy/code-shell-core": "0.9.31",
|
|
65
|
+
"@cjhyy/code-shell-web": "0.9.31",
|
|
66
66
|
"@modelcontextprotocol/sdk": "^1.31.0",
|
|
67
67
|
"@types/ws": "^8.18.1",
|
|
68
68
|
"ws": "^8.21.0",
|
|
69
|
-
"@cjhyy/code-shell-link": "0.9.
|
|
69
|
+
"@cjhyy/code-shell-link": "0.9.31"
|
|
70
70
|
},
|
|
71
71
|
"engines": {
|
|
72
72
|
"node": ">=20.10"
|