@dsh-workbench/core 1.1.3 → 1.1.5

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.
Files changed (47) hide show
  1. package/client.js +1370 -585
  2. package/dist/client/client.body.js +1370 -585
  3. package/dist/client/index.js +1225 -440
  4. package/dist/host/index.js +784 -114
  5. package/dist/types/app/layouts/approval-detail.d.ts +6 -3
  6. package/dist/types/app/layouts/market/add-module-registry-prefs.d.ts +11 -0
  7. package/dist/types/app/layouts/market/discover-confirm.d.ts +3 -2
  8. package/dist/types/app/layouts/market/market-check.d.ts +12 -0
  9. package/dist/types/app/layouts/market/market-header.d.ts +1 -3
  10. package/dist/types/app/layouts/market/use-discover.d.ts +2 -1
  11. package/dist/types/app/layouts/market/use-git-transport.d.ts +2 -2
  12. package/dist/types/app/layouts/market/use-module-versions.d.ts +3 -0
  13. package/dist/types/app/layouts/market/use-settling-modules.d.ts +1 -0
  14. package/dist/types/app/layouts/rightbar/AskAgentButton.d.ts +6 -0
  15. package/dist/types/app/layouts/rightbar/FailureCard.d.ts +8 -0
  16. package/dist/types/app/layouts/rightbar/MarketView.d.ts +4 -1
  17. package/dist/types/app/layouts/rightbar/SharedSection.d.ts +5 -2
  18. package/dist/types/app/layouts/rightbar/failure-card-text.d.ts +14 -0
  19. package/dist/types/app/layouts/rightbar/market-act.d.ts +2 -5
  20. package/dist/types/app/layouts/rightbar/market-change.d.ts +1 -0
  21. package/dist/types/app/layouts/rightbar/market-freshness.d.ts +1 -0
  22. package/dist/types/app/layouts/rightbar/market-hint.d.ts +2 -0
  23. package/dist/types/app/layouts/rightbar/market-install.d.ts +11 -0
  24. package/dist/types/app/layouts/rightbar/market-row-types.d.ts +11 -2
  25. package/dist/types/app/layouts/rightbar/market-rows.d.ts +14 -1
  26. package/dist/types/app/layouts/rightbar/market-section.d.ts +8 -4
  27. package/dist/types/app/layouts/rightbar/market-transient-state.d.ts +3 -8
  28. package/dist/types/app/layouts/rightbar/market-view-text.d.ts +2 -0
  29. package/dist/types/app/layouts/rightbar/use-market-default.d.ts +12 -0
  30. package/dist/types/kernel/client/registry.d.ts +1 -0
  31. package/dist/types/kernel/contract/bundle-install.d.ts +1 -1
  32. package/dist/types/kernel/contract/market-index.d.ts +2 -2
  33. package/dist/types/modules/panels/model/market-install-error.d.ts +3 -0
  34. package/dist/types/modules/panels/model/market-install-error.test.d.ts +1 -0
  35. package/dist/types/modules/panels/model/market-installed.d.ts +19 -0
  36. package/dist/types/modules/panels/model/market-installed.test.d.ts +1 -0
  37. package/dist/types/modules/panels/model/market-registry.d.ts +2 -1
  38. package/dist/types/modules/panels/model/market-remove.d.ts +13 -0
  39. package/dist/types/modules/panels/model/market-remove.test.d.ts +1 -0
  40. package/dist/types/modules/panels/model/market-route.d.ts +2 -1
  41. package/dist/types/modules/panels/model/market.d.ts +1 -0
  42. package/dist/types/shared/api/host/git-probe.d.ts +3 -0
  43. package/dist/types/shared/api/host/market-sources-store.d.ts +2 -1
  44. package/dist/types/shared/api/host/profile-dependencies.d.ts +1 -0
  45. package/dist/types/shared/hooks/market-queries.d.ts +2 -1
  46. package/package.json +3 -3
  47. package/skills/workbench-module-diy/TOOLS.md +11 -2
@@ -1,4 +1,4 @@
1
- import type { ApprovalInput, ReactNode, Translate } from '@dsh-workbench/shared';
1
+ import type { ApprovalInput, ReactNode, Translate, UnitManifest, UnitToolOpencli } from '@dsh-workbench/shared';
2
2
  import type { MarketSourcesPayload, PublishPreview } from '../../kernel/contract/market-index';
3
3
  export interface ApprovalRow {
4
4
  readonly label: string;
@@ -12,6 +12,9 @@ export interface ApprovalPlanView {
12
12
  readonly warn?: string | undefined;
13
13
  }
14
14
  export declare function marketSourceRows(tool: string, args: Readonly<Record<string, unknown>>, payload: MarketSourcesPayload | null | undefined, t: Translate): readonly ApprovalRow[];
15
+ export declare function pluginToolIndexOf(manifests: readonly UnitManifest[]): ReadonlyMap<string, UnitToolOpencli>;
16
+ export declare function pluginApprovalRows(origin: UnitToolOpencli, args: Readonly<Record<string, unknown>>, t: Translate): readonly ApprovalRow[];
17
+ export declare function shellApprovalRenderer(manifests: () => readonly UnitManifest[]): (input: ApprovalInput, t: Translate) => ReactNode;
15
18
  export declare function shellClaimsApprovalDetail(tool: string): boolean;
16
- export declare function shellApprovalPlan(input: ApprovalInput, t: Translate): ApprovalPlanView | undefined;
17
- export declare function shellApprovalDetail(input: ApprovalInput, t: Translate): ReactNode;
19
+ export declare function shellApprovalPlan(input: ApprovalInput, t: Translate, pluginTools?: ReadonlyMap<string, UnitToolOpencli> | undefined): ApprovalPlanView | undefined;
20
+ export declare function shellApprovalDetail(input: ApprovalInput, t: Translate, pluginTools?: ReadonlyMap<string, UnitToolOpencli> | undefined): ReactNode;
@@ -0,0 +1,11 @@
1
+ import { type RegistryChoice, type RegistryOption } from './add-module-text';
2
+ export interface RegistryPrefs {
3
+ readonly choice: RegistryChoice;
4
+ readonly custom: string;
5
+ }
6
+ export declare const DEFAULT_REGISTRY_CHOICE: RegistryChoice;
7
+ export declare function parseRegistryChoice(raw: string | null): RegistryChoice;
8
+ export declare function readRegistryPrefs(): RegistryPrefs;
9
+ export declare function writeRegistryChoice(choice: RegistryChoice): void;
10
+ export declare function writeRegistryCustom(value: string): void;
11
+ export declare function reconcileRegistryChoice(choice: RegistryChoice, choices: readonly RegistryOption[]): RegistryChoice;
@@ -1,5 +1,5 @@
1
1
  import type { Translate } from '@dsh-workbench/shared';
2
- import type { DiscoverEntry, DiscoverVersionRow } from '../../../kernel/contract/market-index';
2
+ import type { DiscoverEntry, DiscoverVersionRow, GitTransportKind } from '../../../kernel/contract/market-index';
3
3
  export interface DiscoverChoice {
4
4
  readonly entry: DiscoverEntry;
5
5
  readonly version: DiscoverVersionRow;
@@ -8,7 +8,8 @@ export interface DiscoverConfirmProps {
8
8
  readonly t: Translate;
9
9
  readonly locale: string;
10
10
  readonly choice: DiscoverChoice | null;
11
+ readonly transports: Readonly<Record<string, GitTransportKind>>;
11
12
  readonly onCancel: () => void;
12
13
  readonly onConfirm: (url?: string) => void;
13
14
  }
14
- export declare function DiscoverConfirm({ t, locale, choice, onCancel, onConfirm }: DiscoverConfirmProps): JSX.Element | null;
15
+ export declare function DiscoverConfirm({ t, locale, choice, transports, onCancel, onConfirm }: DiscoverConfirmProps): JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ import type { Translate } from '@dsh-workbench/shared';
2
+ import type { LatestCheckSummary } from '../rightbar/market-rows';
3
+ export interface MarketCheckProps {
4
+ readonly t: Translate;
5
+ readonly checkedAt: number | null;
6
+ readonly latestCheck?: LatestCheckSummary | undefined;
7
+ readonly checking: boolean;
8
+ readonly failed: boolean;
9
+ readonly disabled: boolean;
10
+ readonly onCheck: () => void;
11
+ }
12
+ export declare function MarketCheck({ t, checkedAt, latestCheck, checking, failed, disabled, onCheck, }: MarketCheckProps): JSX.Element;
@@ -5,9 +5,7 @@ export interface MarketHeaderProps {
5
5
  readonly idPrefix: string;
6
6
  readonly tab: MarketTab;
7
7
  readonly busy: boolean;
8
- readonly checking: boolean;
9
8
  readonly onTab: (tab: MarketTab) => void;
10
- readonly onReload: () => void;
11
9
  readonly onAdd: () => void;
12
10
  }
13
- export declare function MarketHeader({ t, idPrefix, tab, busy, checking, onTab, onReload, onAdd }: MarketHeaderProps): JSX.Element;
11
+ export declare function MarketHeader({ t, idPrefix, tab, busy, onTab, onAdd }: MarketHeaderProps): JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import type { Translate } from '@dsh-workbench/shared';
2
- import type { DiscoverEntry, DiscoverPayload, DiscoverVersionRow, MarketSourceConfig } from '../../../kernel/contract/market-index';
2
+ import type { DiscoverEntry, DiscoverPayload, DiscoverVersionRow, GitTransportKind, MarketSourceConfig } from '../../../kernel/contract/market-index';
3
3
  import { type DiscoverSort } from './discover-view';
4
4
  interface InstallTarget {
5
5
  readonly entry: DiscoverEntry;
@@ -25,6 +25,7 @@ export interface DiscoverController {
25
25
  readonly failure: string | null;
26
26
  readonly sources: DiscoverPayload['sources'];
27
27
  readonly selected: string | null;
28
+ readonly transports: Readonly<Record<string, GitTransportKind>>;
28
29
  readonly entries: readonly DiscoverEntry[];
29
30
  readonly shown: readonly DiscoverEntry[];
30
31
  readonly total: number;
@@ -1,4 +1,4 @@
1
- import type { GitProbeStatus, MarketIndexGitSource } from '../../../kernel/contract/market-index';
1
+ import type { GitProbeStatus, GitTransportKind, MarketIndexGitSource } from '../../../kernel/contract/market-index';
2
2
  export type TransportProbe = GitProbeStatus | 'checking' | 'unknown';
3
3
  export interface GitTransportRow {
4
4
  readonly kind: 'https' | 'ssh';
@@ -16,4 +16,4 @@ export interface GitTransportState {
16
16
  setCustom(value: string): void;
17
17
  checkCustom(): void;
18
18
  }
19
- export declare function useGitTransport(source: MarketIndexGitSource | null): GitTransportState;
19
+ export declare function useGitTransport(source: MarketIndexGitSource | null, preferredKind?: GitTransportKind | undefined): GitTransportState;
@@ -1,4 +1,5 @@
1
1
  import type { ModuleVersion, WorkbenchSelfUpdate, WorkbenchVersion } from '../../../kernel/contract/bundle-install';
2
+ import type { MarketInstalledModule } from '../../../kernel/contract/market-index';
2
3
  import type { InstalledPlugin } from '../../../shared/api/installed-plugins';
3
4
  export interface ModuleVersionsState {
4
5
  readonly modules: readonly ModuleVersion[] | null;
@@ -7,6 +8,7 @@ export interface ModuleVersionsState {
7
8
  readonly selfUpdate: WorkbenchSelfUpdate | null;
8
9
  readonly read: boolean;
9
10
  readonly checking: boolean;
11
+ readonly failed: boolean;
10
12
  readonly checkedAt: number | null;
11
13
  }
12
14
  export interface ModuleVersionsView extends ModuleVersionsState {
@@ -19,5 +21,6 @@ export declare function bumpModuleVersionsEpoch(): void;
19
21
  export declare function moduleVersionsValue(): ModuleVersionsState;
20
22
  export declare function resetModuleVersions(): void;
21
23
  export declare function subscribeModuleVersions(listener: () => void): () => void;
24
+ export declare function withMarketUpdates(modules: readonly ModuleVersion[], rows: readonly MarketInstalledModule[]): readonly ModuleVersion[];
22
25
  export declare function runModuleVersionsRead(force?: boolean, fresh?: boolean): Promise<void>;
23
26
  export declare function useModuleVersions(): ModuleVersionsView;
@@ -0,0 +1 @@
1
+ export declare function useSettlingModules(installedKey: string, rosterKey: string, activeKey: string): ReadonlySet<string>;
@@ -0,0 +1,6 @@
1
+ import type { Translate } from '@dsh-workbench/shared';
2
+ export declare function AskAgentButton({ t, text, label, }: {
3
+ readonly t: Translate;
4
+ readonly text: string;
5
+ readonly label: string;
6
+ }): JSX.Element;
@@ -0,0 +1,8 @@
1
+ import type { Translate } from '@dsh-workbench/shared';
2
+ import type { InstallFailure } from '@dsh-workbench/shared';
3
+ export declare function FailureCard({ t, failure, onRecheck, rechecking, }: {
4
+ readonly t: Translate;
5
+ readonly failure: InstallFailure;
6
+ readonly onRecheck: () => void;
7
+ readonly rechecking: boolean;
8
+ }): JSX.Element;
@@ -20,14 +20,17 @@ export interface MarketViewProps {
20
20
  }) => void;
21
21
  readonly onPending?: ((pending: boolean) => void) | undefined;
22
22
  readonly updates?: ModuleUpdateMap | undefined;
23
+ readonly updatesCheckedAt?: number | null | undefined;
24
+ readonly updatesFailed?: boolean | undefined;
23
25
  readonly installed?: readonly InstalledWorkbenchModule[] | undefined;
24
26
  readonly installedRead?: boolean | undefined;
25
27
  readonly workbench?: WorkbenchVersion | null | undefined;
26
28
  readonly selfUpdate?: WorkbenchSelfUpdate | null | undefined;
27
29
  readonly plugins?: readonly InstalledPlugin[] | null | undefined;
28
30
  readonly settling?: ReadonlySet<string> | undefined;
31
+ readonly installing?: boolean | undefined;
29
32
  readonly mock?: MarketMock | undefined;
30
33
  readonly defaults?: readonly string[] | undefined;
31
34
  readonly changed?: Readonly<Record<string, number>> | undefined;
32
35
  }
33
- export declare function MarketView({ t, titleOf, manifests, installable, capabilities, freshness, onChanged, onPending, updates, installed, installedRead, workbench, selfUpdate, plugins, settling, mock, defaults, changed, }: MarketViewProps): JSX.Element;
36
+ export declare function MarketView({ t, titleOf, manifests, installable, capabilities, freshness, onChanged, onPending, updates, updatesCheckedAt, updatesFailed, installed, installedRead, workbench, selfUpdate, plugins, settling, installing, mock, defaults, changed, }: MarketViewProps): JSX.Element;
@@ -1,11 +1,14 @@
1
1
  import type { Translate } from '@dsh-workbench/shared';
2
2
  import { type SharedRow } from './market-rows';
3
+ import type { MarketFailure } from './market-row-types';
3
4
  import { type Pending } from './market-view-text';
4
5
  import type { MarketRowAction } from './market-rows';
5
- export declare function SharedSection({ t, rows, pending, failureOf, act, }: {
6
+ export declare function SharedSection({ t, rows, pending, failureOf, act, onRecheck, rechecking, }: {
6
7
  readonly t: Translate;
7
8
  readonly rows: readonly SharedRow[];
8
9
  readonly pending: Pending | null;
9
- readonly failureOf: (id: string) => string | null;
10
+ readonly failureOf: (id: string) => MarketFailure | null;
10
11
  readonly act: (id: string, action: MarketRowAction) => Promise<void>;
12
+ readonly onRecheck: () => void;
13
+ readonly rechecking: boolean;
11
14
  }): JSX.Element | null;
@@ -0,0 +1,14 @@
1
+ import type { InstallFailure, Translate } from '@dsh-workbench/shared';
2
+ export interface FailureCardModel {
3
+ readonly title: string;
4
+ readonly fact: string;
5
+ readonly fixLabel: string;
6
+ readonly fix: string;
7
+ readonly copiedHint: string;
8
+ readonly command: string;
9
+ readonly output: string;
10
+ readonly exitCode: number | null;
11
+ }
12
+ export declare function shellPath(path: string): string;
13
+ export declare function ownerLabel(uid: number): string;
14
+ export declare function failureCardOf(failure: InstallFailure, t: Translate): FailureCardModel;
@@ -1,15 +1,12 @@
1
1
  import type { Translate, WriteOutcome } from '@dsh-workbench/shared';
2
- import type { MarketRow } from './market-row-types';
2
+ import type { MarketFailure, MarketRow } from './market-row-types';
3
3
  import { type MarketRowAction } from './market-rows';
4
4
  import { type HeldRow, type Pending } from './market-view-text';
5
5
  export interface MarketActSeats {
6
6
  readonly setPending: (next: Pending | null) => void;
7
7
  readonly setHeld: (next: HeldRow | undefined) => void;
8
8
  readonly setConfirming: (next: string | null) => void;
9
- readonly setFailed: (next: {
10
- readonly id: string;
11
- readonly message: string;
12
- } | null) => void;
9
+ readonly setFailed: (next: MarketFailure | null) => void;
13
10
  readonly setNotice: (next: string | null) => void;
14
11
  }
15
12
  export interface MarketActOptions {
@@ -2,3 +2,4 @@ import type { Translate } from '@dsh-workbench/shared';
2
2
  import type { BundleChange } from '../../../kernel/contract/bundle-install';
3
3
  export declare function changeOf(value: unknown): BundleChange | undefined;
4
4
  export declare function changeFailure(change: BundleChange | undefined, t: Translate): string | undefined;
5
+ export declare function appliedUnitsOf(value: unknown): readonly string[];
@@ -1,6 +1,7 @@
1
1
  import type { Translate } from '@dsh-workbench/shared';
2
2
  export declare const MARKET_STALE_MS = 600000;
3
3
  export declare function checkedAgoText(at: number, now: number, t: Translate): string;
4
+ export declare function checkedAgo(at: number, t: Translate): string;
4
5
  export interface MarketFreshness {
5
6
  readonly loaded: boolean;
6
7
  readonly checking: boolean;
@@ -13,5 +13,7 @@ export interface MarketHintInput {
13
13
  readonly plugins?: readonly InstalledPlugin[] | null | undefined;
14
14
  readonly workbench?: WorkbenchVersion | null | undefined;
15
15
  readonly busy?: ReadonlySet<string> | undefined;
16
+ readonly installing?: boolean | undefined;
17
+ readonly applied?: ReadonlySet<string> | undefined;
16
18
  }
17
19
  export declare function marketHintOf(input: MarketHintInput): PanelHint | null;
@@ -0,0 +1,11 @@
1
+ export interface MarketInstallState {
2
+ readonly installing: boolean;
3
+ readonly applied: ReadonlySet<string>;
4
+ }
5
+ export declare function marketInstallState(): MarketInstallState;
6
+ export declare function subscribeMarketInstall(listener: () => void): () => void;
7
+ export declare function publishMarketInstalling(token: string, active: boolean): void;
8
+ export declare function publishMarketApplied(units: readonly string[]): void;
9
+ export declare function resetMarketInstall(): void;
10
+ export declare function useMarketInstallState(): MarketInstallState;
11
+ export declare function usePublishMarketInstalling(token: string, active: boolean): void;
@@ -1,8 +1,15 @@
1
1
  import type { ModuleUpdateBlock } from '../../../kernel/contract/bundle-install';
2
- export type MarketRowAction = 'install' | 'update' | 'update-bundle' | 'remove-bundle' | 'uninstall' | 'update-dependency' | 'update-plugin' | 'uninstall-plugin' | 'update-workbench' | 'migrate-workbench' | 'dismiss-followup';
2
+ import type { MarketInstalledModule } from '../../../kernel/contract/market-index';
3
+ import type { InstallFailure } from '@dsh-workbench/shared';
4
+ export interface MarketFailure {
5
+ readonly id: string;
6
+ readonly message: string;
7
+ readonly failure?: InstallFailure;
8
+ }
9
+ export type MarketRowAction = 'install' | 'update' | 'update-bundle' | 'install-version' | 'remove-bundle' | 'uninstall' | 'update-dependency' | 'update-plugin' | 'uninstall-plugin' | 'update-workbench' | 'migrate-workbench' | 'dismiss-followup';
3
10
  export type MarketState = 'checking' | 'installed' | 'inactive' | 'unusable' | 'broken' | 'outdated' | 'pending-restart' | 'pending-followup' | 'missing' | 'unchecked' | 'unknown';
4
11
  export interface MarketNote {
5
- readonly key: 'panels.market.needEnv' | 'panels.market.noSource' | 'panels.market.badSource' | 'panels.market.needCommands' | 'panels.market.needBinary' | 'panels.market.needLib' | 'panels.market.moduleRefused' | 'panels.market.moduleRestartHint' | 'panels.market.pluginAlsoKnownAs' | 'panels.market.pluginBroken';
12
+ readonly key: 'panels.market.needEnv' | 'panels.market.noSource' | 'panels.market.badSource' | 'panels.market.needCommands' | 'panels.market.needBinary' | 'panels.market.needLib' | 'panels.market.moduleRefused' | 'panels.market.moduleRestartHint' | 'panels.market.pluginAlsoKnownAs' | 'panels.market.pluginBroken' | 'panels.market.latestNoRegistry' | 'panels.market.latestProbeFailed';
6
13
  readonly params: Readonly<Record<string, string>>;
7
14
  readonly tone?: 'plain' | 'alert';
8
15
  }
@@ -12,6 +19,7 @@ export interface ModuleUpdate {
12
19
  readonly latest?: string;
13
20
  readonly local?: boolean;
14
21
  readonly blocked?: ModuleUpdateBlock;
22
+ readonly market?: MarketInstalledModule;
15
23
  }
16
24
  export interface MarketFollowUp {
17
25
  readonly id: string;
@@ -35,6 +43,7 @@ export interface MarketRow {
35
43
  readonly latest?: string;
36
44
  };
37
45
  readonly moduleUpdate?: ModuleUpdate;
46
+ readonly market?: MarketInstalledModule;
38
47
  readonly pkg?: string;
39
48
  readonly local?: boolean;
40
49
  readonly versionLabel?: string;
@@ -1,4 +1,5 @@
1
- import type { ModuleUpdateBlock, ModuleVersion } from '../../../kernel/contract/bundle-install';
1
+ import type { LatestUnavailable, ModuleUpdateBlock, ModuleVersion } from '../../../kernel/contract/bundle-install';
2
+ import type { MarketInstalledModule } from '../../../kernel/contract/market-index';
2
3
  import type { Translate, UnitManifest, UnitTitle } from '@dsh-workbench/shared';
3
4
  import type { MarketNameMap } from './market-names';
4
5
  import type { MarketRow, MarketRowAction, MarketState, ModuleUpdate } from './market-row-types';
@@ -18,9 +19,11 @@ export interface InstalledWorkbenchModule {
18
19
  readonly title?: UnitTitle | undefined;
19
20
  readonly latest?: string | undefined;
20
21
  readonly latestBlocked?: ModuleUpdateBlock | undefined;
22
+ readonly latestUnavailable?: LatestUnavailable | undefined;
21
23
  readonly local?: boolean | undefined;
22
24
  readonly refused?: readonly string[] | undefined;
23
25
  readonly clientRefused?: readonly string[] | undefined;
26
+ readonly market?: MarketInstalledModule | undefined;
24
27
  }
25
28
  export declare function withClientRefusals(modules: readonly InstalledWorkbenchModule[], refusals: readonly {
26
29
  readonly unit: string;
@@ -29,8 +32,14 @@ export declare function withClientRefusals(modules: readonly InstalledWorkbenchM
29
32
  }[]): readonly InstalledWorkbenchModule[];
30
33
  export declare function refusalReasons(host: readonly string[] | undefined, client: readonly string[] | undefined): readonly string[];
31
34
  export declare function installedIdSet(installed: readonly InstalledWorkbenchModule[] | undefined): ReadonlySet<string> | null;
35
+ export interface LatestCheckSummary {
36
+ readonly checked: number;
37
+ readonly unknown: number;
38
+ }
39
+ export declare function latestCheckSummary(modules: readonly InstalledWorkbenchModule[] | undefined): LatestCheckSummary;
32
40
  export declare function installedRows(modules: readonly InstalledWorkbenchModule[], manifests: readonly UnitManifest[], listed: ReadonlySet<string>, names?: MarketNameMap | undefined, defaults?: ReadonlySet<string>, changed?: Readonly<Record<string, number>>): MarketRow[];
33
41
  export declare function marketSwitchLocked(row: MarketRow): boolean;
42
+ export declare function marketAsksAgent(row: MarketRow): boolean;
34
43
  export declare function marketActions(row: MarketRow): MarketRowAction[];
35
44
  export declare function capabilityOutdated(capabilities: CapabilityMap | null, unit: string): boolean;
36
45
  export declare function marketCatalog(manifests: readonly UnitManifest[], installable: ReadonlySet<string> | null | undefined): readonly UnitManifest[];
@@ -44,4 +53,8 @@ export interface MarketSection {
44
53
  }
45
54
  export declare function marketOrder(rows: readonly MarketRow[], titleOf: (row: MarketRow) => string): MarketRow[];
46
55
  export declare function marketSections(rows: readonly MarketRow[]): MarketSection[];
56
+ export declare function checkingRows(rows: readonly MarketRow[], scope: {
57
+ readonly all: boolean;
58
+ readonly units: ReadonlySet<string>;
59
+ }): MarketRow[];
47
60
  export declare function marketRows(manifests: readonly UnitManifest[], capabilities: CapabilityMap | null, updates?: ModuleUpdateMap, defaults?: ReadonlySet<string>, changed?: Readonly<Record<string, number>>): MarketRow[];
@@ -1,18 +1,22 @@
1
- import type { Translate } from '@dsh-workbench/shared';
2
- import type { MarketRow } from './market-row-types';
1
+ import type { ReactNode, Translate } from '@dsh-workbench/shared';
2
+ import type { MarketFailure, MarketRow } from './market-row-types';
3
3
  import { type MarketRowAction } from './market-rows';
4
4
  import type { MarketSectionIcon } from './market-section-icon';
5
5
  import { type Pending } from './market-view-text';
6
- export declare function MarketSection({ t, titleKey, icon, rows, pending, failureOf, act, confirmActions, onConfirming, onDefault, boardBusy, }: {
6
+ export declare function MarketSection({ t, titleKey, icon, rows, pending, failureOf, act, confirmActions, onConfirming, onDefault, boardBusy, headAction, keepHead, onRecheck, rechecking, }: {
7
7
  readonly t: Translate;
8
8
  readonly titleKey?: string;
9
9
  readonly icon?: MarketSectionIcon;
10
10
  readonly rows: readonly MarketRow[];
11
11
  readonly pending: Pending | null;
12
- readonly failureOf: (id: string) => string | null;
12
+ readonly failureOf: (id: string) => MarketFailure | null;
13
13
  readonly act: (id: string, action: MarketRowAction) => Promise<void>;
14
14
  readonly onDefault?: ((id: string, next: boolean) => void) | undefined;
15
15
  readonly boardBusy?: boolean | undefined;
16
16
  readonly confirmActions: readonly MarketRowAction[];
17
17
  readonly onConfirming: (id: string | null) => void;
18
+ readonly headAction?: ReactNode;
19
+ readonly keepHead?: boolean;
20
+ readonly onRecheck: () => void;
21
+ readonly rechecking: boolean;
18
22
  }): JSX.Element | null;
@@ -1,18 +1,13 @@
1
1
  import type { MarketMock } from './market-mock';
2
2
  import type { Pending } from './market-view-text';
3
+ import type { MarketFailure } from './market-row-types';
3
4
  export interface MarketTransient {
4
5
  readonly pending: Pending | null;
5
6
  readonly setPending: (next: Pending | null) => void;
6
7
  readonly confirming: string | null;
7
8
  readonly setConfirming: (next: string | null) => void;
8
- readonly failed: {
9
- readonly id: string;
10
- readonly message: string;
11
- } | null;
12
- readonly setFailed: (next: {
13
- readonly id: string;
14
- readonly message: string;
15
- } | null) => void;
9
+ readonly failed: MarketFailure | null;
10
+ readonly setFailed: (next: MarketFailure | null) => void;
16
11
  readonly notice: string | null;
17
12
  readonly setNotice: (next: string | null) => void;
18
13
  }
@@ -48,3 +48,5 @@ export declare function pendingRowOf(input: {
48
48
  readonly rows: readonly MarketRow[];
49
49
  readonly names: MarketNameMap;
50
50
  }): MarketRow | undefined;
51
+ export declare function askAgentReason(row: MarketRow, t: Translate): string;
52
+ export declare function askAgentText(row: MarketRow, t: Translate): string;
@@ -0,0 +1,12 @@
1
+ import type { Translate } from '@dsh-workbench/shared';
2
+ export interface MarketDefaultSeat {
3
+ readonly pending: boolean;
4
+ setDefault(id: string, next: boolean): Promise<void>;
5
+ }
6
+ export declare function useMarketDefault(input: {
7
+ readonly t: Translate;
8
+ readonly mocked: boolean;
9
+ readonly defaults: readonly string[];
10
+ readonly changed: Readonly<Record<string, number>>;
11
+ readonly setNotice: (next: string | null) => void;
12
+ }): MarketDefaultSeat;
@@ -11,6 +11,7 @@ export interface ClientUnitRegistry {
11
11
  register(face: UnitClientFace): () => void;
12
12
  all(): readonly UnitClientFace[];
13
13
  manifests(): readonly UnitManifest[];
14
+ declared(): readonly UnitManifest[];
14
15
  installable(): ReadonlySet<string> | null;
15
16
  refusals(): readonly ClientUnitRefusal[];
16
17
  setManifests(manifests: readonly UnitManifest[], installable?: readonly string[]): void;
@@ -1,2 +1,2 @@
1
1
  export { BUNDLE_REGISTRIES_ROUTE, BUNDLE_INSPECT_ROUTE, BUNDLE_REGISTRY_DEFAULT, MODULE_VERSIONS_ROUTE, SELF_UPDATE_STATES, RESTART_REASONS } from '@dsh-workbench/shared/contract/protocol/bundle-install';
2
- export type { BundleRegistry, BundleRegistries, BundleInspectProblem, BundleSpecKind, BundleInspectionAccepted, BundleInspectionRefused, BundleInspectionPlugin, BundleInspection, BundleRegistriesPayload, BundleInspectionPayload, BundleApplication, SelfUpdateState, WorkbenchSelfUpdate, RestartReason, BundleChangeStage, BundleFailureKind, BundlePackageResult, BundleChange, BundleInstallRequest, BundleCancellation, BundleSupplyState, BundleModulePayload, BundleSupplyPayload, BundleInstalledPlugin, BundleInstallPayload, BundleRemovePayload, BundleCancellationPayload, ModuleVersion, ModuleUpdateBlock, WorkbenchVersion, ModuleVersionsPayload } from '@dsh-workbench/shared/contract/protocol/bundle-install';
2
+ export type { BundleRegistry, BundleRegistries, BundleInspectProblem, BundleSpecKind, BundleInspectionAccepted, BundleInspectionRefused, BundleInspectionPlugin, BundleInspection, BundleRegistriesPayload, BundleInspectionPayload, BundleApplication, SelfUpdateState, WorkbenchSelfUpdate, RestartReason, BundleChangeStage, BundleFailureKind, BundlePackageResult, BundleChange, BundleInstallRequest, BundleCancellation, BundleSupplyState, BundleModulePayload, BundleSupplyPayload, BundleInstalledPlugin, BundleInstallPayload, BundleRemovePayload, BundleCancellationPayload, LatestUnavailable, ModuleVersion, ModuleUpdateBlock, WorkbenchVersion, ModuleVersionsPayload } from '@dsh-workbench/shared/contract/protocol/bundle-install';
@@ -1,2 +1,2 @@
1
- export { MARKET_DISCOVER_ROUTE, MARKET_DOC_ROUTE, MARKET_GIT_PROBE_ROUTE, MARKET_INDEX_FORMAT, MARKET_INDEX_PATH, MARKET_PUBLISH_PREVIEW_ROUTE, MARKET_SOURCES_RESOURCE, MARKET_SOURCES_ROUTE, MARKET_WORKBENCH_LABEL, } from '@dsh-workbench/shared/contract/protocol/market-index';
2
- export type { DiscoverCompat, DiscoverDoc, DiscoverDocKind, DiscoverEntry, DiscoverFilter, DiscoverInstallState, DiscoverPayload, DiscoverProblem, DiscoverSourceRow, DiscoverState, DiscoverVersionRow, GitProbePayload, GitProbeStatus, IndexSourceSpec, MarketClaim, MarketIndex, MarketIndexCategory, MarketIndexEngines, MarketIndexEntry, MarketIndexEntryMetadata, MarketIndexGitSource, MarketIndexLabel, MarketIndexMetadata, MarketIndexNpmSource, MarketIndexParse, MarketIndexProblem, MarketIndexProblemKind, MarketIndexSortKey, MarketIndexSource, MarketIndexVersion, MarketLocalizedText, MarketPublishDestination, MarketSourceConfig, MarketSourceKind, MarketSourcePolicy, MarketSourcesAction, MarketSourcesPayload, PublishChangelog, PublishPreview, } from '@dsh-workbench/shared/contract/protocol/market-index';
1
+ export { MARKET_DISCOVER_ROUTE, MARKET_DOC_ROUTE, MARKET_GIT_PROBE_ROUTE, MARKET_INSTALLED_ROUTE, MARKET_INDEX_FORMAT, MARKET_INDEX_PATH, MARKET_PUBLISH_PREVIEW_ROUTE, MARKET_SOURCES_RESOURCE, MARKET_SOURCES_ROUTE, MARKET_WORKBENCH_LABEL, } from '@dsh-workbench/shared/contract/protocol/market-index';
2
+ export type { DiscoverCompat, DiscoverDoc, DiscoverDocKind, DiscoverEntry, DiscoverFilter, DiscoverInstallState, DiscoverPayload, DiscoverProblem, DiscoverSourceRow, DiscoverState, DiscoverVersionRow, GitProbePayload, GitProbeStatus, GitTransportKind, MarketInstalledModule, MarketInstalledPayload, IndexSourceSpec, MarketClaim, MarketIndex, MarketIndexCategory, MarketIndexEngines, MarketIndexEntry, MarketIndexEntryMetadata, MarketIndexGitSource, MarketIndexLabel, MarketIndexMetadata, MarketIndexNpmSource, MarketIndexParse, MarketIndexProblem, MarketIndexProblemKind, MarketIndexSortKey, MarketIndexSource, MarketIndexVersion, MarketLocalizedText, MarketPublishDestination, MarketSourceConfig, MarketSourceKind, MarketSourcePolicy, MarketSourcesAction, MarketSourcesPayload, PublishChangelog, PublishPreview, } from '@dsh-workbench/shared/contract/protocol/market-index';
@@ -0,0 +1,3 @@
1
+ import type { InstallFailure } from '@dsh-workbench/shared';
2
+ import { WorkbenchDataError } from '@dsh-workbench/shared/host';
3
+ export declare function installError(failure: InstallFailure): WorkbenchDataError;
@@ -0,0 +1,19 @@
1
+ import type { GitTransportKind, MarketIndex, MarketInstalledModule, MarketInstalledPayload, MarketSourceConfig } from '@dsh-workbench/shared/contract/protocol/market-index';
2
+ import type { RouteTable } from '@dsh-workbench/shared/host';
3
+ import type { ProfileModule } from '@dsh-workbench/shared/host';
4
+ import type { GitProbeStatus } from '@dsh-workbench/shared/contract/protocol/market-index';
5
+ export interface InstalledIndexInput {
6
+ readonly sources: readonly MarketSourceConfig[];
7
+ readonly cached: (source: MarketSourceConfig) => MarketIndex | undefined;
8
+ readonly modules: readonly ProfileModule[];
9
+ readonly dependencyOf: (pkg: string) => string | undefined;
10
+ readonly isNewer: (latest: string, installed: string) => boolean;
11
+ readonly probe?: ((url: string) => Promise<GitProbeStatus>) | undefined;
12
+ readonly preferred?: ((host: string) => GitTransportKind | undefined) | undefined;
13
+ }
14
+ export declare function installedFromIndexes(input: InstalledIndexInput): Promise<readonly MarketInstalledModule[]>;
15
+ export declare function marketInstalledRoutes(read: () => MarketInstalledPayload | Promise<MarketInstalledPayload>): RouteTable;
16
+ export declare function transportOfSpec(spec: string): {
17
+ readonly host: string;
18
+ readonly kind: GitTransportKind;
19
+ } | undefined;
@@ -3,10 +3,11 @@ import type { BundleManager } from '@dsh-workbench/shared/host';
3
3
  import type { RegistryNotebook } from '@dsh-workbench/shared/host';
4
4
  export interface RegistryFixDeps {
5
5
  readonly registries?: RegistryNotebook | undefined;
6
+ readonly profileDir?: string | null | undefined;
6
7
  readonly logger?: {
7
8
  info?(message: string): void;
8
9
  warn?(message: string): void;
9
10
  } | undefined;
10
11
  }
11
- export declare function rememberInstalledSource(deps: RegistryFixDeps, manager: BundleManager, pkg: string, registry: string | undefined): Promise<void>;
12
+ export declare function rememberInstalledSource(deps: RegistryFixDeps, manager: BundleManager, pkg: string, registry: string | undefined, version?: string | undefined): Promise<void>;
12
13
  export declare function retryAfterRegistryFix(deps: RegistryFixDeps, manager: BundleManager, pkg: string, change: BundleChange): Promise<BundleChange>;
@@ -0,0 +1,13 @@
1
+ import type { BundleChange } from '../../../kernel/contract/bundle-install';
2
+ import type { BundleManager } from '@dsh-workbench/shared/host';
3
+ import { type RegistryFixDeps } from './market-registry';
4
+ export interface RemoveBundleOptions {
5
+ readonly manager: BundleManager;
6
+ readonly pkg: string;
7
+ readonly profileDir?: string | null | undefined;
8
+ readonly registryFix: RegistryFixDeps;
9
+ readonly logger?: {
10
+ warn?(message: string): void;
11
+ } | undefined;
12
+ }
13
+ export declare function removeDshBundle(options: RemoveBundleOptions): Promise<BundleChange>;
@@ -22,9 +22,10 @@ export interface BundleInstallDeps {
22
22
  readonly ledger?: PluginLedger | undefined;
23
23
  readonly runAll: (commands: readonly PluginSourceCommand[]) => Promise<void>;
24
24
  readonly supplyAfter: (module: InstalledModule, change: BundleChange) => Promise<BundleSupply>;
25
- readonly rememberSource: (manager: BundleManager, pkg: string, registry: string | undefined) => Promise<void>;
25
+ readonly rememberSource: (manager: BundleManager, pkg: string, registry: string | undefined, version?: string | undefined) => Promise<void>;
26
26
  readonly remove?: ((pkg: string) => Promise<BundleChange>) | undefined;
27
27
  }
28
+ export declare function bundleNameOf(change: BundleChange, spec: string): string;
28
29
  export declare function installDshBundle(deps: Omit<BundleInstallDeps, 'spec' | 'options'>, spec: string, options?: BundleInstallOptions): Promise<BundleInstallOutcome>;
29
30
  export type ReplaceBundleDeps = Omit<BundleInstallDeps, 'spec' | 'options' | 'remove'> & {
30
31
  readonly remove: (pkg: string) => Promise<BundleChange>;
@@ -25,6 +25,7 @@ export declare function createMarketService(options: {
25
25
  modules?: (() => readonly ProfileModule[]) | undefined;
26
26
  workbench?: ((pkg: string) => ProfilePackage | undefined) | undefined;
27
27
  registries?: RegistryNotebook | undefined;
28
+ profileDir?: string | null | undefined;
28
29
  ledger?: PluginLedger | undefined;
29
30
  references?: (() => PluginReferences) | undefined;
30
31
  dshHome?: (() => string) | undefined;
@@ -4,3 +4,6 @@ export declare function classifyGitProbe(stderr: string, timedOut: boolean): Git
4
4
  export declare function probeGitAddress(shell: DshShell, url: string, options?: {
5
5
  readonly timeoutMs?: number;
6
6
  }): Promise<GitProbePayload>;
7
+ export declare function probeGitAddressCached(shell: DshShell, url: string, options?: {
8
+ readonly timeoutMs?: number;
9
+ }): Promise<GitProbePayload>;
@@ -1,4 +1,4 @@
1
- import type { MarketSourcesAction, MarketSourcesPayload } from '@dsh-workbench/shared/contract/protocol/market-index';
1
+ import type { GitTransportKind, MarketSourcesAction, MarketSourcesPayload } from '@dsh-workbench/shared/contract/protocol/market-index';
2
2
  export type MarketSourcesWrite = Exclude<MarketSourcesAction, {
3
3
  readonly action: 'init';
4
4
  } | {
@@ -7,6 +7,7 @@ export type MarketSourcesWrite = Exclude<MarketSourcesAction, {
7
7
  export interface MarketSourcesStore {
8
8
  read(): MarketSourcesPayload;
9
9
  apply(action: MarketSourcesWrite): Promise<MarketSourcesPayload>;
10
+ rememberTransport(host: string, kind: GitTransportKind): Promise<void>;
10
11
  }
11
12
  export interface MarketSourcesStoreOptions {
12
13
  readonly root: string;
@@ -0,0 +1 @@
1
+ export declare function dependencyReader(profileDir: string | null): (pkg: string) => string | undefined;
@@ -1,10 +1,11 @@
1
1
  import type { ApiResponse } from '@dsh-workbench/shared';
2
- import { type DiscoverDoc, type DiscoverDocKind, type DiscoverPayload, type GitProbePayload, type MarketSourcesPayload, type PublishPreview } from '../../kernel/contract/market-index';
2
+ import { type DiscoverDoc, type DiscoverDocKind, type DiscoverPayload, type GitProbePayload, type MarketInstalledPayload, type MarketSourcesPayload, type PublishPreview } from '../../kernel/contract/market-index';
3
3
  export declare function readMarketDiscover(options?: {
4
4
  readonly force?: boolean;
5
5
  }): Promise<ApiResponse<DiscoverPayload>>;
6
6
  export declare function readMarketSources(): Promise<ApiResponse<MarketSourcesPayload>>;
7
7
  export declare function readGitProbe(url: string): Promise<ApiResponse<GitProbePayload>>;
8
+ export declare function readMarketInstalled(): Promise<ApiResponse<MarketInstalledPayload>>;
8
9
  export declare function readMarketDoc(name: string, version: string, kind: DiscoverDocKind): Promise<ApiResponse<{
9
10
  readonly doc: DiscoverDoc;
10
11
  }>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/core",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "个人工作台:Agent 工作台(左栏 + 常驻对话 + 自研右侧数据面板)。",
5
5
  "type": "module",
6
6
  "icon": "./icon.svg",
@@ -100,8 +100,8 @@
100
100
  "proper-lockfile": "^4.1.2",
101
101
  "which": "^7.0.0",
102
102
  "write-file-atomic": "^8.0.0",
103
- "@dsh-workbench/shared": "1.1.3",
104
- "@dsh-workbench/adapters-default": "1.1.3"
103
+ "@dsh-workbench/shared": "1.1.5",
104
+ "@dsh-workbench/adapters-default": "1.1.5"
105
105
  },
106
106
  "license": "MIT",
107
107
  "repository": {
@@ -108,18 +108,27 @@
108
108
  ]
109
109
  },
110
110
  { "kind": "lib", "name": "opencli-workflow", "purpose": "发布编排" },
111
- { "kind": "bin", "name": "acme", "purpose": "平台命令" },
111
+ {
112
+ "kind": "bin",
113
+ "name": "acme",
114
+ "purpose": "平台命令",
115
+ "install": { "kind": "command", "line": "brew install acme/tap/cli", "platforms": ["darwin"] },
116
+ "docs": "https://internal/acme-cli"
117
+ },
112
118
  { "kind": "env", "name": "ACME_TOKEN", "purpose": "访问令牌", "secret": true }
113
119
  ]
114
120
  ```
115
121
 
116
122
  - `sources` 按顺序试(本地 → 私有 → 公共)。没写 `sources` 就是「我自己装,你只帮我判」——外壳只探不代装。
123
+ - `bin` 想让人一键装,就写 `install.line`(一条能直接粘进终端的命令,`platforms` 可限定平台);
124
+ 不写就只显示「缺这条命令」,按钮都不会有。`docs` 是给人和 agent 看的补充链接。
117
125
  - `extension` 的 `sources[].kind` 只有 `npm` / `git` / `local`;`lib` 只认 `npm`。
118
126
  未知 `kind` 或 `source.kind` 判红;need 里未知字段只警告,`x-` 前缀忽略。
119
127
  - 未装好文案由模块写:`libInstallCommand({ need, source })`(`@dsh-workbench/shared/host`)拼好源与缓存目录,
120
128
  原样输出;放进失败态。
121
129
  - `contracts` 判据:`apiVersion` 必须是 3;`needs` 走同一份 `NEED_KINDS` 注册表校验(`purpose` 必填、
122
- `bin`/`env` 不许带 `sources`、`lib` 只认 npm 源);声明了 `lib` 必须用 `libInstallCommand`。
130
+ `bin`/`env` 不许带 `sources`(`bin` 要代装就写 `install`)、`lib` 只认 npm 源);
131
+ 声明了 `lib` 必须用 `libInstallCommand`。
123
132
  未知 `runtime` 不判红:探针会给「这个运行时工作台还不认识」的 `unchecked`,等运行时 provider 补上。
124
133
 
125
134
  ## 9 长任务