dsh-plugin-shop 0.4.1 → 0.4.2

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.
@@ -48,6 +48,12 @@ export declare const zh: {
48
48
  installedVersion: string;
49
49
  latestVersion: string;
50
50
  update: string;
51
+ installed: string;
52
+ uninstall: string;
53
+ uninstalling: string;
54
+ uninstallFailed: string;
55
+ uninstallTransportFailed: string;
56
+ uninstalledRestartNotice: string;
51
57
  enabledSwitch: string;
52
58
  toggleFailed: string;
53
59
  hotApplyNote: string;
@@ -103,6 +109,12 @@ export declare const en: {
103
109
  installedVersion: string;
104
110
  latestVersion: string;
105
111
  update: string;
112
+ installed: string;
113
+ uninstall: string;
114
+ uninstalling: string;
115
+ uninstallFailed: string;
116
+ uninstallTransportFailed: string;
117
+ uninstalledRestartNotice: string;
106
118
  enabledSwitch: string;
107
119
  toggleFailed: string;
108
120
  hotApplyNote: string;
@@ -1,4 +1,5 @@
1
1
  /** Install driving hook for one entry: start, poll to terminal, reset. */
2
+ import { type Dispatch, type SetStateAction } from 'react';
2
3
  import { type InstallView } from './present.ts';
3
4
  import type { InstallArgs, ShopInstallResult, ShopInstallStatusResult } from '../host/index.ts';
4
5
  export interface UseInstallResult {
@@ -6,6 +7,14 @@ export interface UseInstallResult {
6
7
  start: (args: InstallArgs) => Promise<void>;
7
8
  reset: () => void;
8
9
  }
10
+ /** The poll loop shared by the install and uninstall drivers: while the view
11
+ * is `running`, poll once per second and fold each status through the
12
+ * reducer. A poll failure is transient — the host retains the record, so the
13
+ * next tick finds it. The rejection handler must be present: an unhandled
14
+ * rejection here would escape the poll loop. */
15
+ export declare function usePollStatus(view: InstallView, setView: Dispatch<SetStateAction<InstallView>>, installStatus: (args: {
16
+ installId: string;
17
+ }) => Promise<ShopInstallStatusResult>): void;
9
18
  /** Drive one install: rejections, the polling loop at INSTALL_POLL_MS, and
10
19
  * terminal states. The interval is cleared on unmount and whenever the view
11
20
  * leaves `running`, so a done/failed/rejected install never polls again. */
@@ -0,0 +1,21 @@
1
+ /** Uninstall driving hook for one entry: start, poll to terminal. Shares the
2
+ * install view machine and poll loop; the only difference is the start
3
+ * mapping — an uninstall business failure (not in the catalog / not
4
+ * installed) lands in the `failed` view with the host's published detail,
5
+ * never in the install `rejected` codes, which belong to the install gate
6
+ * (§7.2). */
7
+ import type { ShopInstallStatusResult, ShopUninstallResult } from '../host/index.ts';
8
+ import type { InstallView } from './present.ts';
9
+ export interface UseUninstallResult {
10
+ view: InstallView;
11
+ start: (args: {
12
+ name: string;
13
+ }) => Promise<void>;
14
+ }
15
+ /** Drive one uninstall: the host's business union, the shared polling loop,
16
+ * and terminal states. The `rejected` install state never occurs here. */
17
+ export declare function useUninstall(uninstall: (args: {
18
+ name: string;
19
+ }) => Promise<ShopUninstallResult>, installStatus: (args: {
20
+ installId: string;
21
+ }) => Promise<ShopInstallStatusResult>): UseUninstallResult;
@@ -1,4 +1,7 @@
1
- /** Install executor: spawn the dsh CLI, stream its output, serialize per profile. */
1
+ /** Plugin-command executor: spawn the dsh CLI, stream its output, serialize
2
+ * per profile. One implementation drives both `dsh plugin add` (install) and
3
+ * `dsh plugin remove` (uninstall); the only differences are the verb and the
4
+ * post-exit manifest confirmation. */
2
5
  export type InstallState = 'running' | 'done' | 'failed';
3
6
  export interface InstallStatus {
4
7
  state: InstallState;
@@ -13,11 +16,6 @@ interface RunningInstall {
13
16
  }
14
17
  /**
15
18
  * Run one `dsh plugin --profile <profile> add <spec>` and track it.
16
- * Never rolls back; a failure surfaces stderr verbatim plus the recovery hint
17
- * (§10). The shop never passes build-script flags: `allowBuilds` stays the
18
- * user's explicit decision in the CLI (§7.2).
19
- * The child inherits the current environment unless `env` is given — the
20
- * real-install test pins DSH_HOME to a temporary directory this way.
21
19
  * When `expectedName` is given, a zero exit is confirmed against the profile
22
20
  * manifest (§7.2 step 6) before the install reports `done`.
23
21
  */
@@ -29,4 +27,18 @@ export declare function startInstall(options: {
29
27
  expectedName?: string;
30
28
  onStatus?: (status: InstallStatus) => void;
31
29
  }): RunningInstall;
30
+ /**
31
+ * Run one `dsh plugin --profile <profile> remove <name>` and track it.
32
+ * When `expectedName` is given, a zero exit is confirmed against the profile
33
+ * manifest — the bundle must actually have LEFT `dsh.profile.bundles` — before
34
+ * the uninstall reports `done`.
35
+ */
36
+ export declare function startUninstall(options: {
37
+ profile: string;
38
+ name: string;
39
+ dshBin?: string;
40
+ env?: NodeJS.ProcessEnv;
41
+ expectedName?: string;
42
+ onStatus?: (status: InstallStatus) => void;
43
+ }): RunningInstall;
32
44
  export {};
@@ -49,11 +49,25 @@ export interface ShopSetEnabledResult {
49
49
  ok: boolean;
50
50
  detail?: string;
51
51
  }
52
- /** `shop/outdated` entry (§7.3): one installed plugin behind the catalog. */
53
- export interface ShopOutdatedEntry {
52
+ /** `shop/uninstallStart` result (§7.3): a name outside the catalog or not
53
+ * installed is a typed wire value with an author-readable `detail`, not a
54
+ * thrown RPC error. */
55
+ export type ShopUninstallResult = {
56
+ ok: true;
57
+ installId: string;
58
+ } | {
59
+ ok: false;
60
+ detail: string;
61
+ };
62
+ /** `shop/installed` entry (§7.3): one installed catalog plugin. `installed`
63
+ * is the profile manifest's dependency spec verbatim (a range, a tag, or
64
+ * `workspace:*`); `outdated` is the Host's verdict that the installed version
65
+ * sits behind the catalog's — the client never does version math. */
66
+ export interface ShopInstalledEntry {
54
67
  name: string;
55
68
  installed: string;
56
69
  latest: string;
70
+ outdated: boolean;
57
71
  }
58
72
  /** `shop/catalog` result (§7.3), plus the denied list for the install gate's UI. */
59
73
  export interface ShopCatalogResult {
@@ -127,7 +141,24 @@ export declare class ShopGateway extends TypertRemoteService {
127
141
  installStatus(args: {
128
142
  installId: string;
129
143
  }): ShopInstallStatusResult;
130
- /** Installed plugins whose installed version is older than the catalog's (§7.3). */
131
- outdated(): Promise<ShopOutdatedEntry[]>;
144
+ /** Installed catalog plugins (§7.3): every entry of the snapshot the profile
145
+ * manifest declares as a dependency, with the Host's `outdated` verdict
146
+ * attached. The tab's shelf cards and its installed section both derive
147
+ * from this one list. */
148
+ installed(): Promise<ShopInstalledEntry[]>;
149
+ /** Whether an installed dependency spec sits behind the catalog's version.
150
+ * A spec identical to the catalog version is current by definition; a
151
+ * pnpm-written non-semver spec like `workspace:*` is not reportable and
152
+ * reads as current rather than killing the RPC. */
153
+ private isBehind;
154
+ /** Uninstall one installed catalog plugin from the profile (§7.3 follow-up
155
+ * amendment). Removing revokes privilege rather than granting it, so there
156
+ * is no acknowledgement gate. The name must be a catalog entry the profile
157
+ * manifest declares as a dependency — the RPC cannot remove profile
158
+ * dependencies the shop does not manage (the base bundle, the shop
159
+ * itself). The same install records/polling serve the client. */
160
+ uninstall(args: {
161
+ name: string;
162
+ }): Promise<ShopUninstallResult>;
132
163
  }
133
164
  export default ShopGateway;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-shop",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "The DeepSeek Harness plugin shop: browse, install, enable, and update dsh plugins from a git-auditable catalog.",
5
5
  "repository": {
6
6
  "type": "git",