@senguoyun/dsh-arkme 0.1.61 → 0.1.63
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/assets/desktop_call/manifest.json +2 -1
- package/docs/desktop-call-invitations.md +46 -0
- package/lib/client.js +2984 -1590
- package/lib/client.js.map +1 -1
- package/lib/harness-model-client.js +3 -0
- package/lib/harness-session-client.js +49 -0
- package/lib/index.js +29 -2
- package/lib/persistent-extension.js +1 -1
- package/lib/{persistent-runtime-CXd9RuRR.js → persistent-runtime-CBKy5v5l.js} +125 -37
- package/lib/sdk.js +3 -0
- package/lib/types/arkme-service.d.ts +9 -1
- package/lib/types/arkme-service.d.ts.map +1 -1
- package/lib/types/client/ArkmeAvatar.d.ts.map +1 -1
- package/lib/types/client/ArkmeCallInviteDialog.d.ts +5 -0
- package/lib/types/client/ArkmeCallInviteDialog.d.ts.map +1 -0
- package/lib/types/client/ArkmeCallSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeConversationSearch.d.ts.map +1 -1
- package/lib/types/client/ArkmeFileViewer.d.ts.map +1 -1
- package/lib/types/client/ArkmeLongArticleDialog.d.ts +5 -0
- package/lib/types/client/ArkmeLongArticleDialog.d.ts.map +1 -1
- package/lib/types/client/ArkmeNoteDetails.d.ts.map +1 -1
- package/lib/types/client/ArkmeOutgoingCallHost.d.ts.map +1 -1
- package/lib/types/client/ArkmePrivateCallMenu.d.ts.map +1 -1
- package/lib/types/client/ArkmeProductNavigation.d.ts.map +1 -1
- package/lib/types/client/ArkmeRichContent.d.ts +3 -0
- package/lib/types/client/ArkmeRichContent.d.ts.map +1 -1
- package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
- package/lib/types/client/ArkmeTopicDirectoryPopover.d.ts.map +1 -1
- package/lib/types/client/DeepSeekHarnessSurface.d.ts.map +1 -1
- package/lib/types/client/harness-session-client.d.ts.map +1 -1
- package/lib/types/client/harness-session-selection.d.ts +9 -0
- package/lib/types/client/harness-session-selection.d.ts.map +1 -0
- package/lib/types/client/harness-window-drag.d.ts +16 -0
- package/lib/types/client/harness-window-drag.d.ts.map +1 -0
- package/lib/types/client/outgoing-call-bridge.d.ts +1 -0
- package/lib/types/client/outgoing-call-bridge.d.ts.map +1 -1
- package/lib/types/client/outgoing-call-runtime.d.ts +16 -1
- package/lib/types/client/outgoing-call-runtime.d.ts.map +1 -1
- package/lib/types/client/outgoing-call-ui-controller.d.ts +3 -0
- package/lib/types/client/outgoing-call-ui-controller.d.ts.map +1 -1
- package/lib/types/client/use-resizable-call-browser.d.ts +13 -0
- package/lib/types/client/use-resizable-call-browser.d.ts.map +1 -0
- package/lib/types/harness-embed-route.d.ts.map +1 -1
- package/lib/types/harness-session-restore-script.d.ts +9 -0
- package/lib/types/harness-session-restore-script.d.ts.map +1 -0
- package/lib/types/host-api.d.ts.map +1 -1
- package/lib/types/outgoing-call-contract.d.ts +12 -0
- package/lib/types/outgoing-call-contract.d.ts.map +1 -1
- package/lib/types/sdk/index.d.ts +3 -0
- package/lib/types/sdk/index.d.ts.map +1 -1
- package/lib/types/services/call-history-service.d.ts.map +1 -1
- package/lib/types/services/chat-service.d.ts.map +1 -1
- package/lib/types/services/file-transfers.d.ts +5 -1
- package/lib/types/services/file-transfers.d.ts.map +1 -1
- package/lib/types/services/outgoing-call-service.d.ts +6 -1
- package/lib/types/services/outgoing-call-service.d.ts.map +1 -1
- package/lib/types/types.d.ts +3 -1
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -1155,6 +1155,9 @@ window.__ModuleLoader__.load({
|
|
|
1155
1155
|
async localFiles(signal) {
|
|
1156
1156
|
return this.call("files.local.list", void 0, signal);
|
|
1157
1157
|
}
|
|
1158
|
+
async openLocalFileFolder(fileRef, signal) {
|
|
1159
|
+
return this.call("files.local.open-folder", { fileRef }, signal);
|
|
1160
|
+
}
|
|
1158
1161
|
async openLocalFile(fileRef, signal) {
|
|
1159
1162
|
return this.call("files.local.open", { fileRef }, signal);
|
|
1160
1163
|
}
|
|
@@ -8,6 +8,52 @@ window.__ModuleLoader__.load({
|
|
|
8
8
|
/** Same-origin bridge owned and disposed by the embedded session client. */
|
|
9
9
|
const HARNESS_SESSION_NAVIGATION_KEY = "__arkmeHarnessSessionNavigation";
|
|
10
10
|
//#endregion
|
|
11
|
+
//#region src/client/harness-session-selection.ts
|
|
12
|
+
/** The embedded runtime owns selection. Visibility/presence clears must never erase it. */
|
|
13
|
+
function observeHarnessSessionSelection(sessions, bridge) {
|
|
14
|
+
if (bridge === void 0) return () => {};
|
|
15
|
+
let stopped = false;
|
|
16
|
+
let pending;
|
|
17
|
+
let retry;
|
|
18
|
+
const persist = async (selection) => {
|
|
19
|
+
if (stopped || pending !== selection) return;
|
|
20
|
+
try {
|
|
21
|
+
if (!await bridge.save(selection.sessionId, selection.subagentAddress)) stopped = true;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (stopped || pending !== selection) return;
|
|
24
|
+
console.warn("Arkme could not persist the current Harness session.", error);
|
|
25
|
+
if (++selection.failures <= 3) retry = setTimeout(() => {
|
|
26
|
+
retry = void 0;
|
|
27
|
+
persist(selection);
|
|
28
|
+
}, 1e3);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const changed = () => {
|
|
32
|
+
const snapshot = sessions.list.getSnapshot();
|
|
33
|
+
if (stopped || snapshot.phase !== "ready" || !snapshot.current || !snapshot.byId[snapshot.current]) return;
|
|
34
|
+
const key = JSON.stringify([snapshot.current, snapshot.currentAddress]);
|
|
35
|
+
if (pending?.key === key) return;
|
|
36
|
+
if (retry !== void 0) {
|
|
37
|
+
clearTimeout(retry);
|
|
38
|
+
retry = void 0;
|
|
39
|
+
}
|
|
40
|
+
pending = {
|
|
41
|
+
sessionId: snapshot.current,
|
|
42
|
+
subagentAddress: snapshot.currentAddress,
|
|
43
|
+
key,
|
|
44
|
+
failures: 0
|
|
45
|
+
};
|
|
46
|
+
persist(pending);
|
|
47
|
+
};
|
|
48
|
+
const unsubscribe = sessions.list.subscribe(changed);
|
|
49
|
+
changed();
|
|
50
|
+
return () => {
|
|
51
|
+
stopped = true;
|
|
52
|
+
if (retry !== void 0) clearTimeout(retry);
|
|
53
|
+
unsubscribe();
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
11
57
|
//#region src/client/harness-session-client.ts
|
|
12
58
|
const inject = [
|
|
13
59
|
"sessions",
|
|
@@ -23,6 +69,8 @@ window.__ModuleLoader__.load({
|
|
|
23
69
|
const apiPath = document.querySelector("meta[name=\"arkme-session-api\"]")?.content;
|
|
24
70
|
const sessions = ctx.sessions;
|
|
25
71
|
if (sessions === void 0) return () => void 0;
|
|
72
|
+
const parent = window.parent;
|
|
73
|
+
const stopPersistence = observeHarnessSessionSelection(sessions, parent?.arkmeDesktop?.sessionSelection);
|
|
26
74
|
const frameWindow = window;
|
|
27
75
|
const navigation = {
|
|
28
76
|
async has(sessionId) {
|
|
@@ -49,6 +97,7 @@ window.__ModuleLoader__.load({
|
|
|
49
97
|
};
|
|
50
98
|
frameWindow[HARNESS_SESSION_NAVIGATION_KEY] = navigation;
|
|
51
99
|
const disposeNavigation = () => {
|
|
100
|
+
stopPersistence();
|
|
52
101
|
if (frameWindow["__arkmeHarnessSessionNavigation"] === navigation) delete frameWindow[HARNESS_SESSION_NAVIGATION_KEY];
|
|
53
102
|
};
|
|
54
103
|
if (apiPath === void 0 || !/^\/[A-Za-z0-9/_-]+$/.test(apiPath)) return disposeNavigation;
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as ARKME_DEFAULT_SHARE_WEBSITE, A as inspectNativeBundleArtifactV3, At as registerDSHAgentInputRecordSync, D as bundleSha256, Dt as ArkmePluginError, E as arkmeSandboxEntryId, Et as normalizeRecentEmojiIds, F as assertExtensionArtifactSize, Ft as __require, G as validateVoiceprintPcm16Wav, I as canonicalExtensionJson, It as __toCommonJS, J as arkmeRequiredLinkMetadataFallback, K as arkmeExtensionShareRefFromLink, L as sha256Hex, M as packLocalNativeBundleDirectoryV3, Mt as __commonJSMin, N as readNativeBundleTarballV3, Nt as __esmMin, O as canonicalBundleJson, Ot as retryAfterMillis, P as renderArkmeSandboxHostEntry, Pt as __exportAll, Q as parseArkmeRecordReeditAttachments, R as unpackArkmeExtension, S as ARKME_BUNDLE_ARTIFACT_KIND, St as sameRecordingImportIdentity, T as ArkmeBundleArtifactError, Tt as isRecentEmojiId, U as ARKME_EXTENSION_RUNTIME_UNAVAILABLE_MESSAGE, W as ArkmeService, X as arkmeRichBackgroundSound, Y as arkmeFileBackgroundSound, Z as ArkmeRecordReeditDraftConflict, _ as arkmeClientContentDigest, _t as SecretValue, at as ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES, b as verifyExtensionResolutionSignature, bt as isUnresolvedRecordingImportJob, c as persistentExtensionBundleDirectory, ct as mergeMemberJoinEvents, d as readPersistentExtensionActivation, dt as ARKME_TOOL_FILE_MAX_BYTES, et as ARKME_PROVIDER_CONTRACT_VERSION, f as refreshPersistentClientWrapper, ft as arkmeCanInlineLocalFile, g as activeProfileExtensionOwnerConflicts, gt as ArkmeOutgoingCallError, h as renderArkmeBundleClientBundle, ht as isArkmeBotAvatarRef, i as invokePersistentArkmeExtension, it as ARKME_WORLD_PUBLISH_MAX_IMAGES, j as packBundleFiles, jt as createDesktopLifecycleReader, k as inspectBundleArtifact, kt as recordOwnerId, l as persistentExtensionPackageIdentity, lt as validateMemberUpdate, m as writePersistentExtensionActivation, mt as arkmePickedFileKind, o as persistentArkmeExtensionRuntimeState, ot as applyMemberUpdate, p as repairPersistentExtensionInstallation, pt as arkmeNormalizedFileMimeType, q as arkmeIsGenericLinkMetadataTitle, r as deactivatePersistentArkmeExtension, s as materializePersistentExtensionBundle, st as cachedMemberItem, t as activatePersistentArkmeExtension, u as quarantinePersistentExtension, ut as ARKME_RUNTIME_INSTANCE_ID, v as arkmeClientContentDigestFromSource, vt as ArkmeDirectMessageAdmissionError, w as ARKME_NATIVE_BUNDLE_ARTIFACT_KIND, wt as recordingImportFileNameKey, x as verifyNativeBundleResolutionSignature, xt as recordingImportFileKind, y as verifyBundleResolutionSignature, yt as isRecordingInstantOnOrAfterUnixEpoch, z as ARKME_EXTENSION_FORMAT } from "./persistent-runtime-
|
|
1
|
+
import { $ as ARKME_DEFAULT_SHARE_WEBSITE, A as inspectNativeBundleArtifactV3, At as registerDSHAgentInputRecordSync, D as bundleSha256, Dt as ArkmePluginError, E as arkmeSandboxEntryId, Et as normalizeRecentEmojiIds, F as assertExtensionArtifactSize, Ft as __require, G as validateVoiceprintPcm16Wav, I as canonicalExtensionJson, It as __toCommonJS, J as arkmeRequiredLinkMetadataFallback, K as arkmeExtensionShareRefFromLink, L as sha256Hex, M as packLocalNativeBundleDirectoryV3, Mt as __commonJSMin, N as readNativeBundleTarballV3, Nt as __esmMin, O as canonicalBundleJson, Ot as retryAfterMillis, P as renderArkmeSandboxHostEntry, Pt as __exportAll, Q as parseArkmeRecordReeditAttachments, R as unpackArkmeExtension, S as ARKME_BUNDLE_ARTIFACT_KIND, St as sameRecordingImportIdentity, T as ArkmeBundleArtifactError, Tt as isRecentEmojiId, U as ARKME_EXTENSION_RUNTIME_UNAVAILABLE_MESSAGE, W as ArkmeService, X as arkmeRichBackgroundSound, Y as arkmeFileBackgroundSound, Z as ArkmeRecordReeditDraftConflict, _ as arkmeClientContentDigest, _t as SecretValue, at as ARKME_WORLD_PUBLISH_MAX_IMAGE_BYTES, b as verifyExtensionResolutionSignature, bt as isUnresolvedRecordingImportJob, c as persistentExtensionBundleDirectory, ct as mergeMemberJoinEvents, d as readPersistentExtensionActivation, dt as ARKME_TOOL_FILE_MAX_BYTES, et as ARKME_PROVIDER_CONTRACT_VERSION, f as refreshPersistentClientWrapper, ft as arkmeCanInlineLocalFile, g as activeProfileExtensionOwnerConflicts, gt as ArkmeOutgoingCallError, h as renderArkmeBundleClientBundle, ht as isArkmeBotAvatarRef, i as invokePersistentArkmeExtension, it as ARKME_WORLD_PUBLISH_MAX_IMAGES, j as packBundleFiles, jt as createDesktopLifecycleReader, k as inspectBundleArtifact, kt as recordOwnerId, l as persistentExtensionPackageIdentity, lt as validateMemberUpdate, m as writePersistentExtensionActivation, mt as arkmePickedFileKind, o as persistentArkmeExtensionRuntimeState, ot as applyMemberUpdate, p as repairPersistentExtensionInstallation, pt as arkmeNormalizedFileMimeType, q as arkmeIsGenericLinkMetadataTitle, r as deactivatePersistentArkmeExtension, s as materializePersistentExtensionBundle, st as cachedMemberItem, t as activatePersistentArkmeExtension, u as quarantinePersistentExtension, ut as ARKME_RUNTIME_INSTANCE_ID, v as arkmeClientContentDigestFromSource, vt as ArkmeDirectMessageAdmissionError, w as ARKME_NATIVE_BUNDLE_ARTIFACT_KIND, wt as recordingImportFileNameKey, x as verifyNativeBundleResolutionSignature, xt as recordingImportFileKind, y as verifyBundleResolutionSignature, yt as isRecordingInstantOnOrAfterUnixEpoch, z as ARKME_EXTENSION_FORMAT } from "./persistent-runtime-CBKy5v5l.js";
|
|
2
2
|
import { _ as parsePluginUpdateManifest, b as validatePluginUpdateServiceOrigin, d as writePluginUpdateLifecycleLog, f as PluginUpdateInstallStateStore, g as existingCachedPluginArtifactPath, h as downloadAndCachePluginArtifact, m as PluginUpdateArtifactError, n as buildTargetInstallArgs, o as reconcilePluginUpdaterProfilePolicy, p as ARKME_PLUGIN_PACKAGE_NAME$1, t as assertTargetArtifactIntegrity, u as detachManagedProfilePluginLink, v as pluginUpdateEndpointUrl, y as validatePluginUpdateArtifactOrigin } from "./plugin-updater-helper-y7wzJLOx.js";
|
|
3
3
|
import { a as securePrivateDirectory, c as securePrivateFileSync, i as prepareProfilePackageManager, n as isArkmeProfilePackageName, o as securePrivateDirectorySync, r as localExtensionPnpmArgs, s as securePrivateFile, t as applyArkmeProfileBundlePolicy } from "./profile-bundle-policy-DLXDyohJ.js";
|
|
4
4
|
import { i as invokeArkmeBundle, n as arkmeBundleActive, r as deactivateArkmeBundle } from "./bundle-runtime-CE73h3vS.js";
|
|
@@ -11891,7 +11891,8 @@ async function dispatchArkmeHostOperation(service, operation, params, updateMana
|
|
|
11891
11891
|
case "chat.member.private.open": return await service.openPrivateChatFromMember(stringParam(params, "sourceRef"), stringParam(params, "memberRef"), requestSignal === void 0 ? {} : { signal: requestSignal });
|
|
11892
11892
|
case "files.capabilities": return service.fileCapabilities();
|
|
11893
11893
|
case "files.local.list": return await service.fileList();
|
|
11894
|
-
case "files.local.open": return await service.
|
|
11894
|
+
case "files.local.open-folder": return await service.fileOpenLocalFolder(stringParam(params, "fileRef"), requestSignal);
|
|
11895
|
+
case "files.local.open": return await service.fileOpenLocal(stringParam(params, "fileRef"), requestSignal);
|
|
11895
11896
|
case "files.local.remove":
|
|
11896
11897
|
await service.fileRemove(stringParam(params, "fileRef"));
|
|
11897
11898
|
return { removed: true };
|
|
@@ -12026,6 +12027,9 @@ async function dispatchArkmeHostOperation(service, operation, params, updateMana
|
|
|
12026
12027
|
}
|
|
12027
12028
|
});
|
|
12028
12029
|
}
|
|
12030
|
+
case "calls.invite.create": return await service.createShareCallLink(outgoingMediaTypeParam(params));
|
|
12031
|
+
case "calls.receiver.prepare": return await service.prepareCallReceiver();
|
|
12032
|
+
case "calls.receiver.claim": return await service.claimIncomingCall(requiredCallParam(params, "callRequestId", "call-request-invalid"));
|
|
12029
12033
|
case "calls.outgoing.prepare": return await service.prepareOutgoingCall({
|
|
12030
12034
|
sourceRef: requiredCallParam(params, "sourceRef", "call-source-invalid", 4096),
|
|
12031
12035
|
mediaType: outgoingMediaTypeParam(params),
|
|
@@ -12256,6 +12260,25 @@ async function openDshHostPath(ctx, path, signal) {
|
|
|
12256
12260
|
if (response.result.ok !== true || !isRecord(response.result.value) || response.result.value.opened !== true) throw new Error("DSH apiProxy.host.openPath 返回了无效响应");
|
|
12257
12261
|
}
|
|
12258
12262
|
//#endregion
|
|
12263
|
+
//#region src/harness-session-restore-script.ts
|
|
12264
|
+
/**
|
|
12265
|
+
* The outer runtime and native iframe share an origin, but own different stores.
|
|
12266
|
+
* An outer pending-list projection can overwrite the native boot key with {}.
|
|
12267
|
+
* Route only this iframe's official selection read to the parent preload cache;
|
|
12268
|
+
* do not change other keys, sessionStorage, writes, or the upstream runtime.
|
|
12269
|
+
* This must precede every boot script, including asynchronously loaded modules.
|
|
12270
|
+
*/
|
|
12271
|
+
const HARNESS_SESSION_RESTORE_SCRIPT = `(() => {
|
|
12272
|
+
const bridge = window.parent?.arkmeDesktop?.sessionSelection;
|
|
12273
|
+
if (typeof bridge?.restore !== 'function') return;
|
|
12274
|
+
const storage = window.localStorage;
|
|
12275
|
+
const getItem = Storage.prototype.getItem;
|
|
12276
|
+
Storage.prototype.getItem = function(key) {
|
|
12277
|
+
if (this === storage && key === 'dsh.sessions.current') return bridge.restore();
|
|
12278
|
+
return getItem.call(this, key);
|
|
12279
|
+
};
|
|
12280
|
+
})();`;
|
|
12281
|
+
//#endregion
|
|
12259
12282
|
//#region src/harness-embed-route.ts
|
|
12260
12283
|
const ARKME_PLUGIN_PACKAGE_NAME = "@senguoyun/dsh-arkme";
|
|
12261
12284
|
const DSH_CLIENT_HMR_PACKAGE_NAME = "@deepseek-ai/dsh-client-hmr";
|
|
@@ -12464,6 +12487,10 @@ function createHarnessEmbedRouteHandler(options) {
|
|
|
12464
12487
|
projectedGraph.rev = shortHash(`${projectedGraph.rev}:${rev}`);
|
|
12465
12488
|
}
|
|
12466
12489
|
let html = replaceHarnessBootGraph(await options.readRootHtml(request), fullGraph, projectedGraph);
|
|
12490
|
+
if (options.sessionClient !== void 0) {
|
|
12491
|
+
if (!/<head(?:\s[^>]*)?>/i.test(html)) throw new Error("harness session restore requires a document head");
|
|
12492
|
+
html = html.replace(/<head(?:\s[^>]*)?>/i, (head) => `${head}<script data-arkme-session-restore>${HARNESS_SESSION_RESTORE_SCRIPT}<\/script>`);
|
|
12493
|
+
}
|
|
12467
12494
|
if (options.selectionClientRevision && /^[a-f0-9]+$/.test(options.selectionClientRevision)) html = html.replace("</head>", `<meta name="arkme-native-selection" content="/arkme-self/harness-native-selection-client.js?rev=${options.selectionClientRevision}"></head>`);
|
|
12468
12495
|
if (options.sessionClient?.apiPath !== void 0) {
|
|
12469
12496
|
const apiPath = options.sessionClient.apiPath;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as persistentArkmeExtensionActive, i as invokePersistentArkmeExtension, n as applyPersistentArkmeHostExtension, o as persistentArkmeExtensionRuntimeState, r as deactivatePersistentArkmeExtension, t as activatePersistentArkmeExtension } from "./persistent-runtime-
|
|
1
|
+
import { a as persistentArkmeExtensionActive, i as invokePersistentArkmeExtension, n as applyPersistentArkmeHostExtension, o as persistentArkmeExtensionRuntimeState, r as deactivatePersistentArkmeExtension, t as activatePersistentArkmeExtension } from "./persistent-runtime-CBKy5v5l.js";
|
|
2
2
|
export { activatePersistentArkmeExtension, applyPersistentArkmeHostExtension, deactivatePersistentArkmeExtension, invokePersistentArkmeExtension, persistentArkmeExtensionActive, persistentArkmeExtensionRuntimeState };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
3
3
|
import { chmodSync, constants, createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
4
|
-
import { chmod as chmod$1, copyFile,
|
|
4
|
+
import { chmod as chmod$1, copyFile, lstat, mkdir, open, opendir, readFile, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
5
5
|
import { createCipheriv, createDecipheriv, createHash, createHmac, createPublicKey, randomBytes, randomUUID, timingSafeEqual, verify } from "node:crypto";
|
|
6
6
|
import minpath, { basename, dirname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
7
7
|
import { fileURLToPath, fileURLToPath as urlToPath } from "node:url";
|
|
@@ -17146,7 +17146,7 @@ function formatLinkAsAutolink(node, state) {
|
|
|
17146
17146
|
* @import {Link, Parents} from 'mdast'
|
|
17147
17147
|
* @import {Exit} from '../types.js'
|
|
17148
17148
|
*/
|
|
17149
|
-
link
|
|
17149
|
+
link.peek = linkPeek;
|
|
17150
17150
|
/**
|
|
17151
17151
|
* @param {Link} node
|
|
17152
17152
|
* @param {Parents | undefined} _
|
|
@@ -17154,7 +17154,7 @@ link$1.peek = linkPeek;
|
|
|
17154
17154
|
* @param {Info} info
|
|
17155
17155
|
* @returns {string}
|
|
17156
17156
|
*/
|
|
17157
|
-
function link
|
|
17157
|
+
function link(node, _, state, info) {
|
|
17158
17158
|
const quote = checkQuote(state);
|
|
17159
17159
|
const suffix = quote === "\"" ? "Quote" : "Apostrophe";
|
|
17160
17160
|
const tracker = state.createTracker(info);
|
|
@@ -17623,7 +17623,7 @@ const handle = {
|
|
|
17623
17623
|
image,
|
|
17624
17624
|
imageReference,
|
|
17625
17625
|
inlineCode,
|
|
17626
|
-
link
|
|
17626
|
+
link,
|
|
17627
17627
|
linkReference,
|
|
17628
17628
|
list: list$1,
|
|
17629
17629
|
listItem,
|
|
@@ -39129,8 +39129,23 @@ var CallHistoryService = class {
|
|
|
39129
39129
|
cacheMs: 2e3,
|
|
39130
39130
|
failureCooldownMs: 2e3
|
|
39131
39131
|
});
|
|
39132
|
-
const
|
|
39132
|
+
const rawItems = this.historyItems(raw);
|
|
39133
|
+
const items = await Promise.all(rawItems.map(async (item) => await this.normalizeHistoryItem(item, session.userId)));
|
|
39134
|
+
const validItems = items.filter((item) => item !== void 0);
|
|
39133
39135
|
await this.attachPeerPresentation(validItems, session, signal);
|
|
39136
|
+
items.forEach((item, index) => {
|
|
39137
|
+
if (item === void 0) return;
|
|
39138
|
+
const source = rawItems[index];
|
|
39139
|
+
const record = {
|
|
39140
|
+
...source,
|
|
39141
|
+
...objectValue$2(source.trtc ?? source.call ?? source.call_record)
|
|
39142
|
+
};
|
|
39143
|
+
const names = /* @__PURE__ */ new Map();
|
|
39144
|
+
for (const [id, name] of Object.entries(objectValue$2(record.participant_display_names ?? record.participantDisplayNames))) if (Number(id) > 0 && typeof name === "string" && name.trim()) names.set(Number(id), name.trim());
|
|
39145
|
+
if (item.peerUserId !== void 0 && !/^Arkme 用户 \d+$/.test(item.peerDisplayName)) names.set(item.peerUserId, item.peerDisplayName);
|
|
39146
|
+
const summary = safeSummary(renderCallRecordSummary(record, session.userId, names));
|
|
39147
|
+
if (summary) item.summaryPreview = summary;
|
|
39148
|
+
});
|
|
39134
39149
|
const hasMore = booleanValue$9(raw.has_more ?? raw.hasMore);
|
|
39135
39150
|
const nextCursor = firstString$1(raw, [
|
|
39136
39151
|
"next_cursor",
|
|
@@ -39255,13 +39270,6 @@ var CallHistoryService = class {
|
|
|
39255
39270
|
const calleeUserIds = numberList(item.callee_user_ids ?? item.calleeUserIds);
|
|
39256
39271
|
const connectedUserIds = numberList(item.connected_user_ids ?? item.connectedUserIds);
|
|
39257
39272
|
const peerUserId = this.resolvePeerUserId(viewerUserId, callerUserId, calleeUserIds, connectedUserIds, item);
|
|
39258
|
-
const summaryText = safeSummary(firstString$1(item, [
|
|
39259
|
-
"call_summary",
|
|
39260
|
-
"callSummary",
|
|
39261
|
-
"summary_text",
|
|
39262
|
-
"summaryText",
|
|
39263
|
-
"summary"
|
|
39264
|
-
]));
|
|
39265
39273
|
const summaryUpdatedAtMillis = firstEpochMillis(item, [
|
|
39266
39274
|
"call_summary_updated_at",
|
|
39267
39275
|
"callSummaryUpdatedAt",
|
|
@@ -39305,7 +39313,6 @@ var CallHistoryService = class {
|
|
|
39305
39313
|
"summary_status",
|
|
39306
39314
|
"summaryStatus"
|
|
39307
39315
|
])),
|
|
39308
|
-
...summaryText === "" ? {} : { summaryPreview: summaryText },
|
|
39309
39316
|
...summaryUpdatedAtMillis > 0 ? { summaryUpdatedAtMillis } : {},
|
|
39310
39317
|
canOpenDetail: true,
|
|
39311
39318
|
canRedial: peerUserId > 0,
|
|
@@ -47909,6 +47916,8 @@ var ChatService = class {
|
|
|
47909
47916
|
textContent,
|
|
47910
47917
|
textFormat,
|
|
47911
47918
|
sourceType,
|
|
47919
|
+
templateKind: numberValue$19(item.template_kind ?? item.templateKind),
|
|
47920
|
+
displayKind: numberValue$19(item.display_kind ?? item.displayKind),
|
|
47912
47921
|
...contentBlocks.length === 0 ? {} : { contentBlocks },
|
|
47913
47922
|
...files.length > contentBlocks.length ? { mediaUnavailable: true } : {},
|
|
47914
47923
|
...segments.length === 0 ? {} : { segments },
|
|
@@ -82222,6 +82231,54 @@ var OutgoingCallService = class {
|
|
|
82222
82231
|
callDiag("dispose", {});
|
|
82223
82232
|
this.broker.dispose();
|
|
82224
82233
|
}
|
|
82234
|
+
async createShareCallLink(mediaType) {
|
|
82235
|
+
if (mediaType !== "audio" && mediaType !== "video") throw new ArkmePluginError("call-media-invalid", "通话类型无效", false, 400);
|
|
82236
|
+
const session = await this.runtime.requireSession();
|
|
82237
|
+
const data = await this.runtime.authenticatedWebrtcPost("/api/v1/trtc/share-call-link/create", { call_media_type: mediaType === "video" ? 1 : 0 }, session);
|
|
82238
|
+
const current = await this.runtime.accountScopedSession();
|
|
82239
|
+
if (current?.userId !== session.userId || current.refreshToken !== session.refreshToken) throw new ArkmePluginError("call-account-changed", "登录账号已变化,请重试", false, 409);
|
|
82240
|
+
const profile = objectValue$2(data.sharer_profile);
|
|
82241
|
+
let url;
|
|
82242
|
+
try {
|
|
82243
|
+
url = new URL(stringValue$2(data.call_url), this.runtime.config.webrtcBaseUrl);
|
|
82244
|
+
} catch {
|
|
82245
|
+
throw new ArkmePluginError("call-link-invalid", "通话邀请链接无效,请重试", true, 502);
|
|
82246
|
+
}
|
|
82247
|
+
if (url.origin !== new URL(this.runtime.config.webrtcBaseUrl).origin || url.protocol !== "https:" || url.pathname !== "/share-call" || !url.searchParams.get("token")?.trim() || url.username || url.password || numberValue$9(data.expires_at) <= Date.now() || data.call_media_type !== (mediaType === "video" ? 1 : 0) || numberValue$9(profile.user_id) !== session.userId) throw new ArkmePluginError("call-link-invalid", "通话邀请链接无效,请重试", true, 502);
|
|
82248
|
+
return {
|
|
82249
|
+
callUrl: url.href,
|
|
82250
|
+
expiresAtMillis: numberValue$9(data.expires_at),
|
|
82251
|
+
mediaType,
|
|
82252
|
+
sharerDisplayName: stringValue$2(profile.display_name).trim() || "Arkme 用户"
|
|
82253
|
+
};
|
|
82254
|
+
}
|
|
82255
|
+
async prepareCallReceiver() {
|
|
82256
|
+
const session = await this.runtime.requireSession();
|
|
82257
|
+
const profile = (await this.profile.refreshProfile()).profile;
|
|
82258
|
+
if (profile === null) throw new ArkmePluginError("profile-contract-invalid", "无法读取当前账号资料", true, 502);
|
|
82259
|
+
const credentials = await this.runtime.authenticatedWebrtcPost("/api/v1/trtc/credentials", {}, session);
|
|
82260
|
+
const current = await this.runtime.accountScopedSession();
|
|
82261
|
+
if (current?.userId !== session.userId || current.refreshToken !== session.refreshToken) throw new ArkmePluginError("call-account-changed", "登录账号已变化,请重试", false, 409);
|
|
82262
|
+
const sdkAppId = numberValue$9(credentials.sdk_app_id);
|
|
82263
|
+
const userId = stringValue$2(credentials.user_id).trim();
|
|
82264
|
+
const userSig = stringValue$2(credentials.user_sig).trim();
|
|
82265
|
+
if (!Number.isSafeInteger(sdkAppId) || sdkAppId <= 0 || userId === "" || userSig === "") throw new ArkmePluginError("call-credentials-invalid", "桌面通话初始化失败", true, 502);
|
|
82266
|
+
return {
|
|
82267
|
+
accountUserId: session.userId,
|
|
82268
|
+
bootstrap: {
|
|
82269
|
+
sdkAppId,
|
|
82270
|
+
userId,
|
|
82271
|
+
userSig,
|
|
82272
|
+
nickName: profile.displayName.trim() || "Arkme 用户",
|
|
82273
|
+
avatar: "",
|
|
82274
|
+
outgoingOnly: false
|
|
82275
|
+
}
|
|
82276
|
+
};
|
|
82277
|
+
}
|
|
82278
|
+
async claimIncomingCall(callRequestId) {
|
|
82279
|
+
const session = await this.runtime.requireSession();
|
|
82280
|
+
return { expiresAtMillis: this.broker.acquireLease(session.userId, callRequestId) };
|
|
82281
|
+
}
|
|
82225
82282
|
async requestOutgoingCall(sourceRef, mediaType, signal) {
|
|
82226
82283
|
const session = await this.runtime.requireSession();
|
|
82227
82284
|
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
@@ -86659,17 +86716,21 @@ var FileTransfers = class {
|
|
|
86659
86716
|
recursive: true,
|
|
86660
86717
|
mode: 448
|
|
86661
86718
|
});
|
|
86719
|
+
const sourceInfo = await stat(source);
|
|
86720
|
+
const targetInfo = await lstat(target).catch((error) => {
|
|
86721
|
+
if (error.code === "ENOENT") return void 0;
|
|
86722
|
+
throw error;
|
|
86723
|
+
});
|
|
86724
|
+
if (targetInfo !== void 0 && !targetInfo.isFile()) throw fail("file-open-target-invalid", "本地打开副本不是普通文件");
|
|
86725
|
+
if (targetInfo !== void 0 && (targetInfo.dev !== sourceInfo.dev || targetInfo.ino !== sourceInfo.ino)) return target;
|
|
86726
|
+
const temporary = join(directory, `${randomUUID()}.tmp`);
|
|
86662
86727
|
try {
|
|
86663
|
-
await
|
|
86664
|
-
|
|
86665
|
-
|
|
86666
|
-
|
|
86667
|
-
|
|
86668
|
-
await unlink(target).catch(() => {});
|
|
86669
|
-
await link(source, target);
|
|
86670
|
-
}
|
|
86728
|
+
await copyFile(source, temporary, constants.COPYFILE_FICLONE);
|
|
86729
|
+
await chmod$1(temporary, 384);
|
|
86730
|
+
await rename(temporary, target);
|
|
86731
|
+
} finally {
|
|
86732
|
+
await unlink(temporary).catch(() => {});
|
|
86671
86733
|
}
|
|
86672
|
-
await chmod$1(target, 384);
|
|
86673
86734
|
return target;
|
|
86674
86735
|
}
|
|
86675
86736
|
async assertUser(userId, signal) {
|
|
@@ -86834,25 +86895,40 @@ var FileTransfers = class {
|
|
|
86834
86895
|
file: publicFile(file)
|
|
86835
86896
|
};
|
|
86836
86897
|
}
|
|
86837
|
-
async openLocal(ref) {
|
|
86838
|
-
|
|
86898
|
+
async openLocal(ref, signal) {
|
|
86899
|
+
return {
|
|
86900
|
+
opened: true,
|
|
86901
|
+
file: await this.openLocalTarget(ref, "file", signal)
|
|
86902
|
+
};
|
|
86903
|
+
}
|
|
86904
|
+
async openLocalFolder(ref, signal) {
|
|
86905
|
+
await this.openLocalTarget(ref, "folder", signal);
|
|
86906
|
+
return { folderOpened: true };
|
|
86907
|
+
}
|
|
86908
|
+
async openLocalTarget(ref, target, signal) {
|
|
86909
|
+
if (this.ports.openPath === void 0) throw fail("file-open-unavailable", target === "folder" ? "当前宿主不能打开本机文件夹" : "当前宿主不能使用本机应用打开文件");
|
|
86839
86910
|
const controller = new AbortController();
|
|
86840
86911
|
this.controllers.add(controller);
|
|
86912
|
+
const operationSignal = signal === void 0 ? controller.signal : AbortSignal.any([signal, controller.signal]);
|
|
86841
86913
|
try {
|
|
86914
|
+
operationSignal.throwIfAborted();
|
|
86842
86915
|
const userId = await this.ports.currentUser();
|
|
86843
|
-
const { file } = await this.
|
|
86844
|
-
|
|
86845
|
-
|
|
86846
|
-
|
|
86847
|
-
|
|
86848
|
-
|
|
86849
|
-
|
|
86850
|
-
|
|
86851
|
-
|
|
86852
|
-
|
|
86916
|
+
const { file, path } = await this.exclusive(async () => {
|
|
86917
|
+
await this.assertUser(userId, operationSignal);
|
|
86918
|
+
const { file } = await this.readLocal(ref);
|
|
86919
|
+
await this.assertUser(userId, operationSignal);
|
|
86920
|
+
return {
|
|
86921
|
+
file,
|
|
86922
|
+
path: await this.nativeOpenPath(userId, ref, file)
|
|
86923
|
+
};
|
|
86924
|
+
});
|
|
86925
|
+
await this.assertUser(userId, operationSignal);
|
|
86926
|
+
await this.ports.openPath(target === "folder" ? dirname(path) : path, operationSignal);
|
|
86927
|
+
await this.assertUser(userId, operationSignal);
|
|
86928
|
+
return file;
|
|
86853
86929
|
} catch (error) {
|
|
86854
86930
|
if (error instanceof ArkmePluginError) throw error;
|
|
86855
|
-
throw fail("file-open-failed", "文件打开失败,请重试");
|
|
86931
|
+
throw target === "folder" ? fail("file-folder-open-failed", "文件夹打开失败,请重试") : fail("file-open-failed", "文件打开失败,请重试");
|
|
86856
86932
|
} finally {
|
|
86857
86933
|
this.controllers.delete(controller);
|
|
86858
86934
|
}
|
|
@@ -90353,8 +90429,11 @@ var ArkmeService = class {
|
|
|
90353
90429
|
attachLocalFileOpener(openPath) {
|
|
90354
90430
|
this.localFileOpener = openPath;
|
|
90355
90431
|
}
|
|
90356
|
-
async fileOpenLocal(ref) {
|
|
90357
|
-
return await this.filesOwner().openLocal(ref);
|
|
90432
|
+
async fileOpenLocal(ref, signal) {
|
|
90433
|
+
return await this.filesOwner().openLocal(ref, signal);
|
|
90434
|
+
}
|
|
90435
|
+
async fileOpenLocalFolder(ref, signal) {
|
|
90436
|
+
return await this.filesOwner().openLocalFolder(ref, signal);
|
|
90358
90437
|
}
|
|
90359
90438
|
async fileRemove(ref) {
|
|
90360
90439
|
await this.filesOwner().remove(ref);
|
|
@@ -90649,6 +90728,15 @@ var ArkmeService = class {
|
|
|
90649
90728
|
async prepareOutgoingCall(input) {
|
|
90650
90729
|
return await this.outgoingCall.prepareOutgoingCall(input);
|
|
90651
90730
|
}
|
|
90731
|
+
async createShareCallLink(mediaType) {
|
|
90732
|
+
return await this.outgoingCall.createShareCallLink(mediaType);
|
|
90733
|
+
}
|
|
90734
|
+
async prepareCallReceiver() {
|
|
90735
|
+
return await this.outgoingCall.prepareCallReceiver();
|
|
90736
|
+
}
|
|
90737
|
+
async claimIncomingCall(callRequestId) {
|
|
90738
|
+
return await this.outgoingCall.claimIncomingCall(callRequestId);
|
|
90739
|
+
}
|
|
90652
90740
|
async heartbeatOutgoingCall(callRequestId) {
|
|
90653
90741
|
return await this.outgoingCall.heartbeatOutgoingCall(callRequestId);
|
|
90654
90742
|
}
|
package/lib/sdk.js
CHANGED
|
@@ -1150,6 +1150,9 @@ var ArkmeSdk = class {
|
|
|
1150
1150
|
async localFiles(signal) {
|
|
1151
1151
|
return this.call("files.local.list", void 0, signal);
|
|
1152
1152
|
}
|
|
1153
|
+
async openLocalFileFolder(fileRef, signal) {
|
|
1154
|
+
return this.call("files.local.open-folder", { fileRef }, signal);
|
|
1155
|
+
}
|
|
1153
1156
|
async openLocalFile(fileRef, signal) {
|
|
1154
1157
|
return this.call("files.local.open", { fileRef }, signal);
|
|
1155
1158
|
}
|
|
@@ -100,7 +100,10 @@ export declare class ArkmeService {
|
|
|
100
100
|
file: ArkmeLocalFile;
|
|
101
101
|
}>;
|
|
102
102
|
attachLocalFileOpener(openPath: (path: string, signal: AbortSignal) => Promise<void>): void;
|
|
103
|
-
fileOpenLocal(ref: string): Promise<import("./file-transfer-contract.js").ArkmeFileOpenResult>;
|
|
103
|
+
fileOpenLocal(ref: string, signal?: AbortSignal): Promise<import("./file-transfer-contract.js").ArkmeFileOpenResult>;
|
|
104
|
+
fileOpenLocalFolder(ref: string, signal?: AbortSignal): Promise<{
|
|
105
|
+
folderOpened: true;
|
|
106
|
+
}>;
|
|
104
107
|
fileRemove(ref: string): Promise<void>;
|
|
105
108
|
fileSend(input: ArkmeFileSendInput): Promise<import("./file-transfer-contract.js").ArkmeFileSendTask>;
|
|
106
109
|
fileSendTasks(sourceRef?: string): Promise<import("./file-transfer-contract.js").ArkmeFileSendTask[]>;
|
|
@@ -203,6 +206,11 @@ export declare class ArkmeService {
|
|
|
203
206
|
callRequestId: string;
|
|
204
207
|
signal?: AbortSignal;
|
|
205
208
|
}): Promise<ArkmeOutgoingCallPrepareResult>;
|
|
209
|
+
createShareCallLink(mediaType: ArkmeOutgoingCallMediaType): Promise<import("./outgoing-call-contract.js").ArkmeShareCallLink>;
|
|
210
|
+
prepareCallReceiver(): Promise<import("./outgoing-call-contract.js").ArkmeCallReceiverPrepareResult>;
|
|
211
|
+
claimIncomingCall(callRequestId: string): Promise<{
|
|
212
|
+
expiresAtMillis: number;
|
|
213
|
+
}>;
|
|
206
214
|
heartbeatOutgoingCall(callRequestId: string): Promise<{
|
|
207
215
|
expiresAtMillis: number;
|
|
208
216
|
}>;
|