@dsh-workbench/core 1.0.0 → 1.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.
Files changed (41) hide show
  1. package/README.md +16 -3
  2. package/bin/dsh-workbench +38 -6
  3. package/client.js +669 -305
  4. package/dist/client/client.body.js +669 -305
  5. package/dist/client/index.js +669 -305
  6. package/dist/host/index.js +445 -37
  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/scripts/seed-profile.sh +9 -7
  35. package/scripts/share-data-root.mjs +272 -64
  36. package/skills/workbench-module-diy/FAMILY.md +1 -1
  37. package/skills/workbench-module-diy/REVIEW.md +2 -2
  38. package/skills/workbench-module-diy/SKILL.md +1 -0
  39. package/skills/workbench-module-diy/TOOLS.md +1 -1
  40. package/skills/workbench-module-diy/WIRING.md +3 -1
  41. package/skills/workbench-module-diy/WRITES.md +1 -1
@@ -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.0",
3
+ "version": "1.1.0",
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.0",
104
- "@dsh-workbench/adapters-default": "1.0.0"
103
+ "@dsh-workbench/shared": "1.1.0",
104
+ "@dsh-workbench/adapters-default": "1.1.0"
105
105
  },
106
106
  "license": "MIT",
107
107
  "repository": {
@@ -2,14 +2,14 @@
2
2
  #
3
3
  # 一次性引导:从 shipped 的 web 模板创建 workbench profile,
4
4
  # 继承 web 的 **bundle 清单**(这台机器上装了哪些 bundle),
5
- # 补上可写根那一行,并把会话 / 项目 / 附件指回跟 web 共用的数据根。
5
+ # 补上可写根那一行;新 profile 直接跟 web 共用数据根,旧 profile 保持原状,等用户跑 migrate。
6
6
  #
7
7
  # **设置不在这里继承**(这里曾经把 web 的 cordis.patch.yml 快照一份过来):
8
8
  # 工作台自己的 patch 是唯一真相,想同步 web 的哪几行由用户走「设置 → 配置同步」。
9
9
  # 为什么这么分(安装 vs 设置)、为什么不再是自动的:内部设计记录
10
10
  #
11
- # 幂等 / 可续跑:profile 已存在就跳过创建,数据根已经是共用的就什么都不写
12
- # —— 重复运行不会覆盖任何东西。
11
+ # 幂等 / 可续跑:profile 已存在就跳过创建;数据根已经是共用的、或旧数据还没迁
12
+ # (只提示 migrate)就什么都不写 —— 重复运行不会覆盖任何东西。
13
13
  # 安全:全程只**读** web 的 profile 目录,只**写** workbench 自己的目录。
14
14
  #
15
15
  # 用法:
@@ -176,10 +176,11 @@ console.log("→ profile 里那条 link: 指的是我这份装出来的副本(
176
176
  '
177
177
  fi
178
178
 
179
- # ── 第 3 步:数据根跟 web 共用 + 可写根那一行 ───────────────────────────
179
+ # ── 第 3 步:数据根配置 + 可写根那一行 ─────────────────────────────────
180
180
  #
181
- # 会话 / 项目 / 附件不再按 profile 分家:跟 `dsh web` 和 Desktop 一样只分 profile,
182
- # 数据都在 `$DSH_HOME` 下(旧实例的那三行隔离补丁与旧数据由 share-data-root.mjs 收回来)。
181
+ # 新 profile 跟 `dsh web` / Desktop 一样只分 profile,数据落在 `$DSH_HOME`。
182
+ # 旧 profile 如果还有没迁的数据,这里只打印 migrate 提示,保持隔离、不动数据;
183
+ # 用户自己跑 `dsh-workbench migrate` 才切共用根并并数据。
183
184
  # 每一步都幂等:已经是共用数据根的 profile 一个字节都不写。
184
185
  WORKBENCH_PROFILE="$PROFILE" DSH_HOME="$DSH_HOME" DSH_WORKBENCH_HOME="$WORKBENCH_HOME" \
185
186
  node "$REPO_DIR/scripts/share-data-root.mjs" || die "整理数据根失败(见上一行)"
@@ -202,7 +203,8 @@ fi
202
203
 
203
204
  cat <<EOF
204
205
 
205
- profile '$DST_PROFILE' 的骨架好了(bundle 清单 + 可写根;会话 / 项目 / 附件跟 web 共用)。
206
+ profile '$DST_PROFILE' 的骨架好了(bundle 清单 + 可写根)。
207
+ 旧实例如果还有数据没迁,启动时会提示;要切共用根并并旧数据,跑 dsh-workbench migrate。
206
208
 
207
209
  设置按创建时的勾选从 $SRC_PROFILE_NAME 继承(只同步改已有插件的行;挂新插件的行不同步);
208
210
  直接跑 setup 时只继承 bundle 清单,想要 web 那边的模型供应商 / 搜索源 / MCP,起工作台后去