zyrk 0.3.9 → 0.4.9

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 (121) hide show
  1. package/README.md +146 -34
  2. package/SECURITY.md +42 -0
  3. package/VERSION +1 -1
  4. package/bin/zyrk.js +9 -1
  5. package/dist/cli/main.d.ts +0 -14
  6. package/dist/cli/main.d.ts.map +1 -1
  7. package/dist/cli/main.js +157 -25
  8. package/dist/cli/npm-delegate.d.ts.map +1 -1
  9. package/dist/cli/npm-delegate.js +11 -16
  10. package/dist/commands/dependencies.d.ts +1 -0
  11. package/dist/commands/dependencies.d.ts.map +1 -1
  12. package/dist/commands/dependencies.js +1 -0
  13. package/dist/commands/deploy.d.ts.map +1 -1
  14. package/dist/commands/deploy.js +294 -39
  15. package/dist/commands/maintenance.d.ts +1 -0
  16. package/dist/commands/maintenance.d.ts.map +1 -1
  17. package/dist/commands/maintenance.js +44 -17
  18. package/dist/commands/patch.d.ts +1 -0
  19. package/dist/commands/patch.d.ts.map +1 -1
  20. package/dist/commands/patch.js +24 -7
  21. package/dist/commands/project.d.ts +2 -0
  22. package/dist/commands/project.d.ts.map +1 -1
  23. package/dist/commands/project.js +178 -55
  24. package/dist/commands/store.js +84 -25
  25. package/dist/dlx/run.d.ts +3 -4
  26. package/dist/dlx/run.d.ts.map +1 -1
  27. package/dist/dlx/run.js +166 -45
  28. package/dist/errors.d.ts.map +1 -1
  29. package/dist/errors.js +9 -4
  30. package/dist/extract/tarball.d.ts +4 -0
  31. package/dist/extract/tarball.d.ts.map +1 -1
  32. package/dist/extract/tarball.js +86 -4
  33. package/dist/fetch/all.d.ts +10 -4
  34. package/dist/fetch/all.d.ts.map +1 -1
  35. package/dist/fetch/all.js +118 -77
  36. package/dist/fetch/package.d.ts +20 -0
  37. package/dist/fetch/package.d.ts.map +1 -1
  38. package/dist/fetch/package.js +127 -54
  39. package/dist/fetch/registry.d.ts +23 -7
  40. package/dist/fetch/registry.d.ts.map +1 -1
  41. package/dist/fetch/registry.js +309 -53
  42. package/dist/install/import-npm-workspace.d.ts +5 -0
  43. package/dist/install/import-npm-workspace.d.ts.map +1 -0
  44. package/dist/install/import-npm-workspace.js +283 -0
  45. package/dist/install/import-npm.d.ts.map +1 -1
  46. package/dist/install/import-npm.js +16 -7
  47. package/dist/install/lock.d.ts +2 -0
  48. package/dist/install/lock.d.ts.map +1 -1
  49. package/dist/install/lock.js +98 -5
  50. package/dist/install/metadata.d.ts +6 -0
  51. package/dist/install/metadata.d.ts.map +1 -1
  52. package/dist/install/metadata.js +15 -2
  53. package/dist/install/private.d.ts +46 -0
  54. package/dist/install/private.d.ts.map +1 -0
  55. package/dist/install/private.js +304 -0
  56. package/dist/install/registry.d.ts.map +1 -1
  57. package/dist/install/registry.js +47 -8
  58. package/dist/install/repair.d.ts +22 -0
  59. package/dist/install/repair.d.ts.map +1 -0
  60. package/dist/install/repair.js +115 -0
  61. package/dist/install/run.d.ts +14 -1
  62. package/dist/install/run.d.ts.map +1 -1
  63. package/dist/install/run.js +225 -54
  64. package/dist/install/source-policy.d.ts +11 -0
  65. package/dist/install/source-policy.d.ts.map +1 -0
  66. package/dist/install/source-policy.js +8 -0
  67. package/dist/install/workspace-graph.d.ts +62 -0
  68. package/dist/install/workspace-graph.d.ts.map +1 -0
  69. package/dist/install/workspace-graph.js +365 -0
  70. package/dist/install/workspace-install.d.ts +3 -0
  71. package/dist/install/workspace-install.d.ts.map +1 -0
  72. package/dist/install/workspace-install.js +561 -0
  73. package/dist/install/workspace-lock.d.ts +16 -0
  74. package/dist/install/workspace-lock.d.ts.map +1 -0
  75. package/dist/install/workspace-lock.js +428 -0
  76. package/dist/install/workspace-mutation.d.ts +10 -0
  77. package/dist/install/workspace-mutation.d.ts.map +1 -0
  78. package/dist/install/workspace-mutation.js +154 -0
  79. package/dist/install/workspace-transaction.d.ts +26 -0
  80. package/dist/install/workspace-transaction.d.ts.map +1 -0
  81. package/dist/install/workspace-transaction.js +191 -0
  82. package/dist/install/workspaces.d.ts +66 -0
  83. package/dist/install/workspaces.d.ts.map +1 -0
  84. package/dist/install/workspaces.js +343 -0
  85. package/dist/lockfile/fingerprints.d.ts +10 -0
  86. package/dist/lockfile/fingerprints.d.ts.map +1 -1
  87. package/dist/lockfile/fingerprints.js +10 -1
  88. package/dist/lockfile/read.d.ts.map +1 -1
  89. package/dist/lockfile/read.js +10 -0
  90. package/dist/lockfile/types.d.ts +6 -3
  91. package/dist/lockfile/types.d.ts.map +1 -1
  92. package/dist/lockfile/types.js +3 -2
  93. package/dist/lockfile/write.d.ts +7 -10
  94. package/dist/lockfile/write.d.ts.map +1 -1
  95. package/dist/lockfile/write.js +83 -52
  96. package/dist/log.d.ts +3 -0
  97. package/dist/log.d.ts.map +1 -1
  98. package/dist/log.js +53 -6
  99. package/dist/project/projection.d.ts.map +1 -1
  100. package/dist/project/projection.js +20 -4
  101. package/dist/resolve/resolver.d.ts +25 -1
  102. package/dist/resolve/resolver.d.ts.map +1 -1
  103. package/dist/resolve/resolver.js +167 -31
  104. package/dist/store/objects.d.ts +4 -1
  105. package/dist/store/objects.d.ts.map +1 -1
  106. package/dist/store/objects.js +51 -14
  107. package/dist/store/realize.d.ts +6 -0
  108. package/dist/store/realize.d.ts.map +1 -1
  109. package/dist/store/realize.js +78 -3
  110. package/dist/store/verify.d.ts +1 -0
  111. package/dist/store/verify.d.ts.map +1 -1
  112. package/dist/store/verify.js +15 -6
  113. package/dist/util/integrity.d.ts +14 -4
  114. package/dist/util/integrity.d.ts.map +1 -1
  115. package/dist/util/integrity.js +44 -9
  116. package/dist/util/locks.d.ts.map +1 -1
  117. package/dist/util/locks.js +94 -61
  118. package/dist/util/proc.d.ts +21 -0
  119. package/dist/util/proc.d.ts.map +1 -1
  120. package/dist/util/proc.js +105 -0
  121. package/package.json +6 -3
package/README.md CHANGED
@@ -37,9 +37,9 @@ zyrk --help
37
37
  zyrk --version
38
38
  ```
39
39
 
40
- Requires **Node.js 24 or newer**. The source runs directly with Node's native
41
- TypeScript support; no compilation step or native toolchain is required to
42
- install zyrk itself.
40
+ Requires **Node.js 24 or newer**. Published packages contain compiled JavaScript. A checkout runs TypeScript
41
+ through Node's native type stripping; the check gate also builds and tests the
42
+ source-free package layout. Installing zyrk requires no native toolchain.
43
43
 
44
44
  From a checkout:
45
45
 
@@ -90,19 +90,63 @@ Offline installs use locked verified sources and fail if an input is missing.
90
90
  Manifest, lock, and projection changes are journaled for process-crash recovery;
91
91
  a failed resolution, verification, or build-policy check keeps the prior graph.
92
92
 
93
- Dependency install scripts and implicit native builds are blocked by default.
94
- `--ignore-scripts` explicitly produces an **intentionally unbuilt** installation.
95
- Root install hooks are reported and never run automatically. Script approval,
96
- private native builds, runtime-mutable packages, workspaces, overrides, Git/local
97
- sources, and authenticated or mixed scoped registries are not supported by this
98
- install path yet. Unsupported platform constraints and failed optional packages
99
- currently fail installation instead of being silently omitted. macOS/Windows
100
- compatibility and framework support remain unverified.
93
+ Dependency install scripts and implicit `binding.gyp` builds require explicit
94
+ approval. Review first, trust the selected sources, then install:
101
95
 
102
- Use `--registry=https://your-registry.example/` for a compatible unauthenticated
103
- registry. The adapter reads the default registry from user/project `.npmrc`, and
104
- fails closed on scoped registry routing or disabled TLS verification. Tool
105
- commands (`dlx`/`create`) still use their existing public-registry configuration.
96
+ ```bash
97
+ zyrk approve-builds # inspect exact sources and commands; executes no package code
98
+ zyrk approve-builds esbuild # approve reviewed candidates by package name
99
+ zyrk install
100
+ zyrk rebuild --offline # rebuild the complete approved locked graph
101
+ ```
102
+
103
+ Approvals are local to the exact graph, sources, patch contents, and script
104
+ policy. Mandatory user denies override project approvals. Approved scripts run
105
+ with your account's permissions; permission is not a sandbox. Packages that need
106
+ writes use a complete private dependency generation under `.zyrk-local/`, with
107
+ independent writable files and dependency links confined to that generation.
108
+ Build failure keeps the previous project graph active. `--ignore-scripts`
109
+ explicitly publishes an **intentionally unbuilt** installation. Root install
110
+ hooks never run automatically. A project can request runtime writable packages
111
+ with `"zyrk": { "mutablePackages": ["package-name"] }`; this also uses a complete
112
+ private graph.
113
+
114
+ Default registry and authentication settings are loaded from user/project
115
+ `.npmrc` for installation, dependency edits, `dlx`, and `create`. Environment
116
+ token placeholders are supported. Credentials are restricted to their configured
117
+ scheme, host, port, and path; redirects cannot expand that scope. Use
118
+ `--registry=https://your-registry.example/` on install for an explicit registry.
119
+ Mixed scoped routing and disabled TLS verification are rejected before public
120
+ lookup. Git sources, non-workspace local sources, and overrides remain unsupported;
121
+ they fail explicitly. Optional dependencies incompatible with the selected platform
122
+ are omitted; missing packages, integrity failures, and other optional failures
123
+ remain errors. Platform selection is recorded in the lock. macOS, Windows, and
124
+ broad framework compatibility have not passed their release gates.
125
+
126
+ ### Workspaces
127
+
128
+ Standard `package.json` workspaces use one root lock and a recoverable transaction
129
+ for all importer projections. Workspace packages remain editable live directories;
130
+ registry closures independent of live sources can still use shared realizations.
131
+ Run install or dependency edits from the root or a member directory. Root settings
132
+ and registry policy apply to every member.
133
+
134
+ ```bash
135
+ zyrk install
136
+ zyrk run --workspace app start # exact workspace name or relative path
137
+ zyrk run --recursive build # dependency-first member scripts
138
+ cd packages/app
139
+ zyrk add package-name # edit this importer, preserve other selections
140
+ ```
141
+
142
+ Frozen/offline installs, live peers, patches, mutable registry packages, inspection,
143
+ and repair have workspace fixtures. Builds that reach live workspace sources are
144
+ blocked before execution. Existing npm v2/v3 workspace `package-lock.json` selections can be adopted with
145
+ `zyrk import --from npm`, preserving exact versions, aliases and live members.
146
+ Adoption validates the complete graph before project changes; npm shrinkwrap
147
+ precedence and unsupported bundled/external links fail explicitly. Portable
148
+ workspace export still needs its adapter. Recursive execution supports
149
+ member scripts; filters are exact names or paths, not arbitrary glob expressions.
106
150
 
107
151
  ### Run a one-off tool
108
152
 
@@ -115,15 +159,17 @@ When running from source, replace `zyrk` with `node bin/zyrk.js`.
115
159
 
116
160
  `dlx` resolves the requested package and its dependencies, verifies downloaded
117
161
  archives, creates a dependency-aware tool graph, and launches the selected
118
- JavaScript bin entry with the supplied arguments. Its temporary projection is
162
+ JavaScript, shell, or native executable bin entry with the supplied arguments. Its temporary projection is
119
163
  removed afterward; verified sources and shared realizations remain in the
120
164
  store.
121
165
 
122
166
  `create` uses the same execution path and maps initializer names to their
123
167
  `create-*` packages. For example, `vite` maps to `create-vite`, while a scoped
124
168
  initializer stays in its scope. Compatibility depends on the selected tool:
125
- closures declaring install lifecycle scripts are currently blocked, and native
126
- or shell executable bins are not supported by the JavaScript-only launcher.
169
+ closures declaring install lifecycle scripts, implicit native builds, or bundled
170
+ install hooks are blocked. Dependency executables are available on the tool
171
+ PATH. Parent cancellation terminates the supervised process group with bounded
172
+ escalation on POSIX systems.
127
173
 
128
174
  These commands run the tool's code with your account's permissions. The tool
129
175
  working directory is your current directory. A temporary tool projection is
@@ -131,16 +177,77 @@ not a sandbox.
131
177
 
132
178
  ### Current command coverage
133
179
 
134
- | Surface | Current behavior |
135
- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
136
- | `install`, `i` | Resolve or reuse the lock, verify sources, and publish shared project dependencies. |
137
- | `--help`, `--version` | Show the CLI surface and package version. |
138
- | `dlx`, `create` | Resolve, fetch, verify archives, and run temporary tool environments. |
139
- | `publish`, `unpublish`, `access`, `deprecate`, `dist-tag`, `owner` | Explicitly delegate to your npm CLI. |
140
- | `token`, `adduser`, `login`, `logout`, `whoami`, `ping`, `pack` | Explicitly delegate to your npm CLI. |
141
- | `add`, `remove`, `update`, `run`, `exec` | Report `ZYRK_NOT_IMPLEMENTED`. |
142
- | `store`, `projects`, `repair`, `import`, `deploy`, `docker` | Report `ZYRK_NOT_IMPLEMENTED`. |
143
- | `list`, `why`, `doctor`, `approve-builds`, `rebuild`, `audit`, `patch`, `patch-commit` | Report `ZYRK_NOT_IMPLEMENTED`. |
180
+ | Commands | Behavior |
181
+ | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
182
+ | `install`, `i`, `add`, `remove`, `update` | Resolve or reuse exact selections; publish verified dependencies transactionally. |
183
+ | `import --from npm` | Adopt supported npm v2/v3 lock selections without changing versions. |
184
+ | `fetch --frozen-lockfile` | Prefetch verified locked sources without running scripts or publishing a projection. |
185
+ | `run`, `exec` | Execute project scripts or installed binaries; `exec` never fetches. |
186
+ | `dlx`, `create` | Verify and run temporary tool closures. |
187
+ | `list`, `why`, `doctor` | Inspect selected dependencies, dependency paths, and project health. |
188
+ | `approve-builds`, `rebuild` | Review and approve exact build candidates; build a new private generation. |
189
+ | `audit` | Query exact selected versions under the project privacy policy; distinguish unavailable service from no known advisories. |
190
+ | `patch`, `patch-commit` | Create a private editing area and portable source-bound patch; apply on reinstall. |
191
+ | `repair` | Re-fetch corrupt locked sources and publish a new realization closure without editing existing shared inodes. |
192
+ | `store path/status/verify/gc/pin/unpin`, `projects list/forget` | Inspect storage, verify content, and manage explicit retention roots. |
193
+ | `deploy`, `docker init/build/run` | Export supported production closures or generate and invoke a pinned Docker setup. |
194
+ | `publish`, `unpublish`, `access`, `deprecate`, `dist-tag`, `owner`, `token`, `adduser`, `login`, `logout`, `whoami`, `ping`, `pack` | Explicitly delegate to your npm CLI. |
195
+
196
+ ### Patches, recovery, and cleanup
197
+
198
+ ```bash
199
+ zyrk patch package-name # prints a private editing directory
200
+ # Edit files in that directory, then:
201
+ zyrk patch-commit <editing-directory>
202
+ zyrk install # refresh the lock and apply the patch privately
203
+ zyrk install --offline --frozen-lockfile
204
+
205
+ zyrk doctor
206
+ zyrk store verify --full
207
+ zyrk repair # preserve locked versions, publish replacement instances
208
+ zyrk store gc --dry-run
209
+ zyrk store gc
210
+ ```
211
+
212
+ Commit `package.json`, `package-lock.json`, and `.zyrk/patches/` artifacts.
213
+ Keep `.zyrk-local/` out of version control: it contains approvals, private builds,
214
+ logs, and local install state. Patches bind to verified source manifests; changed
215
+ patches invalidate frozen selections. Other projects retain their selected
216
+ package instances. Repair retains incident evidence and replaces corrupted
217
+ object pathnames, so existing hard links are never rewritten in place.
218
+
219
+ GC uses recorded project roots, pins, leases, a store coordination lock, and a
220
+ 30-day grace period. Preview collection before removing retention roots. Live
221
+ or uncertain owners are retained. A process killed inside the short lock-publication
222
+ guard can leave a guard requiring manual recovery after all zyrk processes stop;
223
+ zyrk fails closed instead of guessing which process owns it.
224
+
225
+ ### Export an application
226
+
227
+ Declare runtime files explicitly and select a direct Node entry:
228
+
229
+ ```bash
230
+ zyrk deploy --out ./dist-runtime --omit=dev --files dist --entry dist/server.js
231
+ node ./dist-runtime/dist/server.js
232
+ ```
233
+
234
+ The exporter validates that links stay inside the output and excludes the host
235
+ store. Generic export supports shared production graphs and relocatable private
236
+ JavaScript outputs, including selected patches and generated files. Native binaries,
237
+ host-path-dependent outputs, workspace export, and arbitrary shell startup adapters
238
+ remain unsupported. Exports validate active generation/profile metadata and reject
239
+ credentials or escaping links. Structural validation does not prove application health. Run an
240
+ application smoke test from the exported directory with host-store access removed.
241
+
242
+ `zyrk docker init` requires a supported Node image pinned by SHA-256, a local CLI
243
+ tarball pinned by SHA-512, runtime files, and an entry. It generates reviewable
244
+ `Dockerfile`, `.dockerignore`, `zyrk-docker.json`, and `ZYRK_DOCKER.md`. Builds fetch
245
+ with an optional BuildKit npmrc secret, then install and export without networking.
246
+ `zyrk docker build --tag app:local` and `zyrk docker run --tag app:local` require a
247
+ reachable Docker daemon. Generated configuration has fixture coverage. The opt-in
248
+ `node scripts/docker-smoke.mjs` gate exercises a pinned image and a network-free
249
+ runtime. A Linux daemon run passed cold/warm builds, imports and asset access
250
+ without host mounts. Broad framework compatibility still requires application-specific checks.
144
251
 
145
252
  Native commands that support `--json` return a versioned result envelope.
146
253
  `dlx` and `create` reject that option because the tool owns stdout. Delegated
@@ -164,16 +271,18 @@ The design separates three things:
164
271
  publication. Extraction rejects unsafe paths and links and normalizes modes.
165
272
  - **Dependency context:** a package instance records its selected dependency
166
273
  wiring, so incompatible versions and peer contexts are not merged.
167
- - **Mutable work:** the planned build/runtime mutation model uses private
168
- project generations. Writable build outputs must not change shared source.
274
+ - **Mutable work:** approved builds, patches, and runtime-writable packages use
275
+ independent private project generations. Writable outputs do not alter shared source.
169
276
 
170
277
  Read-only modes help prevent accidental writes; they are not a security boundary
171
278
  against code running as the same OS user. Shared stores should be used only by
172
279
  mutually trusted processes. Do not share them across unrelated CI trust domains.
173
280
 
174
- Native tool commands currently use the public npm registry. Private registry
175
- configuration and credential support are not implemented; do not use these
176
- commands for internal tools that depend on private registry routing.
281
+ Archive expansion, metadata sizes, resolution growth, fetch totals, and operation
282
+ deadlines are bounded. These limits defend against accidental and hostile
283
+ resource exhaustion; they do not make executed dependencies trustworthy.
284
+ Security reports belong in the private reporting channel described in
285
+ [SECURITY.md](SECURITY.md).
177
286
 
178
287
  ## Global installs and npm delegation
179
288
 
@@ -222,7 +331,10 @@ tag after the commit. Keep changes focused and never bypass the hooks.
222
331
 
223
332
  CI checks pushed commits and pull requests. The separate
224
333
  [npm publishing action](.github/workflows/npm-publish.yml) is triggered when a
225
- GitHub release is created; ordinary commits do not trigger that action.
334
+ GitHub release is published. It verifies the release tag, formatting, typecheck,
335
+ build, and tests, then publishes that exact commit. Ordinary commits do not
336
+ publish packages. Dependabot and a scheduled advisory check supplement CI; an
337
+ unavailable advisory service fails separately from a clean result.
226
338
 
227
339
  The contributor guide is [AGENTS.md](AGENTS.md). Bug reports and reproducible
228
340
  compatibility cases belong in
package/SECURITY.md ADDED
@@ -0,0 +1,42 @@
1
+ # Security policy
2
+
3
+ zyrk is pre-release software under active construction. There is no stable or
4
+ long-term-support release line. Security fixes target current development and
5
+ the latest published pre-release; older versions do not receive promised
6
+ backports. No response or remediation deadline is guaranteed.
7
+
8
+ ## Report a vulnerability privately
9
+
10
+ Use [GitHub private vulnerability reporting](https://github.com/kingjethro999/zyrk/security/advisories/new).
11
+ Private reporting is enabled for this repository. Please keep exploit details,
12
+ credentials, and affected users' data out of public issues and discussions.
13
+
14
+ If the form is unavailable, use the contact links on
15
+ [the maintainer's profile](https://github.com/kingjethro999) to request a private
16
+ reporting channel. A public request should contain no vulnerability details.
17
+
18
+ Include the affected version or commit, Node.js version, OS and filesystem,
19
+ a minimal reproduction using disposable fixtures, expected and observed
20
+ behavior, and the likely impact. Describe relevant registry, script-policy,
21
+ store, and command options. Redact tokens, credentials, private package names,
22
+ and personal filesystem paths. A report should not require access to a real
23
+ account or production data to reproduce.
24
+
25
+ The maintainer will assess the report and coordinate fixes and disclosure when
26
+ possible. Please allow coordination before publishing a working exploit. This
27
+ project offers no bug bounty or guaranteed response time.
28
+
29
+ ## Scope and operational limits
30
+
31
+ Reports involving integrity verification, archive extraction, credentials,
32
+ shared-store mutation, project isolation, subprocess cleanup, and portable
33
+ exports are useful. The shared store is scoped to one OS account. Package code
34
+ runs with that account's permissions when explicitly invoked or approved;
35
+ read-only modes and subprocess supervision are not a sandbox. Compatibility
36
+ and platform support are limited to the cases documented and tested in the
37
+ repository.
38
+
39
+ Scheduled dependency audits and Dependabot updates supplement review. An audit
40
+ service failure is reported as unavailable and fails the scheduled check;
41
+ only a valid successful zero-finding report counts as clean. A clean dependency
42
+ audit does not establish that zyrk or its dependencies are free of vulnerabilities.
package/VERSION CHANGED
@@ -1 +1 @@
1
- v0.3.9
1
+ v0.4.9
package/bin/zyrk.js CHANGED
@@ -1,5 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { runCli } from "../dist/cli/main.js";
2
+ import { existsSync } from "node:fs";
3
+
4
+ // Checkouts run the current source. Published packages contain emitted JS only.
5
+ const source = new URL("../src/cli/main.ts", import.meta.url);
6
+ const { runCli } = await import(
7
+ existsSync(source)
8
+ ? source.href
9
+ : new URL("../dist/cli/main.js", import.meta.url).href
10
+ );
3
11
 
4
12
  process.exitCode = await runCli({
5
13
  argv: process.argv.slice(2),
@@ -1,17 +1,3 @@
1
- /**
2
- * zyrk command dispatch (SPEC 15).
3
- *
4
- * This is the roadmap skeleton, not the whole implementation: `dlx` and
5
- * `create` run temporary tool environments; `--help`, `--version`, the
6
- * global-install rejection, and explicit npm delegation do their jobs.
7
- * `install` publishes a verified shared project graph. Other dependency
8
- * commands fail with ZYRK_NOT_IMPLEMENTED rather than pretending to work;
9
- * unknown commands fail with ZYRK_USAGE
10
- * and the help text.
11
- * Nothing here launches a subprocess: rejection happens before resolution,
12
- * downloads, lifecycle execution, project/store mutation, or any child
13
- * process (SPEC 15.3.1).
14
- */
15
1
  import { ZyrkError } from "../errors.ts";
16
2
  export { ZyrkError };
17
3
  import { RegistryClient } from "../fetch/registry.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAkBH,OAAO,EAAe,SAAS,EAAe,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,OAAO,EAAoB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAM3C,OAAO,EAAqC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhF,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAmDzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBhD;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6EF;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GACnD,SAAS,CAgDX;AAmBD,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CACxC,CAAC;AAEF,gFAAgF;AAChF,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAqPpE"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAe,SAAS,EAAe,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,OAAO,EAAoB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAM3C,OAAO,EAAqC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhF,eAAO,MAAM,uBAAuB,IAAI,CAAC;AA2DzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBhD;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6EF;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GACnD,SAAS,CAgDX;AAmBD,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CACxC,CAAC;AAEF,gFAAgF;AAChF,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAqZpE"}
package/dist/cli/main.js CHANGED
@@ -1,16 +1,11 @@
1
- /**
2
- * zyrk command dispatch (SPEC 15).
3
- *
4
- * This is the roadmap skeleton, not the whole implementation: `dlx` and
5
- * `create` run temporary tool environments; `--help`, `--version`, the
6
- * global-install rejection, and explicit npm delegation do their jobs.
7
- * `install` publishes a verified shared project graph. Other dependency
8
- * commands fail with ZYRK_NOT_IMPLEMENTED rather than pretending to work;
9
- * unknown commands fail with ZYRK_USAGE
10
- * and the help text.
11
- * Nothing here launches a subprocess: rejection happens before resolution,
12
- * downloads, lifecycle execution, project/store mutation, or any child
13
- * process (SPEC 15.3.1).
1
+ import { runMaintenanceCommand } from "../commands/maintenance.js";
2
+ import { runDeployCommand } from "../commands/deploy.js";
3
+ import { runPatchCommand } from "../commands/patch.js";
4
+ import { sanitizeDiagnostic, redactSecrets } from "../log.js";
5
+ /** zyrk command dispatch (SPEC 15).
6
+ * Native handlers share validated graph and registry adapters; delegated registry
7
+ * operations preserve npm arguments. Global install rejection precedes effects.
8
+ * Unsupported command modes fail explicitly in their handler.
14
9
  */
15
10
  import { installProject } from "../install/run.js";
16
11
  import { installRegistry } from "../install/registry.js";
@@ -76,6 +71,14 @@ const IMPLEMENTED_COMMANDS = new Set([
76
71
  "repair",
77
72
  "store",
78
73
  "projects",
74
+ "fetch",
75
+ "audit",
76
+ "approve-builds",
77
+ "rebuild",
78
+ "patch",
79
+ "patch-commit",
80
+ "deploy",
81
+ "docker",
79
82
  ]);
80
83
  export function helpText(version) {
81
84
  const lines = [
@@ -125,7 +128,7 @@ function fail(error, parsed, stdoutHint = "") {
125
128
  body.remedy = error.remedy;
126
129
  return {
127
130
  exitCode: exitCodeFor(error),
128
- stdout: `${JSON.stringify(body)}\n`,
131
+ stdout: `${JSON.stringify(sanitizeDiagnostic(body))}\n`,
129
132
  stderr: "",
130
133
  };
131
134
  }
@@ -216,6 +219,11 @@ export async function runCli(options) {
216
219
  options.stderr.write(result.stderr);
217
220
  return result.exitCode;
218
221
  };
222
+ if (!parsed.help &&
223
+ !parsed.version &&
224
+ parsed.command &&
225
+ isGlobalInstallRequest(parsed.command, parsed.commandArgs, options.env))
226
+ return emit(fail(globalInstallError(parsed.command), parsed));
219
227
  // Delegation bypasses dispatch: zyrk interprets no command arguments
220
228
  // itself, adds no JSON envelope, and forwards every non-zyrk token
221
229
  // verbatim — before the command as well as after it. A leading
@@ -244,6 +252,128 @@ export async function runCli(options) {
244
252
  return emit(fail(toZyrkError(error, "zyrk failed while delegating to npm."), parsed));
245
253
  }
246
254
  }
255
+ if (!parsed.help &&
256
+ !parsed.version &&
257
+ parsed.command &&
258
+ [
259
+ "fetch",
260
+ "audit",
261
+ "approve-builds",
262
+ "rebuild",
263
+ "repair",
264
+ "patch",
265
+ "patch-commit",
266
+ "deploy",
267
+ "docker",
268
+ ].includes(parsed.command)) {
269
+ try {
270
+ const command = parsed.command, cwd = options.cwd ?? process.cwd();
271
+ if (command === "deploy" || command === "docker")
272
+ return await runDeployCommand({
273
+ command,
274
+ args: parsed.commandArgs,
275
+ cwd,
276
+ env: options.env,
277
+ stdout: options.stdout,
278
+ stderr: options.stderr,
279
+ json: parsed.json,
280
+ });
281
+ const tools = options.tools
282
+ ? await options.tools()
283
+ : await defaultTools(options.env, version, cwd);
284
+ let result;
285
+ if (command === "patch" || command === "patch-commit")
286
+ result = await runPatchCommand({
287
+ command,
288
+ args: parsed.commandArgs,
289
+ cwd,
290
+ store: tools.store,
291
+ });
292
+ else if (command === "approve-builds") {
293
+ if (parsed.commandArgs.some((v) => v.startsWith("-") && v !== "--all"))
294
+ throw new ZyrkError("ZYRK_USAGE", "Unsupported build approval option.", {
295
+ remedy: "Use approve-builds to review; approve-builds <name...> or --all explicitly trusts reviewed source code.",
296
+ });
297
+ const selected = parsed.commandArgs.includes("--all")
298
+ ? ["*"]
299
+ : parsed.commandArgs;
300
+ result = await installProject({
301
+ ...tools,
302
+ projectDir: cwd,
303
+ env: options.env,
304
+ reviewBuilds: true,
305
+ ...(selected.length ? { approveBuilds: selected } : {}),
306
+ });
307
+ }
308
+ else if (command === "rebuild") {
309
+ if (parsed.commandArgs.some((v) => v !== "--offline"))
310
+ throw new ZyrkError("ZYRK_USAGE", "Rebuild operates on the complete approved project graph.", { remedy: "Use zyrk rebuild [--offline]; review approvals first." });
311
+ result = await installProject({
312
+ ...tools,
313
+ projectDir: cwd,
314
+ env: options.env,
315
+ frozen: true,
316
+ rebuild: true,
317
+ offline: parsed.commandArgs.includes("--offline"),
318
+ });
319
+ }
320
+ else if (command === "repair") {
321
+ if (parsed.commandArgs.some((arg) => arg !== "--offline"))
322
+ throw new ZyrkError("ZYRK_USAGE", "Repair accepts only --offline.", {
323
+ remedy: "Use zyrk repair to rebuild verified instances selected by the lock.",
324
+ });
325
+ result = await installProject({
326
+ ...tools,
327
+ projectDir: cwd,
328
+ env: options.env,
329
+ frozen: true,
330
+ repair: true,
331
+ offline: parsed.commandArgs.includes("--offline"),
332
+ });
333
+ }
334
+ else
335
+ result = await runMaintenanceCommand({
336
+ command: command,
337
+ env: options.env,
338
+ args: parsed.commandArgs,
339
+ projectDir: cwd,
340
+ ...tools,
341
+ });
342
+ const payload = (command === "audit" ? sanitizeDiagnostic(result) : result);
343
+ if (Array.isArray(payload.builds))
344
+ payload.builds = sanitizeDiagnostic(payload.builds);
345
+ const exitCode = payload.status === "unavailable" || payload.thresholdExceeded === true
346
+ ? 1
347
+ : 0;
348
+ if (parsed.json)
349
+ return emit({
350
+ exitCode,
351
+ stdout: `${JSON.stringify({ schemaVersion: CLI_JSON_SCHEMA_VERSION, ...payload, status: payload.status ?? "ok" })}\n`,
352
+ stderr: "",
353
+ });
354
+ if (command === "approve-builds") {
355
+ const builds = (payload.builds ?? []);
356
+ return emit({
357
+ exitCode,
358
+ stdout: builds.length
359
+ ? builds
360
+ .map((b) => `${b.name}@${b.version} ${b.sourceId}\n${b.stages.map((s) => ` ${s.name}: ${redactSecrets(s.command)}`).join("\n")}`)
361
+ .join("\n") +
362
+ "\nReview runs no package code. Approval trusts these exact candidate sources.\n"
363
+ : "No dependency builds require approval.\n",
364
+ stderr: "",
365
+ });
366
+ }
367
+ return emit({
368
+ exitCode,
369
+ stdout: `${JSON.stringify(payload)}\n`,
370
+ stderr: "",
371
+ });
372
+ }
373
+ catch (error) {
374
+ return emit(fail(toZyrkError(error, `zyrk ${parsed.command} failed.`), parsed));
375
+ }
376
+ }
247
377
  if (!parsed.help &&
248
378
  !parsed.version &&
249
379
  (parsed.command === "install" || parsed.command === "i")) {
@@ -300,6 +430,7 @@ export async function runCli(options) {
300
430
  };
301
431
  const result = await installProject({
302
432
  ...flags,
433
+ env: options.env,
303
434
  specs,
304
435
  projectDir: cwd,
305
436
  ...tools,
@@ -342,10 +473,11 @@ export async function runCli(options) {
342
473
  parsed.command === "import")) {
343
474
  try {
344
475
  const tools = options.tools === undefined
345
- ? await defaultTools(options.env, version)
476
+ ? await defaultTools(options.env, version, options.cwd ?? process.cwd())
346
477
  : await options.tools();
347
478
  const result = await runDependencyCommand({
348
479
  command: parsed.command,
480
+ env: options.env,
349
481
  args: parsed.commandArgs,
350
482
  projectDir: options.cwd ?? process.cwd(),
351
483
  store: tools.store,
@@ -397,13 +529,16 @@ export async function runCli(options) {
397
529
  !parsed.version &&
398
530
  (parsed.command === "store" || parsed.command === "projects")) {
399
531
  try {
400
- const tools = options.tools === undefined
401
- ? await defaultTools(options.env, version)
402
- : await options.tools();
532
+ const store = options.tools === undefined
533
+ ? await Store.open({
534
+ root: resolveStoreRoot({ env: options.env }).root,
535
+ create: false,
536
+ })
537
+ : (await options.tools()).store;
403
538
  const result = await runStoreCommand({
404
539
  command: parsed.command,
405
540
  args: parsed.commandArgs,
406
- store: tools.store,
541
+ store,
407
542
  cwd: options.cwd ?? process.cwd(),
408
543
  json: parsed.json,
409
544
  });
@@ -426,15 +561,12 @@ export async function runCli(options) {
426
561
  }
427
562
  return emit(dispatch(parsed, { version, env: options.env }));
428
563
  }
429
- async function defaultTools(env, version) {
564
+ async function defaultTools(env, version, cwd = process.cwd()) {
565
+ const registry = await installRegistry({ cwd, env, version });
430
566
  const store = await Store.open({
431
567
  root: resolveStoreRoot({ env }).root,
432
568
  create: true,
433
569
  });
434
- const registry = new RegistryClient({
435
- registry: DEFAULT_REGISTRY,
436
- userAgent: `zyrk/${version}`,
437
- });
438
570
  return { store, registry };
439
571
  }
440
572
  async function runToolCommand(command, parsed, options, version) {
@@ -457,7 +589,7 @@ async function runToolCommand(command, parsed, options, version) {
457
589
  });
458
590
  }
459
591
  const tools = options.tools === undefined
460
- ? await defaultTools(options.env, version)
592
+ ? await defaultTools(options.env, version, options.cwd ?? process.cwd())
461
593
  : await options.tools();
462
594
  const base = {
463
595
  store: tools.store,
@@ -1 +1 @@
1
- {"version":3,"file":"npm-delegate.d.ts","sourceRoot":"","sources":["../../src/cli/npm-delegate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAuBH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAEvD,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAK7C;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAC3C,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA2B7E"}
1
+ {"version":3,"file":"npm-delegate.d.ts","sourceRoot":"","sources":["../../src/cli/npm-delegate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAsBH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAEvD,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAK7C;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAC3C,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB7E"}
@@ -16,9 +16,8 @@
16
16
  * operate outside zyrk's dependency management. Global installs are never
17
17
  * delegated (F-018); see parse.ts.
18
18
  */
19
- import { spawn } from "node:child_process";
20
19
  import { ZyrkError } from "../errors.js";
21
- import { closeCode } from "../util/proc.js";
20
+ import { superviseChild } from "../util/proc.js";
22
21
  /** Delegated command, its aliases collapsed, plus help text. */
23
22
  const DELEGATED_COMMANDS = [
24
23
  [["publish"], "Publish the current package to the registry (via npm)."],
@@ -49,20 +48,16 @@ export function delegatedHelpLines() {
49
48
  */
50
49
  export async function delegateToNpm(options) {
51
50
  options.stderr.write(`zyrk: delegating \`zyrk ${options.command}\` to npm; zyrk does not implement publishing or registry authentication.\n`);
52
- return new Promise((resolve, reject) => {
53
- const child = spawn("npm", [options.command, ...options.args], {
51
+ try {
52
+ return (await superviseChild("npm", [options.command, ...options.args], {
54
53
  env: options.env,
55
- stdio: "inherit",
54
+ })).exitCode;
55
+ }
56
+ catch (error) {
57
+ throw new ZyrkError("ZYRK_NPM_UNAVAILABLE", "zyrk could not launch npm for an explicitly delegated command.", {
58
+ detail: { command: options.command },
59
+ remedy: "Install Node.js with npm on PATH, or run the npm command directly.",
60
+ cause: error,
56
61
  });
57
- child.on("error", (error) => {
58
- reject(new ZyrkError("ZYRK_NPM_UNAVAILABLE", "zyrk could not launch npm for an explicitly delegated command.", {
59
- detail: { command: options.command },
60
- remedy: "Install Node.js with npm on PATH, or run the npm command directly.",
61
- cause: error,
62
- }));
63
- });
64
- child.on("close", (code, signal) => {
65
- resolve(closeCode(code, signal));
66
- });
67
- });
62
+ }
68
63
  }
@@ -8,5 +8,6 @@ export declare function runDependencyCommand(options: {
8
8
  projectDir: string;
9
9
  store: Store;
10
10
  registry: RegistryClient;
11
+ env?: NodeJS.ProcessEnv;
11
12
  }): Promise<InstallResult>;
12
13
  //# sourceMappingURL=dependencies.d.ts.map