@deepseek-ai/dsh-plugin-manager 0.1.6-alpha.2 → 0.1.7-alpha.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.
@@ -1,5 +1,5 @@
1
1
  import { type ProfileManifest } from '@deepseek-ai/dsh-app-boot';
2
- import type { PackageResult } from './types.ts';
2
+ import type { PackageResult, Registry } from './types.ts';
3
3
  /** Profile and invocation locations supplied by the launcher. */
4
4
  export interface PackageOperationContext {
5
5
  profile: string;
@@ -80,13 +80,37 @@ export interface PackageViewOptions {
80
80
  signal?: AbortSignal;
81
81
  /** Bound on the lookup, in milliseconds. */
82
82
  timeoutMs: number;
83
+ /** The registry asked; null asks the one pnpm's own configuration names. */
84
+ registry?: Registry;
83
85
  }
86
+ /**
87
+ * Read the registry pnpm's own configuration names in the profile: its `.npmrc` chain and workspace settings,
88
+ * as `pnpm config get registry` resolves them.
89
+ * @param dir Profile directory.
90
+ * @param options The pnpm executable and the time bound.
91
+ * @returns The registry URL as pnpm printed it, or null when pnpm did not answer with one.
92
+ */
93
+ export declare function readProfileRegistry(dir: string, options: {
94
+ command?: string;
95
+ args?: readonly string[];
96
+ env?: Readonly<Record<string, string>>;
97
+ timeoutMs: number;
98
+ }): Promise<string | null>;
99
+ /**
100
+ * The argument that sends one pnpm command to a registry.
101
+ * @param registry - the registry, or null for the one pnpm's own configuration names.
102
+ * @returns `--registry=<url>` for a URL; nothing for null.
103
+ */
104
+ export declare function registryArguments(registry: Registry): string[];
84
105
  /**
85
106
  * Ask the registry what a spec names through `pnpm view`, run in the profile
86
- * directory so the registry, proxy, and authentication settings of an install apply.
107
+ * directory so the registry, proxy, and authentication settings of an install
108
+ * apply. The lookup makes one request without pnpm's own retries: a registry
109
+ * that does not answer is reported within `timeoutMs`, and the registries
110
+ * configured after it are the retry.
87
111
  * @param dir Profile directory.
88
112
  * @param spec One registry spec: a package name with an optional range.
89
- * @param options Cancellation and the time bound.
113
+ * @param options The registry, cancellation, and the time bound.
90
114
  * @returns pnpm's exit, output, and how the lookup ended.
91
115
  */
92
116
  export declare function viewProfilePackage(dir: string, spec: string, options: PackageViewOptions): Promise<PackageViewResult>;
@@ -4,7 +4,7 @@ import { mkdir, mkdtemp, open } from 'node:fs/promises';
4
4
  import { join, resolve } from 'node:path';
5
5
  import { execa } from 'execa';
6
6
  import { withFileLock, writeFileAtomic } from '@deepseek-ai/dsh-atomic-write';
7
- import { DEFAULT_PROFILE_BUNDLES, initProfile, PROFILE_TEMPLATES, readProfileManifest, resolveBundleDir, resolveProfileDir, loadOverlayPatches, } from '@deepseek-ai/dsh-app-boot';
7
+ import { DEFAULT_PROFILE_BUNDLES, bundlePatchPaths, initProfile, PROFILE_TEMPLATES, readProfileManifest, resolveBundleDir, resolveProfileDir, loadOverlayPatches, } from '@deepseek-ai/dsh-app-boot';
8
8
  import { scrubbedParentEnv } from '@deepseek-ai/dsh-subprocess';
9
9
  /** Resolve relative package specs against the caller's directory.
10
10
  * @param argument One pnpm argument.
@@ -54,7 +54,8 @@ async function reconcile(before, dir, anchor, options) {
54
54
  options.onOutput?.(`dsh: warning: ${name} declares no dsh.bundle — installed as a plain dependency, not a profile layer\n`, 'stderr');
55
55
  continue;
56
56
  }
57
- loadOverlayPatches('dsh', join(resolveBundleDir('dsh', name, anchor, dir), metadata.dsh.bundle.patch));
57
+ for (const file of bundlePatchPaths(resolveBundleDir('dsh', name, anchor, dir), metadata.dsh.bundle))
58
+ loadOverlayPatches('dsh', file);
58
59
  if (!bundles.includes(name)) {
59
60
  bundles.push(name);
60
61
  }
@@ -153,16 +154,45 @@ export async function runPluginCommand(context, args, options) {
153
154
  return runProfilePnpm(context, args, options);
154
155
  }, options.lockWaitMs === undefined ? undefined : { waitMs: options.lockWaitMs });
155
156
  }
157
+ /**
158
+ * Read the registry pnpm's own configuration names in the profile: its `.npmrc` chain and workspace settings,
159
+ * as `pnpm config get registry` resolves them.
160
+ * @param dir Profile directory.
161
+ * @param options The pnpm executable and the time bound.
162
+ * @returns The registry URL as pnpm printed it, or null when pnpm did not answer with one.
163
+ */
164
+ export async function readProfileRegistry(dir, options) {
165
+ const result = await execa(options.command ?? 'pnpm', [...options.args ?? [], 'config', 'get', 'registry'], {
166
+ cwd: dir, env: { ...scrubbedParentEnv(), ...options.env }, extendEnv: false, reject: false, stdin: 'ignore', timeout: options.timeoutMs,
167
+ });
168
+ // The registry is the last line: pnpm may print a notice before it.
169
+ const answer = result.exitCode === 0 ? result.stdout.trim().replace(/^[\s\S]*\n/, '').trim() : '';
170
+ return /^https?:\/\/\S+$/.test(answer) ? answer : null;
171
+ }
172
+ /**
173
+ * The argument that sends one pnpm command to a registry.
174
+ * @param registry - the registry, or null for the one pnpm's own configuration names.
175
+ * @returns `--registry=<url>` for a URL; nothing for null.
176
+ */
177
+ export function registryArguments(registry) {
178
+ return registry === null ? [] : [`--registry=${registry}`];
179
+ }
156
180
  /**
157
181
  * Ask the registry what a spec names through `pnpm view`, run in the profile
158
- * directory so the registry, proxy, and authentication settings of an install apply.
182
+ * directory so the registry, proxy, and authentication settings of an install
183
+ * apply. The lookup makes one request without pnpm's own retries: a registry
184
+ * that does not answer is reported within `timeoutMs`, and the registries
185
+ * configured after it are the retry.
159
186
  * @param dir Profile directory.
160
187
  * @param spec One registry spec: a package name with an optional range.
161
- * @param options Cancellation and the time bound.
188
+ * @param options The registry, cancellation, and the time bound.
162
189
  * @returns pnpm's exit, output, and how the lookup ended.
163
190
  */
164
191
  export async function viewProfilePackage(dir, spec, options) {
165
- const result = await execa(options.command ?? 'pnpm', [...options.args ?? [], 'view', spec, 'name', 'version', 'description', 'dsh', '--json'], {
192
+ const result = await execa(options.command ?? 'pnpm', [
193
+ ...options.args ?? [], 'view', spec, 'name', 'version', 'description', 'dsh', '--json',
194
+ ...registryArguments(options.registry ?? null), '--config.fetch-retries=0',
195
+ ], {
166
196
  cwd: dir, env: { ...scrubbedParentEnv(), ...options.env }, extendEnv: false, reject: false, stdin: 'ignore',
167
197
  timeout: options.timeoutMs, ...options.signal === undefined ? {} : { cancelSignal: options.signal },
168
198
  });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Which registries one package operation asks, in order, and what a failed
3
+ * attempt could not reach. A registry is asked with pnpm's `--registry`;
4
+ * `null` is the one pnpm's own configuration names. This module runs in the
5
+ * browser too, through the package's `./registry` entry, so the dialog and
6
+ * the Host follow one rule.
7
+ * @module @deepseek-ai/dsh-plugin-manager/registry
8
+ */
9
+ import type { ParsedInstallSpec } from './install-spec.ts';
10
+ import type { PluginInstallFailureKind, PluginRegistries, Registry } from './types.ts';
11
+ /** npm's own registry: what pnpm names without any configuration, and the one public registry a plan trusts as such. */
12
+ export declare const OFFICIAL_NPM_REGISTRY = "https://registry.npmjs.org/";
13
+ /** An http(s) URL, as pnpm's `--registry` takes it. */
14
+ export declare const REGISTRY_URL: RegExp;
15
+ /**
16
+ * Parse a registry URL into the form pnpm compares registries in: lower-case host, trailing slash.
17
+ * @param url - the registry as configured or requested.
18
+ * @returns the normalized URL.
19
+ * @throws {Error} for anything but an http(s) URL.
20
+ */
21
+ export declare function normalizeRegistry(url: string): string;
22
+ /**
23
+ * The registries one operation asks, first to last.
24
+ *
25
+ * The configured set is the configured first registry and the fallbacks; a
26
+ * requested registry is asked first when it is one of them, alone otherwise,
27
+ * so a private registry never falls through to a public one. pnpm's own
28
+ * registry (`null`) belongs to the set only when what it names is known to
29
+ * be public: npm's own registry or one of the configured fallbacks. While it
30
+ * names anything else, or is unknown, it is asked alone, and a public
31
+ * registry asked instead never falls back into it. A registry pnpm's own
32
+ * configuration already names is asked once.
33
+ * @param requested - the caller's registry; undefined defers to the configured first one.
34
+ * @param configured - the configured first registry, the fallbacks after it, and what pnpm's own configuration names.
35
+ * @returns the registries to ask, in order; never empty.
36
+ */
37
+ export declare function registryPlan(requested: Registry | undefined, configured: PluginRegistries): Registry[];
38
+ /**
39
+ * What a failed attempt could not reach or get an answer from.
40
+ * @param kind - how the attempt failed.
41
+ * @param log - what the attempt printed.
42
+ * @param spec - the spec the attempt installed.
43
+ * @returns `registry` for a failure another registry can change; `spec-host` when an error line names the host a git
44
+ * or tarball spec is fetched from, which no registry stands in for; `other` for a failure neither explains.
45
+ */
46
+ export declare function attributeFailure(kind: PluginInstallFailureKind, log: string, spec: ParsedInstallSpec): 'registry' | 'spec-host' | 'other';
47
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Which registries one package operation asks, in order, and what a failed
3
+ * attempt could not reach. A registry is asked with pnpm's `--registry`;
4
+ * `null` is the one pnpm's own configuration names. This module runs in the
5
+ * browser too, through the package's `./registry` entry, so the dialog and
6
+ * the Host follow one rule.
7
+ * @module @deepseek-ai/dsh-plugin-manager/registry
8
+ */
9
+ /** npm's own registry: what pnpm names without any configuration, and the one public registry a plan trusts as such. */
10
+ export const OFFICIAL_NPM_REGISTRY = 'https://registry.npmjs.org/';
11
+ /** An http(s) URL, as pnpm's `--registry` takes it. */
12
+ export const REGISTRY_URL = /^https?:\/\/\S+$/;
13
+ /**
14
+ * Parse a registry URL into the form pnpm compares registries in: lower-case host, trailing slash.
15
+ * @param url - the registry as configured or requested.
16
+ * @returns the normalized URL.
17
+ * @throws {Error} for anything but an http(s) URL.
18
+ */
19
+ export function normalizeRegistry(url) {
20
+ let parsed;
21
+ try {
22
+ parsed = new URL(url);
23
+ }
24
+ catch { /* named below: only an http(s) URL is a registry */ }
25
+ if (parsed === undefined || (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')) {
26
+ throw new Error(`a registry must be an http(s) URL: ${url}`);
27
+ }
28
+ if (!parsed.pathname.endsWith('/'))
29
+ parsed.pathname += '/';
30
+ return parsed.href;
31
+ }
32
+ /**
33
+ * The registries one operation asks, first to last.
34
+ *
35
+ * The configured set is the configured first registry and the fallbacks; a
36
+ * requested registry is asked first when it is one of them, alone otherwise,
37
+ * so a private registry never falls through to a public one. pnpm's own
38
+ * registry (`null`) belongs to the set only when what it names is known to
39
+ * be public: npm's own registry or one of the configured fallbacks. While it
40
+ * names anything else, or is unknown, it is asked alone, and a public
41
+ * registry asked instead never falls back into it. A registry pnpm's own
42
+ * configuration already names is asked once.
43
+ * @param requested - the caller's registry; undefined defers to the configured first one.
44
+ * @param configured - the configured first registry, the fallbacks after it, and what pnpm's own configuration names.
45
+ * @returns the registries to ask, in order; never empty.
46
+ */
47
+ export function registryPlan(requested, configured) {
48
+ const own = configured.resolved === null ? null : normalizeRegistry(configured.resolved);
49
+ const fallbacks = configured.fallbackRegistries.map(normalizeRegistry);
50
+ const ownIsPublic = own !== null && (own === OFFICIAL_NPM_REGISTRY || fallbacks.includes(own));
51
+ // What a registry is compared as: pnpm's own registry stands for the URL it names, once that is known.
52
+ const keyOf = (registry) => registry === null ? own : normalizeRegistry(registry);
53
+ const known = [];
54
+ const keys = [];
55
+ for (const registry of [configured.registry, ...configured.fallbackRegistries]) {
56
+ if (registry === null && !ownIsPublic)
57
+ continue;
58
+ const key = keyOf(registry);
59
+ if (keys.includes(key))
60
+ continue;
61
+ known.push(registry === null ? null : normalizeRegistry(registry));
62
+ keys.push(key);
63
+ }
64
+ const first = requested === undefined ? configured.registry : requested;
65
+ const firstKey = keyOf(first);
66
+ const normalizedFirst = first === null ? null : normalizeRegistry(first);
67
+ // A private or unknown registry of pnpm's own, whichever way it was asked for, is asked alone.
68
+ if ((first === null || firstKey === own) && !ownIsPublic)
69
+ return [normalizedFirst];
70
+ if (!keys.includes(firstKey))
71
+ return [normalizedFirst];
72
+ return [normalizedFirst, ...known.filter((_registry, index) => keys[index] !== firstKey)];
73
+ }
74
+ /** The failures after which another registry can answer differently: this one was unreachable, or its copy may be stale. */
75
+ const NEXT_REGISTRY_KINDS = new Set(['network', 'timeout', 'not-found', 'no-matching-version']);
76
+ /** A line of pnpm or git output that reports a failure, as opposed to a warning or progress line. */
77
+ const ERROR_LINE = /ERR_|ERROR|\berror\b|fatal:|Could not resolve|unable to access|ssh:|\bE[A-Z]{4,}\b/;
78
+ /**
79
+ * What a failed attempt could not reach or get an answer from.
80
+ * @param kind - how the attempt failed.
81
+ * @param log - what the attempt printed.
82
+ * @param spec - the spec the attempt installed.
83
+ * @returns `registry` for a failure another registry can change; `spec-host` when an error line names the host a git
84
+ * or tarball spec is fetched from, which no registry stands in for; `other` for a failure neither explains.
85
+ */
86
+ export function attributeFailure(kind, log, spec) {
87
+ if (!NEXT_REGISTRY_KINDS.has(kind))
88
+ return 'other';
89
+ const host = spec.kind === 'git' || spec.kind === 'tarball' ? spec.host?.toLowerCase() : undefined;
90
+ if (host === undefined)
91
+ return 'registry';
92
+ const named = log.split('\n').some(line => ERROR_LINE.test(line) && line.toLowerCase().includes(host));
93
+ return named ? 'spec-host' : 'registry';
94
+ }
95
+ //# sourceMappingURL=registry.js.map
@@ -16,6 +16,7 @@ export function apply(ctx) {
16
16
  target: { type: 'string', description: 'Plugin entry id, bundle package name, or installation spec, according to action.' },
17
17
  enabled: { type: 'boolean', description: 'Required for set operations; defaults to true for installation.' },
18
18
  approvedBuilds: { type: 'array', items: { type: 'string' }, description: 'For install_bundle: pass names from pendingBuilds only after the user explicitly approves running their install scripts in the conversation. This grants persistent permission for this profile.' },
19
+ registry: { type: 'string', description: 'For install_bundle: the npm registry URL asked first, when the user names one; otherwise the configured registry is asked, and its configured fallbacks while a registry is unreachable.' },
19
20
  offset: { type: 'number', description: 'Zero-based list offset; defaults to 0.' },
20
21
  limit: { type: 'number', description: 'List page size, from 1 to 100; defaults to 25.' },
21
22
  },
@@ -41,7 +42,9 @@ export function apply(ctx) {
41
42
  throw new Error('offset must be a non-negative integer and limit must be an integer from 1 to 100');
42
43
  }
43
44
  const rows = args.action === 'list_plugins' ? await manager.listPlugins() : await manager.listBundles();
44
- const entries = rows.slice(offset, offset + limit);
45
+ const entries = rows.slice(offset, offset + limit).map(({ meta: _meta, ...row }) => 'rows' in row
46
+ ? { ...row, rows: row.rows.map(({ meta: _rowMeta, ...declared }) => declared) }
47
+ : row);
45
48
  return JSON.stringify({ entries, total: rows.length,
46
49
  nextOffset: offset + entries.length < rows.length ? offset + entries.length : null });
47
50
  }
@@ -59,6 +62,7 @@ export function apply(ctx) {
59
62
  return JSON.stringify(await manager.installBundle(args.target, {
60
63
  ...args.enabled === undefined ? {} : { enabled: args.enabled },
61
64
  ...args.approvedBuilds === undefined ? {} : { approvedBuilds: args.approvedBuilds },
65
+ ...args.registry === undefined ? {} : { registry: args.registry },
62
66
  }));
63
67
  case 'remove_bundle':
64
68
  if (args.target === undefined)
@@ -1,5 +1,6 @@
1
1
  /** Public plugin management records shared with clients. */
2
2
  import type { Branded } from '@deepseek-ai/dsh-brand';
3
+ import type { PluginLocalizedMeta } from '@deepseek-ai/dsh-package-manifest';
3
4
  import type { PluginInventoryEntry } from '@deepseek-ai/dsh-host-plugin-inventory/types';
4
5
  export type { PluginEntryId } from '@deepseek-ai/dsh-host-plugin-inventory/types';
5
6
  import type { PluginEntryId } from '@deepseek-ai/dsh-host-plugin-inventory/types';
@@ -24,6 +25,8 @@ export interface BundleRowInfo {
24
25
  rowId: string;
25
26
  /** The module the row names. */
26
27
  moduleName: string;
28
+ /** Local package display metadata, including rows whose bundle is disabled. */
29
+ meta?: PluginLocalizedMeta;
27
30
  /** The Loader entry carrying this row, when exactly one live entry has its id. */
28
31
  entryId?: PluginEntryId;
29
32
  }
@@ -31,8 +34,11 @@ export interface BundleRowInfo {
31
34
  export interface BundleInfo {
32
35
  name: string;
33
36
  version?: string;
34
- /** `description` of the package manifest. */
37
+ /** Local display text with available translations or literal fallbacks, or a metadata diagnostic. */
38
+ meta?: PluginLocalizedMeta;
39
+ /** Untranslated `description` of this bundle's package manifest. */
35
40
  description?: string;
41
+ /** Selected in the profile manifest; a load error means its layer was skipped. */
36
42
  enabled: boolean;
37
43
  /** Whether the profile's own dependencies hold the package; false for a bundle the dsh installation supplies. */
38
44
  installed: boolean;
@@ -49,6 +55,15 @@ export interface BundleInfo {
49
55
  /** Ids of rows the bundle's patch changes without declaring them: the built-in rows it configures or disables. */
50
56
  overrides: string[];
51
57
  }
58
+ /** A registry to install from: an http(s) URL, or null for the one pnpm's own configuration names. */
59
+ export type Registry = string | null;
60
+ /** The registries the manager asks: the configured first one, its fallbacks in order, and what pnpm's own configuration names. */
61
+ export interface PluginRegistries {
62
+ readonly registry: Registry;
63
+ readonly fallbackRegistries: readonly string[];
64
+ /** The URL pnpm's own configuration names in the profile, read from pnpm; null when it could not be read. */
65
+ readonly resolved: string | null;
66
+ }
52
67
  /** How a pnpm run failed, read off how it ended and what it printed. */
53
68
  export type PluginInstallFailureKind = 'pnpm-missing' | 'timeout' | 'not-found' | 'no-matching-version' | 'network' | 'disk-full' | 'permission' | 'build-blocked' | 'integrity' | 'unknown';
54
69
  /** Pnpm completion, including a retrieval path for unabridged diagnostics. */
@@ -79,6 +94,13 @@ export interface ChangeResult {
79
94
  pendingBuilds?: string[];
80
95
  /** Package script permissions saved before this installation attempt. */
81
96
  approvedBuilds?: string[];
97
+ /** The registries the installation asked, in order; `packageResult` is the last one's run. */
98
+ registries?: Registry[];
99
+ /**
100
+ * What the last failed run could not reach or get an answer from: the registry it asked, or the host a git or
101
+ * tarball spec is fetched from, which no registry stands in for; absent for a failure neither explains.
102
+ */
103
+ failedAt?: 'registry' | 'spec-host';
82
104
  }
83
105
  /** Identifies one installation from its start to its settlement, including its log chunks and cancellation. */
84
106
  export type PluginInstallRequestId = Branded<'PluginInstallRequestId'>;
@@ -88,6 +110,13 @@ export interface InstallBundleOptions {
88
110
  requestId?: PluginInstallRequestId;
89
111
  /** Explicitly allow these pending packages' scripts for this profile, then install; a name no longer pending refuses the call. */
90
112
  approvedBuilds?: string[];
113
+ /** The registry asked first; absent, the configured one. The configured fallbacks follow while a registry is unreachable or stale. */
114
+ registry?: Registry;
115
+ }
116
+ /** Where an inspection asks. */
117
+ export interface InspectOptions {
118
+ /** The registry asked first; absent, the configured one. */
119
+ readonly registry?: Registry;
91
120
  }
92
121
  /** The form one install spec takes, in pnpm's vocabulary. */
93
122
  export type InstallSpecKind = 'registry' | 'path' | 'git' | 'tarball';
@@ -107,16 +136,28 @@ export type PluginSpecInspection = {
107
136
  readonly description?: string;
108
137
  /** Whether the package declares a bundle patch; null when the spec's form does not say. */
109
138
  readonly bundle: boolean | null;
139
+ /** The registry that answered for a name, and for the other forms the one an install of the spec asks first. */
140
+ readonly registry: Registry;
141
+ /** The host a git spec or a tarball URL is fetched from, which no registry stands in for. */
142
+ readonly host?: string;
110
143
  } | {
111
144
  readonly status: 'refused';
112
145
  readonly problem: PluginInspectProblem;
113
146
  /** What pnpm, the registry, or the file system said. */
114
147
  readonly reason: string;
148
+ /** The registries asked, in order, when the refusal came from asking them; `reason` is the last one's. */
149
+ readonly registries?: Registry[];
115
150
  };
116
- /** The Host phase of one installation, before its install call settles. */
151
+ /** The Host phase of one installation, before its install call settles; `installing` is announced once per registry asked. */
117
152
  export interface PluginInstallProgress {
118
153
  readonly requestId: PluginInstallRequestId;
119
154
  readonly phase: 'installing' | 'cancelling' | 'applying';
155
+ /** With `installing`: the registry this attempt asks, its one-based position, and how many the installation may ask. */
156
+ readonly attempt?: {
157
+ readonly registry: Registry;
158
+ readonly index: number;
159
+ readonly total: number;
160
+ };
120
161
  }
121
162
  /** Cancellation is confirmed only after process exit and file restoration. */
122
163
  export interface PluginInstallCancellation {
@@ -159,9 +200,10 @@ declare module '@deepseek-ai/cordis' {
159
200
  */
160
201
  'plugin-manager/install-log'(chunk: PluginInstallLogChunk): void;
161
202
  /**
162
- * An installation moved between its Host phases.
203
+ * An installation moved between its Host phases. `installing` is announced once per registry the
204
+ * installation asks, with the attempt's registry and position; `cancelling` and `applying` once.
163
205
  * @mode emit
164
- * @param progress - the installation's request id and phase.
206
+ * @param progress - the installation's request id and phase, with the attempt while installing.
165
207
  */
166
208
  'plugin-manager/install-state'(progress: PluginInstallProgress): void;
167
209
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-plugin-manager",
3
3
  "description": "Current-profile plugin and bundle management shared by dsh CLI, Web and agent tools",
4
- "version": "0.1.6-alpha.2",
4
+ "version": "0.1.7-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -22,6 +22,10 @@
22
22
  "types": "./lib/types/types.d.ts",
23
23
  "default": "./lib/types/types.js"
24
24
  },
25
+ "./registry": {
26
+ "types": "./lib/types/registry.d.ts",
27
+ "default": "./lib/types/registry.js"
28
+ },
25
29
  "./typert": {
26
30
  "types": "./lib/typert.host.d.ts",
27
31
  "default": "./lib/typert.host.js"
@@ -55,23 +59,23 @@
55
59
  "execa": "^10.0.0",
56
60
  "yaml": "^2.9.0",
57
61
  "zod": "^4.4.3",
58
- "@deepseek-ai/dsh-app-boot": "^0.1.6-alpha.2",
59
- "@deepseek-ai/dsh-atomic-write": "^0.1.6-alpha.2",
60
- "@deepseek-ai/schemastery": "^3.18.2",
61
- "@deepseek-ai/dsh-util-values": "^0.1.6-alpha.2"
62
+ "@deepseek-ai/dsh-app-boot": "^0.1.7-alpha.1",
63
+ "@deepseek-ai/dsh-atomic-write": "^0.1.7-alpha.1",
64
+ "@deepseek-ai/schemastery": "^3.18.3",
65
+ "@deepseek-ai/dsh-util-values": "^0.1.7-alpha.1"
62
66
  },
63
67
  "peerDependencies": {
64
- "@deepseek-ai/cordis": "^4.0.2",
65
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
66
- "@deepseek-ai/dsh-subprocess": "^0.1.6-alpha.2",
67
- "@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
68
- "@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2",
69
- "@deepseek-ai/dsh-host-plugin-inventory": "^0.1.6-alpha.2",
70
- "@deepseek-ai/dsh-brand": "^0.1.6-alpha.2",
71
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.2",
72
- "@deepseek-ai/dsh-hmr": "^0.1.6-alpha.2",
73
- "@deepseek-ai/dsh-user-approval": "^0.1.6-alpha.2",
74
- "@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.2"
68
+ "@deepseek-ai/cordis": "^4.0.3",
69
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
70
+ "@deepseek-ai/dsh-host-plugin-inventory": "^0.1.7-alpha.1",
71
+ "@deepseek-ai/dsh-subprocess": "^0.1.7-alpha.1",
72
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.7-alpha.1",
73
+ "@deepseek-ai/dsh-tools": "^0.1.7-alpha.1",
74
+ "@deepseek-ai/dsh-hmr": "^0.1.7-alpha.1",
75
+ "@deepseek-ai/dsh-brand": "^0.1.7-alpha.1",
76
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.7-alpha.1",
77
+ "@deepseek-ai/dsh-sandbox": "^0.1.7-alpha.1",
78
+ "@deepseek-ai/dsh-user-approval": "^0.1.7-alpha.1"
75
79
  },
76
80
  "peerDependenciesMeta": {
77
81
  "@deepseek-ai/dsh-hmr": {
@@ -82,21 +86,22 @@
82
86
  }
83
87
  },
84
88
  "devDependencies": {
85
- "@deepseek-ai/cordis": "^4.0.2",
86
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
87
- "@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
88
- "@deepseek-ai/dsh-subprocess": "^0.1.6-alpha.2",
89
- "@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2",
90
- "@deepseek-ai/dsh-hmr": "^0.1.6-alpha.2",
91
- "@deepseek-ai/cordis-plugin-timer": "^1.1.4",
92
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.2",
93
- "@deepseek-ai/dsh-brand": "^0.1.6-alpha.2",
94
- "@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
95
- "@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.2",
96
- "@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.2",
97
- "@deepseek-ai/dsh-user-approval": "^0.1.6-alpha.2",
98
- "@deepseek-ai/dsh-host-plugin-inventory": "^0.1.6-alpha.2",
99
- "@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2",
100
- "@deepseek-ai/dsh-session": "^0.1.6-alpha.2"
89
+ "@deepseek-ai/dsh-package-manifest": "^0.1.7-alpha.1",
90
+ "@deepseek-ai/cordis": "^4.0.3",
91
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
92
+ "@deepseek-ai/dsh-host-plugin-inventory": "^0.1.7-alpha.1",
93
+ "@deepseek-ai/dsh-subprocess": "^0.1.7-alpha.1",
94
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.7-alpha.1",
95
+ "@deepseek-ai/dsh-tools": "^0.1.7-alpha.1",
96
+ "@deepseek-ai/dsh-system-prompt": "^0.1.7-alpha.1",
97
+ "@deepseek-ai/dsh-hmr": "^0.1.7-alpha.1",
98
+ "@deepseek-ai/cordis-plugin-timer": "^1.1.5",
99
+ "@deepseek-ai/dsh-brand": "^0.1.7-alpha.1",
100
+ "@deepseek-ai/dsh-session": "^0.1.7-alpha.1",
101
+ "@deepseek-ai/dsh-session-projection": "^0.1.7-alpha.1",
102
+ "@deepseek-ai/dsh-sandbox": "^0.1.7-alpha.1",
103
+ "@deepseek-ai/dsh-user-approval": "^0.1.7-alpha.1",
104
+ "@deepseek-ai/dsh-agent": "^0.1.7-alpha.1",
105
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.7-alpha.1"
101
106
  }
102
107
  }