@dsh-workbench/shared 0.1.9 → 0.1.11
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/api/blocker-table.js +10 -0
- package/dist/api/dsh-client.d.ts +26 -3
- package/dist/api/dsh.d.ts +10 -0
- package/dist/api/workbench-contract.d.ts +1 -1
- package/dist/components/ApprovalDetail.js +6 -2
- package/dist/components/CardBoundary.d.ts +21 -0
- package/dist/components/CardBoundary.js +34 -0
- package/dist/host/tool-approval.d.ts +10 -1
- package/dist/host/tool-approval.js +24 -169
- package/dist/host/unit-face.d.ts +2 -1
- package/dist/host/unit-libs.d.ts +1 -1
- package/dist/i18n/en.js +20 -0
- package/dist/i18n/index.d.ts +21 -1
- package/dist/i18n/merge.d.ts +9 -0
- package/dist/i18n/merge.js +22 -0
- package/dist/i18n/zh.d.ts +20 -0
- package/dist/i18n/zh.js +20 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/react.d.ts +1 -0
- package/dist/lib/react.js +1 -0
- package/package.json +1 -1
- package/src/api/__tests__/blocker-table.test.ts +13 -0
- package/src/api/blocker-table.ts +11 -0
- package/src/api/dsh-client.ts +27 -1
- package/src/api/dsh.ts +5 -0
- package/src/api/workbench-contract.ts +1 -1
- package/src/components/ApprovalDetail.tsx +9 -1
- package/src/components/CardBoundary.tsx +56 -0
- package/src/host/tool-approval.ts +41 -187
- package/src/host/unit-face.ts +2 -1
- package/src/host/unit-libs.ts +1 -1
- package/src/i18n/en.ts +20 -0
- package/src/i18n/merge.test.ts +62 -1
- package/src/i18n/merge.ts +36 -0
- package/src/i18n/zh.ts +20 -0
- package/src/index.ts +1 -0
- package/src/lib/react.ts +2 -0
|
@@ -99,6 +99,16 @@ export function blockerOfCapability(capability, t) {
|
|
|
99
99
|
...(sourceUnknown ? [{ kind: 'open-market', label: t('blocker.market.open'), unit: capability.unit }] : []),
|
|
100
100
|
...(capability.command === undefined || sourceUnknown ? [] : [copyAction(t, capability.command)]),
|
|
101
101
|
];
|
|
102
|
+
if (capability.status === 'failed') {
|
|
103
|
+
return {
|
|
104
|
+
id: 'unit-mount-failed',
|
|
105
|
+
severity: 'block',
|
|
106
|
+
title: t('env.unit.failed'),
|
|
107
|
+
hint: t('env.unit.failedHint'),
|
|
108
|
+
...(capability.detail === undefined ? {} : { detail: capability.detail }),
|
|
109
|
+
actions: [retryAction(t)],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
102
112
|
if (capability.status === 'missing-plugin') {
|
|
103
113
|
return {
|
|
104
114
|
id: 'unit-missing-plugin',
|
package/dist/api/dsh-client.d.ts
CHANGED
|
@@ -99,12 +99,16 @@ export interface DshUiWorkspace {
|
|
|
99
99
|
startSession(workspaceId: string): void;
|
|
100
100
|
pickDirectory(): Promise<string | null>;
|
|
101
101
|
}
|
|
102
|
+
export interface DshWorkspaceWritten {
|
|
103
|
+
readonly workspaceId?: string;
|
|
104
|
+
readonly title?: string;
|
|
105
|
+
}
|
|
102
106
|
export interface DshWorkspaces {
|
|
107
|
+
readonly list: DshObservable<WorkspaceSnapshot>;
|
|
103
108
|
create(request: {
|
|
104
109
|
path: string;
|
|
105
|
-
}): Promise<
|
|
106
|
-
|
|
107
|
-
} | undefined>;
|
|
110
|
+
}): Promise<DshWorkspaceWritten | undefined>;
|
|
111
|
+
rename(workspaceId: string, title: string): Promise<DshWorkspaceWritten>;
|
|
108
112
|
}
|
|
109
113
|
export interface DshReferenceInsert {
|
|
110
114
|
readonly source: string;
|
|
@@ -156,6 +160,12 @@ export interface DshSessionsService {
|
|
|
156
160
|
getSnapshot(): SessionsSnapshot;
|
|
157
161
|
};
|
|
158
162
|
scope(sessionId: string): unknown | undefined;
|
|
163
|
+
create?(request: {
|
|
164
|
+
readonly workspaceId?: string;
|
|
165
|
+
readonly sessionId?: string;
|
|
166
|
+
readonly cwd?: string;
|
|
167
|
+
readonly agentPreset?: string;
|
|
168
|
+
}): Promise<unknown>;
|
|
159
169
|
}
|
|
160
170
|
export interface DshObservable<T> {
|
|
161
171
|
getSnapshot(): T;
|
|
@@ -168,6 +178,18 @@ export interface DshSidebarRight {
|
|
|
168
178
|
openResource(address: string, options?: unknown): void;
|
|
169
179
|
openTab(kind: string, options?: unknown): void;
|
|
170
180
|
}
|
|
181
|
+
export interface DshSessionsRemote {
|
|
182
|
+
create(request: {
|
|
183
|
+
readonly workspaceId?: string;
|
|
184
|
+
readonly cwd?: string;
|
|
185
|
+
readonly agentPreset?: string;
|
|
186
|
+
}): Promise<{
|
|
187
|
+
readonly sessionId: string;
|
|
188
|
+
}>;
|
|
189
|
+
}
|
|
190
|
+
export interface DshClientRemote {
|
|
191
|
+
readonly sessions: DshSessionsRemote;
|
|
192
|
+
}
|
|
171
193
|
export interface DshClientContext {
|
|
172
194
|
get<T = unknown>(name: string): T | undefined;
|
|
173
195
|
provide(name: string, value: unknown): void;
|
|
@@ -178,4 +200,5 @@ export interface DshClientContext {
|
|
|
178
200
|
readonly uiWorkspace: DshUiWorkspace;
|
|
179
201
|
readonly workspaces: DshWorkspaces;
|
|
180
202
|
readonly shortcuts: DshShortcutCatalog;
|
|
203
|
+
readonly remote: DshClientRemote;
|
|
181
204
|
}
|
package/dist/api/dsh.d.ts
CHANGED
|
@@ -91,6 +91,7 @@ export interface DshHostContext {
|
|
|
91
91
|
get<T = unknown>(name: string): T | undefined;
|
|
92
92
|
provide(name: string, value: unknown): () => void;
|
|
93
93
|
effect(effect: () => void | (() => void), label?: string): () => void;
|
|
94
|
+
inject(names: readonly string[], effect: (scoped: DshHostContext) => void): () => void;
|
|
94
95
|
readonly logger?: DshLogger;
|
|
95
96
|
readonly webServer: {
|
|
96
97
|
register(route: DshWebRoute): () => void;
|
|
@@ -128,7 +129,16 @@ export interface DshWorkspaceRegistry {
|
|
|
128
129
|
path?: string;
|
|
129
130
|
title?: string;
|
|
130
131
|
} | undefined;
|
|
132
|
+
resolveByPath(path: string): Promise<{
|
|
133
|
+
readonly id: unknown;
|
|
134
|
+
} | undefined>;
|
|
135
|
+
create(path: string, title?: string): Promise<{
|
|
136
|
+
id?: string;
|
|
137
|
+
path?: string;
|
|
138
|
+
title?: string;
|
|
139
|
+
} | undefined>;
|
|
131
140
|
}
|
|
141
|
+
export type DshHomePath = (relative: string) => string;
|
|
132
142
|
export interface DshToolDefinition {
|
|
133
143
|
name: string;
|
|
134
144
|
description: string;
|
|
@@ -10,7 +10,7 @@ export interface PluginStatePayload {
|
|
|
10
10
|
}
|
|
11
11
|
export interface CapabilityPayload {
|
|
12
12
|
readonly unit: string;
|
|
13
|
-
readonly status: 'ok' | 'missing-commands' | 'missing-plugin' | 'unchecked';
|
|
13
|
+
readonly status: 'ok' | 'failed' | 'missing-commands' | 'missing-plugin' | 'unchecked';
|
|
14
14
|
readonly plugin?: string;
|
|
15
15
|
readonly required: readonly string[];
|
|
16
16
|
readonly missing: readonly string[];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { h } from '../lib/react.js';
|
|
2
2
|
import { CodeBlock } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
|
+
import { CardBoundary } from './CardBoundary.js';
|
|
3
4
|
import './ApprovalDetail.css';
|
|
4
5
|
function callOf(snapshot, callId) {
|
|
5
6
|
if (callId === undefined)
|
|
@@ -29,8 +30,11 @@ export function ApprovalDetail(props) {
|
|
|
29
30
|
const input = { tool: call?.name ?? '', args };
|
|
30
31
|
const command = typeof args.command === 'string' ? args.command : '';
|
|
31
32
|
const owner = (props.units ?? []).find((face) => face.approval?.tools.includes(input.tool) === true);
|
|
32
|
-
if (owner?.approval !== undefined)
|
|
33
|
-
|
|
33
|
+
if (owner?.approval !== undefined) {
|
|
34
|
+
const Render = owner.approval.render;
|
|
35
|
+
return (h(CardBoundary, { unit: owner.manifest.id, resetKey: props.callId ?? '', t: t },
|
|
36
|
+
h(Render, { input: input, t: t })));
|
|
37
|
+
}
|
|
34
38
|
if (command === '')
|
|
35
39
|
return null;
|
|
36
40
|
return (h(CodeBlock, { code: command, className: "wb-approvalCommand", copyLabel: t('blocker.copy'), copiedLabel: t('env.copied') }));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Translate } from '../api/dsh-client.js';
|
|
2
|
+
import type { ReactNode } from '../lib/react.js';
|
|
3
|
+
import { Component } from '../lib/react.js';
|
|
4
|
+
export interface CardBoundaryProps {
|
|
5
|
+
readonly unit: string;
|
|
6
|
+
readonly resetKey: string;
|
|
7
|
+
readonly t: Translate;
|
|
8
|
+
readonly children?: ReactNode | undefined;
|
|
9
|
+
}
|
|
10
|
+
export interface CardBoundaryState {
|
|
11
|
+
readonly reason: string | null;
|
|
12
|
+
}
|
|
13
|
+
export declare function errorReasonOf(error: unknown): string;
|
|
14
|
+
export declare class CardBoundary extends Component<CardBoundaryProps, CardBoundaryState> {
|
|
15
|
+
state: CardBoundaryState;
|
|
16
|
+
static getDerivedStateFromError(error: unknown): CardBoundaryState;
|
|
17
|
+
componentDidCatch(error: unknown): void;
|
|
18
|
+
componentDidUpdate(previous: CardBoundaryProps): void;
|
|
19
|
+
private readonly retry;
|
|
20
|
+
render(): ReactNode;
|
|
21
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Button } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
2
|
+
import { Component, h } from '../lib/react.js';
|
|
3
|
+
import { Note } from './Note.js';
|
|
4
|
+
export function errorReasonOf(error) {
|
|
5
|
+
if (error instanceof Error)
|
|
6
|
+
return error.message;
|
|
7
|
+
return typeof error === 'string' ? error : JSON.stringify(error) ?? String(error);
|
|
8
|
+
}
|
|
9
|
+
export class CardBoundary extends Component {
|
|
10
|
+
state = { reason: null };
|
|
11
|
+
static getDerivedStateFromError(error) {
|
|
12
|
+
return { reason: errorReasonOf(error) };
|
|
13
|
+
}
|
|
14
|
+
componentDidCatch(error) {
|
|
15
|
+
console.error(`[dsh-workbench] 模块 ${this.props.unit} 渲染失败:${errorReasonOf(error)}`, error);
|
|
16
|
+
}
|
|
17
|
+
componentDidUpdate(previous) {
|
|
18
|
+
if (previous.resetKey !== this.props.resetKey && this.state.reason !== null) {
|
|
19
|
+
this.setState({ reason: null });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
retry = () => {
|
|
23
|
+
this.setState({ reason: null });
|
|
24
|
+
};
|
|
25
|
+
render() {
|
|
26
|
+
const { reason } = this.state;
|
|
27
|
+
if (reason === null)
|
|
28
|
+
return this.props.children;
|
|
29
|
+
return (h(Note, { tone: "problem" },
|
|
30
|
+
h("span", null, this.props.t('panels.cardBroken', { unit: this.props.unit, reason })),
|
|
31
|
+
' ',
|
|
32
|
+
h(Button, { type: "button", variant: "outline", size: "sm", onClick: this.retry }, this.props.t('panels.cardRetry'))));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -21,9 +21,18 @@ export interface ApprovalCall {
|
|
|
21
21
|
readonly arguments?: unknown;
|
|
22
22
|
readonly workspace?: string | undefined;
|
|
23
23
|
}
|
|
24
|
+
export type ApprovalVerdict = {
|
|
25
|
+
readonly kind: 'read';
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'ask';
|
|
28
|
+
readonly reason: string;
|
|
29
|
+
readonly question: ApprovalDetail;
|
|
30
|
+
readonly fallback: ApprovalDetail;
|
|
31
|
+
};
|
|
32
|
+
export type ApprovalPolicy = (call: ApprovalCall) => ApprovalVerdict | undefined;
|
|
24
33
|
export interface ApprovalContext {
|
|
25
|
-
readonly titleOf?: ((id: string) => string | undefined) | undefined;
|
|
26
34
|
readonly writes?: boolean | undefined;
|
|
35
|
+
readonly policy?: ApprovalPolicy | undefined;
|
|
27
36
|
readonly detailOf?: ((call: ApprovalCall) => ApprovalFacts | undefined | Promise<ApprovalFacts | undefined>) | undefined;
|
|
28
37
|
}
|
|
29
38
|
export declare function approvalFor(call: ApprovalCall, context?: ApprovalContext): Promise<AskDecision | undefined>;
|
|
@@ -1,190 +1,45 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
return texts.generic;
|
|
4
|
-
return { en: `${detail.en} — ${texts.question.en}`, zh: `${detail.zh} —— ${texts.question.zh}` };
|
|
1
|
+
function messageOf(error) {
|
|
2
|
+
return error instanceof Error ? error.message : String(error);
|
|
5
3
|
}
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const value = raw;
|
|
4
|
+
function compose(detail, verdict) {
|
|
5
|
+
if (detail === undefined || typeof detail.zh !== 'string' || detail.zh.trim() === '') {
|
|
6
|
+
return verdict.fallback;
|
|
7
|
+
}
|
|
11
8
|
return {
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
en: `${detail.en} — ${verdict.question.en}`,
|
|
10
|
+
zh: `${detail.zh} —— ${verdict.question.zh}`,
|
|
14
11
|
};
|
|
15
12
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const UNKNOWN = { kind: 'unknown' };
|
|
19
|
-
function ask(spec) {
|
|
20
|
-
return { kind: 'ask', spec };
|
|
21
|
-
}
|
|
22
|
-
function confirmed(call) {
|
|
23
|
-
const raw = call.arguments;
|
|
24
|
-
if (typeof raw !== 'object' || raw === null)
|
|
13
|
+
export async function approvalFor(call, context = {}) {
|
|
14
|
+
if (context.writes !== true)
|
|
25
15
|
return undefined;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
function effectOf(call, context) {
|
|
30
|
-
const name = call.name ?? '';
|
|
31
|
-
const { action, id } = actionOf(call);
|
|
32
|
-
const readAction = action !== undefined && action !== '' && READ_ONLY_ACTIONS.has(action);
|
|
33
|
-
const what = () => {
|
|
34
|
-
if (id === undefined || id === '')
|
|
35
|
-
return '一个模块';
|
|
36
|
-
return `「${context.titleOf?.(id) ?? id}」`;
|
|
37
|
-
};
|
|
38
|
-
if (name === 'workbench_cmdb_release') {
|
|
39
|
-
if (confirmed(call) !== true)
|
|
40
|
-
return READ;
|
|
41
|
-
return ask({
|
|
42
|
-
reason: 'confirm=true releases a version to a real environment',
|
|
43
|
-
generic: {
|
|
44
|
-
en: 'The agent wants to deploy a version for real (confirm: true) — it deploys on the platform (non-production). Allow?',
|
|
45
|
-
zh: 'agent 想在非生产环境上**真的部署一个版本**(confirm: true)—— 会在平台上部署。允许吗?',
|
|
46
|
-
},
|
|
47
|
-
question: {
|
|
48
|
-
en: 'it deploys on the platform for real (non-production). Allow?',
|
|
49
|
-
zh: '会在平台上真的部署一次(非生产环境)。允许吗?',
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
if (name === 'workbench_coding_issue_comment' || name === 'workbench_coding_issue_transfer') {
|
|
54
|
-
if (confirmed(call) !== true)
|
|
55
|
-
return READ;
|
|
56
|
-
const comment = name === 'workbench_coding_issue_comment';
|
|
57
|
-
return ask({
|
|
58
|
-
reason: comment
|
|
59
|
-
? 'confirm=true posts a comment on the platform'
|
|
60
|
-
: 'confirm=true moves an issue to another status on the platform',
|
|
61
|
-
generic: comment
|
|
62
|
-
? {
|
|
63
|
-
en: 'The agent wants to post a comment on the platform for real (confirm: true) — it writes on the platform. Allow?',
|
|
64
|
-
zh: 'agent 想**真的给一条缺陷加评论**(confirm: true)—— 会写平台数据。允许吗?',
|
|
65
|
-
}
|
|
66
|
-
: {
|
|
67
|
-
en: 'The agent wants to move an issue to another status for real (confirm: true) — it writes on the platform. Allow?',
|
|
68
|
-
zh: 'agent 想**真的把一条缺陷流转到别的状态**(confirm: true)—— 会写平台数据。允许吗?',
|
|
69
|
-
},
|
|
70
|
-
question: comment
|
|
71
|
-
? {
|
|
72
|
-
en: 'it posts that comment on the platform for real. Allow?',
|
|
73
|
-
zh: '会在平台上真的发表这条评论。允许吗?',
|
|
74
|
-
}
|
|
75
|
-
: {
|
|
76
|
-
en: 'it changes that issue status on the platform for real. Allow?',
|
|
77
|
-
zh: '会在平台上真的改这条缺陷的状态。允许吗?',
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
if (name === 'workbench_modules') {
|
|
82
|
-
if (readAction)
|
|
83
|
-
return READ;
|
|
84
|
-
if (action === 'update-dependency') {
|
|
85
|
-
return ask({
|
|
86
|
-
reason: `workbench_modules update-dependency ${id ?? ''} upgrades a shared dependency on this machine`,
|
|
87
|
-
generic: {
|
|
88
|
-
en: `The agent wants to upgrade the shared dependency ${what()} (it changes what is installed on this machine). Allow?`,
|
|
89
|
-
zh: `agent 想升级共用依赖 ${what()}(会改这台机器上装的东西)。允许吗?`,
|
|
90
|
-
},
|
|
91
|
-
question: {
|
|
92
|
-
en: 'it upgrades that shared dependency on this machine. Allow?',
|
|
93
|
-
zh: `会升级共用依赖 ${what()}。允许吗?`,
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
const verb = action === 'install' ? '装' : action === 'uninstall' ? '卸载' : action === 'update' ? '更新' : '装 / 更新 / 卸载';
|
|
98
|
-
return ask({
|
|
99
|
-
reason: `workbench_modules ${action ?? '(unknown action)'} ${id ?? ''} changes plugins on this machine`.trim(),
|
|
100
|
-
generic: {
|
|
101
|
-
en: `The agent wants to ${verb === '装' ? 'install' : verb === '卸载' ? 'remove' : verb === '更新' ? 'update' : 'install/update/remove'} the module ${what()} (it changes plugins on this machine). Allow?`,
|
|
102
|
-
zh: `agent 想${verb}模块 ${what()}(会改这台机器上的插件)。允许吗?`,
|
|
103
|
-
},
|
|
104
|
-
question: {
|
|
105
|
-
en: 'it changes plugins on this machine. Allow?',
|
|
106
|
-
zh: '会改这台机器上的插件。允许吗?',
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
if (name !== 'workbench_panels')
|
|
111
|
-
return UNKNOWN;
|
|
112
|
-
if (readAction)
|
|
113
|
-
return READ;
|
|
114
|
-
if (action === 'hide') {
|
|
115
|
-
return ask({
|
|
116
|
-
reason: 'workbench_panels hide removes a module from the panel',
|
|
117
|
-
generic: {
|
|
118
|
-
en: `The agent wants to remove ${what()} from this project's panel (its agent tools go offline here too). Allow?`,
|
|
119
|
-
zh: `agent 想把 ${what()} 从这个项目的面板上收起来(这个项目里它的 agent 工具也一起下线)。允许吗?`,
|
|
120
|
-
},
|
|
121
|
-
question: {
|
|
122
|
-
en: 'it takes that module off this panel (its agent tools go offline here too). Allow?',
|
|
123
|
-
zh: `${what()}会从这个项目的面板上收起来(这个项目里它的 agent 工具也一起下线)。允许吗?`,
|
|
124
|
-
},
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
if (action === 'move') {
|
|
128
|
-
return ask({
|
|
129
|
-
reason: 'workbench_panels move reorders the panel',
|
|
130
|
-
generic: {
|
|
131
|
-
en: `The agent wants to reorder this project's panel (put ${what()} first). Allow?`,
|
|
132
|
-
zh: `agent 想调整这个项目面板的顺序(把 ${what()} 放前面)。允许吗?`,
|
|
133
|
-
},
|
|
134
|
-
question: {
|
|
135
|
-
en: `it reorders this panel (${what()} goes first). Allow?`,
|
|
136
|
-
zh: `会调整这个项目面板的顺序(${what()}放前面)。允许吗?`,
|
|
137
|
-
},
|
|
138
|
-
});
|
|
16
|
+
let verdict;
|
|
17
|
+
try {
|
|
18
|
+
verdict = context.policy?.(call);
|
|
139
19
|
}
|
|
140
|
-
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
zh: 'agent 想清空这个项目的面板(所有模块在这个项目里都下线)。允许吗?',
|
|
146
|
-
},
|
|
147
|
-
question: {
|
|
148
|
-
en: 'it clears this panel (every module goes offline here). Allow?',
|
|
149
|
-
zh: '会清空这个项目的面板(所有模块在这个项目里都下线)。允许吗?',
|
|
150
|
-
},
|
|
151
|
-
});
|
|
20
|
+
catch (error) {
|
|
21
|
+
return {
|
|
22
|
+
kind: 'deny',
|
|
23
|
+
reason: `问"要不要审批"的时候套件的策略抛了错,已经停下:${messageOf(error)}`,
|
|
24
|
+
};
|
|
152
25
|
}
|
|
153
|
-
|
|
154
|
-
reason: `workbench_panels ${action ?? '(unknown action)'} changes the user's panel`,
|
|
155
|
-
generic: {
|
|
156
|
-
en: `The agent wants to add ${what()} to this project's panel. Allow?`,
|
|
157
|
-
zh: `agent 想把 ${what()} 加到**这个项目**的面板上。允许吗?`,
|
|
158
|
-
},
|
|
159
|
-
question: {
|
|
160
|
-
en: `it adds ${what()} to this project's panel. Allow?`,
|
|
161
|
-
zh: `会把 ${what()} 加到**这个项目**的面板上。允许吗?`,
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
export async function approvalFor(call, context = {}) {
|
|
166
|
-
const effect = effectOf(call, context);
|
|
167
|
-
if (effect.kind === 'read')
|
|
26
|
+
if (verdict?.kind === 'read')
|
|
168
27
|
return undefined;
|
|
169
|
-
if (
|
|
170
|
-
if (context.writes !== true)
|
|
171
|
-
return undefined;
|
|
28
|
+
if (verdict?.kind !== 'ask') {
|
|
172
29
|
return {
|
|
173
30
|
kind: 'deny',
|
|
174
|
-
reason: `${call.name ?? '这把工具'}
|
|
175
|
-
'
|
|
31
|
+
reason: `${call.name ?? '这把工具'} 在清单里声明会写东西,但它的套件没认领这次调用 —— 停下:` +
|
|
32
|
+
'在套件的 needsApproval 里补一条审批(含"这次会发生什么"),别让写静默过去',
|
|
176
33
|
};
|
|
177
34
|
}
|
|
178
|
-
const { spec } = effect;
|
|
179
35
|
let facts;
|
|
180
36
|
try {
|
|
181
37
|
facts = await context.detailOf?.(call);
|
|
182
38
|
}
|
|
183
39
|
catch (error) {
|
|
184
|
-
|
|
185
|
-
return { kind: 'deny', reason: `拿不到"这次会发生什么",已经停下:${why}` };
|
|
40
|
+
return { kind: 'deny', reason: `拿不到"这次会发生什么",已经停下:${messageOf(error)}` };
|
|
186
41
|
}
|
|
187
42
|
if (facts !== undefined && 'blocked' in facts)
|
|
188
43
|
return { kind: 'deny', reason: facts.blocked };
|
|
189
|
-
return { kind: 'ask', reason:
|
|
44
|
+
return { kind: 'ask', reason: verdict.reason, displayReason: compose(facts, verdict) };
|
|
190
45
|
}
|
package/dist/host/unit-face.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { RouteTable } from '../host/http.js';
|
|
|
4
4
|
import type { LongTaskBase, LongTaskHost, LongTaskRegistry } from '../host/long-task.js';
|
|
5
5
|
import type { ProvisionHandler } from '../host/provision.js';
|
|
6
6
|
import type { UnitCapability } from './unit-libs.js';
|
|
7
|
-
import type { ApprovalCall, ApprovalFacts } from '../host/tool-approval.js';
|
|
7
|
+
import type { ApprovalCall, ApprovalFacts, ApprovalPolicy } from '../host/tool-approval.js';
|
|
8
8
|
import type { ValueHandoff } from '../host/value-handoff.js';
|
|
9
9
|
import type { WorkspaceStore } from '../host/workspace-store.js';
|
|
10
10
|
export interface UnitMountDeps {
|
|
@@ -59,6 +59,7 @@ export interface UnitMountResult {
|
|
|
59
59
|
readonly provision?: ProvisionHandler;
|
|
60
60
|
readonly longTasks?: LongTaskRegistry<LongTaskBase> | undefined;
|
|
61
61
|
readonly approvalDetail?: ((call: ApprovalCall) => ApprovalFacts | undefined | Promise<ApprovalFacts | undefined>) | undefined;
|
|
62
|
+
readonly needsApproval?: ApprovalPolicy | undefined;
|
|
62
63
|
}
|
|
63
64
|
export interface UnitHostFace {
|
|
64
65
|
readonly manifest: UnitManifest;
|
package/dist/host/unit-libs.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export interface UnitPluginState {
|
|
|
23
23
|
}
|
|
24
24
|
export interface UnitCapability {
|
|
25
25
|
readonly unit: string;
|
|
26
|
-
readonly status: "ok" | "missing-commands" | "missing-plugin" | "unchecked";
|
|
26
|
+
readonly status: "ok" | "failed" | "missing-commands" | "missing-plugin" | "unchecked";
|
|
27
27
|
readonly plugin?: string;
|
|
28
28
|
readonly required: readonly string[];
|
|
29
29
|
readonly missing: readonly string[];
|
package/dist/i18n/en.js
CHANGED
|
@@ -7,6 +7,20 @@ export const en = {
|
|
|
7
7
|
'project.none': 'No project',
|
|
8
8
|
'project.empty': 'No projects yet. Use “Add project” below.',
|
|
9
9
|
'project.add': 'Add project…',
|
|
10
|
+
'project.search.label': 'Search workspaces',
|
|
11
|
+
'project.search.placeholder': 'Search workspaces (folder / name / path)',
|
|
12
|
+
'project.search.empty': 'No workspace matches “{query}”.',
|
|
13
|
+
'project.rename.row': 'Rename “{name}”',
|
|
14
|
+
'project.rename.current': 'Give this workspace a display name…',
|
|
15
|
+
'project.rename.title': 'Give “{name}” a display name',
|
|
16
|
+
'project.rename.description': 'Shown after the folder name. It renames the workspace itself.',
|
|
17
|
+
'project.rename.field': 'Display name',
|
|
18
|
+
'project.rename.placeholder': 'e.g. Workbench shell',
|
|
19
|
+
'project.rename.hint': 'Empty = folder name only',
|
|
20
|
+
'project.rename.save': 'Save',
|
|
21
|
+
'project.rename.saving': 'Saving…',
|
|
22
|
+
'project.rename.cancel': 'Cancel',
|
|
23
|
+
'project.rename.failed': 'Rename failed. Try again.',
|
|
10
24
|
'session.new': 'New session',
|
|
11
25
|
'session.new.label': 'Start a session in the current project',
|
|
12
26
|
'session.empty': 'No sessions in this project yet.',
|
|
@@ -30,11 +44,13 @@ export const en = {
|
|
|
30
44
|
'panels.enabled': 'enabled in this project',
|
|
31
45
|
'panels.disabled': 'not enabled in this project',
|
|
32
46
|
'panels.choose': 'Choose modules',
|
|
47
|
+
'panels.buildModule': 'Build a module',
|
|
33
48
|
'panels.failed': 'Could not save the change. Try again.',
|
|
34
49
|
'panels.hintEffect': 'Disabling = the agent cannot reach that data',
|
|
35
50
|
'panels.dragHint': 'Drag to reorder',
|
|
36
51
|
'panels.unknownStep': 'No suite provides this view',
|
|
37
52
|
'panels.labelWithHint': '{label} ({hint})',
|
|
53
|
+
'panels.dep.failed': '⚠ failed to start',
|
|
38
54
|
'panels.dep.missingPlugin': '⚠ not ready yet',
|
|
39
55
|
'panels.dep.missingCommands': '⚠ needs an update',
|
|
40
56
|
'panels.dep.unchecked': '⚠ cannot check',
|
|
@@ -228,6 +244,8 @@ export const en = {
|
|
|
228
244
|
'blocker.exec.hint': 'Make sure opencli is installed and on PATH (which opencli).',
|
|
229
245
|
'blocker.unknown.title': 'Something went wrong',
|
|
230
246
|
'panels.reading': 'Reading the panel setup…',
|
|
247
|
+
'panels.cardBroken': 'This module will not render: {unit} ({reason})',
|
|
248
|
+
'panels.cardRetry': 'Retry',
|
|
231
249
|
'panels.empty': 'No modules on the panel yet',
|
|
232
250
|
'panels.emptyHint': 'You can also just tell the agent: “add a module to the panel”.',
|
|
233
251
|
'env.title': 'Preparing the workbench',
|
|
@@ -266,6 +284,8 @@ export const en = {
|
|
|
266
284
|
'env.step.warm': 'Warming up site sessions',
|
|
267
285
|
'env.warm.done': '{n} site(s) warmed up',
|
|
268
286
|
'env.warm.short': 'Not warmed this time — harmless; the panel heals on first read',
|
|
287
|
+
'env.unit.failed': 'This module cannot start',
|
|
288
|
+
'env.unit.failedHint': 'It failed while assembling itself; other modules are unaffected.',
|
|
269
289
|
'env.unit.missingPlugin': 'This module is not ready yet',
|
|
270
290
|
'env.unit.missingCommandsHint': 'Updating it should fix this.',
|
|
271
291
|
'env.unit.unchecked': 'Cannot check: no shell channel',
|
package/dist/i18n/index.d.ts
CHANGED
|
@@ -9,6 +9,20 @@ export declare const dictionaries: {
|
|
|
9
9
|
readonly 'project.none': "未选择项目";
|
|
10
10
|
readonly 'project.empty': "还没有项目。用下面的「添加项目」选一个目录。";
|
|
11
11
|
readonly 'project.add': "添加项目…";
|
|
12
|
+
readonly 'project.search.label': "搜索工作区";
|
|
13
|
+
readonly 'project.search.placeholder': "搜索工作区(目录名 / 中文名 / 路径)";
|
|
14
|
+
readonly 'project.search.empty': "没有匹配「{query}」的工作区。";
|
|
15
|
+
readonly 'project.rename.row': "改「{name}」的中文名";
|
|
16
|
+
readonly 'project.rename.current': "改当前工作区的中文名…";
|
|
17
|
+
readonly 'project.rename.title': "给「{name}」配一个中文名";
|
|
18
|
+
readonly 'project.rename.description': "显示在目录名后面。改的是工作区本身的名字。";
|
|
19
|
+
readonly 'project.rename.field': "中文名";
|
|
20
|
+
readonly 'project.rename.placeholder': "例如:工作台外壳";
|
|
21
|
+
readonly 'project.rename.hint': "留空 = 只显示目录名";
|
|
22
|
+
readonly 'project.rename.save': "保存";
|
|
23
|
+
readonly 'project.rename.saving': "保存中…";
|
|
24
|
+
readonly 'project.rename.cancel': "取消";
|
|
25
|
+
readonly 'project.rename.failed': "改名失败了,再试一次。";
|
|
12
26
|
readonly 'session.new': "新会话";
|
|
13
27
|
readonly 'session.new.label': "在当前项目新建会话";
|
|
14
28
|
readonly 'session.empty': "这个项目还没有会话。";
|
|
@@ -32,11 +46,13 @@ export declare const dictionaries: {
|
|
|
32
46
|
readonly 'panels.enabled': "这个项目已启用";
|
|
33
47
|
readonly 'panels.disabled': "这个项目未启用";
|
|
34
48
|
readonly 'panels.choose': "选择模块";
|
|
49
|
+
readonly 'panels.buildModule': "造一个模块";
|
|
35
50
|
readonly 'panels.failed': "改配置失败了,再试一次。";
|
|
36
51
|
readonly 'panels.hintEffect': "停用 = agent 拿不到相关数据";
|
|
37
52
|
readonly 'panels.dragHint': "拖动调整顺序";
|
|
38
53
|
readonly 'panels.unknownStep': "这一层没有套件提供";
|
|
39
54
|
readonly 'panels.labelWithHint': "{label}({hint})";
|
|
55
|
+
readonly 'panels.dep.failed': "⚠ 起不来";
|
|
40
56
|
readonly 'panels.dep.missingPlugin': "⚠ 还没装好";
|
|
41
57
|
readonly 'panels.dep.missingCommands': "⚠ 需要更新";
|
|
42
58
|
readonly 'panels.dep.unchecked': "⚠ 检测不了";
|
|
@@ -230,6 +246,8 @@ export declare const dictionaries: {
|
|
|
230
246
|
readonly 'blocker.exec.hint': "确认 opencli 已安装且在 PATH 里(which opencli)。";
|
|
231
247
|
readonly 'blocker.unknown.title': "出了点问题";
|
|
232
248
|
readonly 'panels.reading': "正在读取面板配置…";
|
|
249
|
+
readonly 'panels.cardBroken': "这个模块起不来:{unit}({reason})";
|
|
250
|
+
readonly 'panels.cardRetry': "重试";
|
|
233
251
|
readonly 'panels.empty': "面板里还没有模块";
|
|
234
252
|
readonly 'panels.emptyHint': "也可以直接跟 agent 说:「把某个模块加到面板」。";
|
|
235
253
|
readonly 'env.title': "准备工作台";
|
|
@@ -268,6 +286,8 @@ export declare const dictionaries: {
|
|
|
268
286
|
readonly 'env.step.warm': "预热站点登录态";
|
|
269
287
|
readonly 'env.warm.done': "已预热 {n} 个站点";
|
|
270
288
|
readonly 'env.warm.short': "这次没热上 —— 不影响用,面板第一次读取会自己补";
|
|
289
|
+
readonly 'env.unit.failed': "这个模块起不来";
|
|
290
|
+
readonly 'env.unit.failedHint': "它自己装配时报了错,别的模块不受影响。";
|
|
271
291
|
readonly 'env.unit.missingPlugin': "这个模块还没装好";
|
|
272
292
|
readonly 'env.unit.missingCommandsHint': "更新之后就能用了。";
|
|
273
293
|
readonly 'env.unit.unchecked': "检测不了:拿不到执行通道";
|
|
@@ -290,7 +310,7 @@ export declare const dictionaries: {
|
|
|
290
310
|
readonly 'panel.conversation': "对话";
|
|
291
311
|
readonly 'panels.label': "全局面板";
|
|
292
312
|
};
|
|
293
|
-
en: Record<"time.now" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.fix.update" | "blocker.market.open" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "panels.title" | "panels.reset" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.failed" | "panels.hintEffect" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.outdated" | "panels.market.hasNew" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.failed" | "panels.market.needEnv" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.installedSection" | "panels.market.moduleOutdated" | "panels.market.moduleRestartHint" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureGeneric" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label", string>;
|
|
313
|
+
en: Record<"time.now" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.fix.update" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "project.search.label" | "project.search.placeholder" | "project.search.empty" | "project.rename.row" | "project.rename.current" | "project.rename.title" | "project.rename.description" | "project.rename.field" | "project.rename.placeholder" | "project.rename.hint" | "project.rename.save" | "project.rename.saving" | "project.rename.cancel" | "project.rename.failed" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "panels.title" | "panels.reset" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.buildModule" | "panels.failed" | "panels.hintEffect" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.dep.failed" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.outdated" | "panels.market.hasNew" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.failed" | "panels.market.needEnv" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.installedSection" | "panels.market.moduleOutdated" | "panels.market.moduleRestartHint" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureGeneric" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label", string>;
|
|
294
314
|
};
|
|
295
315
|
export type { WorkbenchMessages };
|
|
296
316
|
export interface Dictionaries {
|
package/dist/i18n/merge.d.ts
CHANGED
|
@@ -4,3 +4,12 @@ export interface MessagesContribution {
|
|
|
4
4
|
readonly messages?: Dictionaries | undefined;
|
|
5
5
|
}
|
|
6
6
|
export declare function mergeMessages(base: Dictionaries, contributions: readonly MessagesContribution[]): Dictionaries;
|
|
7
|
+
export interface MessagesProblem {
|
|
8
|
+
readonly unit: string;
|
|
9
|
+
readonly reason: string;
|
|
10
|
+
}
|
|
11
|
+
export interface MessagesMerge {
|
|
12
|
+
readonly dictionaries: Dictionaries;
|
|
13
|
+
readonly problems: readonly MessagesProblem[];
|
|
14
|
+
}
|
|
15
|
+
export declare function mergeMessagesSkipping(base: Dictionaries, contributions: readonly MessagesContribution[]): MessagesMerge;
|