@dsh-workbench/shared 0.1.0
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 +9 -0
- package/dist/api/blocker-table.js +130 -0
- package/dist/api/blocker.d.ts +30 -0
- package/dist/api/blocker.js +1 -0
- package/dist/api/context-ref.d.ts +10 -0
- package/dist/api/context-ref.js +40 -0
- package/dist/api/dsh-client.d.ts +170 -0
- package/dist/api/dsh-client.js +1 -0
- package/dist/api/dsh.d.ts +153 -0
- package/dist/api/dsh.js +1 -0
- package/dist/api/facts.d.ts +27 -0
- package/dist/api/facts.js +146 -0
- package/dist/api/host-write.d.ts +12 -0
- package/dist/api/host-write.js +17 -0
- package/dist/api/long-task.d.ts +18 -0
- package/dist/api/long-task.js +22 -0
- package/dist/api/unit-board.d.ts +14 -0
- package/dist/api/unit-board.js +29 -0
- package/dist/api/unit.d.ts +54 -0
- package/dist/api/unit.js +1 -0
- package/dist/api/workbench-client.d.ts +19 -0
- package/dist/api/workbench-client.js +33 -0
- package/dist/api/workbench-contract.d.ts +32 -0
- package/dist/api/workbench-contract.js +1 -0
- package/dist/components/ApprovalDetail.d.ts +27 -0
- package/dist/components/ApprovalDetail.js +33 -0
- package/dist/components/CardHead.d.ts +16 -0
- package/dist/components/CardHead.js +14 -0
- package/dist/components/ChoiceGroup.d.ts +14 -0
- package/dist/components/ChoiceGroup.js +7 -0
- package/dist/components/LongTaskRow.d.ts +16 -0
- package/dist/components/LongTaskRow.js +28 -0
- package/dist/components/MockStrip.d.ts +14 -0
- package/dist/components/MockStrip.js +7 -0
- package/dist/components/ResourceStates.d.ts +18 -0
- package/dist/components/ResourceStates.js +17 -0
- package/dist/components/SaveBar.d.ts +12 -0
- package/dist/components/SaveBar.js +6 -0
- package/dist/components/StateDot.d.ts +5 -0
- package/dist/components/StateDot.js +10 -0
- package/dist/components/board-module.d.ts +67 -0
- package/dist/components/board-module.js +1 -0
- package/dist/components/icons.d.ts +18 -0
- package/dist/components/icons.js +81 -0
- package/dist/config/constants.d.ts +27 -0
- package/dist/config/constants.js +27 -0
- package/dist/config/storage.d.ts +4 -0
- package/dist/config/storage.js +27 -0
- package/dist/host/__tests__/fakes.d.ts +41 -0
- package/dist/host/__tests__/fakes.js +76 -0
- package/dist/host/__tests__/preflight-fixtures.d.ts +19 -0
- package/dist/host/__tests__/preflight-fixtures.js +47 -0
- package/dist/host/cli-error.d.ts +8 -0
- package/dist/host/cli-error.js +70 -0
- package/dist/host/context-inject.d.ts +24 -0
- package/dist/host/context-inject.js +74 -0
- package/dist/host/data-root.d.ts +3 -0
- package/dist/host/data-root.js +12 -0
- package/dist/host/events.d.ts +9 -0
- package/dist/host/events.js +70 -0
- package/dist/host/facts.d.ts +24 -0
- package/dist/host/facts.js +44 -0
- package/dist/host/git.d.ts +55 -0
- package/dist/host/git.js +64 -0
- package/dist/host/http.d.ts +36 -0
- package/dist/host/http.js +242 -0
- package/dist/host/long-task.d.ts +58 -0
- package/dist/host/long-task.js +148 -0
- package/dist/host/mount-units.d.ts +52 -0
- package/dist/host/mount-units.js +186 -0
- package/dist/host/opencli-runtime.d.ts +22 -0
- package/dist/host/opencli-runtime.js +46 -0
- package/dist/host/opencli.d.ts +37 -0
- package/dist/host/opencli.js +152 -0
- package/dist/host/plugin-source.d.ts +31 -0
- package/dist/host/plugin-source.js +81 -0
- package/dist/host/preflight.d.ts +58 -0
- package/dist/host/preflight.js +233 -0
- package/dist/host/probe-cache.d.ts +6 -0
- package/dist/host/probe-cache.js +19 -0
- package/dist/host/probe-libs.d.ts +45 -0
- package/dist/host/probe-libs.js +61 -0
- package/dist/host/probe-units.d.ts +17 -0
- package/dist/host/probe-units.js +102 -0
- package/dist/host/probe-verdict.d.ts +7 -0
- package/dist/host/probe-verdict.js +143 -0
- package/dist/host/provision.d.ts +14 -0
- package/dist/host/provision.js +12 -0
- package/dist/host/shell.d.ts +14 -0
- package/dist/host/shell.js +23 -0
- package/dist/host/tool-approval.d.ts +29 -0
- package/dist/host/tool-approval.js +190 -0
- package/dist/host/tool-kit.d.ts +19 -0
- package/dist/host/tool-kit.js +37 -0
- package/dist/host/tool-scope.d.ts +32 -0
- package/dist/host/tool-scope.js +84 -0
- package/dist/host/unit-face.d.ts +66 -0
- package/dist/host/unit-face.js +1 -0
- package/dist/host/unit-libs.d.ts +37 -0
- package/dist/host/unit-libs.js +1 -0
- package/dist/host/unit-readiness.d.ts +7 -0
- package/dist/host/unit-readiness.js +5 -0
- package/dist/host/unit-registry.d.ts +9 -0
- package/dist/host/unit-registry.js +33 -0
- package/dist/host/value-handoff.d.ts +16 -0
- package/dist/host/value-handoff.js +21 -0
- package/dist/host/version-range.d.ts +2 -0
- package/dist/host/version-range.js +73 -0
- package/dist/host/workspace-store.d.ts +19 -0
- package/dist/host/workspace-store.js +133 -0
- package/dist/host/write-result.d.ts +1 -0
- package/dist/host/write-result.js +18 -0
- package/dist/host.d.ts +19 -0
- package/dist/host.js +19 -0
- package/dist/i18n/en.d.ts +2 -0
- package/dist/i18n/en.js +162 -0
- package/dist/i18n/index.d.ts +172 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/merge.d.ts +6 -0
- package/dist/i18n/merge.js +40 -0
- package/dist/i18n/zh.d.ts +163 -0
- package/dist/i18n/zh.js +162 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +33 -0
- package/dist/lib/blocker-action.d.ts +13 -0
- package/dist/lib/blocker-action.js +12 -0
- package/dist/lib/busy.d.ts +5 -0
- package/dist/lib/busy.js +7 -0
- package/dist/lib/react.d.ts +10 -0
- package/dist/lib/react.js +9 -0
- package/dist/lib/text.d.ts +4 -0
- package/dist/lib/text.js +48 -0
- package/dist/lib/ui.d.ts +11 -0
- package/dist/lib/ui.js +37 -0
- package/package.json +44 -0
- package/src/api/__tests__/blocker-table.test.ts +253 -0
- package/src/api/__tests__/facts.test.ts +274 -0
- package/src/api/__tests__/host-write.test.ts +55 -0
- package/src/api/__tests__/long-task.test.ts +52 -0
- package/src/api/__tests__/unit-board.test.ts +76 -0
- package/src/api/blocker-table.ts +155 -0
- package/src/api/blocker.ts +25 -0
- package/src/api/context-ref.ts +47 -0
- package/src/api/dsh-client.ts +176 -0
- package/src/api/dsh.ts +156 -0
- package/src/api/facts.ts +166 -0
- package/src/api/host-write.ts +27 -0
- package/src/api/long-task.ts +38 -0
- package/src/api/unit-board.ts +44 -0
- package/src/api/unit.ts +59 -0
- package/src/api/workbench-client.test.ts +92 -0
- package/src/api/workbench-client.ts +59 -0
- package/src/api/workbench-contract.ts +40 -0
- package/src/components/ApprovalDetail.tsx +57 -0
- package/src/components/CardHead.tsx +74 -0
- package/src/components/ChoiceGroup.tsx +38 -0
- package/src/components/LongTaskRow.tsx +65 -0
- package/src/components/MockStrip.tsx +40 -0
- package/src/components/ResourceStates.tsx +44 -0
- package/src/components/SaveBar.tsx +31 -0
- package/src/components/StateDot.tsx +31 -0
- package/src/components/board-module.ts +73 -0
- package/src/components/icons.tsx +232 -0
- package/src/config/constants.test.ts +41 -0
- package/src/config/constants.ts +52 -0
- package/src/config/storage.test.ts +82 -0
- package/src/config/storage.ts +25 -0
- package/src/host/__tests__/fakes.ts +116 -0
- package/src/host/__tests__/opencli-runtime.test.ts +46 -0
- package/src/host/cli-error.ts +77 -0
- package/src/host/data-root.ts +13 -0
- package/src/host/facts.ts +69 -0
- package/src/host/git.ts +99 -0
- package/src/host/http.ts +311 -0
- package/src/host/long-task.ts +235 -0
- package/src/host/opencli-runtime.ts +66 -0
- package/src/host/opencli.ts +210 -0
- package/src/host/plugin-source.ts +145 -0
- package/src/host/provision.ts +34 -0
- package/src/host/shell.ts +42 -0
- package/src/host/tool-approval.ts +243 -0
- package/src/host/tool-kit.ts +56 -0
- package/src/host/unit-face.ts +65 -0
- package/src/host/unit-libs.ts +41 -0
- package/src/host/value-handoff.ts +38 -0
- package/src/host/workspace-store.ts +161 -0
- package/src/host/write-result.ts +16 -0
- package/src/host.ts +19 -0
- package/src/i18n/en.ts +170 -0
- package/src/i18n/index.test.ts +15 -0
- package/src/i18n/index.ts +12 -0
- package/src/i18n/merge.test.ts +60 -0
- package/src/i18n/merge.ts +54 -0
- package/src/i18n/zh.test.ts +40 -0
- package/src/i18n/zh.ts +170 -0
- package/src/index.ts +33 -0
- package/src/lib/blocker-action.test.ts +40 -0
- package/src/lib/blocker-action.ts +28 -0
- package/src/lib/busy.test.ts +27 -0
- package/src/lib/busy.ts +11 -0
- package/src/lib/react.test.ts +26 -0
- package/src/lib/react.ts +16 -0
- package/src/lib/text.test.ts +92 -0
- package/src/lib/text.ts +46 -0
- package/src/lib/ui.test.ts +93 -0
- package/src/lib/ui.ts +38 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { h } from '../lib/react.js';
|
|
2
|
+
export function SaveBar({ busy, disabled, labels, onCancel, onSave }) {
|
|
3
|
+
return (h("div", { className: "wb-formActions" },
|
|
4
|
+
h("button", { type: "button", className: "wb-linkButton", onClick: onCancel, disabled: busy }, labels.cancel),
|
|
5
|
+
h("button", { type: "button", className: "wb-primaryButton", onClick: onSave, disabled: busy || disabled === true }, busy ? labels.saving : labels.save)));
|
|
6
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { h } from '../lib/react.js';
|
|
2
|
+
export function StateDot({ state, size }) {
|
|
3
|
+
if (state === 'ongoing') {
|
|
4
|
+
return (h("svg", { className: "wb-loading", viewBox: "0 0 24 24", width: size, height: size, "aria-hidden": "true", style: { display: 'block' } },
|
|
5
|
+
h("g", { className: "wb-loadingMotion" },
|
|
6
|
+
h("circle", { className: "wb-loadingTrack", cx: 12, cy: 12, r: 9.5 }),
|
|
7
|
+
h("circle", { className: "wb-loadingArc", cx: 12, cy: 12, r: 9.5 }))));
|
|
8
|
+
}
|
|
9
|
+
return (h("span", { className: "wb-stateDot", "data-state": state, style: { width: size, height: size }, "aria-hidden": "true" }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { SessionsSnapshot, Translate, WorkspaceSnapshot, WorkspaceView } from '../api/dsh-client.js';
|
|
3
|
+
import type { UnitManifest } from '../api/unit.js';
|
|
4
|
+
import type { CapabilityPayload } from '../api/workbench-contract.js';
|
|
5
|
+
import type { Dictionaries } from '../i18n/index.js';
|
|
6
|
+
export interface PanelStep {
|
|
7
|
+
readonly kind: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SuiteWorld {
|
|
10
|
+
readonly workspaces: WorkspaceSnapshot;
|
|
11
|
+
readonly sessions: SessionsSnapshot;
|
|
12
|
+
readonly manifests: readonly UnitManifest[];
|
|
13
|
+
readonly panelConfig: {
|
|
14
|
+
readonly shown: Readonly<Record<string, boolean>>;
|
|
15
|
+
} | null;
|
|
16
|
+
readonly capabilities: Readonly<Record<string, CapabilityPayload>> | null;
|
|
17
|
+
readonly current: {
|
|
18
|
+
readonly sessionId: string | null;
|
|
19
|
+
readonly workspace: WorkspaceView | null;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface BoardModuleProps {
|
|
23
|
+
readonly world: SuiteWorld;
|
|
24
|
+
readonly refreshToken: number;
|
|
25
|
+
readonly onRefresh: () => void;
|
|
26
|
+
readonly onNavigate: (step: PanelStep) => void;
|
|
27
|
+
readonly onOpenMarket: () => void;
|
|
28
|
+
readonly onSummary: (summary: ModuleSummary) => void;
|
|
29
|
+
readonly t: Translate;
|
|
30
|
+
}
|
|
31
|
+
export interface ModuleSummary {
|
|
32
|
+
readonly refreshing: boolean;
|
|
33
|
+
readonly at: number | null;
|
|
34
|
+
}
|
|
35
|
+
export interface UnitStep {
|
|
36
|
+
readonly titleKey: string;
|
|
37
|
+
readonly View: (props: BoardModuleProps) => ReactNode;
|
|
38
|
+
}
|
|
39
|
+
export interface BoardModule {
|
|
40
|
+
readonly id: string;
|
|
41
|
+
readonly titleKey: string;
|
|
42
|
+
readonly order: number;
|
|
43
|
+
readonly enabledByDefault: boolean;
|
|
44
|
+
readonly View: (props: BoardModuleProps) => ReactNode;
|
|
45
|
+
readonly steps?: Readonly<Record<string, UnitStep>>;
|
|
46
|
+
}
|
|
47
|
+
export interface UnitClientFace {
|
|
48
|
+
readonly manifest: UnitManifest;
|
|
49
|
+
readonly card: (props: BoardModuleProps) => ReactNode;
|
|
50
|
+
readonly steps?: Readonly<Record<string, UnitStep>>;
|
|
51
|
+
readonly messages?: Dictionaries;
|
|
52
|
+
readonly approval?: {
|
|
53
|
+
readonly tools: readonly string[];
|
|
54
|
+
readonly render: (props: {
|
|
55
|
+
readonly input: ApprovalInput;
|
|
56
|
+
readonly t: Translate;
|
|
57
|
+
}) => ReactNode;
|
|
58
|
+
} | undefined;
|
|
59
|
+
}
|
|
60
|
+
export interface ApprovalInput {
|
|
61
|
+
readonly tool: string;
|
|
62
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
63
|
+
}
|
|
64
|
+
export interface UnitClientApi {
|
|
65
|
+
registerUnit(face: UnitClientFace): () => void;
|
|
66
|
+
manifests(): readonly UnitManifest[];
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface IconProps {
|
|
2
|
+
size?: number;
|
|
3
|
+
}
|
|
4
|
+
export declare function IconPanelLeft({ size }: IconProps): JSX.Element;
|
|
5
|
+
export declare function IconFolder({ size }: IconProps): JSX.Element;
|
|
6
|
+
export declare function IconFolderOpen({ size }: IconProps): JSX.Element;
|
|
7
|
+
export declare function IconChevronDown({ size }: IconProps): JSX.Element;
|
|
8
|
+
export declare function IconPlus({ size }: IconProps): JSX.Element;
|
|
9
|
+
export declare function IconEllipsis({ size }: IconProps): JSX.Element;
|
|
10
|
+
export declare function IconSettings({ size }: IconProps): JSX.Element;
|
|
11
|
+
export declare function IconPin({ size }: IconProps): JSX.Element;
|
|
12
|
+
export declare function IconCheck({ size }: IconProps): JSX.Element;
|
|
13
|
+
export declare function IconNewChat({ size }: IconProps): JSX.Element;
|
|
14
|
+
export declare function IconRefresh({ size }: IconProps): JSX.Element;
|
|
15
|
+
export declare function IconRightUp({ size }: IconProps): JSX.Element;
|
|
16
|
+
export declare function IconConversation({ size }: IconProps): JSX.Element;
|
|
17
|
+
export declare function IconBrandMark({ size }: IconProps): JSX.Element;
|
|
18
|
+
export declare function IconModules({ size }: IconProps): JSX.Element;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { h } from '../lib/react.js';
|
|
2
|
+
function Shell({ size, strokeWidth = 1, viewBox = '0 0 16 16', children, }) {
|
|
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
|
+
}
|
|
5
|
+
export function IconPanelLeft({ size = 16 }) {
|
|
6
|
+
return (h(Shell, { size: size },
|
|
7
|
+
h("path", { d: "M13.5 1.5H2.5C1.94772 1.5 1.5 1.94772 1.5 2.5V13.5C1.5 14.0523 1.94772 14.5 2.5 14.5H13.5C14.0523 14.5 14.5 14.0523 14.5 13.5V2.5C14.5 1.94772 14.0523 1.5 13.5 1.5Z", stroke: "currentColor" }),
|
|
8
|
+
h("path", { d: "M5.5 1.5V14.5", stroke: "currentColor" })));
|
|
9
|
+
}
|
|
10
|
+
export function IconFolder({ size = 16 }) {
|
|
11
|
+
return (h(Shell, { size: size },
|
|
12
|
+
h("path", { d: "M1.50439 3.11059C1.50439 2.55831 1.95211 2.1106 2.50439 2.1106H5.43389C5.67773 2.1106 5.91318 2.19969 6.09593 2.36113L7.71649 3.79265C7.89924 3.95409 8.1347 4.04319 8.3785 4.04319H13.4958C14.0481 4.04319 14.4958 4.4909 14.4958 5.04319V12.8894C14.4958 13.4417 14.0481 13.8894 13.4958 13.8894H2.50439C1.95211 13.8894 1.50439 13.4417 1.50439 12.8894V4.04319V3.11059Z", stroke: "currentColor" }),
|
|
13
|
+
h("path", { d: "M3.63501 7.66614H12.3647", stroke: "currentColor" })));
|
|
14
|
+
}
|
|
15
|
+
export function IconFolderOpen({ size = 16 }) {
|
|
16
|
+
return (h(Shell, { size: size },
|
|
17
|
+
h("path", { d: "M2.55912 7.93683C2.67584 7.49906 3.0723 7.19446 3.52536 7.19446H13.6491C14.3061 7.19446 14.7846 7.81725 14.6153 8.45209L13.4411 12.856C13.3244 13.2938 12.9279 13.5984 12.4748 13.5984H2.35113C1.69411 13.5984 1.21562 12.9756 1.38489 12.3407L2.55912 7.93683Z", fill: "currentColor", opacity: 0.16 }),
|
|
18
|
+
h("path", { d: "M13.6491 6.69446C14.6346 6.69453 15.3522 7.62895 15.0983 8.58118L13.9245 12.9845C13.7494 13.6412 13.1539 14.0988 12.4743 14.0988H2.35126C1.36574 14.0988 0.648153 13.1643 0.902044 12.212L2.07587 7.80774C2.25102 7.15128 2.84567 6.69455 3.52509 6.69446H13.6491ZM3.52509 7.69446C3.29865 7.69455 3.10004 7.84674 3.04169 8.06555L1.86786 12.4698C1.78345 12.7872 2.02285 13.0988 2.35126 13.0988H12.4743C12.7007 13.0988 12.8992 12.9463 12.9577 12.7277L14.1325 8.32336C14.2171 8.00598 13.9776 7.69453 13.6491 7.69446H3.52509Z", fill: "currentColor" }),
|
|
19
|
+
h("path", { d: "M4.7666 1.90137C5.13227 1.90144 5.48571 2.03525 5.75977 2.27734L7.27246 3.61328C7.36379 3.69382 7.48174 3.73828 7.60352 3.73828H12.3994C13.2276 3.73841 13.8993 4.41005 13.8994 5.23828V6.7168C13.8183 6.70327 13.735 6.69436 13.6494 6.69434H12.8994V5.23828C12.8993 4.96233 12.6754 4.73841 12.3994 4.73828H7.60352C7.23781 4.73828 6.88446 4.60438 6.61035 4.3623L5.09766 3.02637C5.00636 2.94576 4.88838 2.90144 4.7666 2.90137H2.0498C1.77366 2.90137 1.5498 3.12523 1.5498 3.40137V9.78223L0.902344 12.2119C0.648452 13.1642 1.36604 14.0986 2.35156 14.0986H2.0498C1.2214 14.0986 0.549838 13.427 0.549805 12.5986V3.40137C0.549805 2.57294 1.22138 1.90137 2.0498 1.90137H4.7666Z", fill: "currentColor" })));
|
|
20
|
+
}
|
|
21
|
+
export function IconChevronDown({ size = 14 }) {
|
|
22
|
+
return (h(Shell, { size: size },
|
|
23
|
+
h("path", { d: "M4 6L7.29289 9.29289C7.68342 9.68342 8.31658 9.68342 8.70711 9.29289L12 6", stroke: "currentColor" })));
|
|
24
|
+
}
|
|
25
|
+
export function IconPlus({ size = 16 }) {
|
|
26
|
+
return (h(Shell, { size: size },
|
|
27
|
+
h("path", { d: "M8 2V14", stroke: "currentColor" }),
|
|
28
|
+
h("path", { d: "M2 8H14", stroke: "currentColor" })));
|
|
29
|
+
}
|
|
30
|
+
export function IconEllipsis({ size = 16 }) {
|
|
31
|
+
return (h(Shell, { size: size },
|
|
32
|
+
h("path", { d: "M3 9C3.55228 9 4 8.55228 4 8C4 7.44772 3.55228 7 3 7C2.44772 7 2 7.44772 2 8C2 8.55228 2.44772 9 3 9Z", fill: "currentColor" }),
|
|
33
|
+
h("path", { d: "M8 9C8.55228 9 9 8.55228 9 8C9 7.44772 8.55228 7 8 7C7.44772 7 7 7.44772 7 8C7 8.55228 7.44772 9 8 9Z", fill: "currentColor" }),
|
|
34
|
+
h("path", { d: "M13 9C13.5523 9 14 8.55228 14 8C14 7.44772 13.5523 7 13 7C12.4477 7 12 7.44772 12 8C12 8.55228 12.4477 9 13 9Z", fill: "currentColor" })));
|
|
35
|
+
}
|
|
36
|
+
export function IconSettings({ size = 16 }) {
|
|
37
|
+
return (h(Shell, { size: size },
|
|
38
|
+
h("path", { d: "M8 9.75012C8.9665 9.75012 9.75 8.96662 9.75 8.00012C9.75 7.03362 8.9665 6.25012 8 6.25012C7.0335 6.25012 6.25 7.03362 6.25 8.00012C6.25 8.96662 7.0335 9.75012 8 9.75012Z", stroke: "currentColor" }),
|
|
39
|
+
h("path", { d: "M13.0107 7.79377C12.9505 7.89401 12.9205 7.94413 12.9205 7.99951C12.9205 8.0549 12.9505 8.10502 13.0106 8.20528L13.9849 9.83006C14.045 9.93029 14.0751 9.9804 14.0751 10.0358C14.0751 10.0911 14.045 10.1413 13.9849 10.2415L13.0037 11.8777C12.9468 11.9726 12.9184 12.0201 12.8725 12.0461C12.8267 12.072 12.7713 12.072 12.6607 12.072H10.6704C10.5598 12.072 10.5045 12.072 10.4586 12.098C10.4128 12.1239 10.3843 12.1714 10.3274 12.2662L9.33825 13.9142C9.28133 14.009 9.25287 14.0564 9.20703 14.0823C9.16118 14.1083 9.10588 14.1083 8.99529 14.1083H7.00486C6.89426 14.1083 6.83896 14.1083 6.79312 14.0823C6.74727 14.0564 6.71881 14.009 6.6619 13.9142L5.67273 12.2662C5.61581 12.1714 5.58735 12.1239 5.54151 12.098C5.49566 12.072 5.44036 12.072 5.32977 12.072H3.33945C3.2288 12.072 3.17347 12.072 3.12761 12.0461C3.08176 12.0201 3.0533 11.9726 2.9964 11.8777L2.0152 10.2415C1.9551 10.1413 1.92505 10.0911 1.92505 10.0358C1.92505 9.9804 1.9551 9.93029 2.0152 9.83006L2.98951 8.20528C3.04963 8.10502 3.07969 8.0549 3.07969 7.99951C3.07968 7.94413 3.04961 7.89401 2.98946 7.79377L2.01529 6.17011C1.95514 6.06987 1.92507 6.01975 1.92507 5.96437C1.92506 5.90899 1.95512 5.85886 2.01524 5.7586L2.9964 4.1224C3.0533 4.0275 3.08176 3.98005 3.12761 3.95408C3.17347 3.92811 3.2288 3.92811 3.33945 3.92811H5.32977C5.44036 3.92811 5.49566 3.92811 5.54151 3.90216C5.58735 3.87621 5.61581 3.82879 5.67273 3.73397L6.6619 2.08599C6.71881 1.99116 6.74727 1.94375 6.79312 1.9178C6.83896 1.89185 6.89426 1.89185 7.00486 1.89185H8.99529C9.10588 1.89185 9.16118 1.89185 9.20703 1.9178C9.25287 1.94375 9.28133 1.99116 9.33825 2.08599L10.3274 3.73397C10.3843 3.82879 10.4128 3.87621 10.4586 3.90216C10.5045 3.92811 10.5598 3.92811 10.6704 3.92811H12.6607C12.7713 3.92811 12.8267 3.92811 12.8725 3.95408C12.9184 3.98005 12.9468 4.0275 13.0037 4.1224L13.9849 5.7586C14.045 5.85886 14.0751 5.90899 14.0751 5.96437C14.0751 6.01975 14.045 6.06987 13.9849 6.17011L13.0107 7.79377Z", stroke: "currentColor", strokeMiterlimit: 10 })));
|
|
40
|
+
}
|
|
41
|
+
export function IconPin({ size = 16 }) {
|
|
42
|
+
return (h(Shell, { size: size },
|
|
43
|
+
h("path", { d: "M9.96976 1.70572L13.1554 3.93629L10.9019 8.12317L11.5158 11.605L10.7192 12.7427L2.52767 7.00693L3.3243 5.86922L6.80612 5.25528L9.96976 1.70572Z", fill: "currentColor", stroke: "currentColor", strokeLinejoin: "round" }),
|
|
44
|
+
h("path", { d: "M6.05285 9.47511C6.27284 9.16094 6.70586 9.08458 7.02003 9.30457C7.3342 9.52455 7.41055 9.95757 7.19057 10.2717L3.98587 14.4708L3.21223 13.9291L6.05285 9.47511Z", fill: "currentColor" })));
|
|
45
|
+
}
|
|
46
|
+
export function IconCheck({ size = 16 }) {
|
|
47
|
+
return (h(Shell, { size: size },
|
|
48
|
+
h("path", { d: "M2.25 8.5L5.49732 11.7473C5.90519 12.1552 6.57263 12.1344 6.95426 11.7018L13.75 4", stroke: "currentColor" })));
|
|
49
|
+
}
|
|
50
|
+
export function IconNewChat({ size = 14 }) {
|
|
51
|
+
return (h(Shell, { size: size, strokeWidth: 1.3 },
|
|
52
|
+
h("path", { d: "M2.37091 11.2501C1.58745 9.89288 1.32067 8.29835 1.61969 6.76006C1.91872 5.22177 2.76342 3.8433 3.99826 2.87846C5.2331 1.91362 6.77494 1.42737 8.33988 1.50925C9.90482 1.59113 11.3875 2.23562 12.5149 3.32406C13.6425 4.41269 14.3387 5.87206 14.4754 7.4334C14.612 8.99474 14.18 10.5529 13.2587 11.8209C12.3375 13.0888 10.9891 13.9813 9.46194 14.3337C8.18691 14.628 6.85895 14.5294 5.64989 14.0605C5.1712 13.8748 4.76962 13.4932 4.26534 13.3967C3.67413 13.2835 2.95257 13.5598 2.03794 14.3337", stroke: "currentColor" }),
|
|
53
|
+
h("path", { d: "M8 5V11", stroke: "currentColor" }),
|
|
54
|
+
h("path", { d: "M5 8H11", stroke: "currentColor" })));
|
|
55
|
+
}
|
|
56
|
+
export function IconRefresh({ size = 16 }) {
|
|
57
|
+
return (h(Shell, { size: size },
|
|
58
|
+
h("path", { d: "M14.5001 8C14.5 9.28552 14.1188 10.5422 13.4045 11.611C12.6903 12.6799 11.6752 13.5129 10.4875 14.0049C9.29982 14.4968 7.99295 14.6255 6.73212 14.3747C5.4713 14.124 4.31314 13.505 3.4041 12.596C2.49514 11.687 1.87614 10.5288 1.62537 9.26798C1.37459 8.00716 1.50331 6.70028 1.99525 5.51261C2.48719 4.32494 3.32025 3.30981 4.3891 2.59557C5.45795 1.88134 6.71458 1.50008 8.0001 1.5C9.9001 1.5 11.7001 2.3 13.0001 3.6L14.5001 5.1", stroke: "currentColor" }),
|
|
59
|
+
h("path", { d: "M14.4999 1.5V5.1H10.8999", stroke: "currentColor" })));
|
|
60
|
+
}
|
|
61
|
+
export function IconRightUp({ size = 14 }) {
|
|
62
|
+
return (h(Shell, { size: size },
|
|
63
|
+
h("path", { d: "M11.7256 2.77441C12.5538 2.77469 13.2256 3.44616 13.2256 4.27441V10.1416H12.2256V4.27441C12.2256 3.99844 12.0015 3.77469 11.7256 3.77441H5.7207V2.77441H11.7256Z", fill: "currentColor" }),
|
|
64
|
+
h("path", { d: "M2.77441 13.2255L12.3756 3.62427", stroke: "currentColor" })));
|
|
65
|
+
}
|
|
66
|
+
export function IconConversation({ size = 16 }) {
|
|
67
|
+
return (h(Shell, { size: size, strokeWidth: 1.3 },
|
|
68
|
+
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" })));
|
|
69
|
+
}
|
|
70
|
+
export function IconBrandMark({ size = 24 }) {
|
|
71
|
+
return (h(Shell, { size: size, strokeWidth: 1.6, viewBox: "0 0 24 24" },
|
|
72
|
+
h("rect", { x: 3, y: 3, width: 18, height: 18, rx: 5, stroke: "currentColor" }),
|
|
73
|
+
h("path", { d: "M8 9.5h8M8 12.5h8M8 15.5h5", stroke: "currentColor", strokeLinecap: "round" })));
|
|
74
|
+
}
|
|
75
|
+
export function IconModules({ size = 16 }) {
|
|
76
|
+
return (h("svg", { width: size, height: size, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true" },
|
|
77
|
+
h("rect", { x: "2.5", y: "2.5", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" }),
|
|
78
|
+
h("rect", { x: "8.9", y: "2.5", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" }),
|
|
79
|
+
h("rect", { x: "2.5", y: "8.9", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" }),
|
|
80
|
+
h("rect", { x: "8.9", y: "8.9", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" })));
|
|
81
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const PLUGIN_ID = "@dsh-workbench/core";
|
|
2
|
+
export declare const API_PREFIX = "/workbench/api";
|
|
3
|
+
export declare const PREFS_PREFIX = "/workbench/api/prefs";
|
|
4
|
+
export declare const EVENTS_PATH = "/workbench/events";
|
|
5
|
+
export declare const ACTIONS_PREFIX = "/workbench/api/actions";
|
|
6
|
+
export declare const PROVISION_PREFIX = "/workbench/api/provision";
|
|
7
|
+
export declare const OPENCLI_PIN = "1.8.8";
|
|
8
|
+
export declare const CODING_ISSUES_SERVICE = "workbenchCodingIssues";
|
|
9
|
+
export declare const PANELS_SERVICE = "workbenchPanels";
|
|
10
|
+
export declare const UNITS_SERVICE = "workbenchUnits";
|
|
11
|
+
export declare const PANEL_LIST_LIMIT = 50;
|
|
12
|
+
export declare const OPENCLI_TIMEOUT_MS = 120000;
|
|
13
|
+
export declare const OPENCLI_MAX_CONCURRENT = 4;
|
|
14
|
+
export declare const WARM_TIMEOUT_MS = 20000;
|
|
15
|
+
export declare const INSTALL_TIMEOUT_MS = 300000;
|
|
16
|
+
export declare const VERSION_CHECK_TIMEOUT_MS = 10000;
|
|
17
|
+
export declare const VERSION_CHECK_TTL_MS = 600000;
|
|
18
|
+
export declare const PROBE_TTL_MS = 30000;
|
|
19
|
+
export declare const MIN_BUSY_MS = 500;
|
|
20
|
+
export declare const HANDOFF_TTL_MS = 15000;
|
|
21
|
+
export declare const GIT_TIMEOUT_MS = 10000;
|
|
22
|
+
export declare const PANEL_POLL_MS = 2000;
|
|
23
|
+
export declare const DEFAULT_WORKSPACE_TITLE = "default-workspace";
|
|
24
|
+
export declare const STORAGE_KEY_PROJECT = "dsh-workbench.project";
|
|
25
|
+
export declare const STORAGE_KEY_RIGHTBAR = "dsh-workbench.rightbar.expanded";
|
|
26
|
+
export declare const LOCALE_NS = "workbench";
|
|
27
|
+
export declare const LOCALES: readonly ["zh", "en"];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const PLUGIN_ID = "@dsh-workbench/core";
|
|
2
|
+
export const API_PREFIX = "/workbench/api";
|
|
3
|
+
export const PREFS_PREFIX = `${API_PREFIX}/prefs`;
|
|
4
|
+
export const EVENTS_PATH = "/workbench/events";
|
|
5
|
+
export const ACTIONS_PREFIX = `${API_PREFIX}/actions`;
|
|
6
|
+
export const PROVISION_PREFIX = `${API_PREFIX}/provision`;
|
|
7
|
+
export const OPENCLI_PIN = "1.8.8";
|
|
8
|
+
export const CODING_ISSUES_SERVICE = "workbenchCodingIssues";
|
|
9
|
+
export const PANELS_SERVICE = "workbenchPanels";
|
|
10
|
+
export const UNITS_SERVICE = "workbenchUnits";
|
|
11
|
+
export const PANEL_LIST_LIMIT = 50;
|
|
12
|
+
export const OPENCLI_TIMEOUT_MS = 120_000;
|
|
13
|
+
export const OPENCLI_MAX_CONCURRENT = 4;
|
|
14
|
+
export const WARM_TIMEOUT_MS = 20_000;
|
|
15
|
+
export const INSTALL_TIMEOUT_MS = 300_000;
|
|
16
|
+
export const VERSION_CHECK_TIMEOUT_MS = 10_000;
|
|
17
|
+
export const VERSION_CHECK_TTL_MS = 600_000;
|
|
18
|
+
export const PROBE_TTL_MS = 30_000;
|
|
19
|
+
export const MIN_BUSY_MS = 500;
|
|
20
|
+
export const HANDOFF_TTL_MS = 15_000;
|
|
21
|
+
export const GIT_TIMEOUT_MS = 10_000;
|
|
22
|
+
export const PANEL_POLL_MS = 2000;
|
|
23
|
+
export const DEFAULT_WORKSPACE_TITLE = "default-workspace";
|
|
24
|
+
export const STORAGE_KEY_PROJECT = "dsh-workbench.project";
|
|
25
|
+
export const STORAGE_KEY_RIGHTBAR = "dsh-workbench.rightbar.expanded";
|
|
26
|
+
export const LOCALE_NS = "workbench";
|
|
27
|
+
export const LOCALES = ["zh", "en"];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function readText(key: string): string | null;
|
|
2
|
+
export declare function writeText(key: string, value: string | null): void;
|
|
3
|
+
export declare function readFlag(key: string, fallback: boolean): boolean;
|
|
4
|
+
export declare function writeFlag(key: string, value: boolean): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function readText(key) {
|
|
2
|
+
try {
|
|
3
|
+
return window.localStorage.getItem(key);
|
|
4
|
+
}
|
|
5
|
+
catch {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export function writeText(key, value) {
|
|
10
|
+
try {
|
|
11
|
+
if (value === null)
|
|
12
|
+
window.localStorage.removeItem(key);
|
|
13
|
+
else
|
|
14
|
+
window.localStorage.setItem(key, value);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function readFlag(key, fallback) {
|
|
20
|
+
const raw = readText(key);
|
|
21
|
+
if (raw === null)
|
|
22
|
+
return fallback;
|
|
23
|
+
return raw === 'true';
|
|
24
|
+
}
|
|
25
|
+
export function writeFlag(key, value) {
|
|
26
|
+
writeText(key, value ? 'true' : 'false');
|
|
27
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { DshShell } from '../../api/dsh.js';
|
|
2
|
+
import type { Opencli } from '../../host/opencli.js';
|
|
3
|
+
export interface ShellCall {
|
|
4
|
+
command: string;
|
|
5
|
+
workdir?: string;
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
onExpiry?: string;
|
|
8
|
+
stdoutMaxBytes?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ShellReply {
|
|
11
|
+
stdout?: string;
|
|
12
|
+
stderr?: string;
|
|
13
|
+
exitCode?: number | null;
|
|
14
|
+
timedOut?: boolean;
|
|
15
|
+
aborted?: boolean;
|
|
16
|
+
failWith?: Error;
|
|
17
|
+
}
|
|
18
|
+
export declare function createFakeShell(replies?: ShellReply[] | ((call: ShellCall, index: number) => ShellReply)): {
|
|
19
|
+
shell: DshShell;
|
|
20
|
+
calls: ShellCall[];
|
|
21
|
+
peak: () => number;
|
|
22
|
+
commands: () => string[];
|
|
23
|
+
};
|
|
24
|
+
export interface OpencliCall {
|
|
25
|
+
args: readonly string[];
|
|
26
|
+
key?: string;
|
|
27
|
+
workdir?: string;
|
|
28
|
+
refresh?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function createFakeOpencli(replies?: Array<unknown | Error> | ((call: OpencliCall, index: number) => unknown | Error)): {
|
|
31
|
+
opencli: Opencli;
|
|
32
|
+
calls: OpencliCall[];
|
|
33
|
+
keys: () => (string | undefined)[];
|
|
34
|
+
};
|
|
35
|
+
export declare function createFakeLogger(): {
|
|
36
|
+
logger: {
|
|
37
|
+
info: () => void;
|
|
38
|
+
warn: (message: string) => void;
|
|
39
|
+
};
|
|
40
|
+
warnings: string[];
|
|
41
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
|
+
const tick = () => delay(0);
|
|
3
|
+
export function createFakeShell(replies = []) {
|
|
4
|
+
const calls = [];
|
|
5
|
+
let running = 0;
|
|
6
|
+
let peak = 0;
|
|
7
|
+
const replyAt = (index) => typeof replies === 'function' ? replies(calls[index], index) : (replies[index] ?? {});
|
|
8
|
+
const shell = {
|
|
9
|
+
resolve(request) {
|
|
10
|
+
calls.push(request);
|
|
11
|
+
return request;
|
|
12
|
+
},
|
|
13
|
+
async execute() {
|
|
14
|
+
const index = calls.length - 1;
|
|
15
|
+
const reply = replyAt(index);
|
|
16
|
+
if (reply.failWith !== undefined)
|
|
17
|
+
throw reply.failWith;
|
|
18
|
+
running += 1;
|
|
19
|
+
peak = Math.max(peak, running);
|
|
20
|
+
return {
|
|
21
|
+
async result() {
|
|
22
|
+
await tick();
|
|
23
|
+
running -= 1;
|
|
24
|
+
return {
|
|
25
|
+
exitCode: reply.exitCode ?? 0,
|
|
26
|
+
timedOut: reply.timedOut ?? false,
|
|
27
|
+
aborted: reply.aborted ?? false,
|
|
28
|
+
stdout: { text: reply.stdout ?? '', truncated: false },
|
|
29
|
+
stderr: { text: reply.stderr ?? '', truncated: false },
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
shell,
|
|
37
|
+
calls,
|
|
38
|
+
peak: () => peak,
|
|
39
|
+
commands: () => calls.map((call) => call.command),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function createFakeOpencli(replies = []) {
|
|
43
|
+
const calls = [];
|
|
44
|
+
const opencli = {
|
|
45
|
+
async json(args, options = {}) {
|
|
46
|
+
const call = {
|
|
47
|
+
args,
|
|
48
|
+
...(options.key === undefined ? {} : { key: options.key }),
|
|
49
|
+
...(options.workdir === undefined ? {} : { workdir: options.workdir }),
|
|
50
|
+
};
|
|
51
|
+
calls.push(call);
|
|
52
|
+
const index = calls.length - 1;
|
|
53
|
+
const reply = typeof replies === 'function' ? replies(call, index) : (replies[index] ?? []);
|
|
54
|
+
if (reply instanceof Error)
|
|
55
|
+
throw reply;
|
|
56
|
+
return { value: reply, at: Date.now() };
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
opencli,
|
|
61
|
+
calls,
|
|
62
|
+
keys: () => calls.map((call) => call.key),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function createFakeLogger() {
|
|
66
|
+
const warnings = [];
|
|
67
|
+
return {
|
|
68
|
+
logger: {
|
|
69
|
+
info: () => { },
|
|
70
|
+
warn: (message) => {
|
|
71
|
+
warnings.push(message);
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
warnings,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createFakeShell } from './fakes';
|
|
2
|
+
export declare const GOOD_BRIDGE_REPORT: string;
|
|
3
|
+
export declare const ALL_OK: {
|
|
4
|
+
stdout: string;
|
|
5
|
+
}[];
|
|
6
|
+
export declare const STALE_DAEMON_BRIDGE: string;
|
|
7
|
+
export declare const BROKEN_BRIDGE: string;
|
|
8
|
+
export declare function build(replies: Parameters<typeof createFakeShell>[0], install?: () => Promise<{
|
|
9
|
+
ok: boolean;
|
|
10
|
+
detail: string;
|
|
11
|
+
}>, warmReads?: () => readonly (readonly string[])[]): {
|
|
12
|
+
fake: {
|
|
13
|
+
shell: import("../..").DshShell;
|
|
14
|
+
calls: import("./fakes").ShellCall[];
|
|
15
|
+
peak: () => number;
|
|
16
|
+
commands: () => string[];
|
|
17
|
+
};
|
|
18
|
+
preflight: import("../preflight").Preflight;
|
|
19
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createPreflight } from '../preflight';
|
|
2
|
+
import { createFakeShell } from './fakes';
|
|
3
|
+
export const GOOD_BRIDGE_REPORT = [
|
|
4
|
+
'opencli v1.8.7 doctor (node v24.15.0)',
|
|
5
|
+
'',
|
|
6
|
+
'[OK] Daemon: running on port 19825 (v1.8.7)',
|
|
7
|
+
'[OK] Extension: connected (v1.0.24)',
|
|
8
|
+
'[OK] Connectivity: connected in 0.0s',
|
|
9
|
+
'',
|
|
10
|
+
'Everything looks good!',
|
|
11
|
+
].join('\n');
|
|
12
|
+
export const ALL_OK = [{ stdout: '1.8.8\n' }, { stdout: GOOD_BRIDGE_REPORT }];
|
|
13
|
+
export const STALE_DAEMON_BRIDGE = [
|
|
14
|
+
'opencli v1.8.7 doctor (node v24.15.0)',
|
|
15
|
+
'',
|
|
16
|
+
'[STALE] Daemon: running on port 19825 (v1.8.8 != CLI v1.8.7)',
|
|
17
|
+
'[OK] Extension: connected (v1.0.24)',
|
|
18
|
+
'[OK] Connectivity: connected in 0.0s',
|
|
19
|
+
'',
|
|
20
|
+
'Issues:',
|
|
21
|
+
' • Stale daemon detected: daemon v1.8.8 != CLI v1.8.7.',
|
|
22
|
+
' Run: opencli daemon restart',
|
|
23
|
+
].join('\n');
|
|
24
|
+
export const BROKEN_BRIDGE = [
|
|
25
|
+
'opencli v1.8.7 doctor (node v24.15.0)',
|
|
26
|
+
'',
|
|
27
|
+
'[MISSING] Daemon: not running',
|
|
28
|
+
'[MISSING] Extension: not connected',
|
|
29
|
+
'[FAIL] Connectivity: failed (daemon not reachable)',
|
|
30
|
+
'',
|
|
31
|
+
'Issues:',
|
|
32
|
+
" • Daemon is not running. It should start automatically when you run an opencli browser command.",
|
|
33
|
+
' • Daemon is running but the Chrome/Chromium extension is not connected.',
|
|
34
|
+
'If the extension is not installed:',
|
|
35
|
+
' 1. Download from https://github.com/jackwener/opencli/releases',
|
|
36
|
+
' 2. Open chrome://extensions/ → Enable Developer Mode',
|
|
37
|
+
' 3. Click "Load unpacked" → select the extension folder',
|
|
38
|
+
].join('\n');
|
|
39
|
+
export function build(replies, install, warmReads) {
|
|
40
|
+
const fake = createFakeShell(replies);
|
|
41
|
+
const preflight = createPreflight({
|
|
42
|
+
shell: fake.shell,
|
|
43
|
+
...(install === undefined ? {} : { install }),
|
|
44
|
+
...(warmReads === undefined ? {} : { warmReads }),
|
|
45
|
+
});
|
|
46
|
+
return { fake, preflight };
|
|
47
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface CliErrorEnvelope {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly message: string;
|
|
4
|
+
readonly help?: string;
|
|
5
|
+
readonly exitCode?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseCliErrorEnvelope(text: string | undefined): CliErrorEnvelope | undefined;
|
|
8
|
+
export declare function helpUrlOf(envelope: CliErrorEnvelope): string | undefined;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
function unquote(raw) {
|
|
2
|
+
const value = raw.trim();
|
|
3
|
+
if (value.length >= 2 && ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'")))) {
|
|
4
|
+
return value.slice(1, -1);
|
|
5
|
+
}
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
function joinBlock(previous, line, fold) {
|
|
9
|
+
if (previous === '')
|
|
10
|
+
return line;
|
|
11
|
+
return fold ? `${previous} ${line}` : `${previous}\n${line}`;
|
|
12
|
+
}
|
|
13
|
+
export function parseCliErrorEnvelope(text) {
|
|
14
|
+
if (text === undefined || text.trim() === '')
|
|
15
|
+
return undefined;
|
|
16
|
+
const lines = text.split('\n');
|
|
17
|
+
const start = lines.findIndex((line) => /^error:\s*$/.test(line.trim()) || /^error:\s*\S/.test(line.trim()));
|
|
18
|
+
if (start === -1)
|
|
19
|
+
return undefined;
|
|
20
|
+
const scalars = {};
|
|
21
|
+
let current;
|
|
22
|
+
let block;
|
|
23
|
+
const errorIndent = lines[start]?.search(/\S/) ?? 0;
|
|
24
|
+
for (const line of lines.slice(start + 1)) {
|
|
25
|
+
if (line.trim() === '')
|
|
26
|
+
continue;
|
|
27
|
+
const indent = line.search(/\S/);
|
|
28
|
+
if (block !== undefined && indent > block.indent) {
|
|
29
|
+
scalars[block.key] = joinBlock(scalars[block.key] ?? '', line.trim(), block.fold);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
block = undefined;
|
|
33
|
+
if (indent <= errorIndent)
|
|
34
|
+
break;
|
|
35
|
+
const match = /^\s*(code|message|help|exitCode):\s*(.*)$/.exec(line);
|
|
36
|
+
if (match === null) {
|
|
37
|
+
if (current !== undefined)
|
|
38
|
+
scalars[current] = `${scalars[current] ?? ''} ${line.trim()}`.trim();
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const [, key, value] = match;
|
|
42
|
+
if (key === undefined)
|
|
43
|
+
continue;
|
|
44
|
+
const raw = (value ?? '').trim();
|
|
45
|
+
const marker = /^([|>])[0-9]*([+-]?)$/.exec(raw);
|
|
46
|
+
if (marker !== null) {
|
|
47
|
+
scalars[key] = '';
|
|
48
|
+
block = { key, fold: marker[1] === '>', indent };
|
|
49
|
+
current = key;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
scalars[key] = unquote(raw);
|
|
53
|
+
current = key;
|
|
54
|
+
}
|
|
55
|
+
const code = scalars['code'];
|
|
56
|
+
const message = scalars['message'];
|
|
57
|
+
if (code === undefined || code === '')
|
|
58
|
+
return undefined;
|
|
59
|
+
const exitCode = scalars['exitCode'];
|
|
60
|
+
return {
|
|
61
|
+
code,
|
|
62
|
+
message: message ?? code,
|
|
63
|
+
...(scalars['help'] === undefined || scalars['help'] === '' ? {} : { help: scalars['help'] }),
|
|
64
|
+
...(exitCode === undefined || Number.isNaN(Number(exitCode)) ? {} : { exitCode: Number(exitCode) }),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function helpUrlOf(envelope) {
|
|
68
|
+
const match = /https?:\/\/[^\s"'`]+/.exec(envelope.help ?? '');
|
|
69
|
+
return match?.[0];
|
|
70
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ContextRef } from '@dsh-workbench/shared';
|
|
2
|
+
import type { ContextRenderer } from './unit-face';
|
|
3
|
+
export declare const CONTEXT_SOURCE_KIND = "workbench";
|
|
4
|
+
export interface ScannableMessage {
|
|
5
|
+
readonly source?: {
|
|
6
|
+
readonly kind?: string;
|
|
7
|
+
};
|
|
8
|
+
readonly content?: readonly {
|
|
9
|
+
readonly type?: string;
|
|
10
|
+
readonly text?: string;
|
|
11
|
+
}[];
|
|
12
|
+
}
|
|
13
|
+
export type { ContextRenderer };
|
|
14
|
+
export declare function collectContextRefs(messages: readonly ScannableMessage[]): ContextRef[];
|
|
15
|
+
export declare function buildContextMessage(text: string, summary: string): unknown;
|
|
16
|
+
export interface ContextInjector {
|
|
17
|
+
inject(messages: readonly ScannableMessage[], agent: unknown): Promise<unknown | undefined>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createContextInjector(options: {
|
|
20
|
+
renderers: ReadonlyMap<string, ContextRenderer>;
|
|
21
|
+
logger?: {
|
|
22
|
+
warn?(message: string): void;
|
|
23
|
+
} | undefined;
|
|
24
|
+
}): ContextInjector;
|