@dsh-workbench/core 0.2.13 → 0.2.15
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/client.js +700 -124
- package/dist/client/client.body.js +700 -124
- package/dist/client/index.js +701 -125
- package/dist/host/index.js +387 -22
- package/dist/types/app/client.d.ts +124 -6
- package/dist/types/app/layouts/rightbar/DebugStrip.d.ts +11 -0
- package/dist/types/app/layouts/rightbar/kit-preview-controls.d.ts +1 -0
- package/dist/types/app/layouts/sidebar/DebugFooterAction.d.ts +13 -0
- package/dist/types/app/layouts/sidebar/ProjectSwitcher.d.ts +4 -1
- package/dist/types/app/layouts/sidebar/SidebarHeader.d.ts +12 -0
- package/dist/types/app/layouts/sidebar/WorkspaceAttentionDot.d.ts +9 -0
- package/dist/types/app/layouts/sidebar/WorkspaceAttentionTag.d.ts +7 -0
- package/dist/types/app/layouts/sidebar/__tests__/current-workspace.test.d.ts +1 -0
- package/dist/types/app/layouts/sidebar/__tests__/debug-ui.test.d.ts +1 -0
- package/dist/types/app/layouts/sidebar/current-workspace.d.ts +8 -0
- package/dist/types/app/layouts/sidebar/debug-footer.d.ts +4 -0
- package/dist/types/app/layouts/sidebar/session-pick.d.ts +2 -1
- package/dist/types/app/layouts/sidebar/use-attention.d.ts +16 -0
- package/dist/types/app/layouts/sidebar/workspace-items.d.ts +2 -0
- package/dist/types/modules/panels/__tests__/diy-harness.d.ts +6 -3
- package/dist/types/modules/panels/model/diy-browser.d.ts +3 -0
- package/dist/types/modules/panels/model/diy-debug-routes.d.ts +2 -0
- package/dist/types/modules/panels/model/diy-debug-routes.test.d.ts +1 -0
- package/dist/types/modules/panels/model/diy-debug-tools.d.ts +8 -0
- package/dist/types/modules/panels/model/diy-debug-tools.test.d.ts +1 -0
- package/dist/types/modules/panels/model/diy-look.d.ts +2 -1
- package/dist/types/modules/panels/model/diy-page.d.ts +12 -0
- package/dist/types/modules/panels/model/diy-scripts.d.ts +2 -1
- package/dist/types/modules/panels/model/diy-tools.d.ts +2 -1
- package/dist/types/modules/panels/model/handoff.d.ts +1 -0
- package/dist/types/modules/panels/unit.d.ts +7 -2
- package/dist/types/modules/sessions/index.d.ts +1 -0
- package/dist/types/modules/sessions/model/attention.d.ts +29 -0
- package/dist/types/modules/sessions/model/attention.test.d.ts +1 -0
- package/dist/types/shared/hooks/use-api-resource.d.ts +1 -0
- package/dist/types/shared/hooks/use-diy-debug.d.ts +4 -0
- package/package.json +2 -2
- package/skills/workbench-module-diy/BUILD.md +1 -1
- package/skills/workbench-module-diy/DATASOURCE.md +1 -1
- package/skills/workbench-module-diy/KIT.md +22 -5
- package/skills/workbench-module-diy/PANEL.md +1 -1
- package/skills/workbench-module-diy/REVIEW.md +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SessionsSnapshot, WorkspaceView } from '@dsh-workbench/shared';
|
|
2
|
+
export interface CurrentWorkspaceInput {
|
|
3
|
+
readonly items: readonly WorkspaceView[];
|
|
4
|
+
readonly sessions: SessionsSnapshot;
|
|
5
|
+
readonly panelActive: boolean;
|
|
6
|
+
readonly storedId: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveCurrentWorkspace(input: CurrentWorkspaceInput): WorkspaceView | null;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { SessionsSnapshot, WorkspaceView } from '@dsh-workbench/shared';
|
|
1
|
+
import type { SessionStatusSnapshot, SessionsSnapshot, WorkspaceView } from '@dsh-workbench/shared';
|
|
2
2
|
export interface PickProjectInput {
|
|
3
3
|
readonly workspaceId: string;
|
|
4
4
|
readonly items: readonly WorkspaceView[];
|
|
5
5
|
readonly sessions: SessionsSnapshot;
|
|
6
|
+
readonly statusById: SessionStatusSnapshot;
|
|
6
7
|
readonly archivedIds: ReadonlySet<string>;
|
|
7
8
|
readonly openSession: (sessionId: string) => void;
|
|
8
9
|
readonly startSession: (workspaceId: string) => void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SessionStatusSnapshot, SessionsSnapshot, WorkspaceView } from '@dsh-workbench/shared';
|
|
2
|
+
import { type Attention } from '../../../modules/sessions';
|
|
3
|
+
export interface SidebarAttentionInput {
|
|
4
|
+
readonly items: readonly WorkspaceView[];
|
|
5
|
+
readonly sessions: SessionsSnapshot;
|
|
6
|
+
readonly statusById: SessionStatusSnapshot;
|
|
7
|
+
readonly archived: readonly string[];
|
|
8
|
+
readonly storedId: string | null;
|
|
9
|
+
readonly panelActive: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface SidebarAttentionState {
|
|
12
|
+
readonly current: WorkspaceView | null;
|
|
13
|
+
readonly archivedIds: ReadonlySet<string>;
|
|
14
|
+
readonly attention: Attention;
|
|
15
|
+
}
|
|
16
|
+
export declare function useSidebarAttention(input: SidebarAttentionInput): SidebarAttentionState;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { SelectFieldOption, Translate, WorkspaceView } from '@dsh-workbench/shared';
|
|
2
|
+
import type { WorkspaceAttention } from '../../../modules/sessions';
|
|
2
3
|
import type { WorkspaceSectionPlan } from './workspace-groups';
|
|
3
4
|
export interface WorkspaceItemsOptions {
|
|
4
5
|
readonly sections: readonly WorkspaceSectionPlan<WorkspaceView>[];
|
|
5
6
|
readonly currentId: string | null;
|
|
6
7
|
readonly hoverId: string | null;
|
|
7
8
|
readonly t: Translate;
|
|
9
|
+
readonly attention: ReadonlyMap<string, WorkspaceAttention>;
|
|
8
10
|
readonly onHover: (workspaceId: string | null) => void;
|
|
9
11
|
readonly onEdit: (workspace: WorkspaceView) => void;
|
|
10
12
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { UnitManifest } from '@dsh-workbench/shared';
|
|
2
|
-
import { type PanelStateStore } from '@dsh-workbench/shared/host';
|
|
2
|
+
import { type DebugStore, type PanelStateStore } from '@dsh-workbench/shared/host';
|
|
3
3
|
import type { BundleInstallOutcome } from '../model/market';
|
|
4
4
|
import { panelsUnit } from '../unit';
|
|
5
5
|
export type Application = 'applied' | 'restart-required' | 'overridden' | 'cancelled' | 'failed';
|
|
@@ -20,10 +20,11 @@ export declare function createDiyRig(): {
|
|
|
20
20
|
scaffold: (unit: string, description?: string) => string;
|
|
21
21
|
markInstalled: (pkg: string, at: string) => void;
|
|
22
22
|
outcomeOf: (application: Application) => BundleInstallOutcome;
|
|
23
|
-
diyExec: () => unknown;
|
|
23
|
+
diyExec: (sessionId?: string) => unknown;
|
|
24
24
|
NORMAL_EXEC: {
|
|
25
25
|
agent: {
|
|
26
26
|
session: {
|
|
27
|
+
id: string;
|
|
27
28
|
header: {
|
|
28
29
|
cwd: string;
|
|
29
30
|
};
|
|
@@ -46,6 +47,7 @@ export declare function createDiyRig(): {
|
|
|
46
47
|
}[];
|
|
47
48
|
failures?: Readonly<Record<string, string>>;
|
|
48
49
|
panelState?: PanelStateStore;
|
|
50
|
+
debug?: DebugStore;
|
|
49
51
|
}) => {
|
|
50
52
|
specs: string[];
|
|
51
53
|
registered: {
|
|
@@ -59,7 +61,7 @@ export declare function createDiyRig(): {
|
|
|
59
61
|
execute: (args: unknown, exec?: unknown) => Promise<unknown>;
|
|
60
62
|
};
|
|
61
63
|
ctx: {
|
|
62
|
-
get: (key: string) => PanelStateStore | {
|
|
64
|
+
get: (key: string) => DebugStore | PanelStateStore | {
|
|
63
65
|
all: () => {
|
|
64
66
|
unit: string;
|
|
65
67
|
}[];
|
|
@@ -86,6 +88,7 @@ export declare function createDiyRig(): {
|
|
|
86
88
|
};
|
|
87
89
|
panels: import("../model/service").PanelsService;
|
|
88
90
|
panelState: PanelStateStore;
|
|
91
|
+
debug: DebugStore;
|
|
89
92
|
registry: {
|
|
90
93
|
all: () => {
|
|
91
94
|
unit: string;
|
|
@@ -23,6 +23,9 @@ export interface WorkbenchPage {
|
|
|
23
23
|
readonly ok: boolean;
|
|
24
24
|
readonly url: string;
|
|
25
25
|
readonly title: string;
|
|
26
|
+
readonly board: string;
|
|
27
|
+
readonly open: boolean | null;
|
|
28
|
+
readonly shown: boolean;
|
|
26
29
|
}
|
|
27
30
|
export declare function workbenchPageOf(shell: DshShell, command: string, session: string): Promise<WorkbenchPage>;
|
|
28
31
|
export declare function writeShotsDir(shell: DshShell, dir: string): Promise<boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DshHostContext, DshToolRegistry } from '@dsh-workbench/shared';
|
|
2
|
+
import type { DebugRefusal, DebugState, DebugStore } from '@dsh-workbench/shared/host';
|
|
3
|
+
export declare function debugRefusalText(code: DebugRefusal, held?: DebugState): string;
|
|
4
|
+
export declare function renderDebugStart(state: DebugState): string;
|
|
5
|
+
export declare function renderDebugPause(state: DebugState): string;
|
|
6
|
+
export declare function renderDebugResume(state: DebugState): string;
|
|
7
|
+
export declare function renderDebugStop(state: DebugState): string;
|
|
8
|
+
export declare function registerDebugTools(ctx: DshHostContext, tools: DshToolRegistry, store: DebugStore): readonly (() => void)[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DshHostContext, DshToolRegistry } from '@dsh-workbench/shared';
|
|
2
|
+
import { type BoardState } from './diy-page';
|
|
2
3
|
import { type Shot } from './diy-browser';
|
|
3
4
|
import { type CardView, type PickRequest, type SlotFacts } from './diy-scripts';
|
|
4
5
|
export declare function registerLookTools(ctx: DshHostContext, tools: DshToolRegistry): readonly (() => void)[];
|
|
@@ -11,4 +12,4 @@ export declare function slotLineOf(view: CardView): string;
|
|
|
11
12
|
export declare function outlineText(view: CardView): string;
|
|
12
13
|
export declare function contrastLineOf(view: CardView): string;
|
|
13
14
|
export declare function renderLook(unit: string, view: CardView, shot: Shot, pick: PickRequest): string;
|
|
14
|
-
export declare function renderMissingCard(unit: string,
|
|
15
|
+
export declare function renderMissingCard(unit: string, view: CardView, board: BoardState): string;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { DshHostContext, DshShell, DshToolRunContext } from '@dsh-workbench/shared';
|
|
2
|
+
import type { DebugState } from '@dsh-workbench/shared/host';
|
|
3
|
+
import { type WorkbenchPage } from './diy-browser';
|
|
4
|
+
export type BoardState = 'workshop' | 'other' | 'hidden' | 'unknown';
|
|
2
5
|
export interface PageHandle {
|
|
3
6
|
readonly packagesDir: string;
|
|
4
7
|
readonly unit: string;
|
|
@@ -7,9 +10,18 @@ export interface PageHandle {
|
|
|
7
10
|
readonly command: string;
|
|
8
11
|
readonly session: string;
|
|
9
12
|
readonly bound: boolean;
|
|
13
|
+
readonly board: BoardState;
|
|
14
|
+
readonly boardPath: string;
|
|
10
15
|
}
|
|
11
16
|
export interface PageOptions {
|
|
12
17
|
readonly requireWorkbench?: boolean | undefined;
|
|
13
18
|
readonly requireUnit?: boolean | undefined;
|
|
19
|
+
readonly requireBoard?: 'workshop' | false | undefined;
|
|
20
|
+
readonly requirePact?: boolean | undefined;
|
|
14
21
|
}
|
|
22
|
+
export declare function debugPausedText(held: DebugState): string;
|
|
23
|
+
export declare function debugForeignPactText(held: DebugState): string;
|
|
24
|
+
export declare function debugStalledText(held: DebugState): string;
|
|
25
|
+
export declare function boardStateOf(page: WorkbenchPage, workshop: string | null): BoardState;
|
|
26
|
+
export declare function boardGateText(board: BoardState, unit: string, page: WorkbenchPage, workshop: string | null): string;
|
|
15
27
|
export declare function pageAt(ctx: DshHostContext, exec: DshToolRunContext, raw: unknown, options?: PageOptions): Promise<PageHandle>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const PAGE_PROBE = "(async () => {\n const answer = await fetch('/workbench/api/health').then((one) => one.json()).catch(() => null);\n return JSON.stringify({\n plugin: answer === null ? null : answer.plugin,\n pid: answer === null ? null : answer.pid,\n url: location.href,\n title: document.title,\n });\n})()";
|
|
1
|
+
export declare const PAGE_PROBE = "(async () => {\n const answer = await fetch('/workbench/api/health').then((one) => one.json()).catch(() => null);\n const bar = document.querySelector('.wb-rightbar');\n const board = bar === null ? '' : (bar.getAttribute('data-wb-board') ?? '');\n const open = bar === null ? null : bar.hasAttribute('data-wb-open');\n const shown = bar === null ? false : getComputedStyle(bar).visibility !== 'hidden';\n return JSON.stringify({\n plugin: answer === null ? null : answer.plugin,\n pid: answer === null ? null : answer.pid,\n url: location.href,\n title: document.title,\n board,\n open,\n shown,\n });\n})()";
|
|
2
2
|
export declare function cardSelectorOf(unit: string): string;
|
|
3
3
|
export type DomMode = 'none' | 'outline' | 'html';
|
|
4
4
|
export interface PickRequest {
|
|
@@ -18,6 +18,7 @@ export declare function pickOf(raw: Record<string, unknown>): PickRequest;
|
|
|
18
18
|
export interface CardView {
|
|
19
19
|
readonly ok: boolean;
|
|
20
20
|
readonly anchored: boolean;
|
|
21
|
+
readonly visible: boolean;
|
|
21
22
|
readonly width: number;
|
|
22
23
|
readonly height: number;
|
|
23
24
|
readonly head: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DshHostContext } from '@dsh-workbench/shared';
|
|
2
|
+
import type { DebugStore } from '@dsh-workbench/shared/host';
|
|
2
3
|
import type { MarketService } from './market';
|
|
3
4
|
import type { PanelsService } from './service';
|
|
4
|
-
export declare function registerDiyTools(ctx: DshHostContext, market: MarketService, panels: PanelsService): Array<() => void>;
|
|
5
|
+
export declare function registerDiyTools(ctx: DshHostContext, market: MarketService, panels: PanelsService, debug: DebugStore): Array<() => void>;
|
|
@@ -2,6 +2,7 @@ import type { UnitCall } from '@dsh-workbench/shared/host';
|
|
|
2
2
|
import type { HandoffEntry } from '@dsh-workbench/shared/host';
|
|
3
3
|
import type { UnitManifest } from '@dsh-workbench/shared/host';
|
|
4
4
|
export declare const PANELS_FACT = "panels";
|
|
5
|
+
export declare const DIY_DEBUG_FACT = "diy-debug";
|
|
5
6
|
export declare function panelsHandoffEntry(target?: {
|
|
6
7
|
readonly path?: string | undefined;
|
|
7
8
|
}): HandoffEntry | undefined;
|
|
@@ -37,9 +37,14 @@ export declare const DIY_NET_STOP_TOOL = "workbench_diy_net_stop";
|
|
|
37
37
|
export declare const DIY_LOGS_WATCH_TOOL = "workbench_diy_logs_watch";
|
|
38
38
|
export declare const DIY_LOGS_READ_TOOL = "workbench_diy_logs_read";
|
|
39
39
|
export declare const DIY_LOGS_STOP_TOOL = "workbench_diy_logs_stop";
|
|
40
|
-
export declare const
|
|
40
|
+
export declare const DIY_DEBUG_START_TOOL = "workbench_diy_debug_start";
|
|
41
|
+
export declare const DIY_DEBUG_PAUSE_TOOL = "workbench_diy_debug_pause";
|
|
42
|
+
export declare const DIY_DEBUG_RESUME_TOOL = "workbench_diy_debug_resume";
|
|
43
|
+
export declare const DIY_DEBUG_STOP_TOOL = "workbench_diy_debug_stop";
|
|
44
|
+
export declare const ALL_TOOLS: readonly ["workbench_panels_list", "workbench_panels_show", "workbench_panels_hide", "workbench_panels_move", "workbench_panels_reset", "workbench_panels_follow", "workbench_modules_list", "workbench_modules_install", "workbench_modules_update", "workbench_modules_uninstall", "workbench_modules_install_bundle", "workbench_modules_update_dependency", "workbench_modules_update_plugin", "workbench_modules_uninstall_plugin", "workbench_modules_update_workbench", "workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_recon", "workbench_diy_probe", "workbench_diy_look", "workbench_diy_install", "workbench_diy_show", "workbench_diy_click", "workbench_diy_type", "workbench_diy_fill", "workbench_diy_keys", "workbench_diy_hover", "workbench_diy_select", "workbench_diy_scroll", "workbench_diy_reload", "workbench_diy_viewport", "workbench_diy_net_watch", "workbench_diy_net_read", "workbench_diy_net_stop", "workbench_diy_logs_watch", "workbench_diy_logs_read", "workbench_diy_logs_stop", "workbench_diy_debug_start", "workbench_diy_debug_pause", "workbench_diy_debug_resume", "workbench_diy_debug_stop"];
|
|
41
45
|
export type PanelsToolName = (typeof ALL_TOOLS)[number];
|
|
42
46
|
export declare const READ_TOOLS: readonly ["workbench_panels_list", "workbench_modules_list", "workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_recon", "workbench_diy_probe", "workbench_diy_look", "workbench_diy_click", "workbench_diy_type", "workbench_diy_fill", "workbench_diy_keys", "workbench_diy_hover", "workbench_diy_select", "workbench_diy_scroll", "workbench_diy_reload", "workbench_diy_viewport", "workbench_diy_net_watch", "workbench_diy_net_read", "workbench_diy_net_stop", "workbench_diy_logs_watch", "workbench_diy_logs_read", "workbench_diy_logs_stop"];
|
|
43
|
-
export declare const WRITE_TOOLS: readonly ["workbench_panels_show", "workbench_panels_hide", "workbench_panels_move", "workbench_panels_reset", "workbench_panels_follow", "workbench_modules_install", "workbench_modules_update", "workbench_modules_uninstall", "workbench_modules_install_bundle", "workbench_modules_update_dependency", "workbench_modules_update_plugin", "workbench_modules_uninstall_plugin", "workbench_modules_update_workbench", "workbench_diy_install", "workbench_diy_show"];
|
|
47
|
+
export declare const WRITE_TOOLS: readonly ["workbench_panels_show", "workbench_panels_hide", "workbench_panels_move", "workbench_panels_reset", "workbench_panels_follow", "workbench_modules_install", "workbench_modules_update", "workbench_modules_uninstall", "workbench_modules_install_bundle", "workbench_modules_update_dependency", "workbench_modules_update_plugin", "workbench_modules_uninstall_plugin", "workbench_modules_update_workbench", "workbench_diy_install", "workbench_diy_show", "workbench_diy_debug_start", "workbench_diy_debug_pause", "workbench_diy_debug_resume", "workbench_diy_debug_stop"];
|
|
44
48
|
export declare const DIY_TOOLS: readonly ["workbench_diy_list", "workbench_diy_status", "workbench_diy_panel", "workbench_diy_recon", "workbench_diy_probe", "workbench_diy_look", "workbench_diy_install", "workbench_diy_show", "workbench_diy_click", "workbench_diy_type", "workbench_diy_fill", "workbench_diy_keys", "workbench_diy_hover", "workbench_diy_select", "workbench_diy_scroll", "workbench_diy_reload", "workbench_diy_viewport", "workbench_diy_net_watch", "workbench_diy_net_read", "workbench_diy_net_stop", "workbench_diy_logs_watch", "workbench_diy_logs_read", "workbench_diy_logs_stop"];
|
|
49
|
+
export declare const DIY_DEBUG_TOOLS: readonly ["workbench_diy_debug_start", "workbench_diy_debug_pause", "workbench_diy_debug_resume", "workbench_diy_debug_stop"];
|
|
45
50
|
export declare const panelsUnit: UnitManifest;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { currentSessionId, orderByRecency, sessionNode, orderSessionRows, sessionRows, workspaceOfSession, sessionStatuses, visiblePendingKind, type SessionNode, type SessionStatusDot, } from './model/session-node';
|
|
2
2
|
export { scrollEdgesOf, type ScrollEdges } from './model/scroll-edges';
|
|
3
|
+
export { attentionLabel, attentionOf, attentionOfSession, attentionSessionIdOf, attentionWordLabel, type Attention, type AttentionInput, type AttentionSeverity, type WorkspaceAttention, } from './model/attention';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SessionStatusSnapshot, SessionSummary, SessionsSnapshot, Translate, WorkspaceView } from '@dsh-workbench/shared';
|
|
2
|
+
export type AttentionSeverity = 'warning' | 'ongoing' | 'done';
|
|
3
|
+
export interface WorkspaceAttention {
|
|
4
|
+
readonly severity: AttentionSeverity;
|
|
5
|
+
readonly count: number;
|
|
6
|
+
}
|
|
7
|
+
export interface Attention {
|
|
8
|
+
readonly byWorkspace: ReadonlyMap<string, WorkspaceAttention>;
|
|
9
|
+
readonly elsewhere: WorkspaceAttention | null;
|
|
10
|
+
readonly overall: WorkspaceAttention | null;
|
|
11
|
+
}
|
|
12
|
+
export interface AttentionInput {
|
|
13
|
+
readonly workspaces: readonly WorkspaceView[];
|
|
14
|
+
readonly sessions: SessionsSnapshot;
|
|
15
|
+
readonly statusById: SessionStatusSnapshot;
|
|
16
|
+
readonly archivedIds: ReadonlySet<string>;
|
|
17
|
+
readonly currentWorkspaceId: string | null;
|
|
18
|
+
}
|
|
19
|
+
export declare function attentionOfSession(summary: SessionSummary, statusById: SessionStatusSnapshot, sessions: SessionsSnapshot): AttentionSeverity | undefined;
|
|
20
|
+
export interface AttentionPickInput {
|
|
21
|
+
readonly workspace: WorkspaceView | null;
|
|
22
|
+
readonly sessions: SessionsSnapshot;
|
|
23
|
+
readonly statusById: SessionStatusSnapshot;
|
|
24
|
+
readonly archivedIds: ReadonlySet<string>;
|
|
25
|
+
}
|
|
26
|
+
export declare function attentionSessionIdOf(input: AttentionPickInput): string | null;
|
|
27
|
+
export declare function attentionOf(input: AttentionInput): Attention;
|
|
28
|
+
export declare function attentionLabel(attention: WorkspaceAttention, t: Translate): string;
|
|
29
|
+
export declare function attentionWordLabel(attention: WorkspaceAttention, t: Translate): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-workbench/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"description": "个人工作台:Agent 工作台外壳(左栏 + 常驻对话 + 自研右侧数据面板)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"icon": "./icon.svg",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"access": "public"
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@dsh-workbench/shared": "0.2.
|
|
90
|
+
"@dsh-workbench/shared": "0.2.15"
|
|
91
91
|
},
|
|
92
92
|
"scripts": {
|
|
93
93
|
"build": "node scripts/build.mjs && node scripts/build-types.mjs",
|
|
@@ -145,6 +145,6 @@ export function apply(ctx) {
|
|
|
145
145
|
"空"和"还没开始"是两件事,说错了他会去查他根本没配的东西。
|
|
146
146
|
|
|
147
147
|
**卡片必须在拿不到数据时也画得出来**(第一次读、卡在审批、平台没登录)。
|
|
148
|
-
|
|
148
|
+
任何一种输入(待机 / 在读 / 有值 / 有值但空 / 读不到)下抛异常、屏上冒出 `undefined` / `NaN` 的卡片 = 用户眼里的"卡片一直不出来"。这是 `check:cards` 守的那条。
|
|
149
149
|
|
|
150
150
|
→ 拿到依赖、装上、改一行、发出去:[WIRING.md](WIRING.md)。
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
| 超时 / 网络不通 | "这次没读到,稍后重试" + 重试 |
|
|
98
98
|
| 站点改版、字段没了 | "读到的形状和预期不一样"(别显示空白,也别显示 0) |
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
任何一种输入(待机 / 在读 / 有值 / 有值但空 / 读不到)下抛异常、屏上冒出 `undefined` / `NaN` 的卡片 = 用户眼里的"卡片一直不出来"。这条 `check:cards` 会拦(见 [REVIEW.md](REVIEW.md))。
|
|
101
101
|
|
|
102
102
|
## 错误码不是随便写的(阻断屏按它换文案)
|
|
103
103
|
|
|
@@ -86,6 +86,20 @@ h(Field, { label: t('myunit.mode'), hint: t('myunit.modeHint') },
|
|
|
86
86
|
**`SelectField`** —— 下拉:默认是**常规下拉框**(跟 `TextField` 一套),无边框那种给 `variant: 'ghost'`;
|
|
87
87
|
搜索、分组、禁用项、加载态、空态、页脚都是它的 prop。
|
|
88
88
|
**`SaveBar`** —— 设置面底下那条"取消 / 保存"(`busy` / `disabled` / `labels` / `onCancel` / `onSave`)。
|
|
89
|
+
**`FormActions`** —— **操作区**(一组按钮):`actions: { key, label, kind?: 'default' | 'danger' | 'primary', onClick, disabled?, busy? }[]`。
|
|
90
|
+
**顺序 / 间距 / 换行都归它** —— `primary` 永远在右、`danger` 紧挨它左侧、一个区只许一颗 `primary`、
|
|
91
|
+
窄了自动折行且 `primary` 落在右下角;`busy` 自带 `Spinner`。调用点只给"有哪些动作、哪个是主要、点了做什么":
|
|
92
|
+
**别自己写 `gap` / `margin` / 顺序,也别借 `.wb-formActions` 槽类手摆**(`check:style` 的 F3 会红,没有豁免)。
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
h(FormActions, { actions: [
|
|
96
|
+
{ key: 'retry', label: t('myunit.retry'), onClick: onRetry, disabled: busy },
|
|
97
|
+
{ key: 'confirm', label: t('myunit.confirm'), kind: 'primary', onClick: submit, disabled: busy },
|
|
98
|
+
] })
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`danger` 只标"这是破坏性的"(渲成描边 + 危险色,**永远不当填充的 `primary`**);**二次确认那半归调用点**
|
|
102
|
+
(先问一句或弹窗都行),口径见 [ADR-0054](../../../../docs/adr/0054-the-action-area-is-one-component.md) §2 规则三。
|
|
89
103
|
|
|
90
104
|
**别手写 `<button>` / `<input>` / `<select>`**:dsh 有 `Button`(`variant` / `size`),
|
|
91
105
|
kit 有上面这几件;手写的会拿到浏览器默认样式,而且**判据会红**(`check:style`)。
|
|
@@ -124,7 +138,9 @@ h(FormRows, null,
|
|
|
124
138
|
是一个意思;**loading 那颗一律是 `Spinner`**(`h(Spinner, { size: 14 })`)—— **别自己写转圈**。
|
|
125
139
|
|
|
126
140
|
**尺寸口径**:字段控件默认 **28**(dsh 紧凑档),**别自己调高**;行距**只有一档**、归 `FormRow(s)`,
|
|
127
|
-
模块里不该出现管行距的 `gap` / `margin
|
|
141
|
+
模块里不该出现管行距的 `gap` / `margin`(横向的、卡片/清单网格的不算)。标签列也归它:
|
|
142
|
+
**长标签不折行;同一 `FormRows` 共用一个标签列(列宽由最长的标签定),别自己给标签写宽度**
|
|
143
|
+
(非行的子项,比如分组标题 `<p>`,自动通栏)。
|
|
128
144
|
|
|
129
145
|
**反例(别这么写)**:
|
|
130
146
|
|
|
@@ -134,12 +150,13 @@ h('div', { className: styles.form }, …) // ← .form { gap:
|
|
|
134
150
|
```
|
|
135
151
|
|
|
136
152
|
`<span className={styles.label}>` 紧邻控件、或给表单容器自己写 `gap` —— 这正是 `check:style` 那条
|
|
137
|
-
棘轮(F1 手写行 / F2 自己管行距)盯的东西;`FORM_ROW_EXEMPT`
|
|
138
|
-
|
|
153
|
+
棘轮(F1 手写行 / F2 自己管行距)盯的东西;`FORM_ROW_EXEMPT` 是这张表的历史账,**2026-10-17 已经清空**
|
|
154
|
+
(外壳 0.2.13 之后按"迁一处删一行"迁完,ADR-0052 §10)—— 表空了仍然**不是"可以继续这么写"的许可**:
|
|
155
|
+
现在再这么写直接红,没有豁免那一层。
|
|
139
156
|
|
|
140
157
|
**时点**:这一层随外壳**发版**后模块才能用 —— 模块的 `peerDependencies` 下限得先有它
|
|
141
158
|
(`check:kit` 拿 peer 下限那份外壳比,不抬必红);迁移步骤见
|
|
142
|
-
[ADR-0052](../../../../docs/adr/0052-the-form-row-is-one-component.md) §10
|
|
159
|
+
[ADR-0052](../../../../docs/adr/0052-the-form-row-is-one-component.md) §10。已迁完的包下限在 `^0.2.14`。
|
|
143
160
|
|
|
144
161
|
## 6 别的
|
|
145
162
|
|
|
@@ -149,7 +166,7 @@ h('div', { className: styles.form }, …) // ← .form { gap:
|
|
|
149
166
|
- **`Stack`** —— 竖排 + 统一间距(懒得分组时的默认容器)。
|
|
150
167
|
- **`BlockerState`** —— 阻断屏:要登录 / 没权限 / 能力没装好那一类(`blocker` / `t` / `onRetry` / `onOpenMarket`)。
|
|
151
168
|
- **`Tip`** —— Tooltip:图标钮与只有图的地方**必须**有它(或 `aria-label`)。
|
|
152
|
-
- **别给模块带夹具**:2026-10-16 起模板 / `init` 文案 / 这份指引都不带评审夹具了(`?wbMock=1` 那套、`useFixturePick` / `MockStrip` / `mockNote` 都从模板里删了)。夹具是模块作者负担里最不值的那一份 —— 而**你自己那份 `plugin.test.ts`
|
|
169
|
+
- **别给模块带夹具**:2026-10-16 起模板 / `init` 文案 / 这份指引都不带评审夹具了(`?wbMock=1` 那套、`useFixturePick` / `MockStrip` / `mockNote` 都从模板里删了)。夹具是模块作者负担里最不值的那一份 —— 而**你自己那份 `plugin.test.ts` 就能把五态各喂一遍**,而 `check:cards` 会拿七种外壳侧输入各喂一遍(它只问"退化得干不干净",不断言"画的是哪一态那一屏")。外壳自己那套 `?wbMock=1` 夹具是给**外壳的卡片**用的,模块不必跟(机制仍在,谁想要仍然可以用,但**不是你要做的事**)。
|
|
153
170
|
- **图标** —— `IconPanelScreen`(面板/卡片那类)、`IconModuleMark`(我们的模块类型标)、
|
|
154
171
|
`IconNpm` / `IconOpencli`(包类型);其余图形一律从 dsh 的 `Icon*Regular` 拿,**别自己画图标**。
|
|
155
172
|
|
|
@@ -164,7 +164,7 @@ agent 那一侧也要能通过模块自己的能力读到同一份偏好。
|
|
|
164
164
|
- **平台没给的那一格就不占位**(不留孤零零的字段名、不留空的一行)。
|
|
165
165
|
- **读不到就说读不到**,并说清为什么(例:手上这份能力太旧);**绝不显示 0**。
|
|
166
166
|
- 有确定答案就不打扰他(能按默认读出来就别弹设置面)。
|
|
167
|
-
- 真机上造不出来的状态也要**在设计上**画出来(照这一格写清)—— 但**不必为它写夹具**:2026-10-16 起模板与指引都不带评审夹具,模块自己的 `plugin.test.ts`
|
|
167
|
+
- 真机上造不出来的状态也要**在设计上**画出来(照这一格写清)—— 但**不必为它写夹具**:2026-10-16 起模板与指引都不带评审夹具,模块自己的 `plugin.test.ts` 把五态各喂一遍就够(`check:cards` 会拿**七种外壳侧输入**各喂一遍 —— 它只问"退化得干不干净",**不断言**"画的是哪一态那一屏")。
|
|
168
168
|
|
|
169
169
|
### 7.1 图例就是把屏幕画成 ASCII
|
|
170
170
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
| `source` | 非种子词的 `@deepseek-ai/*`、宿主侧碰 dsh 的浏览器包、`@/` 指到工作台源码 | `…在宿主侧可达` / `不是平台种子词` | 宿主侧只用 Node 侧的东西;dsh 原语一律走 `kit`;`@/` 只指自己的 `src/` |
|
|
12
12
|
| `primitives` | 声明了 `external` 却没有产物物证 ⇒ dsh 原语被**内联**成第二份实例 | `…用了却没声明 external` / `宿主产物里出现了` | 在 `dsh.client.external` 里显式声明它;确认产物里是 `require(...)` 而不是被打包进来 |
|
|
13
13
|
| `kit` | 用了 peer 下限那份外壳**还没有**的 kit 成员 ⇒ 卡片首帧 `Element type is invalid`,整块面板被 React 卸掉 | `kit.components.X 在这份外壳里没有` / `peer 下限比 devDependency 还旧` | 只用 peer 范围里真有的成员;把 `peerDependencies` 的下限提到你实际用的那档 |
|
|
14
|
-
| `cards` |
|
|
14
|
+
| `cards` | 卡片在某一种**外壳侧输入**下崩 / 空白 / 变脏 ⇒ 用户看到"卡片一直不出来 / 点一下白屏 / 屏上冒出 `undefined`"。判据拿七种输入各喂一遍(待机 / 在读 / 在读但保留旧值 / 有值 / 有值但空容器 / 读不到 / 能力闸缺插件),`zh`、`en` 各一遍;取数走**你装的那份真壳**的 `useUnitBoard` | `loading(zh) 卡片抛了` / `loading(zh) 卡片返回空` / `屏上出现了 undefined`(`NaN` / `[object Object]` / `null` 同形) / `t('x') 在 zh 里没有落点` / `卡片没套外壳的卡壳` / `清单的 card.titleKey「x」在模块字典的 en 里没有` | 让卡片在五态下都画得出来(已有的加载 / 空 / 阻断态);外面套 `kit.components.Card`;清单写了 `titleKey`,`registerUnit` 交的 `messages` 里 `zh` / `en` 都得有那一条;**卡片与它用的 kit 组件问过的每个键也都要有落点**(判据自己当 `t`,没命中就报原始键名)。判据**不断言**"画的是哪一态那一屏" —— 那归你自己那份 `plugin.test.ts` |
|
|
15
15
|
| `standalone` | "只有工作台源码在场才编得过" ⇒ 发布出去就散架 | `build 在外壳源码不在场时失败` / `typecheck 在外壳源码不在场时失败` | 别引用工作台源码;`tsconfig` 里 `paths` 的值必须是**相对路径**(`"./src/*"`,不是 `"src/*"`) |
|
|
16
16
|
| `markers` | 内网域名 / 企业内部名泄进要公开发布的包 | `命中内网 npm 源` / `命中内网域名` | 那些值不该写进包里;要配就落到模块自己的配置面,或走用户自己声明的来源 |
|
|
17
17
|
| `alias` | `@/` 伸进工作台源码 ⇒ 装的人手上没有那份源码 | `…指向外壳源码` | `@/` 只许指自己的 `src/`;跨包的东西走包名 |
|