@olares/lares-core 0.15.34 → 0.15.36
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/i18n/mobile.js +7 -3
- package/larepass/approval.js +43 -0
- package/larepass/mux.js +20 -6
- package/package.json +2 -1
package/i18n/mobile.js
CHANGED
|
@@ -42,8 +42,9 @@ export const ZH = {
|
|
|
42
42
|
"goal.pause": "暂停目标",
|
|
43
43
|
"goal.resume": "继续目标",
|
|
44
44
|
"goal.clear": "清除目标",
|
|
45
|
-
"approval.waiting": "
|
|
46
|
-
"approval.
|
|
45
|
+
"approval.waiting": "等待审批",
|
|
46
|
+
"approval.detail": "审批详情",
|
|
47
|
+
"approval.escalation": "工具 {toolName} 请求越权执行",
|
|
47
48
|
"approval.reject": "拒绝",
|
|
48
49
|
"approval.allowOnce": "允许一次",
|
|
49
50
|
"question.waiting": "需要你的选择",
|
|
@@ -175,6 +176,7 @@ export const ZH = {
|
|
|
175
176
|
"desktop.manual": "手动排序",
|
|
176
177
|
"desktop.commands": "命令",
|
|
177
178
|
"desktop.noCommands": "这个会话没有可用命令",
|
|
179
|
+
"permission.title": "权限",
|
|
178
180
|
// Preset keys arrive from the host as kebab ids; the words live here.
|
|
179
181
|
"permission.read-only": "只读",
|
|
180
182
|
"permission.read-only.hint": "只读文件;写入和风险命令需要确认。",
|
|
@@ -262,7 +264,8 @@ export const EN = {
|
|
|
262
264
|
"goal.resume": "Resume goal",
|
|
263
265
|
"goal.clear": "Clear goal",
|
|
264
266
|
"approval.waiting": "Waiting for approval",
|
|
265
|
-
"approval.
|
|
267
|
+
"approval.detail": "Approval details",
|
|
268
|
+
"approval.escalation": "Tool {toolName} requests privileged execution",
|
|
266
269
|
"approval.reject": "Reject",
|
|
267
270
|
"approval.allowOnce": "Allow once",
|
|
268
271
|
"question.waiting": "Your input is needed",
|
|
@@ -393,6 +396,7 @@ export const EN = {
|
|
|
393
396
|
"desktop.manual": "Manual",
|
|
394
397
|
"desktop.commands": "Commands",
|
|
395
398
|
"desktop.noCommands": "No commands for this session",
|
|
399
|
+
"permission.title": "Permission",
|
|
396
400
|
"permission.read-only": "Read Only",
|
|
397
401
|
"permission.read-only.hint": "Read files only; writes and risky commands require approval.",
|
|
398
402
|
"permission.workspace-write": "Workspace Write",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The approval card dsh shows in the composer: localized reason as the
|
|
3
|
+
* headline, and the correlated tool call's command underneath.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
function commandFromArgs(argsRaw) {
|
|
7
|
+
try {
|
|
8
|
+
const args = JSON.parse(argsRaw ?? "");
|
|
9
|
+
return typeof args?.command === "string" ? args.command : "";
|
|
10
|
+
} catch {
|
|
11
|
+
return "";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function approvalCommand(items, callId) {
|
|
16
|
+
if (!callId) return "";
|
|
17
|
+
const rows = Array.isArray(items) ? items : [];
|
|
18
|
+
for (let index = rows.length - 1; index >= 0; index -= 1) {
|
|
19
|
+
const row = rows[index];
|
|
20
|
+
if (row?.type === "tool" && row.callId === callId) return commandFromArgs(row.argsRaw);
|
|
21
|
+
}
|
|
22
|
+
return "";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function localizedReason(displayReason, locale) {
|
|
26
|
+
if (typeof displayReason === "string") return displayReason;
|
|
27
|
+
if (!displayReason || typeof displayReason !== "object") return "";
|
|
28
|
+
const lang = String(locale ?? "en").toLowerCase().startsWith("zh") ? "zh" : "en";
|
|
29
|
+
const text = displayReason[lang] ?? displayReason.en;
|
|
30
|
+
return typeof text === "string" ? text : "";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function presentApproval(approval, items = [], locale = "en") {
|
|
34
|
+
if (!approval) return null;
|
|
35
|
+
const localized = localizedReason(approval.displayReason, locale);
|
|
36
|
+
const reason = localized || (typeof approval.reason === "string" ? approval.reason : "");
|
|
37
|
+
return {
|
|
38
|
+
toolName: typeof approval.toolName === "string" ? approval.toolName : "",
|
|
39
|
+
callId: approval.callId,
|
|
40
|
+
reason,
|
|
41
|
+
command: approvalCommand(items, approval.callId),
|
|
42
|
+
};
|
|
43
|
+
}
|
package/larepass/mux.js
CHANGED
|
@@ -40,6 +40,24 @@ export function remoteEventsOpen(streamId) {
|
|
|
40
40
|
return remoteStreamOpen(streamId, "$events");
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/** String audit reason plus the localized display copy, when the host sent one. */
|
|
44
|
+
function approvalFields(source) {
|
|
45
|
+
const displayReason = source?.displayReason && typeof source.displayReason === "object"
|
|
46
|
+
? source.displayReason
|
|
47
|
+
: null;
|
|
48
|
+
const reason = typeof source?.reason === "string"
|
|
49
|
+
? source.reason
|
|
50
|
+
: typeof source?.displayReason === "string"
|
|
51
|
+
? source.displayReason
|
|
52
|
+
: "";
|
|
53
|
+
return {
|
|
54
|
+
toolName: source?.toolName,
|
|
55
|
+
callId: source?.callId,
|
|
56
|
+
reason,
|
|
57
|
+
...(displayReason ? { displayReason } : {}),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
43
61
|
/**
|
|
44
62
|
* One `$events` item. A waterfall this client does not answer passes as
|
|
45
63
|
* `next` so the Host is not left waiting on it; `agentId` is the session.
|
|
@@ -69,9 +87,7 @@ export function classifyRemoteEvent(value) {
|
|
|
69
87
|
kind: "approval",
|
|
70
88
|
eventId: value.eventId,
|
|
71
89
|
sessionId,
|
|
72
|
-
|
|
73
|
-
callId: request.callId,
|
|
74
|
-
reason: request.displayReason ?? request.reason,
|
|
90
|
+
...approvalFields(request),
|
|
75
91
|
};
|
|
76
92
|
}
|
|
77
93
|
return { kind: "pass", eventId: value.eventId };
|
|
@@ -305,9 +321,7 @@ export function classifyMuxEnvelope(envelope) {
|
|
|
305
321
|
sessionId,
|
|
306
322
|
rpcId,
|
|
307
323
|
approvalId: frame.approvalId,
|
|
308
|
-
|
|
309
|
-
callId: frame.callId,
|
|
310
|
-
reason: frame.reason,
|
|
324
|
+
...approvalFields(frame),
|
|
311
325
|
};
|
|
312
326
|
}
|
|
313
327
|
if (frame.type === "approval/resolved") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olares/lares-core",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.36",
|
|
4
4
|
"description": "Lares 共享业务核心:Router、workspace、文件/媒体、Olares 身份(无 UI、无平台壳)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -174,6 +174,7 @@
|
|
|
174
174
|
"./larepass/permissions": "./larepass/permissions.js",
|
|
175
175
|
"./larepass/commands": "./larepass/commands.js",
|
|
176
176
|
"./larepass/queue": "./larepass/queue.js",
|
|
177
|
+
"./larepass/approval": "./larepass/approval.js",
|
|
177
178
|
"./larepass/references": "./larepass/references.js",
|
|
178
179
|
"./larepass/submission-settings": "./larepass/submission-settings.js",
|
|
179
180
|
"./larepass/turn-metrics": "./larepass/turn-metrics.js",
|