@dsh-workbench/core 1.0.1 → 1.1.1

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 (39) hide show
  1. package/README.md +3 -0
  2. package/client.js +849 -460
  3. package/dist/client/client.body.js +849 -460
  4. package/dist/client/index.js +720 -331
  5. package/dist/host/index.js +448 -41
  6. package/dist/types/app/layouts/market/discover-search.d.ts +8 -0
  7. package/dist/types/app/layouts/market/discover-sources-dialog.d.ts +4 -0
  8. package/dist/types/app/layouts/market/discover-states.d.ts +3 -0
  9. package/dist/types/app/layouts/market/use-add-module.d.ts +0 -1
  10. package/dist/types/app/layouts/market/use-discover.d.ts +1 -0
  11. package/dist/types/app/layouts/rightbar/MarketView.d.ts +3 -1
  12. package/dist/types/app/layouts/rightbar/market-names.d.ts +8 -0
  13. package/dist/types/app/layouts/rightbar/market-row-types.d.ts +11 -3
  14. package/dist/types/app/layouts/rightbar/market-rows.d.ts +6 -4
  15. package/dist/types/app/layouts/rightbar/market-view-text.d.ts +4 -3
  16. package/dist/types/app/units/unit-titles.d.ts +3 -0
  17. package/dist/types/kernel/contract/bundle-install.d.ts +1 -1
  18. package/dist/types/kernel/contract/market-index.d.ts +1 -1
  19. package/dist/types/modules/panels/model/diy-tools.d.ts +1 -1
  20. package/dist/types/modules/panels/model/market-dispatch.d.ts +8 -0
  21. package/dist/types/modules/panels/model/market-follow-up.d.ts +16 -0
  22. package/dist/types/modules/panels/model/market-sources-act.d.ts +2 -0
  23. package/dist/types/modules/panels/model/market-types.d.ts +5 -0
  24. package/dist/types/modules/panels/model/market.d.ts +2 -0
  25. package/dist/types/modules/panels/model/publish-preview-routes.d.ts +1 -1
  26. package/dist/types/shared/api/host/diy-publish-preview.d.ts +11 -0
  27. package/dist/types/shared/api/host/follow-up-dismiss.d.ts +2 -0
  28. package/dist/types/shared/api/host/migrate-workbench.d.ts +20 -0
  29. package/dist/types/shared/api/host/migration-follow-up.d.ts +12 -0
  30. package/dist/types/shared/hooks/market-queries.d.ts +3 -2
  31. package/dist/types/shared/hooks/resource-view.d.ts +14 -0
  32. package/dist/types/shared/hooks/use-api-resource.d.ts +3 -7
  33. package/package.json +3 -3
  34. package/skills/workbench-module-diy/FAMILY.md +1 -1
  35. package/skills/workbench-module-diy/REVIEW.md +2 -2
  36. package/skills/workbench-module-diy/SKILL.md +1 -0
  37. package/skills/workbench-module-diy/TOOLS.md +1 -1
  38. package/skills/workbench-module-diy/WIRING.md +3 -1
  39. package/skills/workbench-module-diy/WRITES.md +1 -1
@@ -0,0 +1,8 @@
1
+ import type { Translate } from '@dsh-workbench/shared';
2
+ export interface DiscoverSearchProps {
3
+ readonly t: Translate;
4
+ readonly value: string;
5
+ readonly disabled: boolean;
6
+ readonly onChange: (value: string) => void;
7
+ }
8
+ export declare function DiscoverSearch({ t, value, disabled, onChange }: DiscoverSearchProps): JSX.Element;
@@ -4,6 +4,9 @@ export interface DiscoverSourcesDialogProps {
4
4
  readonly t: Translate;
5
5
  readonly open: boolean;
6
6
  readonly sources: readonly DiscoverSourceRow[];
7
+ readonly selected: string | null;
8
+ readonly loading: boolean;
9
+ readonly slow: boolean;
7
10
  readonly problem: {
8
11
  readonly id: string;
9
12
  readonly detail: string;
@@ -13,5 +16,6 @@ export interface DiscoverSourcesDialogProps {
13
16
  readonly onClose: () => void;
14
17
  readonly onAdd: (url: string) => void;
15
18
  readonly onRemove: (id: string) => void;
19
+ readonly onSelect: (id: string) => void;
16
20
  }
17
21
  export declare function DiscoverSourcesDialog(props: DiscoverSourcesDialogProps): JSX.Element;
@@ -5,6 +5,9 @@ export declare function DiscoverSkeleton({ label }: {
5
5
  export declare function DiscoverEmptyText({ text }: {
6
6
  readonly text: string;
7
7
  }): JSX.Element;
8
+ export declare function DiscoverLoading({ label }: {
9
+ readonly label: string;
10
+ }): JSX.Element;
8
11
  export declare function DiscoverFailure({ t, text, onRetry, }: {
9
12
  readonly t: Translate;
10
13
  readonly text: string;
@@ -38,7 +38,6 @@ export interface AddModuleState {
38
38
  removeIt(): void;
39
39
  }
40
40
  export declare function useAddModule(options: {
41
- readonly open: boolean;
42
41
  readonly onInstalled: () => void;
43
42
  readonly failedText: string;
44
43
  }): AddModuleState;
@@ -19,6 +19,7 @@ export interface DiscoverController {
19
19
  readonly locale: string;
20
20
  readonly payload: DiscoverPayload | null;
21
21
  readonly loading: boolean;
22
+ readonly slow: boolean;
22
23
  readonly failure: string | null;
23
24
  readonly sources: DiscoverPayload['sources'];
24
25
  readonly selected: string | null;
@@ -4,11 +4,13 @@ import type { CapabilityMap } from '../../../shared/hooks/use-capabilities';
4
4
  import type { MarketFreshness } from './market-freshness';
5
5
  import type { InstalledPlugin } from '../../../shared/api/installed-plugins';
6
6
  import { type InstalledWorkbenchModule } from './market-rows';
7
+ import type { TitleResolve } from './market-names';
7
8
  import type { MarketMock } from './market-mock';
8
9
  import type { ModuleUpdateMap } from './market-rows';
9
10
  import type { WorkbenchSelfUpdate, WorkbenchVersion } from '../../../kernel/contract/bundle-install';
10
11
  export interface MarketViewProps {
11
12
  readonly t: Translate;
13
+ readonly titleOf: TitleResolve;
12
14
  readonly manifests: readonly UnitManifest[];
13
15
  readonly installable?: ReadonlySet<string> | null | undefined;
14
16
  readonly capabilities: CapabilityMap | null;
@@ -28,4 +30,4 @@ export interface MarketViewProps {
28
30
  readonly defaults?: readonly string[] | undefined;
29
31
  readonly changed?: Readonly<Record<string, number>> | undefined;
30
32
  }
31
- export declare function MarketView({ t, manifests, installable, capabilities, freshness, onChanged, onPending, updates, installed, installedRead, workbench, selfUpdate, plugins, settling, mock, defaults, changed, }: MarketViewProps): JSX.Element;
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;
@@ -0,0 +1,8 @@
1
+ import type { Translate, UnitTitle } from '@dsh-workbench/shared';
2
+ export type MarketNameMap = ReadonlyMap<string, string>;
3
+ export interface NameSource {
4
+ readonly unit: string;
5
+ readonly title?: UnitTitle | undefined;
6
+ }
7
+ export type TitleResolve = (title: UnitTitle | undefined) => string;
8
+ export declare function namesOf(t: Translate, modules: readonly NameSource[], titleOf: TitleResolve): MarketNameMap;
@@ -1,15 +1,22 @@
1
- export type MarketRowAction = 'install' | 'update' | 'update-bundle' | 'remove-bundle' | 'uninstall' | 'update-dependency' | 'update-plugin' | 'uninstall-plugin' | 'update-workbench';
2
- export type MarketState = 'checking' | 'installed' | 'inactive' | 'unusable' | 'broken' | 'outdated' | 'pending-restart' | 'missing' | 'unchecked' | 'unknown';
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';
3
+ export type MarketState = 'checking' | 'installed' | 'inactive' | 'unusable' | 'broken' | 'outdated' | 'pending-restart' | 'pending-followup' | 'missing' | 'unchecked' | 'unknown';
3
4
  export interface MarketNote {
4
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';
5
6
  readonly params: Readonly<Record<string, string>>;
6
7
  readonly tone?: 'plain' | 'alert';
7
8
  }
8
- export type MarketHintKey = 'panels.market.moduleRestartHint' | 'panels.market.uncheckedHint';
9
+ export type MarketHintKey = 'panels.market.moduleRestartHint' | 'panels.market.uncheckedHint' | 'panels.market.migrationHint' | 'panels.market.updateNeedsWorkbench' | 'panels.market.updateIncompatible';
9
10
  export interface ModuleUpdate {
10
11
  readonly installed: string;
11
12
  readonly latest?: string;
12
13
  readonly local?: boolean;
14
+ readonly blocked?: ModuleUpdateBlock;
15
+ }
16
+ export interface MarketFollowUp {
17
+ readonly id: string;
18
+ readonly kind: 'data-migration';
19
+ readonly hard: boolean;
13
20
  }
14
21
  export interface MarketRow {
15
22
  readonly id: string;
@@ -34,4 +41,5 @@ export interface MarketRow {
34
41
  readonly defaultShown?: boolean;
35
42
  readonly defaultChanged?: number;
36
43
  readonly broken?: boolean;
44
+ readonly followUp?: MarketFollowUp;
37
45
  }
@@ -1,5 +1,6 @@
1
- import type { ModuleVersion } from '../../../kernel/contract/bundle-install';
2
- import type { Translate, UnitManifest } from '@dsh-workbench/shared';
1
+ import type { ModuleUpdateBlock, ModuleVersion } from '../../../kernel/contract/bundle-install';
2
+ import type { Translate, UnitManifest, UnitTitle } from '@dsh-workbench/shared';
3
+ import type { MarketNameMap } from './market-names';
3
4
  import type { MarketRow, MarketRowAction, MarketState, ModuleUpdate } from './market-row-types';
4
5
  import type { SharedRow } from './market-shared-rows';
5
6
  import type { CapabilityMap } from '../../../shared/hooks/use-capabilities';
@@ -14,7 +15,9 @@ export interface InstalledWorkbenchModule {
14
15
  readonly unit: string;
15
16
  readonly pkg: string;
16
17
  readonly installed: string;
18
+ readonly title?: UnitTitle | undefined;
17
19
  readonly latest?: string | undefined;
20
+ readonly latestBlocked?: ModuleUpdateBlock | undefined;
18
21
  readonly local?: boolean | undefined;
19
22
  readonly refused?: readonly string[] | undefined;
20
23
  readonly clientRefused?: readonly string[] | undefined;
@@ -25,9 +28,8 @@ export declare function withClientRefusals(modules: readonly InstalledWorkbenchM
25
28
  readonly reasons: readonly string[];
26
29
  }[]): readonly InstalledWorkbenchModule[];
27
30
  export declare function refusalReasons(host: readonly string[] | undefined, client: readonly string[] | undefined): readonly string[];
28
- export declare function mergeTitles(known: ReadonlyMap<string, string>, manifests: readonly UnitManifest[]): ReadonlyMap<string, string>;
29
31
  export declare function installedIdSet(installed: readonly InstalledWorkbenchModule[] | undefined): ReadonlySet<string> | null;
30
- export declare function installedRows(modules: readonly InstalledWorkbenchModule[], manifests: readonly UnitManifest[], listed: ReadonlySet<string>, known?: ReadonlyMap<string, string> | undefined, defaults?: ReadonlySet<string>, changed?: Readonly<Record<string, number>>): MarketRow[];
32
+ 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[];
31
33
  export declare function marketSwitchLocked(row: MarketRow): boolean;
32
34
  export declare function marketActions(row: MarketRow): MarketRowAction[];
33
35
  export declare function capabilityOutdated(capabilities: CapabilityMap | null, unit: string): boolean;
@@ -1,5 +1,6 @@
1
- import type { UnitManifest } from '@dsh-workbench/shared';
1
+ import type { Translate } from '@dsh-workbench/shared';
2
2
  import type { CapabilityMap } from '../../../shared/hooks/use-capabilities';
3
+ import { type MarketNameMap, type NameSource, type TitleResolve } from './market-names';
3
4
  import type { MarketRow, MarketRowAction, ModuleUpdateMap } from './market-rows';
4
5
  import type { SharedRow } from './market-shared-rows';
5
6
  export declare const PROGRESS_KEY: Readonly<Record<MarketRowAction, string>>;
@@ -32,7 +33,7 @@ export declare function heldIdOf(pending: Pending | null, held: HeldRow | undefi
32
33
  export declare function pinnedRowOf(pending: Pending | null, held: HeldRow | undefined): MarketRow | undefined;
33
34
  export declare function withPinnedRow(rows: readonly MarketRow[], pinned: MarketRow | undefined): MarketRow[];
34
35
  export declare function marketFootVisible(shown: readonly MarketRow[], installed: readonly MarketRow[]): boolean;
35
- export declare function useMarketTitles(manifests: readonly UnitManifest[], mocked: boolean): ReadonlyMap<string, string>;
36
+ export declare function marketNamesOf(t: Translate, modules: readonly NameSource[], titleOf: TitleResolve, mocked: boolean): MarketNameMap;
36
37
  export interface HeldRowControl {
37
38
  readonly held: HeldRow | undefined;
38
39
  hold(next: HeldRow | undefined): void;
@@ -45,5 +46,5 @@ export declare function pendingRowOf(input: {
45
46
  readonly pending: Pending | null;
46
47
  readonly removing: string | null;
47
48
  readonly rows: readonly MarketRow[];
48
- readonly titles: ReadonlyMap<string, string>;
49
+ readonly names: MarketNameMap;
49
50
  }): MarketRow | undefined;
@@ -0,0 +1,3 @@
1
+ import type { MessagesContribution, UnitManifest } from '@dsh-workbench/shared';
2
+ export declare const UNIT_TITLES_OWNER = "dsh-workbench";
3
+ export declare function unitTitlesOf(manifests: readonly UnitManifest[]): MessagesContribution;
@@ -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, 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, 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_INDEX_FORMAT, MARKET_INDEX_PATH, MARKET_PUBLISH_PREVIEW_ROUTE, MARKET_SOURCES_RESOURCE, MARKET_WORKBENCH_LABEL, } from '@dsh-workbench/shared/contract/protocol/market-index';
1
+ export { MARKET_DISCOVER_ROUTE, MARKET_DOC_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
2
  export type { DiscoverCompat, DiscoverDoc, DiscoverDocKind, DiscoverEntry, DiscoverFilter, DiscoverInstallState, DiscoverPayload, DiscoverProblem, DiscoverSourceRow, DiscoverState, DiscoverVersionRow, IndexSourceSpec, 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';
@@ -4,4 +4,4 @@ import type { PublishPreview } from '@dsh-workbench/shared/contract/protocol/mar
4
4
  import type { MarketService } from './market';
5
5
  import type { PanelsService } from './service';
6
6
  export declare const PUBLISH_TIMEOUT_MS: number;
7
- export declare function registerDiyTools(ctx: DshHostContext, market: MarketService, panels: PanelsService, debug: DebugStore, previewOf?: (unit: string) => PublishPreview | null): Array<() => void>;
7
+ export declare function registerDiyTools(ctx: DshHostContext, market: MarketService, panels: PanelsService, debug: DebugStore, previewOf?: (unit: string) => PublishPreview | null, inferredAuthorOf?: (unit: string) => Promise<string | undefined>): Array<() => void>;
@@ -37,6 +37,14 @@ export type ProvisionResult = {
37
37
  readonly ok: true;
38
38
  readonly action: 'update-workbench';
39
39
  readonly change: BundleChange;
40
+ } | {
41
+ readonly ok: true;
42
+ readonly action: 'migrate-workbench';
43
+ readonly added: number;
44
+ readonly files: number;
45
+ } | {
46
+ readonly ok: true;
47
+ readonly action: 'dismiss-followup';
40
48
  } | {
41
49
  readonly ok: true;
42
50
  readonly action: 'uninstall-plugin';
@@ -0,0 +1,16 @@
1
+ import type { ProfilePackage } from '@dsh-workbench/shared/host';
2
+ import { type MigrationRunInput, type MigrationRunResult } from '../../../shared/api/host/migrate-workbench';
3
+ export interface WorkbenchFollowUpDeps {
4
+ readonly dshHome: (() => string) | undefined;
5
+ readonly profileName: (() => string | null) | undefined;
6
+ readonly workbench: ((pkg: string) => ProfilePackage | undefined) | undefined;
7
+ readonly runMigration?: ((input: MigrationRunInput) => Promise<MigrationRunResult>) | undefined;
8
+ }
9
+ export interface WorkbenchFollowUpActions {
10
+ migrateWorkbench(): Promise<{
11
+ readonly added: number;
12
+ readonly files: number;
13
+ }>;
14
+ dismissFollowUp(id: string): Promise<void>;
15
+ }
16
+ export declare function createWorkbenchFollowUps(deps: WorkbenchFollowUpDeps): WorkbenchFollowUpActions;
@@ -1,7 +1,9 @@
1
1
  import type { MarketSourcesAction } from '@dsh-workbench/shared/contract/protocol/market-index';
2
+ import type { RouteTable } from '@dsh-workbench/shared/host';
2
3
  import type { MarketSourceInitializer } from '../../../shared/api/host/market-source-init';
3
4
  import type { MarketSourcesStore } from '../../../shared/api/host/market-sources-store';
4
5
  export declare const MARKET_SOURCES_ACTION_RESOURCE = "market-sources";
6
+ export declare function marketSourcesRoutes(store: MarketSourcesStore): RouteTable;
5
7
  export declare function parseMarketSourcesAction(payload: unknown): MarketSourcesAction;
6
8
  export declare function marketSourcesAction(store: MarketSourcesStore, init?: MarketSourceInitializer | undefined): {
7
9
  readonly resource: string;
@@ -59,6 +59,11 @@ export interface MarketService {
59
59
  replaceBundle(spec: string, options?: BundleInstallOptions): Promise<BundleInstallOutcome>;
60
60
  updateBundle(unit: string): Promise<BundleInstallOutcome | null>;
61
61
  updateWorkbench(pkg: string): Promise<BundleInstallOutcome>;
62
+ migrateWorkbench(): Promise<{
63
+ readonly added: number;
64
+ readonly files: number;
65
+ }>;
66
+ dismissFollowUp(id: string): Promise<void>;
62
67
  removeBundle(pkg: string): Promise<BundleRemoveOutcome>;
63
68
  cancelInstall(requestId: string): Promise<BundleCancellation | null>;
64
69
  updatePlugin(pkg: string): Promise<PluginUpdateOutcome>;
@@ -5,6 +5,7 @@ import type { InstalledModule, ProfileModule, ProfilePackage } from '@dsh-workbe
5
5
  import type { RegistryNotebook } from '@dsh-workbench/shared/host';
6
6
  import { type SupplyPort, type UnitMountDeps } from '@dsh-workbench/shared/host';
7
7
  import type { SelfUpdateRequest, SelfUpdateStart } from '@dsh-workbench/shared/host';
8
+ import { type WorkbenchFollowUpDeps } from './market-follow-up';
8
9
  import { type PluginReferences } from './plugin-actions';
9
10
  import type { PluginLedger } from './plugin-ledger';
10
11
  import type { MarketService } from './market-types';
@@ -29,6 +30,7 @@ export declare function createMarketService(options: {
29
30
  dshHome?: (() => string) | undefined;
30
31
  profileName?: (() => string | null) | undefined;
31
32
  selfUpdate?: ((request: SelfUpdateRequest, onError: (message: string) => void) => SelfUpdateStart) | undefined;
33
+ runMigration?: WorkbenchFollowUpDeps['runMigration'];
32
34
  logger?: {
33
35
  info?(message: string): void;
34
36
  warn?(message: string): void;
@@ -1,2 +1,2 @@
1
1
  import type { RouteTable } from '@dsh-workbench/shared/host';
2
- export declare function publishPreviewRoutes(workshop: string | null): RouteTable;
2
+ export declare function publishPreviewRoutes(workshop: string | null, inferredAuthorOf?: (unit: string) => Promise<string | undefined>): RouteTable;
@@ -1,4 +1,15 @@
1
+ import type { DshShell } from '@dsh-workbench/shared';
1
2
  import type { PublishPreview } from '@dsh-workbench/shared/contract/protocol/market-index';
3
+ export interface PublishModuleFact {
4
+ readonly dir: string;
5
+ readonly name: string;
6
+ readonly author: string;
7
+ }
8
+ export declare function moduleFactOf(root: string | null | undefined, unit: string): PublishModuleFact | null;
9
+ export declare function localGitIdentityOf(shell: DshShell | undefined, dir: string): Promise<string | undefined>;
10
+ export declare function lastCommitAuthorOf(shell: DshShell | undefined, dir: string): Promise<string | undefined>;
11
+ export declare function inferredAuthorOf(root: string | null | undefined, unit: string, shell: DshShell | undefined): Promise<string | undefined>;
2
12
  export declare function publishPreviewOf(root: string | null | undefined, unit: string, options?: {
3
13
  readonly version?: string | undefined;
14
+ readonly author?: string | undefined;
4
15
  }): PublishPreview | null;
@@ -0,0 +1,2 @@
1
+ export declare function isFollowUpDismissed(runtimeRoot: string, id: string): boolean;
2
+ export declare function dismissFollowUp(runtimeRoot: string, id: string): void;
@@ -0,0 +1,20 @@
1
+ export interface MigrationRunInput {
2
+ readonly script: string;
3
+ readonly env: Readonly<Record<string, string>>;
4
+ }
5
+ export interface MigrationRunResult {
6
+ readonly exitCode: number;
7
+ readonly stdout: string;
8
+ readonly stderr: string;
9
+ }
10
+ export interface MigrateWorkbenchInput {
11
+ readonly home: string;
12
+ readonly profile: string;
13
+ readonly pkg: string;
14
+ readonly run: (input: MigrationRunInput) => Promise<MigrationRunResult>;
15
+ }
16
+ export interface MigrateWorkbenchResult {
17
+ readonly added: number;
18
+ readonly files: number;
19
+ }
20
+ export declare function migrateWorkbench(input: MigrateWorkbenchInput): Promise<MigrateWorkbenchResult>;
@@ -0,0 +1,12 @@
1
+ export interface MigrationFollowUpInput {
2
+ readonly home: string;
3
+ readonly profile: string;
4
+ readonly runtimeRoot?: string | undefined;
5
+ }
6
+ export declare const MIGRATION_FOLLOW_UP_ID = "data-root-migration";
7
+ export interface WorkbenchMigrationFollowUp {
8
+ readonly id: typeof MIGRATION_FOLLOW_UP_ID;
9
+ readonly kind: 'data-migration';
10
+ readonly hard: false;
11
+ }
12
+ export declare function migrationFollowUp(input: MigrationFollowUpInput): WorkbenchMigrationFollowUp | undefined;
@@ -1,11 +1,12 @@
1
1
  import type { ApiResponse } from '@dsh-workbench/shared';
2
- import { type DiscoverDoc, type DiscoverDocKind, type DiscoverPayload, type PublishPreview } from '../../kernel/contract/market-index';
2
+ import { type DiscoverDoc, type DiscoverDocKind, type DiscoverPayload, 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
+ export declare function readMarketSources(): Promise<ApiResponse<MarketSourcesPayload>>;
6
7
  export declare function readMarketDoc(name: string, version: string, kind: DiscoverDocKind): Promise<ApiResponse<{
7
8
  readonly doc: DiscoverDoc;
8
9
  }>>;
9
- export declare function readPublishPreview(unit: string, version?: string): Promise<ApiResponse<{
10
+ export declare function readPublishPreview(unit: string, version?: string, author?: string): Promise<ApiResponse<{
10
11
  readonly preview: PublishPreview | null;
11
12
  }>>;
@@ -0,0 +1,14 @@
1
+ import type { ApiError } from '@dsh-workbench/shared';
2
+ export interface ResourceState<T> {
3
+ readonly phase: 'idle' | 'loading' | 'ready' | 'error';
4
+ readonly value?: T;
5
+ readonly error?: ApiError;
6
+ readonly at?: number;
7
+ }
8
+ export declare const IDLE: ResourceState<never>;
9
+ export declare const LOADING: ResourceState<never>;
10
+ export interface TaggedState<T> {
11
+ readonly identity: string;
12
+ readonly state: ResourceState<T>;
13
+ }
14
+ export declare function resourceViewOf<T>(enabled: boolean, current: TaggedState<T>, identity: string): ResourceState<T>;
@@ -1,15 +1,11 @@
1
- import type { ApiError, ApiResponse, Query } from '@dsh-workbench/shared';
1
+ import type { ApiResponse, Query } from '@dsh-workbench/shared';
2
+ import { type ResourceState } from './resource-view';
2
3
  /**
3
4
  * 一次读的状态:`idle` 没开读 · `loading` 在飞 · `ready` 有值 · `error` 失败;`value` 是 `ApiResponse<T>`、
4
5
  * `at` 是拿到这个值的时间戳。**身份没变的重取(如点刷新)进 `loading` 时上一次的 `value` 与 `at` 会留着**
5
6
  * —— 界面照旧有得画;身份变了、本来就没值、或读到 `error` 时才没有(那时两者都是 `undefined`)。
6
7
  */
7
- export interface ResourceState<T> {
8
- readonly phase: 'idle' | 'loading' | 'ready' | 'error';
9
- readonly value?: T;
10
- readonly error?: ApiError;
11
- readonly at?: number;
12
- }
8
+ export type { ResourceState } from './resource-view';
13
9
  /**
14
10
  * 这次读的身份:`route` 加排好序的 `query`(排序是为了同一次读只有一个 key);给了 `override` 就用它。
15
11
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/core",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
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.0.1",
104
- "@dsh-workbench/adapters-default": "1.0.1"
103
+ "@dsh-workbench/shared": "1.1.1",
104
+ "@dsh-workbench/adapters-default": "1.1.1"
105
105
  },
106
106
  "license": "MIT",
107
107
  "repository": {
@@ -46,5 +46,5 @@
46
46
  ## 4 发布
47
47
 
48
48
  只在用户明确说「帮我发布」后调;先 `_changelog` 把这一版写进 `CHANGELOG.md`。
49
- 出口、署名、标题、安装命令由工具与审批屏处理,不用问、不用补。
49
+ 出口、署名、标题、安装命令由工具与审批屏处理,不用问、不用补;没写作者时审批屏显示推断的署名(市集里上次的 / 同工坊的 / 本机 git 身份),用户觉得不对就拒绝后再说,他点名了才传 `author=…`。
50
50
  需要用户接管时返回 `needsUser: { step, text, command? }`:把 `text` 说给用户,等「好了」再跑;不向用户要 token。
@@ -5,12 +5,12 @@
5
5
  | 判据 | 检查 | 修法 |
6
6
  |---|---|---|
7
7
  | `contracts` | 清单 ↔ 代码 ↔ `design.json` 漂移;dsh 组合期不校验清单 | 按报错改:`unit` 重名换名;`dsh.workbenchFaces` 两个源码入口;六个脚本;`private: true`。`dsh.workbench.tools` 与 `registerTools()` 一致;`design.json` 对键名;生成物过期跑 `sync` |
8
- | `protocol` | `dsh.workbench` 版本 / 形状 / 多余键(外壳静默忽略生字段) | 补 `"apiVersion": 2`;`unit` / `card` / `tools` / `host` 写全(无卡片 `null`、无工具 `[]`);删协议外键(`faces` 在 `dsh.workbenchFaces`;不写 `scope`) |
8
+ | `protocol` | `dsh.workbench` 版本 / 形状 / 多余键(外壳静默忽略生字段) | 补 `"apiVersion": 3`;`unit` / `title` / `card` / `tools` / `host` 写全(名字是 `{ zh, en }` 字面量;无卡片 `null`、无工具 `[]`);删协议外键(`faces` 在 `dsh.workbenchFaces`;不写 `scope`) |
9
9
  | `bundles` | 运行时互串:浏览器产物含 node 内置 / 宿主产物含 DOM、react | 不 import 对方那侧 |
10
10
  | `source` | 非种子 `@deepseek-ai/*`;宿主碰 dsh 浏览器包;`@/` 指外壳;根入口取运行值;客户端引 `/host`;**手写进程 / PATH / 文件锁 / 状态原子写**(import 首选库放行) | 宿主只用 Node 侧;种子词仅在 client 可达文件;`@/` 只指自己 `src/`;运行值:浏览器 `kit`、宿主 `shared/host`;进程/锁/状态写交给外壳 |
11
11
  | `primitives` | 声明 `external` 但产物无物证(原语被内联) | `dsh.client.external` 声明;devDependency 精确版对齐;产物中为 `require(...)` |
12
12
  | `kit` | 用了 peer 下限外壳没有的成员(首帧 `Element type is invalid`) | 只用 peer 范围内成员;下限抬到实际使用版 |
13
- | `cards` | 七种外壳侧输入 × `zh` / `en` 下崩溃 / 空白 / 脏值 | 五态可画;外层 `Card`;`titleKey` 与卡片用到的键双语齐。不断言具体态(归 `plugin.test.ts`) |
13
+ | `cards` | 七种外壳侧输入 × `zh` / `en` 下崩溃 / 空白 / 脏值 | 五态可画;外层 `Card`;卡片自己用到的文案键双语齐(名字走清单 `title`,不再是卡片键)。不断言具体态(归 `plugin.test.ts`) |
14
14
  | `standalone` | 依赖工作台源码才能构建 | 不引用工作台源码;`tsconfig.paths` 用相对路径 |
15
15
  | `markers` | 私有源 / 私网地址 / 内网域名进入公开包 | 不进包;配置落到模块配置面;组织特有的词表由 `DSH_WB_INTERNAL_MARKERS` 提供 |
16
16
  | `alias` | `@/` 指向工作台源码 | `@/` 只指自己 `src/` |
@@ -47,6 +47,7 @@ description: 在工作台里把当前面板调明白,或者给它造一块新
47
47
  审批项标注「要你真用一次」,不打勾。结论只报:已装、在面板哪一格。
48
48
  8. **发布** —— 只在用户说「帮我发布」之后:`workbench_diy_changelog`(`note=…`)记这一版 → `workbench_diy_publish`(`unit=…`)。
49
49
  不手改 `package.json`、不补标题/署名、不问出口:工具与审批屏已经处理;他明确点名安装包 / 公开 / git 才传 target。
50
+ 他说要换作者才传 `author="姓名 <邮箱>"`,别自己编一个;没写作者时审批屏显示推断的署名,他拒绝后再说。
50
51
  验收没过先 `design accept`;`needsUser` 照 `text` 转述。细节见 [WIRING.md](WIRING.md) §5。
51
52
 
52
53
  ## 索引
@@ -118,7 +118,7 @@
118
118
  未知 `kind` 或 `source.kind` 判红;need 里未知字段只警告,`x-` 前缀忽略。
119
119
  - 未装好文案由模块写:`libInstallCommand({ need, source })`(`@dsh-workbench/shared/host`)拼好源与缓存目录,
120
120
  原样输出;放进失败态。
121
- - `contracts` 判据:`apiVersion` 必须是 2;`needs` 走同一份 `NEED_KINDS` 注册表校验(`purpose` 必填、
121
+ - `contracts` 判据:`apiVersion` 必须是 3;`needs` 走同一份 `NEED_KINDS` 注册表校验(`purpose` 必填、
122
122
  `bin`/`env` 不许带 `sources`、`lib` 只认 npm 源);声明了 `lib` 必须用 `libInstallCommand`。
123
123
  未知 `runtime` 不判红:探针会给「这个运行时工作台还不认识」的 `unchecked`,等运行时 provider 补上。
124
124
 
@@ -65,5 +65,7 @@ DIY 族仅在选了 DIY 模式的会话出现(按模式,不按工作区)
65
65
 
66
66
  1. 先把这一版写进 `CHANGELOG.md`(`workbench_diy_changelog`,`note=…`),真卡片验收过(`design accept`)。
67
67
  出口、署名、标题、安装命令都由工具与审批屏处理:不用问、不用补;用户没点名出口就不传 target。
68
+ 用户要换署名(或在审批屏上说作者不对):传 `author="姓名 <邮箱>"`(或只给姓名),别手改 `package.json`,也别自己编。
69
+ 没写作者时审批屏显示推断的署名;他拒绝后说换成谁,再用 `author` 重发。
68
70
  2. 工具回 `needsUser` 时照 `text` 转述,不在对话里要 token / OTP;`otp` 交接后 `verify=true` 只核不发。
69
- 3. 只改市集元数据(标题 / 作者 / 说明)不升版本:`refresh=true`。
71
+ 3. 只改市集元数据(标题 / 作者 / 说明)不升版本:`refresh=true`(换作者时同时传 `author`)。
@@ -23,7 +23,7 @@
23
23
 
24
24
  3. **无现成命令 → 让用户录一次**(你准备,用户执行):
25
25
 
26
- - `workbench_diy_record_prepare({ unit, url, doing })`:开窗置前(**需审批一次**:站点、录哪一下、落点、
26
+ - `workbench_diy_record_prepare({ unit, url, doing })`:开窗置前(**需审批一次**:站点、录哪一下、保存到、
27
27
  录完不切回),装浮条。用户:① 开始录制 ② 做一次动作 ③ 结束录制。不要让用户点第二次。
28
28
  `url` 必须与模块读源同域(`design.json` 声明过读源时跨域当场拒)。
29
29
  - 表填好、提交前,请用户按浮条「截图」:不额外审批;产出整页图 + 页面快照(控件 `name` / `id`、