@deepseek-ai/dsh-app-boot 0.1.6-alpha.2 → 0.1.7-alpha.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.
@@ -7,24 +7,22 @@
7
7
  * `dsh.profile` with its ordered `bundles` list) and a `cordis.patch.yml`
8
8
  * (the user's own patch layer, applied after every bundle layer). Bundles are
9
9
  * npm packages whose manifest declares
10
- * `"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }`; the tree is
11
- * composed by applying each bundle's patch list in `dsh.profile.bundles` order over
12
- * an empty entry list, then the profile's own patches, then any launcher
13
- * layers (`--patch` files and flag-derived patches).
10
+ * `"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }` (one file, or an
11
+ * ordered list of files); the tree is composed by applying each bundle's patch
12
+ * lists in `dsh.profile.bundles` order over an empty entry list, then the
13
+ * profile's own patches, then any launcher layers (`--patch` files and
14
+ * flag-derived patches).
14
15
  *
15
16
  * Module resolution is two-anchor by construction: a bundle name resolves
16
17
  * first from the dsh installation (the launcher's own package), then from the
17
18
  * profile directory. Pnpm-managed entries in the profile's `node_modules`
18
- * resolve first. Dsh-owned links add packages carried only by selected
19
- * bundles, while `$DSH_HOME/profiles/node_modules` supplies the installation
20
- * dependency closure through Node's ordinary parent-walk. Plain Node uses
21
- * symlinks for that shared fallback; packaged executables use ESM proxies so
22
- * external plugins retain the installation's module instances.
19
+ * resolve first. The runtime resolution supplies packages carried by the
20
+ * installation and selected bundles to Node's ESM and CommonJS resolvers.
23
21
  * @module @deepseek-ai/dsh-app-boot/profile
24
22
  */
25
23
  import type { EntryOptions } from '@deepseek-ai/cordis-plugin-loader';
26
24
  import { type PatchOptions } from '@deepseek-ai/cordis-plugin-include';
27
- import type { DshPackageManifest } from '@deepseek-ai/dsh-package-manifest';
25
+ import type { DshBundleManifest, DshPackageManifest } from '@deepseek-ai/dsh-package-manifest';
28
26
  /** Directory under the Harness home holding every profile. */
29
27
  export declare const PROFILES_DIR = "profiles";
30
28
  /** The user patch layer inside a profile directory (hot-reloaded on long-lived surfaces). */
@@ -36,15 +34,31 @@ export interface ProfileTemplate {
36
34
  }
37
35
  /** Package metadata accepted by the profile reader; local profiles need no published identity. */
38
36
  export type ProfileManifest = Partial<DshPackageManifest>;
37
+ /**
38
+ * The patch files a bundle declares, as written: one file for a string
39
+ * `patch`, the listed files in order for an array.
40
+ * @param bundle - the bundle's `dsh.bundle` declaration, as read from package.json.
41
+ * @returns the package-relative patch file paths in application order.
42
+ * @throws {Error} when `patch` is neither a string nor a list of strings.
43
+ */
44
+ export declare function bundlePatchFiles(bundle: DshBundleManifest): string[];
45
+ /**
46
+ * Resolve a bundle declaration to its ordered absolute patch files.
47
+ * @param packageDir - absolute directory of the bundle package.
48
+ * @param bundle - the bundle's `dsh.bundle` declaration, as read from package.json.
49
+ * @returns the absolute patch file paths in application order.
50
+ * @throws {Error} when `patch` is neither a string nor a list of strings.
51
+ */
52
+ export declare function bundlePatchPaths(packageDir: string, bundle: DshBundleManifest): string[];
39
53
  /** One resolved bundle layer of a profile. */
40
54
  export interface ProfileLayer {
41
55
  /** The bundle's package name, as listed in `dsh.profile.bundles`. */
42
56
  packageName: string;
43
57
  /** Absolute directory of the resolved bundle package. */
44
58
  packageDir: string;
45
- /** Absolute path of the bundle's patch file. */
46
- patchPath: string;
47
- /** The parsed patch list. */
59
+ /** Absolute paths of the bundle's patch files, in application order. */
60
+ patchPaths: readonly string[];
61
+ /** The parsed patch lists of every file, concatenated in application order. */
48
62
  patches: PatchOptions[];
49
63
  }
50
64
  /** A loaded profile: resolved bundle layers plus the user's own patch layer. */
@@ -60,8 +74,8 @@ export interface Profile {
60
74
  /** The profile's own patches; empty when the file is absent. */
61
75
  patches: PatchOptions[];
62
76
  }
63
- /** One package selected by the profile module-fallback rules. */
64
- export interface ProfileResolutionEntry {
77
+ /** One package the runtime resolution supplies at the interception layer. */
78
+ export interface RuntimeResolutionEntry {
65
79
  /** Bare package name. */
66
80
  readonly name: string;
67
81
  /** Package directory selected by the existing dependency traversal. */
@@ -70,22 +84,32 @@ export interface ProfileResolutionEntry {
70
84
  readonly version: string | undefined;
71
85
  /** Manifest whose dependency edge selected this package. */
72
86
  readonly declarer: string;
73
- /** Whether every profile or only the active profile receives this fallback. */
87
+ /** Whether every profile or only the active profile receives this entry. */
74
88
  readonly scope: 'installation' | 'profile';
75
89
  }
76
- /** Complete immutable fallback table for one profile launch. */
77
- export interface ProfileResolutionGeneration {
78
- /** Directory containing every profile and the shared fallback position. */
90
+ /**
91
+ * A profile node_modules entry linked to a directory outside the shared profiles tree and the active profile.
92
+ * Importers below `realPath` use Node's real ancestor chain, with peer mappings read at each node_modules position.
93
+ */
94
+ export interface LinkedRoot {
95
+ /** Package name of the profile `node_modules` entry, including its scope. */
96
+ readonly name: string;
97
+ /** Real directory outside the shared profiles tree and active profile; a package.json is optional. */
98
+ readonly realPath: string;
99
+ }
100
+ /** Complete immutable package table for one profile launch. */
101
+ export interface RuntimeResolution {
102
+ /** Directory containing every profile; its node_modules is the interception layer. */
79
103
  readonly profilesDir: string;
80
- /** Active profile directory, when bundle-only fallbacks were included. */
104
+ /** Active profile directory, when profile-scope entries were included. */
81
105
  readonly profileDir: string | undefined;
82
- /** Profile-declared packages already installed before the fallback position. */
106
+ /** Profile-declared packages installed in the profile's own node_modules. */
83
107
  readonly localPackageNames: readonly string[];
84
- /** Installation entries followed by bundle-only entries in precedence order. */
85
- readonly entries: readonly ProfileResolutionEntry[];
108
+ /** Installation-scope entries followed by profile-scope entries in precedence order. */
109
+ readonly entries: readonly RuntimeResolutionEntry[];
110
+ /** Active profile links to external directories, sorted by name. */
111
+ readonly linkedRoots: readonly LinkedRoot[];
86
112
  }
87
- /** Startup backend selection for one computed profile resolution generation. */
88
- export type ProfileResolutionMode = 'link' | 'dual' | 'runtime';
89
113
  /**
90
114
  * Resolve a profile's directory under the Harness home.
91
115
  * @param name - the profile name (`dsh --profile <name>`).
@@ -112,52 +136,36 @@ export declare const OPTIONAL_BUNDLES: readonly string[];
112
136
  * @param bundles - the initial `dsh.profile.bundles` layer list.
113
137
  */
114
138
  export declare function initProfile(dir: string, bundles: readonly string[]): void;
115
- /** Inputs for {@link healProfilesModuleFallback}. */
116
- export interface ProfileModuleFallbackOptions {
139
+ /**
140
+ * Remove the package projections a link-backend launch left in a profile.
141
+ * Only symlinks under the profile's `node_modules` whose target lies inside
142
+ * `<profile>/.dsh-module-fallback/node_modules` are unlinked, then that directory is removed;
143
+ * pnpm-installed packages and every other symlink stay. A profile without the directory is untouched.
144
+ * @param dir - the profile directory.
145
+ */
146
+ export declare function removeLinkProjections(dir: string): void;
147
+ /** Inputs for {@link createRuntimeResolution}. */
148
+ export interface RuntimeResolutionOptions {
117
149
  /** Absolute package.json path of the running dsh installation. */
118
150
  installAnchor: string;
119
151
  /** Loaded profile whose selected bundles may carry profile-local plugins. */
120
152
  profile?: Profile;
121
153
  /** Harness home; defaults to {@link resolveDshHome}. */
122
154
  home?: string;
123
- /** Whether to materialize the computed generation; defaults to true. */
124
- materialize?: boolean;
125
155
  }
126
156
  /**
127
- * Maintain module fallbacks for one profile launch. The shared
128
- * `$DSH_HOME/profiles/node_modules` mirrors the dsh installation dependency
129
- * closure. Plain Node writes symlinks; a packaged executable writes ESM
130
- * proxies under a cross-process lock because operating-system links cannot
131
- * enter pkg's virtual filesystem. Missing packages carried only by selected
132
- * bundles are linked through a profile-owned directory into that profile's
133
- * `node_modules`; pnpm-managed entries remain authoritative, and another
134
- * profile's links cannot change its resolution.
157
+ * Compute the runtime resolution without writing module-resolution files.
135
158
  * @param options - installation anchor, optional loaded profile, and Harness home.
136
- * @returns the computed fallback generation after optional materialization.
137
- */
138
- export declare function healProfilesModuleFallback(options: ProfileModuleFallbackOptions): Promise<ProfileResolutionGeneration>;
139
- /**
140
- * Compute a profile resolution generation without materializing links or proxies.
141
- * @param options - installation anchor, profile, and optional Harness home.
142
- * @returns the complete immutable generation.
143
- */
144
- export declare function createProfileResolutionGeneration(options: Omit<ProfileModuleFallbackOptions, 'materialize'>): Promise<ProfileResolutionGeneration>;
145
- /**
146
- * Supply an application-owned profile with filesystem packages from its installation and selected bundles.
147
- * All fallback links belong to the profile; no shared Harness-home directory is written.
148
- * Existing pnpm-managed packages remain authoritative. The caller serializes profile mutations.
149
- * @param options - owning installation package.json and the loaded application profile.
159
+ * @returns the complete immutable runtime resolution.
150
160
  */
151
- export declare function healIsolatedProfileModuleFallback(options: {
152
- installAnchor: string;
153
- profile: Profile;
154
- }): void;
161
+ export declare function createRuntimeResolution(options: RuntimeResolutionOptions): Promise<RuntimeResolution>;
155
162
  /**
156
- * Detach this profile's fallback links before a package-manager mutation.
157
- * Installed packages and links replaced by pnpm remain untouched; the next profile launch restores fallbacks.
158
- * @param profileDir - profile directory whose package mutation is serialized by the caller.
163
+ * Identify selected bundles that did not produce a loaded layer.
164
+ * @param profile - loaded profile, when present.
165
+ * @param manifest - its parsed manifest, when present.
166
+ * @returns selected bundle names missing from the loaded layers, for resolution and diagnostics.
159
167
  */
160
- export declare function unlinkProfileModuleFallback(profileDir: string): void;
168
+ export declare function skippedProfileBundles(profile: Profile | undefined, manifest: ProfileManifest | undefined): ReadonlySet<string>;
161
169
  /**
162
170
  * Read a profile's manifest.
163
171
  * @param binName - the diagnostic prefix on the thrown error.
@@ -188,20 +196,20 @@ export declare function resolveBundleDir(binName: string, packageName: string, i
188
196
  * Load an already initialized profile directory without resolving it through
189
197
  * the shared Harness home. This is used by application-owned profiles whose
190
198
  * package project and lifecycle belong to that application.
199
+ * Unreadable bundles are reported on stderr and skipped without changing the manifest.
191
200
  * @param binName - the diagnostic prefix on thrown errors.
192
201
  * @param dir - absolute profile package directory.
193
202
  * @param installAnchor - absolute path of the owning dsh app's package.json.
194
203
  * @param options - `userLayer: false` skips reading `cordis.patch.yml`.
195
- * @returns the resolved bundle layers and optional user patch layer.
204
+ * @returns the successfully loaded bundle layers and optional user patch layer.
196
205
  */
197
206
  export declare function loadProfileDirectory(binName: string, dir: string, installAnchor: string, options?: {
198
207
  userLayer?: boolean;
199
208
  }): Profile;
200
209
  /**
201
210
  * Load a profile: resolve every `dsh.profile.bundles` entry to its patch
202
- * layer and parse the profile's own patch file. A listed bundle without a
203
- * `dsh.bundle` manifest fails loud — naming a bundle-less package as a layer
204
- * is a misconfiguration, not "no patches".
211
+ * layer and parse the profile's own patch file. Unreadable bundles are reported
212
+ * on stderr and skipped; profile manifest and user patch errors still throw.
205
213
  * @param binName - the diagnostic prefix on thrown errors.
206
214
  * @param name - the profile name.
207
215
  * @param installAnchor - absolute path of the dsh app's package.json (first resolution anchor).