zyrk 0.6.5 → 0.7.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
@@ -27,6 +27,14 @@ the shared store, exact dependency context, mutation rules, and cleanup contract
27
27
  central to its design. Storage savings, speed, and framework compatibility will
28
28
  be reported only after reproducible measurements and compatibility tests.
29
29
 
30
+ ### The name and the idea
31
+
32
+ The project began as **snpm**, short for “space-efficient npm.” That name was
33
+ already in use, so it became **nexu**; npm's package-name similarity policy
34
+ then blocked publishing that name, and the project became **zyrk**. The names
35
+ changed, while the goal stayed the same: make shared package storage practical,
36
+ careful, and useful in everyday Node.js development.
37
+
30
38
  ## Try the current CLI
31
39
 
32
40
  Install from npm:
@@ -46,11 +54,17 @@ From a checkout:
46
54
  ```bash
47
55
  git clone https://github.com/kingjethro999/zyrk.git zyrk
48
56
  cd zyrk
49
- npm ci
50
- node bin/zyrk.js --help
51
- node bin/zyrk.js --version
57
+ npm install --global zyrk@0.6.6
58
+ zyrk install --frozen-lockfile
59
+ zyrk --help
60
+ zyrk --version
52
61
  ```
53
62
 
63
+ The global npm install bootstraps the `zyrk` executable. Project dependencies
64
+ are installed by zyrk itself. On a fresh checkout, use the published bootstrap
65
+ version first because the source checkout's own development dependencies are
66
+ needed to run its local CLI.
67
+
54
68
  ### One-line install (shell)
55
69
 
56
70
  Linux / macOS:
@@ -90,8 +104,12 @@ Offline installs use locked verified sources and fail if an input is missing.
90
104
  Manifest, lock, and projection changes are journaled for process-crash recovery;
91
105
  a failed resolution, verification, or build-policy check keeps the prior graph.
92
106
 
93
- Dependency install scripts and implicit `binding.gyp` builds require explicit
94
- approval. Review first, trust the selected sources, then install:
107
+ Dependency `preinstall`, `install`, and `postinstall` scripts (plus implicit
108
+ `binding.gyp` builds) are supported. In an interactive terminal, `zyrk install`
109
+ shows the exact candidates and lets you select which scripts to run. Press Enter
110
+ to skip all pending scripts and continue with an intentionally unbuilt install.
111
+ Headless installs also skip unapproved scripts and report that readiness state.
112
+ Review candidates separately with:
95
113
 
96
114
  ```bash
97
115
  zyrk approve-builds # inspect exact sources and commands; executes no package code
@@ -101,8 +119,12 @@ zyrk rebuild --offline # rebuild the complete approved locked graph
101
119
  ```
102
120
 
103
121
  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
122
+ policy. Interactive selections are written to the checked-in
123
+ `zyrk-workspace.json` file with exact package source identities, so collaborators
124
+ can reuse the review alongside the lockfile. Manual `zyrk approve-builds
125
+ <package>` approvals are recorded there too. Mandatory user denies override
126
+ project approvals. Approved scripts run with your account's permissions;
127
+ permission is not a sandbox. Packages that need
106
128
  writes use a complete private dependency generation under `.zyrk-local/`, with
107
129
  independent writable files and dependency links confined to that generation.
108
130
  Build failure keeps the previous project graph active. `--ignore-scripts`
@@ -111,6 +133,24 @@ hooks never run automatically. A project can request runtime writable packages
111
133
  with `"zyrk": { "mutablePackages": ["package-name"] }`; this also uses a complete
112
134
  private graph.
113
135
 
136
+ `zyrk-workspace.json` is portable review state, not a machine-specific store
137
+ manifest. It records each approved package name, version, and exact source ID;
138
+ the file can be committed with `package-lock.json` so collaborators do not have
139
+ to repeat the same approval for the same verified source. User-level denials
140
+ still take precedence.
141
+
142
+ ### Run project scripts
143
+
144
+ Use `zyrk run <script>` or the package-manager shortcut `zyrk <script>`; both
145
+ use the same project-script policy, installed-generation checks, and local
146
+ binary path. Arguments after `--` are passed to the script:
147
+
148
+ ```bash
149
+ zyrk dev
150
+ zyrk test -- --watch
151
+ zyrk run build
152
+ ```
153
+
114
154
  Default registry and authentication settings are loaded from user/project
115
155
  `.npmrc` for installation, dependency edits, `dlx`, and `create`. Environment
116
156
  token placeholders are supported. Credentials are restricted to their configured
@@ -122,7 +162,10 @@ registry; private names never fall back to a public endpoint. Disabled TLS
122
162
  verification is rejected before lookup. Git sources and non-workspace local sources remain unsupported;
123
163
  they fail explicitly. Optional dependencies incompatible with the selected platform
124
164
  are omitted; missing packages, integrity failures, and other optional failures
125
- remain errors. Locks retain exact platform-qualified optional variants; each machine
165
+ remain errors. Platform-specific optional packages that do not match this machine
166
+ are summarized once after installation; these are normal variants for packages
167
+ supporting multiple operating systems and CPUs. Locks retain exact
168
+ platform-qualified optional variants; each machine
126
169
  selects its compatible local closure without rewriting the lock or recording store
127
170
  paths. Older platform-pruned locks need an intentional non-frozen refresh; incomplete
128
171
  npm locks must be freshly resolved before portable adoption. macOS, Windows, and
@@ -194,9 +237,13 @@ limited to one newly created direct child directory. If generation exits without
194
237
  a valid manifest, zyrk reports failure and retains any generated files for review.
195
238
 
196
239
  For Next.js 16.4.2 with dependencies in the external shared store, use
197
- `zyrk run dev -- --webpack` and `zyrk run build -- --webpack`. Strict-root
198
- Turbopack rejects that layout. The [Next compatibility report](docs/next-compatibility.md)
199
- records the tested scaffold, native install, build and HTTP runtime.
240
+ `zyrk run dev -- --webpack` and `zyrk run build -- --webpack`, or explicitly opt
241
+ into Turbopack with `zyrk next --turbopack` before normal `zyrk run dev` / build.
242
+ The [Turbopack guide](docs/next-turbopack.md) explains the experimental additional
243
+ roots, preserved configuration, portable local-state lookup, and deployment
244
+ boundary. The [Next compatibility report](docs/next-compatibility.md) records
245
+ the tested scaffold, native install, build and HTTP runtime. These checks cover
246
+ Linux x64; they do not establish universal framework or device support.
200
247
 
201
248
  Other initializers control their own dependency-install step and may invoke
202
249
  another package manager. Use their skip-install option, when available, then run
@@ -355,24 +402,34 @@ own options and configuration.
355
402
  ## Develop and contribute
356
403
 
357
404
  ```bash
358
- npm ci
359
- npm run setup:hooks
360
- npm run typecheck
361
- npm test
362
- npm run check
363
- npm run format:check
364
- npm run format
405
+ npm install --global zyrk@0.6.6 # bootstrap the CLI, once per machine
406
+ zyrk install --frozen-lockfile
407
+ zyrk run setup:hooks
408
+ zyrk run typecheck
409
+ zyrk run test
410
+ zyrk run check
411
+ zyrk run format:check
412
+ zyrk run format
365
413
  ```
366
414
 
415
+ Linux and macOS development, CI, and release verification use zyrk to install
416
+ the repository's dependencies. The Windows contract job continues to use npm
417
+ while native Windows filesystem and link behavior is being validated. npm is
418
+ also used to publish the package; that is a registry operation, not a project
419
+ dependency install. Vercel deployments should set the install command to
420
+ the commands in [web/vercel.json](web/vercel.json) and set the Vercel project
421
+ root directory to `web/`. The included site uses zyrk for project dependencies
422
+ after npm bootstraps the CLI.
423
+
367
424
  The commit hook runs the full check gate, increments the version in
368
425
  `package.json`, `package-lock.json`, and `VERSION`, and creates a matching version
369
426
  tag after the commit. Keep changes focused and never bypass the hooks.
370
427
 
371
- CI checks pushed commits and pull requests. The separate
372
- [npm publishing action](.github/workflows/npm-publish.yml) is triggered when a
373
- GitHub release is published. It verifies the release tag, formatting, typecheck,
374
- build, and tests, then publishes that exact commit. Ordinary commits do not
375
- publish packages. Dependabot and a scheduled advisory check supplement CI; an
428
+ CI checks pushed commits and pull requests. The
429
+ [npm publishing action](.github/workflows/npm-publish.yml) runs when the commit
430
+ hook's version tag is pushed, verifies formatting, typecheck, build, tests, and
431
+ the tag/version match, then publishes that exact commit. A manual workflow
432
+ dispatch can publish a prior version tag for release backfills. Dependabot and a scheduled advisory check supplement CI; an
376
433
  unavailable advisory service fails separately from a clean result.
377
434
 
378
435
  The contributor guide is [AGENTS.md](AGENTS.md). Bug reports and reproducible
@@ -408,10 +465,29 @@ lists each unique package/version linked after the project transaction commits.
408
465
  Source counts differ from dependency contexts when peers split a package.
409
466
  `--json` disables progress.
410
467
 
411
- Install resolution has a five-minute deadline; each archive extraction has a
412
- two-minute deadline. Set `ZYRK_RESOLVE_TIMEOUT_MS` or `ZYRK_EXTRACT_TIMEOUT_MS`
413
- to an integer from `1` to `900000` milliseconds to adjust these timeouts.
414
- Graph, archive-entry, and byte limits still apply.
468
+ Install resolution has a five-minute deadline, registry requests (including
469
+ archive downloads) have a fifteen-minute deadline, a complete fetch operation
470
+ has a fifteen-minute deadline, and each archive extraction has a two-minute
471
+ deadline. On a slow or unreliable connection, increase the request and complete
472
+ fetch deadlines together. For example, this gives a single request up to 30
473
+ minutes and the entire fetch phase up to 45 minutes:
474
+
475
+ ```bash
476
+ ZYRK_REQUEST_TIMEOUT_MS=1800000 ZYRK_FETCH_TIMEOUT_MS=2700000 zyrk install
477
+ ```
478
+
479
+ To keep the settings for future commands in the current shell, use
480
+ `export ZYRK_REQUEST_TIMEOUT_MS=1800000` and
481
+ `export ZYRK_FETCH_TIMEOUT_MS=2700000`. Both values are milliseconds.
482
+ Resolution and extraction timeouts accept `1` to `900000` (15 minutes); request
483
+ and whole-fetch timeouts accept `1` to `3600000` (60 minutes). For a very slow
484
+ connection, the largest supported combination is:
485
+
486
+ ```bash
487
+ ZYRK_REQUEST_TIMEOUT_MS=3600000 ZYRK_FETCH_TIMEOUT_MS=3600000 zyrk install
488
+ ```
489
+
490
+ These are finite deadlines; graph, archive-entry, and byte limits still apply.
415
491
 
416
492
  Platform gates run the complete check on Ubuntu and macOS/Node 24 and a
417
493
  Windows CLI/artifact contract suite, including paths with spaces and Unicode.
package/VERSION CHANGED
@@ -1 +1 @@
1
- v0.6.5
1
+ v0.7.1
package/bin/zyrk.js CHANGED
@@ -12,6 +12,7 @@ const { runCli } = await import(
12
12
  process.exitCode = await runCli({
13
13
  argv: process.argv.slice(2),
14
14
  env: process.env,
15
+ stdin: process.stdin,
15
16
  stdout: process.stdout,
16
17
  stderr: process.stderr,
17
18
  });
@@ -25,6 +25,7 @@ export type ToolEnvironment = {
25
25
  export type RunCliOptions = {
26
26
  argv: readonly string[];
27
27
  env: NodeJS.ProcessEnv;
28
+ stdin?: NodeJS.ReadStream;
28
29
  stdout: {
29
30
  write(chunk: string): unknown;
30
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AA2BA,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,CAyBhD;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,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,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,CAkapE"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AA+BA,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;AA6DzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA0BhD;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,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAC1B,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CACxC,CAAC;AAuDF,gFAAgF;AAChF,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA2fpE"}
package/dist/cli/main.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { runNextCommand } from "../commands/next.js";
1
2
  import { createInstallProgress } from "./progress.js";
2
3
  import { runMaintenanceCommand } from "../commands/maintenance.js";
3
4
  import { runDeployCommand } from "../commands/deploy.js";
@@ -11,6 +12,8 @@ import { sanitizeDiagnostic, redactSecrets } from "../log.js";
11
12
  import { installProject } from "../install/run.js";
12
13
  import { installRegistry } from "../install/registry.js";
13
14
  import { readFileSync } from "node:fs";
15
+ import { readFile } from "node:fs/promises";
16
+ import { createInterface } from "node:readline/promises";
14
17
  import * as path from "node:path";
15
18
  import { fileURLToPath } from "node:url";
16
19
  import { runCreate, starterSpecFor } from "../dlx/create.js";
@@ -21,7 +24,7 @@ import { runStoreCommand } from "../commands/store.js";
21
24
  import { exitCodeFor, ZyrkError, toZyrkError } from "../errors.js";
22
25
  export { ZyrkError };
23
26
  import { DEFAULT_REGISTRY, RegistryClient } from "../fetch/registry.js";
24
- import { resolveStoreRoot } from "../config/paths.js";
27
+ import { findProjectBoundary, resolveStoreRoot } from "../config/paths.js";
25
28
  import { Store } from "../store/layout.js";
26
29
  import { delegateToNpm, delegatedHelpLines, isDelegatedCommand, } from "./npm-delegate.js";
27
30
  import { isGlobalInstallRequest, parseArgs } from "./parse.js";
@@ -37,6 +40,7 @@ const NATIVE_COMMANDS = [
37
40
  ["exec", "Run an installed executable (never fetches)."],
38
41
  ["dlx", "Explicitly fetch and run a temporary tool environment."],
39
42
  ["create", "Scaffold from a create-* starter package."],
43
+ ["next", "Explicitly configure Next Turbopack: next --turbopack."],
40
44
  ["list, why", "Show the installed graph / why a dependency is selected."],
41
45
  ["doctor", "Diagnose filesystem, links, policy, install-state issues."],
42
46
  ["approve-builds, rebuild", "Review script permissions / rebuild."],
@@ -58,6 +62,7 @@ for (const [names] of NATIVE_COMMANDS) {
58
62
  const IMPLEMENTED_COMMANDS = new Set([
59
63
  "dlx",
60
64
  "create",
65
+ "next",
61
66
  "install",
62
67
  "i",
63
68
  "add",
@@ -86,6 +91,7 @@ export function helpText(version) {
86
91
  `zyrk v${version} — one verified store per user, shared across projects through links.`,
87
92
  "",
88
93
  "Usage: zyrk <command> [args] [--json]",
94
+ " zyrk <script> [args] (shortcut for zyrk run <script> [args])",
89
95
  "",
90
96
  "Dependency commands:",
91
97
  ];
@@ -97,7 +103,7 @@ export function helpText(version) {
97
103
  }
98
104
  lines.push("", "Registry publishing and account commands (via your npm):");
99
105
  lines.push(...delegatedHelpLines());
100
- lines.push("", "Install timeouts: ZYRK_RESOLVE_TIMEOUT_MS and ZYRK_EXTRACT_TIMEOUT_MS (1..900000 ms).", "zyrk never installs packages globally and never runs npm to do it.", "Need a global package? Run npm directly: npm install --global <package-spec>");
106
+ lines.push("", "Install timeouts: ZYRK_RESOLVE_TIMEOUT_MS and ZYRK_EXTRACT_TIMEOUT_MS (1..900000 ms); ZYRK_REQUEST_TIMEOUT_MS (1..3600000 ms); ZYRK_FETCH_TIMEOUT_MS (1..3600000 ms).", "zyrk never installs packages globally and never runs npm to do it.", "Need a global package? Run npm directly: npm install --global <package-spec>");
101
107
  return `${lines.join("\n")}\n`;
102
108
  }
103
109
  function ok(stdout, parsed) {
@@ -209,6 +215,39 @@ function readCliVersion() {
209
215
  return "unknown";
210
216
  }
211
217
  }
218
+ async function promptForBuildApproval(builds, input, output) {
219
+ output.write("\nDependency lifecycle scripts need approval. Review these exact package sources:\n");
220
+ builds.forEach((build, index) => {
221
+ const stages = build.stages
222
+ .map((stage) => `${stage.name}: ${redactSecrets(stage.command)
223
+ .replace(/[\x00-\x1f\x7f-\x9f]/g, "")
224
+ .slice(0, 180)}`)
225
+ .join("; ");
226
+ output.write(` ${index + 1}. ${build.name}@${build.version} (${build.sourceId}) — ${stages}\n`);
227
+ });
228
+ output.write("Enter numbers separated by commas to approve selected sources, `all` to approve all listed sources, or press Enter to skip their scripts and continue unbuilt.\n");
229
+ const prompt = createInterface({
230
+ input,
231
+ output: output,
232
+ terminal: true,
233
+ });
234
+ try {
235
+ const answer = (await prompt.question("Approve builds> ")).trim();
236
+ if (!answer)
237
+ return [];
238
+ if (answer.toLowerCase() === "all")
239
+ return ["*"];
240
+ const numbers = answer.split(/[ ,]+/).map((value) => Number(value));
241
+ if (numbers.some((number) => !Number.isInteger(number) || number < 1 || number > builds.length))
242
+ throw new ZyrkError("ZYRK_USAGE", "Build selection contains an invalid candidate number.", {
243
+ remedy: `Select numbers from 1 to ${builds.length}, enter all, or press Enter to skip scripts.`,
244
+ });
245
+ return [...new Set(numbers)].map((number) => builds[number - 1].sourceId);
246
+ }
247
+ finally {
248
+ prompt.close();
249
+ }
250
+ }
212
251
  /** Parse, dispatch, delegate, or run a tool, and emit. The only impure seam. */
213
252
  export async function runCli(options) {
214
253
  const parsed = parseArgs(options.argv);
@@ -375,6 +414,30 @@ export async function runCli(options) {
375
414
  return emit(fail(toZyrkError(error, `zyrk ${parsed.command} failed.`), parsed));
376
415
  }
377
416
  }
417
+ if (!parsed.help && !parsed.version && parsed.command === "next") {
418
+ try {
419
+ const result = await runNextCommand({
420
+ args: parsed.commandArgs,
421
+ cwd: options.cwd ?? process.cwd(),
422
+ env: options.env,
423
+ });
424
+ return emit({
425
+ exitCode: 0,
426
+ stdout: parsed.json
427
+ ? JSON.stringify({
428
+ schemaVersion: CLI_JSON_SCHEMA_VERSION,
429
+ command: "next",
430
+ status: "ok",
431
+ ...result,
432
+ }) + "\n"
433
+ : `${result.changed ? "Configured" : "Already configured"} Next Turbopack with the project's strict root and the installed external shared realizations. Experimental additional roots require Next.js 16.4+. Backup: ${result.backup}.\n`,
434
+ stderr: "",
435
+ });
436
+ }
437
+ catch (error) {
438
+ return emit(fail(toZyrkError(error, "Next Turbopack configuration failed."), parsed));
439
+ }
440
+ }
378
441
  if (!parsed.help &&
379
442
  !parsed.version &&
380
443
  (parsed.command === "install" || parsed.command === "i")) {
@@ -437,6 +500,11 @@ export async function runCli(options) {
437
500
  env: options.env,
438
501
  specs,
439
502
  projectDir: cwd,
503
+ ...(options.stdin?.isTTY && options.stderr.isTTY && !parsed.json
504
+ ? {
505
+ requestBuildApproval: (builds) => promptForBuildApproval(builds, options.stdin, options.stderr),
506
+ }
507
+ : {}),
440
508
  ...tools,
441
509
  });
442
510
  progress.close();
@@ -493,6 +561,11 @@ export async function runCli(options) {
493
561
  projectDir: options.cwd ?? process.cwd(),
494
562
  store: tools.store,
495
563
  registry: tools.registry,
564
+ ...(options.stdin?.isTTY && options.stderr.isTTY && !parsed.json
565
+ ? {
566
+ requestBuildApproval: (builds) => promptForBuildApproval(builds, options.stdin, options.stderr),
567
+ }
568
+ : {}),
496
569
  });
497
570
  progress.close();
498
571
  if (parsed.json) {
@@ -575,6 +648,48 @@ export async function runCli(options) {
575
648
  return emit(fail(toZyrkError(error, `zyrk ${parsed.command} failed.`), parsed));
576
649
  }
577
650
  }
651
+ // Package scripts are accepted as ergonomic aliases for `zyrk run <name>`.
652
+ // Route through the same project runner so policy, generation leases,
653
+ // local-bin PATH and lifecycle environment stay identical.
654
+ if (!parsed.help &&
655
+ !parsed.version &&
656
+ parsed.command !== undefined &&
657
+ !KNOWN_COMMANDS.has(parsed.command) &&
658
+ parsed.argsBeforeCommand.length === 0) {
659
+ const cwd = options.cwd ?? process.cwd();
660
+ const boundary = await findProjectBoundary(cwd);
661
+ if (boundary) {
662
+ let declared = false;
663
+ try {
664
+ const manifest = JSON.parse(await readFile(path.join(boundary, "package.json"), "utf8"));
665
+ if (manifest.scripts !== null &&
666
+ typeof manifest.scripts === "object" &&
667
+ !Array.isArray(manifest.scripts) &&
668
+ typeof manifest.scripts[parsed.command] === "string")
669
+ declared = true;
670
+ }
671
+ catch {
672
+ // Preserve the normal unknown-command diagnostic when no valid
673
+ // project script can be identified.
674
+ }
675
+ if (declared) {
676
+ try {
677
+ return await runProjectCommand({
678
+ command: "run",
679
+ args: [parsed.command, ...parsed.commandArgs],
680
+ cwd,
681
+ env: options.env,
682
+ stdout: options.stdout,
683
+ stderr: options.stderr,
684
+ json: parsed.json,
685
+ });
686
+ }
687
+ catch (error) {
688
+ return emit(fail(toZyrkError(error, `zyrk ${parsed.command} failed.`), parsed));
689
+ }
690
+ }
691
+ }
692
+ }
578
693
  return emit(dispatch(parsed, { version, env: options.env }));
579
694
  }
580
695
  async function defaultTools(env, version, cwd = process.cwd()) {
@@ -10,5 +10,6 @@ export declare function runDependencyCommand(options: {
10
10
  registry: RegistryClient;
11
11
  env?: NodeJS.ProcessEnv;
12
12
  onProgress?: InstallOptions["onProgress"];
13
+ requestBuildApproval?: InstallOptions["requestBuildApproval"];
13
14
  }): Promise<InstallResult>;
14
15
  //# sourceMappingURL=dependencies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/commands/dependencies.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAavE,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;CAC3C,GAAG,OAAO,CAAC,aAAa,CAAC,CA4HzB"}
1
+ {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/commands/dependencies.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAavE,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,cAAc,CAAC,sBAAsB,CAAC,CAAC;CAC/D,GAAG,OAAO,CAAC,aAAa,CAAC,CA+HzB"}
@@ -16,6 +16,9 @@ export async function runDependencyCommand(options) {
16
16
  registry: options.registry,
17
17
  ...(options.env ? { env: options.env } : {}),
18
18
  ...(options.onProgress ? { onProgress: options.onProgress } : {}),
19
+ ...(options.requestBuildApproval
20
+ ? { requestBuildApproval: options.requestBuildApproval }
21
+ : {}),
19
22
  };
20
23
  const names = [];
21
24
  let from;
@@ -0,0 +1,10 @@
1
+ export declare function runNextCommand(options: {
2
+ args: readonly string[];
3
+ cwd: string;
4
+ env: NodeJS.ProcessEnv;
5
+ }): Promise<{
6
+ changed: boolean;
7
+ config: string;
8
+ backup: string;
9
+ }>;
10
+ //# sourceMappingURL=next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/commands/next.ts"],"names":[],"mappings":"AAqFA,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA0LhE"}