wyvrnpm 1.2.1 → 2.0.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.
package/README.md CHANGED
@@ -1,413 +1,513 @@
1
- # wyvrnpm
2
-
3
- A simple, private C++ package manager that works with any static file hosting provider — Amazon S3, a plain HTTP/HTTPS server, a local directory, or an SMB/UNC network share.
4
-
5
- There is no central registry. You control where packages are hosted.
6
-
7
- ---
8
-
9
- ## Install
10
-
11
- ```bash
12
- npm install -g wyvrnpm
13
- ```
14
-
15
- Requires Node.js >= 18.
16
-
17
- For S3 publishing, also install the AWS SDK:
18
-
19
- ```bash
20
- npm install -g @aws-sdk/client-s3 @aws-sdk/credential-providers
21
- ```
22
-
23
- ---
24
-
25
- ## Quick Start
26
-
27
- ```bash
28
- # 1. Initialise a manifest in your project
29
- wyvrnpm init
30
-
31
- # 2. Configure your package sources once
32
- wyvrnpm configure add-source --kind install --name corp-s3 --url s3://my-bucket/packages --profile my-sso
33
- wyvrnpm configure add-source --kind publish --name default --url s3://my-bucket/packages --profile my-sso
34
-
35
- # 3. Install dependencies (uses configured sources automatically)
36
- wyvrnpm install --platform win_x64
37
-
38
- # 4. Publish your package
39
- wyvrnpm publish --platform win_x64
40
- ```
41
-
42
- ---
43
-
44
- ## Commands
45
-
46
- ### `wyvrnpm init`
47
-
48
- Creates a `wyvrn.json` manifest in the current directory.
49
-
50
- ```bash
51
- wyvrnpm init
52
- wyvrnpm init --root ./my-project
53
- ```
54
-
55
- ---
56
-
57
- ### `wyvrnpm install`
58
-
59
- Resolves the full dependency graph and downloads all packages.
60
-
61
- **Source priority:** CLI `--source` values are used if provided. If omitted, sources are loaded from the [configuration file](#configuration-file).
62
-
63
- ```bash
64
- # Use configured sources (set up via wyvrnpm configure)
65
- wyvrnpm install --platform win_x64
66
-
67
- # Override with explicit sources — ignores config
68
- wyvrnpm install --source https://pkg.example.com/cpp --platform win_x64
69
-
70
- # Multiple sources — tried in order, first to respond wins
71
- wyvrnpm install \
72
- --source https://primary.example.com/cpp \
73
- --source https://mirror.example.com/cpp \
74
- --platform linux_x64
75
- ```
76
-
77
- **Options**
78
-
79
- | Option | Default | Description |
80
- |---|---|---|
81
- | `--source` / `-s` | *(config)* | Base URL of a package source. Repeat for multiple. Overrides config when provided. |
82
- | `--platform` | `win_x64` | Target platform: `win_x64` `win_x86` `linux_x64` `linux_x86` `osx_x64` `osx_arm64` |
83
- | `--timeout` | `300` | HTTP request timeout in seconds |
84
- | `--manifest` | `./wyvrn.json` | Path to the manifest file |
85
- | `--root` | `./` | Project root (packages extracted to `{root}/wyvrn_internal/`) |
86
-
87
- Packages are extracted to `wyvrn_internal/{name}/`. A `wyvrn.lock` file is written alongside the manifest recording the exact resolved versions. On subsequent installs the lock file pins all previously resolved versions — only newly added dependencies are resolved fresh.
88
-
89
- ---
90
-
91
- ### `wyvrnpm publish`
92
-
93
- Zips the project directory and uploads `wyvrn.json` + `wyvrn.zip` to the destination source.
94
-
95
- **Source priority:** CLI `--source` is used if provided (as a URL/URI or a configured source name). If omitted, the first configured publish source is used.
96
-
97
- ```bash
98
- # Use the first configured publish source
99
- wyvrnpm publish --platform win_x64
100
-
101
- # Reference a configured source by name
102
- wyvrnpm publish --source default --platform win_x64
103
-
104
- # Explicit destination URL — ignores config
105
- wyvrnpm publish --source s3://my-bucket/packages --profile my-sso --platform win_x64
106
-
107
- # HTTP server with token auth
108
- wyvrnpm publish --source https://pkg.corp.com --token mytoken --platform linux_x64
109
-
110
- # Local directory or SMB share
111
- wyvrnpm publish --source \\fileserver\packages --platform win_x64
112
- wyvrnpm publish --source /mnt/packages --platform linux_x64
113
-
114
- # Publish build artifacts from a specific directory
115
- wyvrnpm publish --path ./dist --platform win_x64
116
- ```
117
-
118
- **Options**
119
-
120
- | Option | Default | Description |
121
- |---|---|---|
122
- | `--source` / `-s` | *(config)* | Destination URL/URI or configured source name. Overrides config when provided. |
123
- | `--profile` / `-p` | *(config)* | AWS SSO profile for S3 authentication. Overrides config when provided. |
124
- | `--token` | *(config)* | Bearer token for HTTP server authentication. Overrides config when provided. |
125
- | `--platform` | `common` | Target platform sub-path: `win_x64` `win_x86` `linux_x64` `linux_x86` `osx_x64` `osx_arm64` `common` |
126
- | `--path` | `.` | Directory to zip and publish |
127
- | `--manifest` | `./wyvrn.json` | Path to the manifest file |
128
-
129
- Files are uploaded to `{source}/{platform}/{name}/{version}/wyvrn.json` and `wyvrn.zip`.
130
-
131
- ---
132
-
133
- ### `wyvrnpm clean`
134
-
135
- Removes the `wyvrn_internal/` package cache and `wyvrn.lock`.
136
-
137
- ```bash
138
- wyvrnpm clean
139
- ```
140
-
141
- ---
142
-
143
- ### `wyvrnpm configure`
144
-
145
- Manages the [configuration file](#configuration-file). All sub-commands read and write `config.json` in the platform config directory.
146
-
147
- #### `wyvrnpm configure list`
148
-
149
- Prints all configured sources.
150
-
151
- ```
152
- Config: C:\Users\you\AppData\Local\wyvrnpm\config.json
153
-
154
- Install Sources:
155
- corp-s3 s3://my-bucket/packages [profile: my-sso]
156
- fallback https://pkg.corp.com [token: ***]
157
-
158
- Publish Sources:
159
- default s3://my-bucket/packages [profile: my-sso]
160
- ```
161
-
162
- #### `wyvrnpm configure add-source`
163
-
164
- Adds a new source or updates an existing one with the same name.
165
-
166
- ```bash
167
- # S3 with AWS SSO profile (install)
168
- wyvrnpm configure add-source \
169
- --kind install \
170
- --name corp-s3 \
171
- --url s3://my-bucket/packages \
172
- --profile my-sso-profile
173
-
174
- # HTTPS server with token auth (install)
175
- wyvrnpm configure add-source \
176
- --kind install \
177
- --name fallback \
178
- --url https://pkg.corp.com \
179
- --token mytoken
180
-
181
- # Local or SMB path (no auth required)
182
- wyvrnpm configure add-source \
183
- --kind install \
184
- --name local \
185
- --url \\fileserver\packages
186
-
187
- # Publish destination
188
- wyvrnpm configure add-source \
189
- --kind publish \
190
- --name default \
191
- --url s3://my-bucket/packages \
192
- --profile my-sso-profile
193
- ```
194
-
195
- **Options**
196
-
197
- | Option | Required | Description |
198
- |---|---|---|
199
- | `--kind` | Yes | `install` or `publish` |
200
- | `--name` | Yes | Unique name for this source |
201
- | `--url` | Yes | Destination URL, URI, or file path |
202
- | `--profile` | No | AWS SSO profile (S3 sources) |
203
- | `--token` | No | Bearer token (HTTP sources) |
204
-
205
- #### `wyvrnpm configure remove-source`
206
-
207
- Removes a source by name.
208
-
209
- ```bash
210
- wyvrnpm configure remove-source --kind install --name fallback
211
- wyvrnpm configure remove-source --kind publish --name default
212
- ```
213
-
214
- ---
215
-
216
- ## Configuration File
217
-
218
- wyvrnpm stores persistent configuration in a `config.json` file:
219
-
220
- | Platform | Path |
221
- |---|---|
222
- | Windows | `%LOCALAPPDATA%\wyvrnpm\config.json` |
223
- | Linux / macOS | `~/.config/wyvrnpm/config.json` |
224
-
225
- **Example config.json**
226
-
227
- ```json
228
- {
229
- "installSources": [
230
- {
231
- "name": "corp-s3",
232
- "url": "s3://my-bucket/packages",
233
- "profile": "my-sso-profile"
234
- },
235
- {
236
- "name": "fallback",
237
- "url": "https://pkg.corp.com",
238
- "token": "mytoken"
239
- }
240
- ],
241
- "publishSources": [
242
- {
243
- "name": "default",
244
- "url": "s3://my-bucket/packages",
245
- "profile": "my-sso-profile"
246
- }
247
- ]
248
- }
249
- ```
250
-
251
- **CLI options always take priority over config.** Config values are only used when the corresponding CLI option is not provided.
252
-
253
- ---
254
-
255
- ## Publish Providers
256
-
257
- wyvrnpm uses a provider architecture to support different destination types. The correct provider is selected automatically based on the source URL format.
258
-
259
- | Provider | Detected from | Auth |
260
- |---|---|---|
261
- | **S3** | `s3://` URI, or S3 HTTPS endpoint | `--profile` (AWS SSO) |
262
- | **HTTP** | `http://` or `https://` | `--token` (Bearer) |
263
- | **File** | Local path or UNC/SMB share | none |
264
-
265
- ### S3 Provider
266
-
267
- Accepts any of these source formats:
268
-
269
- ```
270
- s3://bucket-name/optional/prefix
271
- https://bucket-name.s3.amazonaws.com/prefix
272
- https://bucket-name.s3.us-east-1.amazonaws.com/prefix
273
- https://s3.amazonaws.com/bucket-name/prefix
274
- https://s3.us-east-1.amazonaws.com/bucket-name/prefix
275
- ```
276
-
277
- Authentication uses AWS SSO via `--profile`. If no profile is given, the default AWS credential chain is used.
278
-
279
- ### HTTP Provider
280
-
281
- Accepts `http://` and `https://` URLs. Uploads files via HTTP `PUT`. Optionally authenticates with a Bearer token via `--token`.
282
-
283
- ### File Provider
284
-
285
- Accepts local directory paths and SMB/UNC network shares. Files are copied with no authentication required.
286
-
287
- ```
288
- /absolute/unix/path
289
- ./relative/path
290
- C:\Windows\path
291
- \\server\share\path
292
- //server/share/path
293
- file:///absolute/path
294
- ```
295
-
296
- ### Adding a Custom Provider
297
-
298
- 1. Create `src/providers/myprovider.js` extending `BaseProvider`:
299
-
300
- ```js
301
- 'use strict';
302
- const BaseProvider = require('./base');
303
-
304
- class MyProvider extends BaseProvider {
305
- static canHandle(source) {
306
- return source.startsWith('myscheme://');
307
- }
308
-
309
- static get providerName() { return 'MyProvider'; }
310
-
311
- async publish(files, options) {
312
- // files.manifest path to wyvrn.json
313
- // files.zip — path to wyvrn.zip
314
- // options.source, options.platform, options.name, options.version
315
- }
316
- }
317
-
318
- module.exports = MyProvider;
319
- ```
320
-
321
- 2. Register it in `src/providers/index.js`:
322
-
323
- ```js
324
- const MyProvider = require('./myprovider');
325
-
326
- const PROVIDERS = [
327
- S3Provider,
328
- HttpProvider,
329
- FileProvider,
330
- MyProvider, // add here
331
- ];
332
- ```
333
-
334
- ---
335
-
336
- ## Registry Layout
337
-
338
- Packages must be hosted at the following path structure relative to the source base:
339
-
340
- ```
341
- {source}/{platform}/{name}/{version}/wyvrn.json <- package manifest
342
- {source}/{platform}/{name}/{version}/wyvrn.zip <- package archive
343
- ```
344
-
345
- The tool also falls back to `razer.json` / `razer.zip` and a `common/` platform path for backwards compatibility.
346
-
347
- **Example (S3):**
348
-
349
- ```
350
- s3://my-bucket/packages/win_x64/OpenSSL/3.0.0.0/wyvrn.json
351
- s3://my-bucket/packages/win_x64/OpenSSL/3.0.0.0/wyvrn.zip
352
- ```
353
-
354
- **Example (HTTP):**
355
-
356
- ```
357
- https://pkg.corp.com/win_x64/OpenSSL/3.0.0.0/wyvrn.json
358
- https://pkg.corp.com/win_x64/OpenSSL/3.0.0.0/wyvrn.zip
359
- ```
360
-
361
- ### Package manifest (wyvrn.json hosted on source)
362
-
363
- ```json
364
- {
365
- "Name": "OpenSSL",
366
- "Version": "3.0.0.0",
367
- "Description": "TLS/SSL toolkit",
368
- "Dependencies": [
369
- { "Name": "zlib", "Version": "1.3.0.0" }
370
- ]
371
- }
372
- ```
373
-
374
- Fields use PascalCase. `Dependencies` is an array — transitive dependencies are resolved automatically.
375
-
376
- ---
377
-
378
- ## Project Manifest (wyvrn.json)
379
-
380
- ```json
381
- {
382
- "name": "my-app",
383
- "version": "1.0.0.0",
384
- "description": "My C++ application",
385
- "kind": "ConsoleApp",
386
- "dependencies": {
387
- "OpenSSL": "3.0.0.0",
388
- "zlib": "1.3.0.0"
389
- }
390
- }
391
- ```
392
-
393
- **`kind` values:** `ConsoleApp`, `StaticLib`, `DynamicLib`, `HeaderOnlyLib`, `WebApp`, `Utility`, `Service`, `TestProject`
394
-
395
- **`dependencies`** maps package names to version strings (`"major.minor.patch.build"`).
396
-
397
- ---
398
-
399
- ## Version Conflict Resolution
400
-
401
- When the dependency graph requires the same package at multiple versions, the highest version wins. If a `wyvrn.lock` exists, locked versions always take priority over any conflicting transitive request. A warning is printed for every conflict detected.
402
-
403
- ---
404
-
405
- ## Ignoring generated files
406
-
407
- Add the following to your `.gitignore`:
408
-
409
- ```
410
- wyvrn_internal/
411
- wyvrn.lock
412
- *.zip
413
- ```
1
+ # wyvrnpm
2
+
3
+ A simple, private C++ package manager that works with any static file hosting provider — Amazon S3, a plain HTTP/HTTPS server, a local directory, or an SMB/UNC network share.
4
+
5
+ There is no central registry. You control where packages are hosted.
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g wyvrnpm
13
+ ```
14
+
15
+ Requires Node.js >= 18.
16
+
17
+ For S3 publishing, also install the AWS SDK:
18
+
19
+ ```bash
20
+ npm install -g @aws-sdk/client-s3 @aws-sdk/credential-providers
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Quick Start
26
+
27
+ ```bash
28
+ # 1. Initialise a manifest in your project
29
+ wyvrnpm init
30
+
31
+ # 2. Configure your package sources once
32
+ wyvrnpm configure add-source --kind install --name corp-s3 --url s3://my-bucket/packages --profile my-sso
33
+ wyvrnpm configure add-source --kind publish --name default --url s3://my-bucket/packages --profile my-sso
34
+
35
+ # 3. Install dependencies (uses configured sources automatically)
36
+ wyvrnpm install --platform win_x64
37
+
38
+ # 4. Publish your package
39
+ wyvrnpm publish --platform win_x64
40
+
41
+ # 5. (Optional) Link local packages for development
42
+ cd ../my-local-lib && wyvrnpm link
43
+ cd ../my-app && wyvrnpm link my-local-lib
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Commands
49
+
50
+ ### `wyvrnpm init`
51
+
52
+ Creates a `wyvrn.json` manifest in the current directory.
53
+
54
+ ```bash
55
+ wyvrnpm init
56
+ wyvrnpm init --root ./my-project
57
+ ```
58
+
59
+ ---
60
+
61
+ ### `wyvrnpm install`
62
+
63
+ Resolves the full dependency graph and downloads all packages.
64
+
65
+ **Source priority:** CLI `--source` values are used if provided. If omitted, sources are loaded from the [configuration file](#configuration-file).
66
+
67
+ ```bash
68
+ # Use configured sources (set up via wyvrnpm configure)
69
+ wyvrnpm install --platform win_x64
70
+
71
+ # Override with explicit sources — ignores config
72
+ wyvrnpm install --source https://pkg.example.com/cpp --platform win_x64
73
+
74
+ # Multiple sources — tried in order, first to respond wins
75
+ wyvrnpm install \
76
+ --source https://primary.example.com/cpp \
77
+ --source https://mirror.example.com/cpp \
78
+ --platform linux_x64
79
+ ```
80
+
81
+ **Options**
82
+
83
+ | Option | Default | Description |
84
+ |---|---|---|
85
+ | `--source` / `-s` | *(config)* | Base URL of a package source. Repeat for multiple. Overrides config when provided. |
86
+ | `--platform` | `win_x64` | Target platform: `win_x64` `win_x86` `linux_x64` `linux_x86` `osx_x64` `osx_arm64` |
87
+ | `--timeout` | `300` | HTTP request timeout in seconds |
88
+ | `--manifest` | `./wyvrn.json` | Path to the manifest file |
89
+ | `--root` | `./` | Project root (packages extracted to `{root}/wyvrn_internal/`) |
90
+
91
+ Packages are extracted to `wyvrn_internal/{name}/`. A `wyvrn.lock` file is written alongside the manifest recording the exact resolved versions. On subsequent installs the lock file pins all previously resolved versions — only newly added dependencies are resolved fresh.
92
+
93
+ ---
94
+
95
+ ### `wyvrnpm publish`
96
+
97
+ Zips the project directory and uploads `wyvrn.json` + `wyvrn.zip` to the destination source.
98
+
99
+ **Source priority:** CLI `--source` is used if provided (as a URL/URI or a configured source name). If omitted, the first configured publish source is used.
100
+
101
+ ```bash
102
+ # Use the first configured publish source
103
+ wyvrnpm publish --platform win_x64
104
+
105
+ # Reference a configured source by name
106
+ wyvrnpm publish --source default --platform win_x64
107
+
108
+ # Explicit destination URL ignores config
109
+ wyvrnpm publish --source s3://my-bucket/packages --profile my-sso --platform win_x64
110
+
111
+ # HTTP server with token auth
112
+ wyvrnpm publish --source https://pkg.corp.com --token mytoken --platform linux_x64
113
+
114
+ # Local directory or SMB share
115
+ wyvrnpm publish --source \\fileserver\packages --platform win_x64
116
+ wyvrnpm publish --source /mnt/packages --platform linux_x64
117
+
118
+ # Publish build artifacts from a specific directory
119
+ wyvrnpm publish --path ./dist --platform win_x64
120
+ ```
121
+
122
+ **Options**
123
+
124
+ | Option | Default | Description |
125
+ |---|---|---|
126
+ | `--source` / `-s` | *(config)* | Destination URL/URI or configured source name. Overrides config when provided. |
127
+ | `--profile` / `-p` | *(config)* | AWS SSO profile for S3 authentication. Overrides config when provided. |
128
+ | `--token` | *(config)* | Bearer token for HTTP server authentication. Overrides config when provided. |
129
+ | `--platform` | `common` | Target platform sub-path: `win_x64` `win_x86` `linux_x64` `linux_x86` `osx_x64` `osx_arm64` `common` |
130
+ | `--path` | `.` | Directory to zip and publish |
131
+ | `--manifest` | `./wyvrn.json` | Path to the manifest file |
132
+
133
+ Files are uploaded to `{source}/{platform}/{name}/{version}/wyvrn.json` and `wyvrn.zip`.
134
+
135
+ ---
136
+
137
+ ### `wyvrnpm clean`
138
+
139
+ Removes the `wyvrn_internal/` package cache and `wyvrn.lock`.
140
+
141
+ ```bash
142
+ wyvrnpm clean
143
+ ```
144
+
145
+ ---
146
+
147
+ ### `wyvrnpm link`
148
+
149
+ Links a local package for development, similar to `npm link`. This allows you to test packages from local source directories without publishing to the registry.
150
+
151
+ #### Register a package globally
152
+
153
+ Run `wyvrnpm link` in a package directory to register it for linking:
154
+
155
+ ```bash
156
+ cd C:\Dev\my-library
157
+ wyvrnpm link
158
+ # [wyvrn] Registered "my-library" -> C:\Dev\my-library
159
+ ```
160
+
161
+ For CMake packages where the installable content is in a subdirectory:
162
+
163
+ ```bash
164
+ cd C:\Dev\my-cmake-lib
165
+ wyvrnpm link --subdir output/install
166
+ # [wyvrn] Registered "my-cmake-lib" -> C:\Dev\my-cmake-lib\output\install
167
+ ```
168
+
169
+ #### Link a package into your project
170
+
171
+ Link a globally registered package:
172
+
173
+ ```bash
174
+ cd C:\Projects\my-app
175
+ wyvrnpm link my-library
176
+ # [wyvrn] Linked: my-library -> C:\Dev\my-library
177
+ ```
178
+
179
+ Or link directly from a path (skip global registration):
180
+
181
+ ```bash
182
+ wyvrnpm link my-library C:\Dev\my-library
183
+ wyvrnpm link my-library C:\Dev\my-library --subdir output/install
184
+ ```
185
+
186
+ #### List registered packages
187
+
188
+ ```bash
189
+ wyvrnpm link --list
190
+ # [wyvrn] Globally registered packages:
191
+ # my-library -> C:\Dev\my-library
192
+ # my-cmake-lib -> C:\Dev\my-cmake-lib\output\install [subdir: output/install]
193
+ ```
194
+
195
+ **Options**
196
+
197
+ | Option | Description |
198
+ |---|---|
199
+ | `--list` | List all globally registered packages |
200
+ | `--subdir` | Subdirectory within the package to link (e.g., `output/install` for CMake packages) |
201
+
202
+ **How it works:**
203
+ - Creates a symlink (Unix) or junction (Windows) in `wyvrn_internal/`
204
+ - Junctions on Windows don't require admin rights
205
+ - Linked packages are recorded in `wyvrn.lock` with a `linked:` prefix
206
+ - `wyvrnpm install` automatically skips downloading linked packages
207
+
208
+ ---
209
+
210
+ ### `wyvrnpm unlink`
211
+
212
+ Removes a linked package from the current project.
213
+
214
+ ```bash
215
+ wyvrnpm unlink my-library
216
+ # [wyvrn] Unlinked: my-library
217
+ ```
218
+
219
+ To unlink and re-download from the registry:
220
+
221
+ ```bash
222
+ wyvrnpm unlink my-library --restore
223
+ # [wyvrn] Unlinked: my-library
224
+ # [wyvrn] Downloading: my-library@1.0.0.0
225
+ ```
226
+
227
+ **Options**
228
+
229
+ | Option | Default | Description |
230
+ |---|---|---|
231
+ | `--restore` | `false` | Re-download the package from registry after unlinking |
232
+ | `--source` | *(config)* | Package source for `--restore` |
233
+ | `--platform` | `win_x64` | Target platform for `--restore` |
234
+
235
+ ---
236
+
237
+ ### `wyvrnpm configure`
238
+
239
+ Manages the [configuration file](#configuration-file). All sub-commands read and write `config.json` in the platform config directory.
240
+
241
+ #### `wyvrnpm configure list`
242
+
243
+ Prints all configured sources.
244
+
245
+ ```
246
+ Config: C:\Users\you\AppData\Local\wyvrnpm\config.json
247
+
248
+ Install Sources:
249
+ corp-s3 s3://my-bucket/packages [profile: my-sso]
250
+ fallback https://pkg.corp.com [token: ***]
251
+
252
+ Publish Sources:
253
+ default s3://my-bucket/packages [profile: my-sso]
254
+ ```
255
+
256
+ #### `wyvrnpm configure add-source`
257
+
258
+ Adds a new source or updates an existing one with the same name.
259
+
260
+ ```bash
261
+ # S3 with AWS SSO profile (install)
262
+ wyvrnpm configure add-source \
263
+ --kind install \
264
+ --name corp-s3 \
265
+ --url s3://my-bucket/packages \
266
+ --profile my-sso-profile
267
+
268
+ # HTTPS server with token auth (install)
269
+ wyvrnpm configure add-source \
270
+ --kind install \
271
+ --name fallback \
272
+ --url https://pkg.corp.com \
273
+ --token mytoken
274
+
275
+ # Local or SMB path (no auth required)
276
+ wyvrnpm configure add-source \
277
+ --kind install \
278
+ --name local \
279
+ --url \\fileserver\packages
280
+
281
+ # Publish destination
282
+ wyvrnpm configure add-source \
283
+ --kind publish \
284
+ --name default \
285
+ --url s3://my-bucket/packages \
286
+ --profile my-sso-profile
287
+ ```
288
+
289
+ **Options**
290
+
291
+ | Option | Required | Description |
292
+ |---|---|---|
293
+ | `--kind` | Yes | `install` or `publish` |
294
+ | `--name` | Yes | Unique name for this source |
295
+ | `--url` | Yes | Destination URL, URI, or file path |
296
+ | `--profile` | No | AWS SSO profile (S3 sources) |
297
+ | `--token` | No | Bearer token (HTTP sources) |
298
+
299
+ #### `wyvrnpm configure remove-source`
300
+
301
+ Removes a source by name.
302
+
303
+ ```bash
304
+ wyvrnpm configure remove-source --kind install --name fallback
305
+ wyvrnpm configure remove-source --kind publish --name default
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Configuration File
311
+
312
+ wyvrnpm stores persistent configuration in a `config.json` file:
313
+
314
+ | Platform | Path |
315
+ |---|---|
316
+ | Windows | `%LOCALAPPDATA%\wyvrnpm\config.json` |
317
+ | Linux / macOS | `~/.config/wyvrnpm/config.json` |
318
+
319
+ **Example config.json**
320
+
321
+ ```json
322
+ {
323
+ "installSources": [
324
+ {
325
+ "name": "corp-s3",
326
+ "url": "s3://my-bucket/packages",
327
+ "profile": "my-sso-profile"
328
+ },
329
+ {
330
+ "name": "fallback",
331
+ "url": "https://pkg.corp.com",
332
+ "token": "mytoken"
333
+ }
334
+ ],
335
+ "publishSources": [
336
+ {
337
+ "name": "default",
338
+ "url": "s3://my-bucket/packages",
339
+ "profile": "my-sso-profile"
340
+ }
341
+ ],
342
+ "linkedPackages": {
343
+ "my-library": { "path": "C:\\Dev\\my-library" },
344
+ "my-cmake-lib": { "path": "C:\\Dev\\my-cmake-lib", "subdir": "output/install" }
345
+ }
346
+ }
347
+ ```
348
+
349
+ The `linkedPackages` field stores globally registered packages for `wyvrnpm link`. Each entry maps a package name to its local path and optional subdirectory.
350
+
351
+ **CLI options always take priority over config.** Config values are only used when the corresponding CLI option is not provided.
352
+
353
+ ---
354
+
355
+ ## Publish Providers
356
+
357
+ wyvrnpm uses a provider architecture to support different destination types. The correct provider is selected automatically based on the source URL format.
358
+
359
+ | Provider | Detected from | Auth |
360
+ |---|---|---|
361
+ | **S3** | `s3://` URI, or S3 HTTPS endpoint | `--profile` (AWS SSO) |
362
+ | **HTTP** | `http://` or `https://` | `--token` (Bearer) |
363
+ | **File** | Local path or UNC/SMB share | none |
364
+
365
+ ### S3 Provider
366
+
367
+ Accepts any of these source formats:
368
+
369
+ ```
370
+ s3://bucket-name/optional/prefix
371
+ https://bucket-name.s3.amazonaws.com/prefix
372
+ https://bucket-name.s3.us-east-1.amazonaws.com/prefix
373
+ https://s3.amazonaws.com/bucket-name/prefix
374
+ https://s3.us-east-1.amazonaws.com/bucket-name/prefix
375
+ ```
376
+
377
+ Authentication uses AWS SSO via `--profile`. If no profile is given, the default AWS credential chain is used.
378
+
379
+ ### HTTP Provider
380
+
381
+ Accepts `http://` and `https://` URLs. Uploads files via HTTP `PUT`. Optionally authenticates with a Bearer token via `--token`.
382
+
383
+ ### File Provider
384
+
385
+ Accepts local directory paths and SMB/UNC network shares. Files are copied with no authentication required.
386
+
387
+ ```
388
+ /absolute/unix/path
389
+ ./relative/path
390
+ C:\Windows\path
391
+ \\server\share\path
392
+ //server/share/path
393
+ file:///absolute/path
394
+ ```
395
+
396
+ ### Adding a Custom Provider
397
+
398
+ 1. Create `src/providers/myprovider.js` extending `BaseProvider`:
399
+
400
+ ```js
401
+ 'use strict';
402
+ const BaseProvider = require('./base');
403
+
404
+ class MyProvider extends BaseProvider {
405
+ static canHandle(source) {
406
+ return source.startsWith('myscheme://');
407
+ }
408
+
409
+ static get providerName() { return 'MyProvider'; }
410
+
411
+ async publish(files, options) {
412
+ // files.manifest — path to wyvrn.json
413
+ // files.zip — path to wyvrn.zip
414
+ // options.source, options.platform, options.name, options.version
415
+ }
416
+ }
417
+
418
+ module.exports = MyProvider;
419
+ ```
420
+
421
+ 2. Register it in `src/providers/index.js`:
422
+
423
+ ```js
424
+ const MyProvider = require('./myprovider');
425
+
426
+ const PROVIDERS = [
427
+ S3Provider,
428
+ HttpProvider,
429
+ FileProvider,
430
+ MyProvider, // add here
431
+ ];
432
+ ```
433
+
434
+ ---
435
+
436
+ ## Registry Layout
437
+
438
+ Packages must be hosted at the following path structure relative to the source base:
439
+
440
+ ```
441
+ {source}/{platform}/{name}/{version}/wyvrn.json <- package manifest
442
+ {source}/{platform}/{name}/{version}/wyvrn.zip <- package archive
443
+ ```
444
+
445
+ The tool also falls back to `razer.json` / `razer.zip` and a `common/` platform path for backwards compatibility.
446
+
447
+ **Example (S3):**
448
+
449
+ ```
450
+ s3://my-bucket/packages/win_x64/OpenSSL/3.0.0.0/wyvrn.json
451
+ s3://my-bucket/packages/win_x64/OpenSSL/3.0.0.0/wyvrn.zip
452
+ ```
453
+
454
+ **Example (HTTP):**
455
+
456
+ ```
457
+ https://pkg.corp.com/win_x64/OpenSSL/3.0.0.0/wyvrn.json
458
+ https://pkg.corp.com/win_x64/OpenSSL/3.0.0.0/wyvrn.zip
459
+ ```
460
+
461
+ ### Package manifest (wyvrn.json hosted on source)
462
+
463
+ ```json
464
+ {
465
+ "Name": "OpenSSL",
466
+ "Version": "3.0.0.0",
467
+ "Description": "TLS/SSL toolkit",
468
+ "Dependencies": [
469
+ { "Name": "zlib", "Version": "1.3.0.0" }
470
+ ]
471
+ }
472
+ ```
473
+
474
+ Fields use PascalCase. `Dependencies` is an array — transitive dependencies are resolved automatically.
475
+
476
+ ---
477
+
478
+ ## Project Manifest (wyvrn.json)
479
+
480
+ ```json
481
+ {
482
+ "name": "my-app",
483
+ "version": "1.0.0.0",
484
+ "description": "My C++ application",
485
+ "kind": "ConsoleApp",
486
+ "dependencies": {
487
+ "OpenSSL": "3.0.0.0",
488
+ "zlib": "1.3.0.0"
489
+ }
490
+ }
491
+ ```
492
+
493
+ **`kind` values:** `ConsoleApp`, `StaticLib`, `DynamicLib`, `HeaderOnlyLib`, `WebApp`, `Utility`, `Service`, `TestProject`
494
+
495
+ **`dependencies`** maps package names to version strings (`"major.minor.patch.build"`).
496
+
497
+ ---
498
+
499
+ ## Version Conflict Resolution
500
+
501
+ When the dependency graph requires the same package at multiple versions, the highest version wins. If a `wyvrn.lock` exists, locked versions always take priority over any conflicting transitive request. A warning is printed for every conflict detected.
502
+
503
+ ---
504
+
505
+ ## Ignoring generated files
506
+
507
+ Add the following to your `.gitignore`:
508
+
509
+ ```
510
+ wyvrn_internal/
511
+ wyvrn.lock
512
+ *.zip
513
+ ```