@dsh-workbench/shared 0.3.4 → 0.3.6
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.d.ts +13 -0
- package/dist/api/blocker-table.js +13 -0
- package/dist/api/blocker.d.ts +6 -0
- package/dist/api/context-ref.d.ts +31 -0
- package/dist/api/context-ref.js +28 -0
- package/dist/api/dsh-client.d.ts +99 -0
- package/dist/api/dsh.d.ts +55 -3
- package/dist/api/facts.d.ts +42 -0
- package/dist/api/facts.js +33 -0
- package/dist/api/host-write.d.ts +18 -0
- package/dist/api/host-write.js +12 -0
- package/dist/api/long-task.d.ts +66 -1
- package/dist/api/long-task.js +59 -0
- package/dist/api/unit-board.d.ts +25 -0
- package/dist/api/unit-board.js +16 -0
- package/dist/api/unit-declaration.d.ts +36 -0
- package/dist/api/unit-declaration.js +24 -0
- package/dist/api/unit.d.ts +32 -0
- package/dist/api/unit.js +5 -0
- package/dist/api/workbench-client.d.ts +25 -0
- package/dist/api/workbench-client.js +13 -0
- package/dist/api/workbench-contract.d.ts +12 -0
- package/dist/components/Activity.d.ts +33 -0
- package/dist/components/Activity.js +24 -0
- package/dist/components/ApprovalDetail.d.ts +12 -0
- package/dist/components/ApprovalDetail.js +9 -0
- package/dist/components/ApprovalPlan.d.ts +14 -0
- package/dist/components/ApprovalPlan.js +8 -0
- package/dist/components/Card.d.ts +13 -0
- package/dist/components/Card.js +10 -0
- package/dist/components/CardAnchor.d.ts +14 -0
- package/dist/components/CardAnchor.js +11 -0
- package/dist/components/CardBoundary.d.ts +20 -0
- package/dist/components/CardBoundary.js +14 -0
- package/dist/components/CardHead.d.ts +13 -0
- package/dist/components/CardHead.js +10 -0
- package/dist/components/ChoiceGroup.d.ts +24 -0
- package/dist/components/ChoiceGroup.js +12 -0
- package/dist/components/Field.d.ts +10 -0
- package/dist/components/Field.js +7 -0
- package/dist/components/Form.css +6 -0
- package/dist/components/Form.d.ts +20 -0
- package/dist/components/Form.js +58 -0
- package/dist/components/FormActions.d.ts +14 -0
- package/dist/components/FormActions.js +5 -0
- package/dist/components/FormNodes.d.ts +103 -0
- package/dist/components/FormNodes.js +153 -0
- package/dist/components/FormRows.css +31 -0
- package/dist/components/FormRows.d.ts +20 -0
- package/dist/components/FormRows.js +14 -0
- package/dist/components/FormTypes.d.ts +59 -0
- package/dist/components/FormTypes.js +1 -0
- package/dist/components/Link.d.ts +12 -0
- package/dist/components/Link.js +9 -0
- package/dist/components/LongTaskRow.css +52 -0
- package/dist/components/LongTaskRow.d.ts +35 -0
- package/dist/components/LongTaskRow.js +45 -4
- package/dist/components/Note.d.ts +11 -0
- package/dist/components/Note.js +8 -0
- package/dist/components/ResourceStates.d.ts +25 -0
- package/dist/components/ResourceStates.js +22 -0
- package/dist/components/Rows.d.ts +17 -0
- package/dist/components/Rows.js +11 -0
- package/dist/components/SaveBar.d.ts +12 -0
- package/dist/components/SaveBar.js +9 -0
- package/dist/components/SelectField.d.ts +26 -0
- package/dist/components/SelectField.js +22 -0
- package/dist/components/SelectFieldNodes.d.ts +24 -0
- package/dist/components/SelectFieldNodes.js +24 -0
- package/dist/components/SettingsSection.d.ts +11 -0
- package/dist/components/SettingsSection.js +8 -0
- package/dist/components/Spinner.d.ts +9 -0
- package/dist/components/Spinner.js +6 -0
- package/dist/components/Stack.d.ts +8 -0
- package/dist/components/Stack.js +5 -0
- package/dist/components/StateBlock.d.ts +13 -0
- package/dist/components/StateBlock.js +10 -0
- package/dist/components/TextField.d.ts +8 -0
- package/dist/components/TextField.js +5 -0
- package/dist/components/board-module.d.ts +30 -0
- package/dist/components/icons.d.ts +38 -0
- package/dist/components/icons.js +35 -0
- package/dist/config/constants.d.ts +42 -0
- package/dist/config/constants.js +42 -0
- package/dist/config/storage.d.ts +4 -0
- package/dist/config/storage.js +4 -0
- package/dist/host/long-task.d.ts +7 -0
- package/dist/host/long-task.js +31 -5
- package/dist/host/tool-approval.d.ts +1 -0
- package/dist/host/unit-face.d.ts +6 -1
- package/dist/i18n/en.d.ts +1 -0
- package/dist/i18n/en.js +10 -8
- package/dist/i18n/index.d.ts +13 -9
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/merge.d.ts +5 -0
- package/dist/i18n/merge.js +2 -0
- package/dist/i18n/zh.d.ts +11 -8
- package/dist/i18n/zh.js +10 -8
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/lib/blocker-action.d.ts +22 -0
- package/dist/lib/blocker-action.js +13 -0
- package/dist/lib/board-fact.d.ts +27 -0
- package/dist/lib/board-fact.js +18 -0
- package/dist/lib/busy.d.ts +10 -0
- package/dist/lib/busy.js +7 -0
- package/dist/lib/diy-debug.d.ts +42 -2
- package/dist/lib/diy-debug.js +19 -1
- package/dist/lib/diy-record.d.ts +41 -0
- package/dist/lib/diy-record.js +17 -0
- package/dist/lib/form-problem.d.ts +10 -0
- package/dist/lib/form-problem.js +10 -0
- package/dist/lib/panel-state.d.ts +60 -0
- package/dist/lib/panel-state.js +30 -0
- package/dist/lib/react.d.ts +39 -0
- package/dist/lib/react.js +36 -0
- package/dist/lib/text.d.ts +22 -0
- package/dist/lib/text.js +22 -0
- package/dist/lib/ui.d.ts +50 -0
- package/dist/lib/ui.js +41 -0
- package/package.json +1 -1
- package/src/api/__tests__/long-task.test.ts +41 -1
- package/src/api/blocker-table.ts +13 -0
- package/src/api/blocker.ts +6 -0
- package/src/api/context-ref.ts +31 -0
- package/src/api/dsh-client.ts +99 -0
- package/src/api/dsh.ts +56 -1
- package/src/api/facts.ts +42 -0
- package/src/api/host-write.ts +18 -0
- package/src/api/long-task.ts +79 -1
- package/src/api/unit-board.ts +25 -0
- package/src/api/unit-declaration.ts +36 -0
- package/src/api/unit.ts +32 -0
- package/src/api/workbench-client.ts +25 -0
- package/src/api/workbench-contract.ts +12 -0
- package/src/components/Activity.tsx +33 -0
- package/src/components/ApprovalDetail.tsx +12 -0
- package/src/components/ApprovalPlan.tsx +14 -0
- package/src/components/Card.tsx +13 -0
- package/src/components/CardAnchor.tsx +14 -0
- package/src/components/CardBoundary.tsx +20 -0
- package/src/components/CardHead.tsx +13 -0
- package/src/components/ChoiceGroup.tsx +24 -0
- package/src/components/Field.tsx +10 -0
- package/src/components/Form.css +6 -0
- package/src/components/Form.test.tsx +475 -0
- package/src/components/Form.tsx +78 -0
- package/src/components/FormActions.tsx +14 -0
- package/src/components/FormNodes.tsx +193 -0
- package/src/components/FormRows.css +31 -0
- package/src/components/FormRows.test.tsx +71 -1
- package/src/components/FormRows.tsx +20 -0
- package/src/components/FormTypes.ts +65 -0
- package/src/components/FormWiring.test.tsx +88 -0
- package/src/components/Link.tsx +12 -0
- package/src/components/LongTaskRow.css +52 -0
- package/src/components/LongTaskRow.tsx +76 -2
- package/src/components/Note.tsx +11 -0
- package/src/components/ResourceStates.tsx +25 -0
- package/src/components/Rows.tsx +17 -0
- package/src/components/SaveBar.tsx +12 -0
- package/src/components/SelectField.tsx +26 -0
- package/src/components/SelectFieldNodes.tsx +24 -0
- package/src/components/SettingsSection.tsx +11 -0
- package/src/components/Spinner.tsx +9 -0
- package/src/components/Stack.tsx +8 -0
- package/src/components/StateBlock.tsx +13 -0
- package/src/components/TextField.tsx +8 -0
- package/src/components/__tests__/long-task-row.test.ts +115 -0
- package/src/components/board-module.ts +30 -0
- package/src/components/icons.tsx +38 -0
- package/src/config/constants.ts +43 -0
- package/src/config/storage.ts +4 -0
- package/src/host/__tests__/long-task.test.ts +264 -0
- package/src/host/long-task.ts +43 -7
- package/src/host/tool-approval.ts +1 -0
- package/src/host/unit-face.ts +7 -1
- package/src/i18n/en.ts +11 -8
- package/src/i18n/index.ts +3 -0
- package/src/i18n/merge.ts +5 -0
- package/src/i18n/zh.ts +11 -8
- package/src/index.ts +6 -2
- package/src/lib/blocker-action.ts +22 -0
- package/src/lib/board-fact.ts +27 -0
- package/src/lib/busy.ts +10 -0
- package/src/lib/diy-debug.test.ts +2 -1
- package/src/lib/diy-debug.ts +44 -3
- package/src/lib/diy-record.ts +41 -0
- package/src/lib/form-problem.ts +10 -0
- package/src/lib/panel-state.ts +60 -0
- package/src/lib/react.ts +39 -0
- package/src/lib/text.ts +22 -0
- package/src/lib/ui.ts +50 -0
|
@@ -3,9 +3,15 @@ import type { SessionsSnapshot, Translate, WorkspaceSnapshot, WorkspaceView } fr
|
|
|
3
3
|
import type { UnitManifest } from '../api/unit.js';
|
|
4
4
|
import type { CapabilityPayload } from '../api/workbench-contract.js';
|
|
5
5
|
import type { Dictionaries } from '../i18n/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* 面板要跳去的一格:只用 `kind` 说去哪,具体负载由各 unit 自己约定。
|
|
8
|
+
*/
|
|
6
9
|
export interface PanelStep {
|
|
7
10
|
readonly kind: string;
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 交给面板渲染的宿主世界:工作区与会话快照、装着的 unit、面板开关、能力表与当前选中。
|
|
14
|
+
*/
|
|
9
15
|
export interface SuiteWorld {
|
|
10
16
|
readonly workspaces: WorkspaceSnapshot;
|
|
11
17
|
readonly sessions: SessionsSnapshot;
|
|
@@ -19,6 +25,9 @@ export interface SuiteWorld {
|
|
|
19
25
|
readonly workspace: WorkspaceView | null;
|
|
20
26
|
};
|
|
21
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* 面板视图的统一 prop:一份世界快照 + 刷新令牌 + 四个通知回调 + 翻译函数。
|
|
30
|
+
*/
|
|
22
31
|
export interface BoardModuleProps {
|
|
23
32
|
readonly world: SuiteWorld;
|
|
24
33
|
readonly refreshToken: number;
|
|
@@ -28,14 +37,23 @@ export interface BoardModuleProps {
|
|
|
28
37
|
readonly onSummary: (summary: ModuleSummary) => void;
|
|
29
38
|
readonly t: Translate;
|
|
30
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* 一张卡报给宿主的摘要:此刻在不在刷新、上次读到是哪个时刻。
|
|
42
|
+
*/
|
|
31
43
|
export interface ModuleSummary {
|
|
32
44
|
readonly refreshing: boolean;
|
|
33
45
|
readonly at: number | null;
|
|
34
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* unit 的一个子步骤:标题文案键 + 渲染这件视图的组件。
|
|
49
|
+
*/
|
|
35
50
|
export interface UnitStep {
|
|
36
51
|
readonly titleKey: string;
|
|
37
52
|
readonly View: (props: BoardModuleProps) => ReactNode;
|
|
38
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* 一个面板单元的注册面:id、标题键、排序、视图,可带一组子步骤。
|
|
56
|
+
*/
|
|
39
57
|
export interface BoardModule {
|
|
40
58
|
readonly id: string;
|
|
41
59
|
readonly titleKey: string;
|
|
@@ -43,6 +61,9 @@ export interface BoardModule {
|
|
|
43
61
|
readonly View: (props: BoardModuleProps) => ReactNode;
|
|
44
62
|
readonly steps?: Readonly<Record<string, UnitStep>>;
|
|
45
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* 模块在浏览器侧交出来的那份面:卡片、子步骤、自己的字典,以及审批渲染。
|
|
66
|
+
*/
|
|
46
67
|
export interface UnitClientFace {
|
|
47
68
|
readonly unit: string;
|
|
48
69
|
readonly card?: (props: BoardModuleProps) => ReactNode;
|
|
@@ -56,13 +77,22 @@ export interface UnitClientFace {
|
|
|
56
77
|
}) => ReactNode;
|
|
57
78
|
} | undefined;
|
|
58
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* 带着自己 manifest 的模块面(外壳按 unit 认领时用)。
|
|
82
|
+
*/
|
|
59
83
|
export interface UnitOwnedClientFace extends UnitClientFace {
|
|
60
84
|
readonly manifest: UnitManifest;
|
|
61
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* 一次审批要看的输入:工具名,与它这次收到的参数。
|
|
88
|
+
*/
|
|
62
89
|
export interface ApprovalInput {
|
|
63
90
|
readonly tool: string;
|
|
64
91
|
readonly args: Readonly<Record<string, unknown>>;
|
|
65
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* 模块注册进外壳的那个口:注册一份面(拿回注销函数)、列出已装 unit。
|
|
95
|
+
*/
|
|
66
96
|
export interface UnitClientApi {
|
|
67
97
|
registerUnit(face: UnitClientFace): () => void;
|
|
68
98
|
manifests(): readonly UnitManifest[];
|
|
@@ -1,10 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 自绘图标的契约:只给边长像素。
|
|
3
|
+
*/
|
|
1
4
|
export interface IconProps {
|
|
2
5
|
size?: number;
|
|
3
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* 会话图标:一枚对话气泡,dsh 的图标表里没有,留给我们自己用;默认 16px。
|
|
9
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
10
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
11
|
+
*/
|
|
4
12
|
export declare function IconConversation({ size }: IconProps): JSX.Element;
|
|
13
|
+
/**
|
|
14
|
+
* 品牌标:侧栏顶上那枚工作台方块标;默认 24px(它是品牌物,别拿它当通用图标)。
|
|
15
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
16
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
17
|
+
*/
|
|
5
18
|
export declare function IconBrandMark({ size }: IconProps): JSX.Element;
|
|
19
|
+
/**
|
|
20
|
+
* opencli 的标:包类型那一格用它;颜色写死的品牌物,不跟主题走。默认 16px。
|
|
21
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
22
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
23
|
+
*/
|
|
6
24
|
export declare function IconOpencli({ size }: IconProps): JSX.Element;
|
|
25
|
+
/**
|
|
26
|
+
* npm 的标:包类型那一格用它;保留品牌红,不跟主题走。默认 16px。
|
|
27
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
28
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
29
|
+
*/
|
|
7
30
|
export declare function IconNpm({ size }: IconProps): JSX.Element;
|
|
31
|
+
/**
|
|
32
|
+
* 四宫格:"模块"这个概念的通用单色图标(侧栏、面板那颗钮、市场节的标题);默认 16px。
|
|
33
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
34
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
35
|
+
*/
|
|
8
36
|
export declare function IconModules({ size }: IconProps): JSX.Element;
|
|
37
|
+
/**
|
|
38
|
+
* 模块类型标:渐变方块 + 白四宫格,用在"这是个模块"的行首;品牌物,颜色不跟主题走。默认 16px。
|
|
39
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
40
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
41
|
+
*/
|
|
9
42
|
export declare function IconModuleMark({ size }: IconProps): JSX.Element;
|
|
43
|
+
/**
|
|
44
|
+
* 面板 / 卡片那类的图标:整屏与柱状那种形状,给"面板"这一档用;默认 16px。
|
|
45
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
46
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
47
|
+
*/
|
|
10
48
|
export declare function IconPanelScreen({ size }: IconProps): JSX.Element;
|
package/dist/components/icons.js
CHANGED
|
@@ -2,15 +2,30 @@ import { h } from '../lib/react.js';
|
|
|
2
2
|
function Shell({ size, strokeWidth = 1, viewBox = '0 0 16 16', children, }) {
|
|
3
3
|
return (h("svg", { width: size, height: size, viewBox: viewBox, fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", strokeWidth: strokeWidth, style: { display: 'block' } }, children));
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* 会话图标:一枚对话气泡,dsh 的图标表里没有,留给我们自己用;默认 16px。
|
|
7
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
8
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
9
|
+
*/
|
|
5
10
|
export function IconConversation({ size = 16 }) {
|
|
6
11
|
return (h(Shell, { size: size, strokeWidth: 1.3 },
|
|
7
12
|
h("path", { d: "M2.5 7.2c0-2.3 2.1-4.2 4.8-4.2h1.4c2.7 0 4.8 1.9 4.8 4.2s-2.1 4.2-4.8 4.2H7.5l-3.2 2v-2.3c-1.1-.8-1.8-2-1.8-3.9Z", stroke: "currentColor", strokeLinejoin: "round" })));
|
|
8
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 品牌标:侧栏顶上那枚工作台方块标;默认 24px(它是品牌物,别拿它当通用图标)。
|
|
16
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
17
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
18
|
+
*/
|
|
9
19
|
export function IconBrandMark({ size = 24 }) {
|
|
10
20
|
return (h(Shell, { size: size, strokeWidth: 1.6, viewBox: "0 0 24 24" },
|
|
11
21
|
h("rect", { x: 3, y: 3, width: 18, height: 18, rx: 5, stroke: "currentColor" }),
|
|
12
22
|
h("path", { d: "M8 9.5h8M8 12.5h8M8 15.5h5", stroke: "currentColor", strokeLinecap: "round" })));
|
|
13
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* opencli 的标:包类型那一格用它;颜色写死的品牌物,不跟主题走。默认 16px。
|
|
26
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
27
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
28
|
+
*/
|
|
14
29
|
export function IconOpencli({ size = 16 }) {
|
|
15
30
|
return (h(Shell, { size: size, viewBox: "0 0 64 64" },
|
|
16
31
|
h("defs", null,
|
|
@@ -21,10 +36,20 @@ export function IconOpencli({ size = 16 }) {
|
|
|
21
36
|
h("rect", { width: 64, height: 64, rx: 14, fill: "#0a0a0f" }),
|
|
22
37
|
h("text", { x: "50%", y: "54%", dominantBaseline: "middle", textAnchor: "middle", fontFamily: "monospace", fontWeight: 700, fontSize: 28, fill: "url(#opencli-mark)" }, ">_")));
|
|
23
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* npm 的标:包类型那一格用它;保留品牌红,不跟主题走。默认 16px。
|
|
41
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
42
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
43
|
+
*/
|
|
24
44
|
export function IconNpm({ size = 16 }) {
|
|
25
45
|
return (h(Shell, { size: size, viewBox: "0 0 1024 1024" },
|
|
26
46
|
h("path", { d: "M64 337.76h896v298.72H512v49.792H312.896v-49.824H64z m49.792 248.928h99.552v-149.376h49.76v149.344h49.792v-199.104H113.792z m248.896-199.136v248.928h99.552v-49.792h99.552v-199.136z m99.552 49.792H512v99.584h-49.792z m149.344-49.792v199.136h99.552v-149.376h49.792v149.344h49.792v-149.344h49.792v149.344h49.792v-199.104z", fill: "#CB3837" })));
|
|
27
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* 四宫格:"模块"这个概念的通用单色图标(侧栏、面板那颗钮、市场节的标题);默认 16px。
|
|
50
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
51
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
52
|
+
*/
|
|
28
53
|
export function IconModules({ size = 16 }) {
|
|
29
54
|
return (h("svg", { width: size, height: size, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true" },
|
|
30
55
|
h("rect", { x: "2.5", y: "2.5", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" }),
|
|
@@ -32,6 +57,11 @@ export function IconModules({ size = 16 }) {
|
|
|
32
57
|
h("rect", { x: "2.5", y: "8.9", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" }),
|
|
33
58
|
h("rect", { x: "8.9", y: "8.9", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" })));
|
|
34
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* 模块类型标:渐变方块 + 白四宫格,用在"这是个模块"的行首;品牌物,颜色不跟主题走。默认 16px。
|
|
62
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
63
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
64
|
+
*/
|
|
35
65
|
export function IconModuleMark({ size = 16 }) {
|
|
36
66
|
return (h(Shell, { size: size, viewBox: "0 0 24 24" },
|
|
37
67
|
h("defs", null,
|
|
@@ -45,6 +75,11 @@ export function IconModuleMark({ size = 16 }) {
|
|
|
45
75
|
h("rect", { x: "4.6", y: "13.2", width: "6.2", height: "6.2", rx: "1.9", fill: "#ffffff", fillOpacity: 0.78 }),
|
|
46
76
|
h("rect", { x: "13.2", y: "13.2", width: "6.2", height: "6.2", rx: "1.9", fill: "#ffffff" })));
|
|
47
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* 面板 / 卡片那类的图标:整屏与柱状那种形状,给"面板"这一档用;默认 16px。
|
|
80
|
+
* @param props.size - 边长像素,同时给 `width` 与 `height`。
|
|
81
|
+
* @returns 一枚 `aria-hidden` 的 svg。
|
|
82
|
+
*/
|
|
48
83
|
export function IconPanelScreen({ size = 16 }) {
|
|
49
84
|
return (h("svg", { width: size, height: size, viewBox: "0 0 1024 1024", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", style: { display: 'block', overflow: 'hidden' } },
|
|
50
85
|
h("path", { d: "M939 112c17.673 0 32 14.327 32 32v554.667c0 17.673-14.327 32-32 32l-394.5-0.001v96c0 3.74-0.642 7.331-1.82 10.668H768.4c17.673 0 32 14.326 32 32 0 17.496-14.042 31.712-31.47 31.995l-0.53 0.004H256.6c-17.673 0-32-14.327-32-32 0-17.496 14.042-31.713 31.47-31.995l0.53-0.005h225.721a31.923 31.923 0 0 1-1.817-10.137l-0.004-0.53v-96H86c-17.496 0-31.713-14.041-31.996-31.47l-0.004-0.53V144c0-17.673 14.327-32 32-32z m-32 64H118v490.666h789V176zM341.9 432c17.496 0 31.713 14.042 31.996 31.47l0.004 0.53v85.333c0 17.673-14.327 32-32 32-17.496 0-31.713-14.041-31.996-31.47l-0.004-0.53V464c0-17.673 14.327-32 32-32z m170.6-85.333c17.496 0 31.713 14.041 31.996 31.47l0.004 0.53v170.666c0 17.673-14.327 32-32 32-17.496 0-31.713-14.041-31.996-31.47l-0.004-0.53V378.667c0-17.673 14.327-32 32-32z m170.6-85.334c17.496 0 31.713 14.042 31.996 31.471l0.004 0.53v256c0 17.672-14.327 32-32 32-17.496 0-31.713-14.042-31.996-31.471l-0.004-0.53v-256c0-17.673 14.327-32 32-32z" })));
|
|
@@ -1,40 +1,82 @@
|
|
|
1
|
+
/** 外壳插件的包名:浏览器模块表与宿主按它注册、认领这枚插件。 */
|
|
1
2
|
export declare const PLUGIN_ID = "@dsh-workbench/core";
|
|
3
|
+
/** 与外壳同批发布的兄弟包名:`release.ts` 用它判一版三包是否都已在源上。 */
|
|
2
4
|
export declare const RELEASE_SIBLINGS: readonly ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
|
|
5
|
+
/** 外壳宿主 HTTP API 的根前缀;prefs / actions / provision 等路由都挂在它下面。 */
|
|
3
6
|
export declare const API_PREFIX = "/workbench/api";
|
|
7
|
+
/** 模块偏好读写的路由前缀,挂在外壳 API 下:走写通道,拒写回 write-refused。 */
|
|
4
8
|
export declare const PREFS_PREFIX = "/workbench/api/prefs";
|
|
9
|
+
/** 事实(facts)SSE 事件流的端点路径;前端 `EventSource` 按它带 `since` 游标续传。 */
|
|
5
10
|
export declare const EVENTS_PATH = "/workbench/events";
|
|
11
|
+
/** 写动作的路由前缀,挂在外壳 API 下:模块的写通道 POST 到这里。 */
|
|
6
12
|
export declare const ACTIONS_PREFIX = "/workbench/api/actions";
|
|
13
|
+
/** 机器供给(provision)的路由前缀:只收 POST,装机时用它铺一份运行环境。 */
|
|
7
14
|
export declare const PROVISION_PREFIX = "/workbench/api/provision";
|
|
15
|
+
/** 面板运行态上报的路径段:崩溃与卡片收尾分别 POST 到 `panel-state/crash`、`panel-state/cards`。 */
|
|
8
16
|
export declare const PANEL_STATE_PATH = "panel-state";
|
|
17
|
+
/** DIY 调试动作的路径段;宿主按它登记 `/workbench/api/diy-debug` 前缀。 */
|
|
9
18
|
export declare const DIY_DEBUG_PATH = "diy-debug";
|
|
19
|
+
/** 调试动作的子路径(`diy-debug/act`);仓内暂无调用点,动作现走 `DIY_DEBUG_SERVICE`。 */
|
|
10
20
|
export declare const DIY_DEBUG_ACT_PATH = "diy-debug/act";
|
|
21
|
+
/** DIY 录制交接的路径段;宿主按它登记 `/workbench/api/diy-record` 前缀。 */
|
|
11
22
|
export declare const DIY_RECORD_PATH = "diy-record";
|
|
23
|
+
/** 录制动作的子路径(`diy-record/act`);仓内暂无调用点,录制现走 `DIY_RECORD_SERVICE`。 */
|
|
12
24
|
export declare const DIY_RECORD_ACT_PATH = "diy-record/act";
|
|
25
|
+
/** 面板运行态的路由前缀,挂在外壳 API 下:上报口用它,拒报回 report-refused。 */
|
|
13
26
|
export declare const PANEL_STATE_PREFIX = "/workbench/api/panel-state";
|
|
27
|
+
/** 钉住的 opencli 插件版本:`opencli-runtime` 按它校验、取那一份。 */
|
|
14
28
|
export declare const OPENCLI_PIN = "1.8.8";
|
|
29
|
+
/** 缺陷看板套件的 dsh 服务名(`workbenchCodingIssues`):套件照它登记自己那份服务。 */
|
|
15
30
|
export declare const CODING_ISSUES_SERVICE = "workbenchCodingIssues";
|
|
31
|
+
/** 面板套件的 dsh 服务名(`workbenchPanels`):宿主经它取套件公布的清单与订阅。 */
|
|
16
32
|
export declare const PANELS_SERVICE = "workbenchPanels";
|
|
33
|
+
/** 单元花名册服务的 dsh 服务名(`workbenchUnits`):模块经它认领自己的单元。 */
|
|
17
34
|
export declare const UNITS_SERVICE = "workbenchUnits";
|
|
35
|
+
/** 面板运行态服务的 dsh 服务名(`workbenchPanelState`):宿主注册,读口按它取。 */
|
|
18
36
|
export declare const PANEL_STATE_SERVICE = "workbenchPanelState";
|
|
37
|
+
/** DIY 调试约定服务的 dsh 服务名(`workbenchDiyDebug`):调试动作走它,不走 HTTP。 */
|
|
19
38
|
export declare const DIY_DEBUG_SERVICE = "workbenchDiyDebug";
|
|
39
|
+
/** DIY 录制交接服务的 dsh 服务名(`workbenchDiyRecord`):`diy-acts.ts` 经它收发录制三拍。 */
|
|
20
40
|
export declare const DIY_RECORD_SERVICE = "workbenchDiyRecord";
|
|
41
|
+
/** 会话投影服务的 dsh 服务名(`sessionProjections`):宿主经 `stateOf(session, 'agentPreset')` 读那一档。 */
|
|
42
|
+
export declare const SESSION_PROJECTIONS_SERVICE = "sessionProjections";
|
|
43
|
+
/** 面板清单一次取回的行数上限(条):外部模块拿它当 opencli `--pageSize`。 */
|
|
21
44
|
export declare const PANEL_LIST_LIMIT = 50;
|
|
45
|
+
/** 单次 opencli 调用的默认超时(毫秒);调用点没传 `timeoutMs` 时按它算。 */
|
|
22
46
|
export declare const OPENCLI_TIMEOUT_MS = 120000;
|
|
47
|
+
/** 同时最多几条 opencli 在跑(条):`opencli.ts` 超出就排队。 */
|
|
23
48
|
export declare const OPENCLI_MAX_CONCURRENT = 4;
|
|
49
|
+
/** 启动预热站点那一跳的超时(毫秒);超时按未热对待,不挡面板。 */
|
|
24
50
|
export declare const WARM_TIMEOUT_MS = 20000;
|
|
51
|
+
/** 装 / 卸模块包的超时(毫秒):pnpm 与取包内容都按它算。 */
|
|
25
52
|
export declare const INSTALL_TIMEOUT_MS = 300000;
|
|
53
|
+
/** 查 registry 版本那一次请求的超时(毫秒)。 */
|
|
26
54
|
export declare const VERSION_CHECK_TIMEOUT_MS = 10000;
|
|
55
|
+
/** 版本查询结果的缓存有效期(毫秒):期内不发第二次请求。 */
|
|
27
56
|
export declare const VERSION_CHECK_TTL_MS = 600000;
|
|
57
|
+
/** 单元探测结果的缓存有效期(毫秒)。 */
|
|
28
58
|
export declare const PROBE_TTL_MS = 30000;
|
|
59
|
+
/** 加载态至少显示多久(毫秒):一瞬完成的读写也得让用户看见那一下。 */
|
|
29
60
|
export declare const MIN_BUSY_MS = 500;
|
|
61
|
+
/** 工具读出来的值交给面板后的保留时长(毫秒):过期就不再算这一拍。 */
|
|
30
62
|
export declare const HANDOFF_TTL_MS = 15000;
|
|
63
|
+
/** 跑本地 git 命令的超时(毫秒);短于对外的 `OPENCLI_TIMEOUT_MS`。 */
|
|
31
64
|
export declare const GIT_TIMEOUT_MS = 10000;
|
|
65
|
+
/** 面板轮询事实的间隔(毫秒):SSE 断了走这条兜底轮询。 */
|
|
32
66
|
export declare const PANEL_POLL_MS = 2000;
|
|
67
|
+
/** 没起中文名的工作区默认标题:左栏按它分组、显示。 */
|
|
33
68
|
export declare const DEFAULT_WORKSPACE_TITLE = "default-workspace";
|
|
69
|
+
/** 记住当前项目的 localStorage 键。 */
|
|
34
70
|
export declare const STORAGE_KEY_PROJECT = "dsh-workbench.project";
|
|
71
|
+
/** 记住右栏展开与否的 localStorage 键。 */
|
|
35
72
|
export declare const STORAGE_KEY_RIGHTBAR = "dsh-workbench.rightbar.expanded";
|
|
73
|
+
/** 记住右栏当前列的 localStorage 键。 */
|
|
36
74
|
export declare const STORAGE_KEY_RIGHTBAR_COLUMN = "dsh-workbench.rightbar.column";
|
|
75
|
+
/** 记住右栏宽度(像素数字的字符串)的 localStorage 键。 */
|
|
37
76
|
export declare const STORAGE_KEY_RIGHTBAR_WIDTH = "dsh-workbench.rightbar.width";
|
|
77
|
+
/** 右栏宽度达到或超过多少像素就按全屏对待(阈值,像素)。 */
|
|
38
78
|
export declare const RIGHTBAR_FULLSCREEN_WIDTH = 768;
|
|
79
|
+
/** dsh i18n 的命名空间:词表都注册在它下面,`ctx.locale.register` / `bind` 按它取。 */
|
|
39
80
|
export declare const LOCALE_NS = "workbench";
|
|
81
|
+
/** 外壳支持的语言标识,顺序即回退顺序:首项是基准,其余词表必须与它逐键同构。 */
|
|
40
82
|
export declare const LOCALES: readonly ["zh", "en"];
|
package/dist/config/constants.js
CHANGED
|
@@ -1,43 +1,85 @@
|
|
|
1
|
+
/** 外壳插件的包名:浏览器模块表与宿主按它注册、认领这枚插件。 */
|
|
1
2
|
export const PLUGIN_ID = "@dsh-workbench/core";
|
|
3
|
+
/** 与外壳同批发布的兄弟包名:`release.ts` 用它判一版三包是否都已在源上。 */
|
|
2
4
|
export const RELEASE_SIBLINGS = [
|
|
3
5
|
"@dsh-workbench/shared",
|
|
4
6
|
"@dsh-workbench/module-tools",
|
|
5
7
|
];
|
|
8
|
+
/** 外壳宿主 HTTP API 的根前缀;prefs / actions / provision 等路由都挂在它下面。 */
|
|
6
9
|
export const API_PREFIX = "/workbench/api";
|
|
10
|
+
/** 模块偏好读写的路由前缀,挂在外壳 API 下:走写通道,拒写回 write-refused。 */
|
|
7
11
|
export const PREFS_PREFIX = `${API_PREFIX}/prefs`;
|
|
12
|
+
/** 事实(facts)SSE 事件流的端点路径;前端 `EventSource` 按它带 `since` 游标续传。 */
|
|
8
13
|
export const EVENTS_PATH = "/workbench/events";
|
|
14
|
+
/** 写动作的路由前缀,挂在外壳 API 下:模块的写通道 POST 到这里。 */
|
|
9
15
|
export const ACTIONS_PREFIX = `${API_PREFIX}/actions`;
|
|
16
|
+
/** 机器供给(provision)的路由前缀:只收 POST,装机时用它铺一份运行环境。 */
|
|
10
17
|
export const PROVISION_PREFIX = `${API_PREFIX}/provision`;
|
|
18
|
+
/** 面板运行态上报的路径段:崩溃与卡片收尾分别 POST 到 `panel-state/crash`、`panel-state/cards`。 */
|
|
11
19
|
export const PANEL_STATE_PATH = "panel-state";
|
|
20
|
+
/** DIY 调试动作的路径段;宿主按它登记 `/workbench/api/diy-debug` 前缀。 */
|
|
12
21
|
export const DIY_DEBUG_PATH = "diy-debug";
|
|
22
|
+
/** 调试动作的子路径(`diy-debug/act`);仓内暂无调用点,动作现走 `DIY_DEBUG_SERVICE`。 */
|
|
13
23
|
export const DIY_DEBUG_ACT_PATH = `${DIY_DEBUG_PATH}/act`;
|
|
24
|
+
/** DIY 录制交接的路径段;宿主按它登记 `/workbench/api/diy-record` 前缀。 */
|
|
14
25
|
export const DIY_RECORD_PATH = "diy-record";
|
|
26
|
+
/** 录制动作的子路径(`diy-record/act`);仓内暂无调用点,录制现走 `DIY_RECORD_SERVICE`。 */
|
|
15
27
|
export const DIY_RECORD_ACT_PATH = `${DIY_RECORD_PATH}/act`;
|
|
28
|
+
/** 面板运行态的路由前缀,挂在外壳 API 下:上报口用它,拒报回 report-refused。 */
|
|
16
29
|
export const PANEL_STATE_PREFIX = `${API_PREFIX}/${PANEL_STATE_PATH}`;
|
|
30
|
+
/** 钉住的 opencli 插件版本:`opencli-runtime` 按它校验、取那一份。 */
|
|
17
31
|
export const OPENCLI_PIN = "1.8.8";
|
|
32
|
+
/** 缺陷看板套件的 dsh 服务名(`workbenchCodingIssues`):套件照它登记自己那份服务。 */
|
|
18
33
|
export const CODING_ISSUES_SERVICE = "workbenchCodingIssues";
|
|
34
|
+
/** 面板套件的 dsh 服务名(`workbenchPanels`):宿主经它取套件公布的清单与订阅。 */
|
|
19
35
|
export const PANELS_SERVICE = "workbenchPanels";
|
|
36
|
+
/** 单元花名册服务的 dsh 服务名(`workbenchUnits`):模块经它认领自己的单元。 */
|
|
20
37
|
export const UNITS_SERVICE = "workbenchUnits";
|
|
38
|
+
/** 面板运行态服务的 dsh 服务名(`workbenchPanelState`):宿主注册,读口按它取。 */
|
|
21
39
|
export const PANEL_STATE_SERVICE = "workbenchPanelState";
|
|
40
|
+
/** DIY 调试约定服务的 dsh 服务名(`workbenchDiyDebug`):调试动作走它,不走 HTTP。 */
|
|
22
41
|
export const DIY_DEBUG_SERVICE = "workbenchDiyDebug";
|
|
42
|
+
/** DIY 录制交接服务的 dsh 服务名(`workbenchDiyRecord`):`diy-acts.ts` 经它收发录制三拍。 */
|
|
23
43
|
export const DIY_RECORD_SERVICE = "workbenchDiyRecord";
|
|
44
|
+
/** 会话投影服务的 dsh 服务名(`sessionProjections`):宿主经 `stateOf(session, 'agentPreset')` 读那一档。 */
|
|
45
|
+
export const SESSION_PROJECTIONS_SERVICE = "sessionProjections";
|
|
46
|
+
/** 面板清单一次取回的行数上限(条):外部模块拿它当 opencli `--pageSize`。 */
|
|
24
47
|
export const PANEL_LIST_LIMIT = 50;
|
|
48
|
+
/** 单次 opencli 调用的默认超时(毫秒);调用点没传 `timeoutMs` 时按它算。 */
|
|
25
49
|
export const OPENCLI_TIMEOUT_MS = 120_000;
|
|
50
|
+
/** 同时最多几条 opencli 在跑(条):`opencli.ts` 超出就排队。 */
|
|
26
51
|
export const OPENCLI_MAX_CONCURRENT = 4;
|
|
52
|
+
/** 启动预热站点那一跳的超时(毫秒);超时按未热对待,不挡面板。 */
|
|
27
53
|
export const WARM_TIMEOUT_MS = 20_000;
|
|
54
|
+
/** 装 / 卸模块包的超时(毫秒):pnpm 与取包内容都按它算。 */
|
|
28
55
|
export const INSTALL_TIMEOUT_MS = 300_000;
|
|
56
|
+
/** 查 registry 版本那一次请求的超时(毫秒)。 */
|
|
29
57
|
export const VERSION_CHECK_TIMEOUT_MS = 10_000;
|
|
58
|
+
/** 版本查询结果的缓存有效期(毫秒):期内不发第二次请求。 */
|
|
30
59
|
export const VERSION_CHECK_TTL_MS = 600_000;
|
|
60
|
+
/** 单元探测结果的缓存有效期(毫秒)。 */
|
|
31
61
|
export const PROBE_TTL_MS = 30_000;
|
|
62
|
+
/** 加载态至少显示多久(毫秒):一瞬完成的读写也得让用户看见那一下。 */
|
|
32
63
|
export const MIN_BUSY_MS = 500;
|
|
64
|
+
/** 工具读出来的值交给面板后的保留时长(毫秒):过期就不再算这一拍。 */
|
|
33
65
|
export const HANDOFF_TTL_MS = 15_000;
|
|
66
|
+
/** 跑本地 git 命令的超时(毫秒);短于对外的 `OPENCLI_TIMEOUT_MS`。 */
|
|
34
67
|
export const GIT_TIMEOUT_MS = 10_000;
|
|
68
|
+
/** 面板轮询事实的间隔(毫秒):SSE 断了走这条兜底轮询。 */
|
|
35
69
|
export const PANEL_POLL_MS = 2000;
|
|
70
|
+
/** 没起中文名的工作区默认标题:左栏按它分组、显示。 */
|
|
36
71
|
export const DEFAULT_WORKSPACE_TITLE = "default-workspace";
|
|
72
|
+
/** 记住当前项目的 localStorage 键。 */
|
|
37
73
|
export const STORAGE_KEY_PROJECT = "dsh-workbench.project";
|
|
74
|
+
/** 记住右栏展开与否的 localStorage 键。 */
|
|
38
75
|
export const STORAGE_KEY_RIGHTBAR = "dsh-workbench.rightbar.expanded";
|
|
76
|
+
/** 记住右栏当前列的 localStorage 键。 */
|
|
39
77
|
export const STORAGE_KEY_RIGHTBAR_COLUMN = "dsh-workbench.rightbar.column";
|
|
78
|
+
/** 记住右栏宽度(像素数字的字符串)的 localStorage 键。 */
|
|
40
79
|
export const STORAGE_KEY_RIGHTBAR_WIDTH = "dsh-workbench.rightbar.width";
|
|
80
|
+
/** 右栏宽度达到或超过多少像素就按全屏对待(阈值,像素)。 */
|
|
41
81
|
export const RIGHTBAR_FULLSCREEN_WIDTH = 768;
|
|
82
|
+
/** dsh i18n 的命名空间:词表都注册在它下面,`ctx.locale.register` / `bind` 按它取。 */
|
|
42
83
|
export const LOCALE_NS = "workbench";
|
|
84
|
+
/** 外壳支持的语言标识,顺序即回退顺序:首项是基准,其余词表必须与它逐键同构。 */
|
|
43
85
|
export const LOCALES = ["zh", "en"];
|
package/dist/config/storage.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
/** 读 localStorage 里的一段文本;没有这个键、或存储不可用(隐私模式)时返回 null。 */
|
|
1
2
|
export declare function readText(key: string): string | null;
|
|
3
|
+
/** 写一段文本进 localStorage;`value` 为 null 时删掉这个键,写不进去就静默作罢。 */
|
|
2
4
|
export declare function writeText(key: string, value: string | null): void;
|
|
5
|
+
/** 读一个布尔开关:键不存在时返回 `fallback`,只有存进去的 `'true'` 算真。 */
|
|
3
6
|
export declare function readFlag(key: string, fallback: boolean): boolean;
|
|
7
|
+
/** 把一个布尔开关写进 localStorage(存 `'true'` / `'false'`);失败静默。 */
|
|
4
8
|
export declare function writeFlag(key: string, value: boolean): void;
|
package/dist/config/storage.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** 读 localStorage 里的一段文本;没有这个键、或存储不可用(隐私模式)时返回 null。 */
|
|
1
2
|
export function readText(key) {
|
|
2
3
|
try {
|
|
3
4
|
return window.localStorage.getItem(key);
|
|
@@ -6,6 +7,7 @@ export function readText(key) {
|
|
|
6
7
|
return null;
|
|
7
8
|
}
|
|
8
9
|
}
|
|
10
|
+
/** 写一段文本进 localStorage;`value` 为 null 时删掉这个键,写不进去就静默作罢。 */
|
|
9
11
|
export function writeText(key, value) {
|
|
10
12
|
try {
|
|
11
13
|
if (value === null)
|
|
@@ -16,12 +18,14 @@ export function writeText(key, value) {
|
|
|
16
18
|
catch {
|
|
17
19
|
}
|
|
18
20
|
}
|
|
21
|
+
/** 读一个布尔开关:键不存在时返回 `fallback`,只有存进去的 `'true'` 算真。 */
|
|
19
22
|
export function readFlag(key, fallback) {
|
|
20
23
|
const raw = readText(key);
|
|
21
24
|
if (raw === null)
|
|
22
25
|
return fallback;
|
|
23
26
|
return raw === 'true';
|
|
24
27
|
}
|
|
28
|
+
/** 把一个布尔开关写进 localStorage(存 `'true'` / `'false'`);失败静默。 */
|
|
25
29
|
export function writeFlag(key, value) {
|
|
26
30
|
writeText(key, value ? 'true' : 'false');
|
|
27
31
|
}
|
package/dist/host/long-task.d.ts
CHANGED
|
@@ -10,24 +10,29 @@ export interface LongTaskBase {
|
|
|
10
10
|
readonly why?: string | undefined;
|
|
11
11
|
readonly startedAt: string;
|
|
12
12
|
readonly at: string;
|
|
13
|
+
readonly session?: string | undefined;
|
|
13
14
|
}
|
|
14
15
|
export interface LongTaskStart {
|
|
15
16
|
readonly workspace: string;
|
|
16
17
|
readonly target: string;
|
|
17
18
|
readonly payload?: unknown;
|
|
19
|
+
readonly session?: string | undefined;
|
|
18
20
|
}
|
|
19
21
|
export interface LongTaskChange<S extends LongTaskBase> {
|
|
20
22
|
readonly kind: 'start' | 'step' | 'settle';
|
|
21
23
|
readonly snapshot: S;
|
|
22
24
|
readonly step?: LongTaskStep | undefined;
|
|
25
|
+
readonly by?: string | undefined;
|
|
23
26
|
}
|
|
24
27
|
export interface LongTaskDeps<S extends LongTaskBase> {
|
|
25
28
|
readonly run: (options: {
|
|
26
29
|
readonly payload: unknown;
|
|
27
30
|
readonly onStep: (step: LongTaskStep) => void;
|
|
31
|
+
readonly signal: AbortSignal;
|
|
28
32
|
}) => Promise<unknown>;
|
|
29
33
|
readonly step?: ((step: LongTaskStep, current: S) => Partial<S>) | undefined;
|
|
30
34
|
readonly outcome?: ((result: unknown, current: S) => Partial<S>) | undefined;
|
|
35
|
+
readonly stopped?: ((current: S) => Partial<S>) | undefined;
|
|
31
36
|
readonly view: (snapshot: S) => Readonly<Record<string, unknown>>;
|
|
32
37
|
readonly now?: (() => string) | undefined;
|
|
33
38
|
readonly nextId?: (() => string) | undefined;
|
|
@@ -39,6 +44,7 @@ export interface LongTaskRegistry<S extends LongTaskBase> {
|
|
|
39
44
|
snapshot(id: string): S | null;
|
|
40
45
|
active(workspace: string, target: string): S | null;
|
|
41
46
|
current(workspace: string): readonly Readonly<Record<string, unknown>>[];
|
|
47
|
+
stop(id: string, by?: string): boolean;
|
|
42
48
|
onChange(listener: (change: LongTaskChange<S>) => void): () => void;
|
|
43
49
|
}
|
|
44
50
|
export declare function createLongTaskRegistry<S extends LongTaskBase>(deps: LongTaskDeps<S>): LongTaskRegistry<S>;
|
|
@@ -52,6 +58,7 @@ export declare function createLongTaskHost(options: {
|
|
|
52
58
|
readonly scope: string;
|
|
53
59
|
readonly unit: string;
|
|
54
60
|
readonly bump: (facts: readonly string[]) => void;
|
|
61
|
+
readonly notify?: ((change: LongTaskChange<LongTaskBase>) => void) | undefined;
|
|
55
62
|
}): {
|
|
56
63
|
readonly host: LongTaskHost;
|
|
57
64
|
dispose(): void;
|
package/dist/host/long-task.js
CHANGED
|
@@ -3,11 +3,18 @@ const LIVE = new Set(['running', 'needs-login']);
|
|
|
3
3
|
const RECENT_MS = 10 * 60 * 1000;
|
|
4
4
|
export function createLongTaskRegistry(deps) {
|
|
5
5
|
const runs = new Map();
|
|
6
|
+
const controls = new Map();
|
|
6
7
|
const now = deps.now ?? (() => new Date().toISOString());
|
|
7
8
|
let counter = 0;
|
|
8
9
|
const nextId = deps.nextId ?? (() => `run-${Date.now()}-${(counter += 1)}`);
|
|
9
10
|
const recentMs = deps.recentMs ?? RECENT_MS;
|
|
10
11
|
const listeners = new Set();
|
|
12
|
+
const live = (id) => {
|
|
13
|
+
const current = runs.get(id);
|
|
14
|
+
if (current === undefined || !LIVE.has(current.status))
|
|
15
|
+
return null;
|
|
16
|
+
return current;
|
|
17
|
+
};
|
|
11
18
|
const notify = (change) => {
|
|
12
19
|
for (const listener of [...listeners]) {
|
|
13
20
|
try {
|
|
@@ -46,7 +53,7 @@ export function createLongTaskRegistry(deps) {
|
|
|
46
53
|
return [...newest.values()]
|
|
47
54
|
.filter((snapshot) => LIVE.has(snapshot.status) || Date.parse(snapshot.at) >= floor)
|
|
48
55
|
.reverse()
|
|
49
|
-
.map((snapshot) => deps.view(snapshot));
|
|
56
|
+
.map((snapshot) => ({ ...deps.view(snapshot), id: snapshot.id }));
|
|
50
57
|
},
|
|
51
58
|
start(options) {
|
|
52
59
|
const running = this.active(options.workspace, options.target);
|
|
@@ -63,11 +70,12 @@ export function createLongTaskRegistry(deps) {
|
|
|
63
70
|
steps: [],
|
|
64
71
|
startedAt,
|
|
65
72
|
at: startedAt,
|
|
73
|
+
...(options.session === undefined ? {} : { session: options.session }),
|
|
66
74
|
});
|
|
67
75
|
notify({ kind: 'start', snapshot: runs.get(id) });
|
|
68
76
|
const onStep = (step) => {
|
|
69
|
-
const current =
|
|
70
|
-
if (current ===
|
|
77
|
+
const current = live(id);
|
|
78
|
+
if (current === null)
|
|
71
79
|
return;
|
|
72
80
|
const steps = [...current.steps, `${step.kind === 'fail' ? '✗ ' : ''}${step.text}`].slice(-20);
|
|
73
81
|
const extra = deps.step?.(step, current) ?? {};
|
|
@@ -83,13 +91,21 @@ export function createLongTaskRegistry(deps) {
|
|
|
83
91
|
...(current.status === 'needs-login' ? { loginUrl: undefined } : {}),
|
|
84
92
|
}, { kind: 'step', step });
|
|
85
93
|
};
|
|
94
|
+
const control = new AbortController();
|
|
95
|
+
controls.set(id, control);
|
|
86
96
|
void deps
|
|
87
|
-
.run({ payload: options.payload, onStep })
|
|
97
|
+
.run({ payload: options.payload, onStep, signal: control.signal })
|
|
88
98
|
.then((result) => {
|
|
89
|
-
const current =
|
|
99
|
+
const current = live(id);
|
|
100
|
+
if (current === null)
|
|
101
|
+
return;
|
|
102
|
+
controls.delete(id);
|
|
90
103
|
patch(id, { status: 'ok', ...(deps.outcome?.(result, current) ?? {}), loginUrl: undefined }, { kind: 'settle' });
|
|
91
104
|
})
|
|
92
105
|
.catch((error) => {
|
|
106
|
+
if (live(id) === null)
|
|
107
|
+
return;
|
|
108
|
+
controls.delete(id);
|
|
93
109
|
patch(id, {
|
|
94
110
|
status: 'failed',
|
|
95
111
|
why: error instanceof Error ? error.message : String(error),
|
|
@@ -98,6 +114,15 @@ export function createLongTaskRegistry(deps) {
|
|
|
98
114
|
});
|
|
99
115
|
return runs.get(id);
|
|
100
116
|
},
|
|
117
|
+
stop(id, by) {
|
|
118
|
+
const current = live(id);
|
|
119
|
+
if (current === null)
|
|
120
|
+
return false;
|
|
121
|
+
controls.get(id)?.abort();
|
|
122
|
+
controls.delete(id);
|
|
123
|
+
patch(id, { ...(deps.stopped?.(current) ?? {}), status: 'stopped', loginUrl: undefined }, { kind: 'settle', by });
|
|
124
|
+
return true;
|
|
125
|
+
},
|
|
101
126
|
snapshot(id) {
|
|
102
127
|
return runs.get(id) ?? null;
|
|
103
128
|
},
|
|
@@ -136,6 +161,7 @@ export function createLongTaskHost(options) {
|
|
|
136
161
|
offs.push(registry.onChange((change) => {
|
|
137
162
|
const named = [runsRouteOf(options.unit), ...(facts?.(change) ?? [])];
|
|
138
163
|
options.bump([...new Set(named)]);
|
|
164
|
+
options.notify?.(change);
|
|
139
165
|
}));
|
|
140
166
|
return registry;
|
|
141
167
|
},
|
package/dist/host/unit-face.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ import type { UnitCapability } from './unit-libs.js';
|
|
|
7
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
|
+
export interface ToolScopeContext {
|
|
11
|
+
readonly workspace: string | null;
|
|
12
|
+
readonly preset: string | null;
|
|
13
|
+
}
|
|
10
14
|
export interface UnitMountDeps {
|
|
11
15
|
readonly manifest: UnitManifest;
|
|
12
16
|
readonly ctx: DshHostContext;
|
|
@@ -24,6 +28,7 @@ export interface UnitMountDeps {
|
|
|
24
28
|
readonly force?: boolean;
|
|
25
29
|
}) => Promise<UnitCapability | undefined>;
|
|
26
30
|
readonly longTasks?: LongTaskHost | undefined;
|
|
31
|
+
readonly longTaskRuns?: (() => ReadonlyMap<string, LongTaskRegistry<LongTaskBase>>) | undefined;
|
|
27
32
|
}
|
|
28
33
|
export type ContextRenderer = (ref: {
|
|
29
34
|
readonly kind: string;
|
|
@@ -40,7 +45,7 @@ export interface UnitMountResult {
|
|
|
40
45
|
registerTools(): Array<() => void>;
|
|
41
46
|
readonly factsOf?: ((call: UnitCall) => readonly string[] | undefined) | undefined;
|
|
42
47
|
readonly gate?: {
|
|
43
|
-
deniedTools(
|
|
48
|
+
deniedTools(context: ToolScopeContext): readonly string[];
|
|
44
49
|
subscribe(listener: () => void): () => void;
|
|
45
50
|
};
|
|
46
51
|
readonly context?: {
|
package/dist/i18n/en.d.ts
CHANGED
package/dist/i18n/en.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** 外壳自带的英文词表:键必须与 `zh` 逐一对应,值不许为空串。 */
|
|
1
2
|
export const en = {
|
|
2
3
|
'brand.name': 'Workbench',
|
|
3
4
|
'toggle.open': 'Open sidebar',
|
|
@@ -408,20 +409,19 @@ export const en = {
|
|
|
408
409
|
'configSync.noSource': 'This machine has no other profile to sync from',
|
|
409
410
|
'configSync.emptyProviders': 'The workbench has no model provider yet — sync the llm- rows from some profile, or configure one under Models.',
|
|
410
411
|
'configSync.failed': 'The sync did not go through; try again.',
|
|
411
|
-
'debug.
|
|
412
|
-
'debug.status
|
|
413
|
-
'debug.
|
|
412
|
+
'debug.workspace': 'this workspace',
|
|
413
|
+
'debug.status': 'Debugging “{title}”',
|
|
414
|
+
'debug.status.trouble': 'Debugging needs your attention ({title})',
|
|
415
|
+
'debug.stalled': 'Debugging paused ({title})',
|
|
414
416
|
'debug.act.pause': 'Pause debugging',
|
|
415
417
|
'debug.act.resume': 'Resume debugging',
|
|
416
418
|
'debug.act.stop': 'Stop debugging',
|
|
417
419
|
'debug.act.stop.ask': 'Confirm stop',
|
|
418
|
-
'debug.card.here.title': '
|
|
420
|
+
'debug.card.here.title': 'Debugging “{title}”',
|
|
419
421
|
'debug.card.here.note': 'Do not switch workspaces or touch the panel',
|
|
420
|
-
'debug.card.away.
|
|
421
|
-
'debug.card.away.note': 'Switch to the Workbench DIY workspace',
|
|
422
|
+
'debug.card.away.note': 'Switch back to “{title}”',
|
|
422
423
|
'debug.card.paused.note': 'Paused',
|
|
423
|
-
'debug.card.hidden.note': 'Switch to the Workbench panel',
|
|
424
|
-
'debug.back': 'Back to the workshop screen',
|
|
424
|
+
'debug.card.hidden.note': 'Switch back to the Workbench panel',
|
|
425
425
|
'record.waiting': 'Recording handoff · your turn',
|
|
426
426
|
'record.waiting.note': 'Press "Start recording" on that page, then "Stop recording" when done (it will not switch you back)',
|
|
427
427
|
'record.recording': 'Recording',
|
|
@@ -436,4 +436,6 @@ export const en = {
|
|
|
436
436
|
'approval.record.noUrl': 'no site given (this call gets refused)',
|
|
437
437
|
'approval.record.oneAction': 'one action',
|
|
438
438
|
'approval.record.noSwitch': 'it will not switch you back (the leftbar footer shows the state)',
|
|
439
|
+
'approval.longTask.what': 'Stops',
|
|
440
|
+
'approval.longTask.signal': 'stopping only sends an interrupt signal — how the platform-side run finishes is up to the module',
|
|
439
441
|
};
|