zyrk 0.7.2 → 0.7.3
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 +15 -9
- package/VERSION +1 -1
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +73 -11
- package/dist/cli/progress.d.ts +8 -2
- package/dist/cli/progress.d.ts.map +1 -1
- package/dist/cli/progress.js +64 -38
- package/dist/cli/terminal.d.ts +9 -0
- package/dist/cli/terminal.d.ts.map +1 -0
- package/dist/cli/terminal.js +41 -0
- package/dist/commands/deploy.d.ts +2 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +7 -1
- package/dist/commands/project.d.ts +2 -0
- package/dist/commands/project.d.ts.map +1 -1
- package/dist/commands/project.js +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,7 +143,9 @@ still take precedence.
|
|
|
143
143
|
|
|
144
144
|
Use `zyrk run <script>` or the package-manager shortcut `zyrk <script>`; both
|
|
145
145
|
use the same project-script policy, installed-generation checks, and local
|
|
146
|
-
binary path.
|
|
146
|
+
binary path. Run the shortcut from a directory whose `package.json` declares
|
|
147
|
+
that script; for example, run `cd web` before `zyrk dev` when the script belongs
|
|
148
|
+
to `web/package.json`. Arguments after `--` are passed to the script:
|
|
147
149
|
|
|
148
150
|
```bash
|
|
149
151
|
zyrk dev
|
|
@@ -456,14 +458,18 @@ overrides are ignored, matching npm root-only policy. Override rule order is
|
|
|
456
458
|
recorded in the manifest fingerprint; frozen installs reject policy drift.
|
|
457
459
|
|
|
458
460
|
`zyrk help` and `zyrk --help` both show help successfully. Installs report
|
|
459
|
-
preparation,
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
`--json` disables progress.
|
|
461
|
+
preparation, verified source counts, realization, approved builds, and project
|
|
462
|
+
linking on stderr. Interactive terminals show the stages as a calm, multi-line
|
|
463
|
+
sequence, followed by a success footer; package downloads show received bytes,
|
|
464
|
+
and a checkmark lists each unique package/version linked after the project
|
|
465
|
+
transaction commits. Both `zyrk add prettier` and `zyrk install prettier` show
|
|
466
|
+
these details. Redirected output uses plain progress messages. Source counters
|
|
467
|
+
distinguish verified reuse from newly downloaded sources. Source counts differ
|
|
468
|
+
from dependency contexts when peers split a package. `--json` disables progress.
|
|
469
|
+
Other native commands use the same terminal language: successful summaries get
|
|
470
|
+
a checkmark, structured inspection output is rendered readably, and actionable
|
|
471
|
+
errors show their stable code and remedy together. `NO_COLOR=1` or `TERM=dumb`
|
|
472
|
+
disables color; redirected output and `--json` remain plain and script-friendly.
|
|
467
473
|
|
|
468
474
|
Install resolution has a five-minute deadline, registry requests (including
|
|
469
475
|
archive downloads) have a fifteen-minute deadline, a complete fetch operation
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v0.7.
|
|
1
|
+
v0.7.3
|
package/dist/cli/main.d.ts
CHANGED
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAoCA,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;AAmFzC,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,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,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,CAiiBpE"}
|
package/dist/cli/main.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { runNextCommand } from "../commands/next.js";
|
|
2
2
|
import { createInstallProgress } from "./progress.js";
|
|
3
|
+
import { renderCommandError, renderCommandOutput } from "./terminal.js";
|
|
3
4
|
import { runMaintenanceCommand } from "../commands/maintenance.js";
|
|
4
5
|
import { runDeployCommand } from "../commands/deploy.js";
|
|
5
6
|
import { runPatchCommand } from "../commands/patch.js";
|
|
@@ -9,7 +10,7 @@ import { sanitizeDiagnostic, redactSecrets } from "../log.js";
|
|
|
9
10
|
* operations preserve npm arguments. Global install rejection precedes effects.
|
|
10
11
|
* Unsupported command modes fail explicitly in their handler.
|
|
11
12
|
*/
|
|
12
|
-
import { installProject } from "../install/run.js";
|
|
13
|
+
import { installProject, } from "../install/run.js";
|
|
13
14
|
import { installRegistry } from "../install/registry.js";
|
|
14
15
|
import { readFileSync } from "node:fs";
|
|
15
16
|
import { readFile } from "node:fs/promises";
|
|
@@ -29,6 +30,26 @@ import { Store } from "../store/layout.js";
|
|
|
29
30
|
import { delegateToNpm, delegatedHelpLines, isDelegatedCommand, } from "./npm-delegate.js";
|
|
30
31
|
import { isGlobalInstallRequest, parseArgs } from "./parse.js";
|
|
31
32
|
export const CLI_JSON_SCHEMA_VERSION = 1;
|
|
33
|
+
function installCompletion(readiness) {
|
|
34
|
+
switch (readiness) {
|
|
35
|
+
case "ready":
|
|
36
|
+
return {
|
|
37
|
+
title: "Installed from the verified shared store.",
|
|
38
|
+
detail: "Your project still uses node_modules and normal imports.",
|
|
39
|
+
};
|
|
40
|
+
case "intentionally-unbuilt":
|
|
41
|
+
return {
|
|
42
|
+
title: "Installed; some dependency builds were intentionally skipped.",
|
|
43
|
+
detail: "Review build policy before running packages that need those builds.",
|
|
44
|
+
};
|
|
45
|
+
case "fetched":
|
|
46
|
+
return { title: "Verified package sources in the shared store." };
|
|
47
|
+
case "lockfile-only":
|
|
48
|
+
return { title: "Lockfile updated; dependencies were not installed." };
|
|
49
|
+
case "build-review":
|
|
50
|
+
return { title: "Build review saved; dependency scripts were not run." };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
32
53
|
/** Spec-defined dependency commands (SPEC 15.1-15.2, fetch, docker). */
|
|
33
54
|
const NATIVE_COMMANDS = [
|
|
34
55
|
["install, i", "Install the locked or newly resolved graph."],
|
|
@@ -253,10 +274,29 @@ export async function runCli(options) {
|
|
|
253
274
|
const parsed = parseArgs(options.argv);
|
|
254
275
|
const version = (options.readVersion ?? readCliVersion)();
|
|
255
276
|
const emit = (result) => {
|
|
277
|
+
const interactive = !parsed.json &&
|
|
278
|
+
!parsed.help &&
|
|
279
|
+
!parsed.version &&
|
|
280
|
+
options.stdout.isTTY === true &&
|
|
281
|
+
parsed.command !== undefined &&
|
|
282
|
+
!isDelegatedCommand(parsed.command);
|
|
283
|
+
const style = {
|
|
284
|
+
isTTY: interactive,
|
|
285
|
+
color: interactive &&
|
|
286
|
+
options.env.NO_COLOR === undefined &&
|
|
287
|
+
options.env.TERM !== "dumb",
|
|
288
|
+
};
|
|
256
289
|
if (result.stdout !== "")
|
|
257
|
-
options.stdout.write(
|
|
290
|
+
options.stdout.write(interactive
|
|
291
|
+
? renderCommandOutput(parsed.command ?? "command", result.stdout, style)
|
|
292
|
+
: result.stdout);
|
|
258
293
|
if (result.stderr !== "")
|
|
259
|
-
options.stderr.write(result.
|
|
294
|
+
options.stderr.write(result.exitCode !== 0
|
|
295
|
+
? renderCommandError(result.stderr, {
|
|
296
|
+
...style,
|
|
297
|
+
isTTY: options.stderr.isTTY === true && !parsed.json,
|
|
298
|
+
})
|
|
299
|
+
: result.stderr);
|
|
260
300
|
return result.exitCode;
|
|
261
301
|
};
|
|
262
302
|
if (!parsed.help &&
|
|
@@ -443,7 +483,9 @@ export async function runCli(options) {
|
|
|
443
483
|
(parsed.command === "install" || parsed.command === "i")) {
|
|
444
484
|
if (isGlobalInstallRequest(parsed.command, parsed.commandArgs, options.env))
|
|
445
485
|
return emit(fail(globalInstallError(parsed.command), parsed));
|
|
446
|
-
const progress = createInstallProgress(options.stderr, parsed.json
|
|
486
|
+
const progress = createInstallProgress(options.stderr, parsed.json, {
|
|
487
|
+
color: options.env.NO_COLOR === undefined && options.env.TERM !== "dumb",
|
|
488
|
+
});
|
|
447
489
|
try {
|
|
448
490
|
if (parsed.commandArgs.includes("--help") ||
|
|
449
491
|
parsed.commandArgs.includes("-h")) {
|
|
@@ -507,7 +549,7 @@ export async function runCli(options) {
|
|
|
507
549
|
: {}),
|
|
508
550
|
...tools,
|
|
509
551
|
});
|
|
510
|
-
progress.close();
|
|
552
|
+
progress.close(installCompletion(result.readiness));
|
|
511
553
|
if (parsed.json)
|
|
512
554
|
return emit({
|
|
513
555
|
exitCode: 0,
|
|
@@ -548,7 +590,9 @@ export async function runCli(options) {
|
|
|
548
590
|
parsed.command === "remove" ||
|
|
549
591
|
parsed.command === "update" ||
|
|
550
592
|
parsed.command === "import")) {
|
|
551
|
-
const progress = createInstallProgress(options.stderr, parsed.json
|
|
593
|
+
const progress = createInstallProgress(options.stderr, parsed.json, {
|
|
594
|
+
color: options.env.NO_COLOR === undefined && options.env.TERM !== "dumb",
|
|
595
|
+
});
|
|
552
596
|
try {
|
|
553
597
|
const tools = options.tools === undefined
|
|
554
598
|
? await defaultTools(options.env, version, options.cwd ?? process.cwd())
|
|
@@ -567,7 +611,10 @@ export async function runCli(options) {
|
|
|
567
611
|
}
|
|
568
612
|
: {}),
|
|
569
613
|
});
|
|
570
|
-
progress.close(
|
|
614
|
+
progress.close({
|
|
615
|
+
title: `Dependency changes installed from the verified shared store.`,
|
|
616
|
+
detail: `${result.packages} packages; ${result.reused} realizations reused.`,
|
|
617
|
+
});
|
|
571
618
|
if (parsed.json) {
|
|
572
619
|
return emit({
|
|
573
620
|
exitCode: 0,
|
|
@@ -730,7 +777,13 @@ async function runToolCommand(command, parsed, options, version) {
|
|
|
730
777
|
env: options.env,
|
|
731
778
|
};
|
|
732
779
|
if (command === "dlx") {
|
|
733
|
-
|
|
780
|
+
const result = await runDlx({ ...base, spec: first });
|
|
781
|
+
if (result.exitCode === 0 && options.stderr.isTTY)
|
|
782
|
+
options.stderr.write(renderCommandOutput("dlx", `zyrk dlx finished ${result.name}@${result.version}.\n`, {
|
|
783
|
+
isTTY: true,
|
|
784
|
+
color: options.env.NO_COLOR === undefined && options.env.TERM !== "dumb",
|
|
785
|
+
}));
|
|
786
|
+
return result.exitCode;
|
|
734
787
|
}
|
|
735
788
|
const isNext = starterSpecFor(first).startsWith("create-next-app@");
|
|
736
789
|
options.stderr.write(isNext
|
|
@@ -738,13 +791,22 @@ async function runToolCommand(command, parsed, options, version) {
|
|
|
738
791
|
? "zyrk: Next scaffolding only; dependency installation was explicitly skipped.\n"
|
|
739
792
|
: "zyrk: Creating Next.js application; dependencies will install with zyrk.\n"
|
|
740
793
|
: "zyrk: This initializer controls its own dependency installation.\n");
|
|
741
|
-
const progress = createInstallProgress(options.stderr, false
|
|
794
|
+
const progress = createInstallProgress(options.stderr, false, {
|
|
795
|
+
color: options.env.NO_COLOR === undefined && options.env.TERM !== "dumb",
|
|
796
|
+
});
|
|
742
797
|
try {
|
|
743
|
-
|
|
798
|
+
const result = await runCreate({
|
|
744
799
|
...base,
|
|
745
800
|
input: first,
|
|
746
801
|
onInstallProgress: progress.update,
|
|
747
|
-
})
|
|
802
|
+
});
|
|
803
|
+
progress.close(result.exitCode === 0
|
|
804
|
+
? {
|
|
805
|
+
title: "Project created successfully.",
|
|
806
|
+
detail: "Open the project directory and run its declared scripts with zyrk.",
|
|
807
|
+
}
|
|
808
|
+
: undefined);
|
|
809
|
+
return result.exitCode;
|
|
748
810
|
}
|
|
749
811
|
finally {
|
|
750
812
|
progress.close();
|
package/dist/cli/progress.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { InstallProgress } from "../install/run.ts";
|
|
2
|
+
export type InstallCompletion = {
|
|
3
|
+
title: string;
|
|
4
|
+
detail?: string;
|
|
5
|
+
};
|
|
2
6
|
/** Presentation only: never writes to stdout or exposes package URLs or paths. */
|
|
3
7
|
export declare function createInstallProgress(stream: {
|
|
4
8
|
write(chunk: string): unknown;
|
|
5
9
|
isTTY?: boolean;
|
|
6
|
-
}, quiet: boolean
|
|
10
|
+
}, quiet: boolean, options?: {
|
|
11
|
+
color?: boolean;
|
|
12
|
+
}): {
|
|
7
13
|
update(event: InstallProgress): void;
|
|
8
|
-
close(): void;
|
|
14
|
+
close(completion?: InstallCompletion): void;
|
|
9
15
|
};
|
|
10
16
|
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAYzD,kFAAkF;AAClF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE;IAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAC1D,KAAK,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAYzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE;IAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAC1D,KAAK,EAAE,OAAO,EACd,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC;IACD,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,KAAK,CAAC,UAAU,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC7C,CA2FA"}
|
package/dist/cli/progress.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const labels = {
|
|
2
2
|
planning: "Preparing installation",
|
|
3
|
-
resolving: "
|
|
3
|
+
resolving: "Preparing installation",
|
|
4
4
|
fetching: "Verifying package sources",
|
|
5
5
|
realizing: "Preparing shared realizations",
|
|
6
6
|
building: "Preparing approved private builds",
|
|
@@ -8,10 +8,16 @@ const labels = {
|
|
|
8
8
|
complete: "Installation complete",
|
|
9
9
|
};
|
|
10
10
|
/** Presentation only: never writes to stdout or exposes package URLs or paths. */
|
|
11
|
-
export function createInstallProgress(stream, quiet) {
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
export function createInstallProgress(stream, quiet, options = {}) {
|
|
12
|
+
const tty = Boolean(stream.isTTY);
|
|
13
|
+
const color = tty && options.color !== false;
|
|
14
|
+
const dim = (value) => (color ? `\u001b[2m${value}\u001b[0m` : value);
|
|
15
|
+
const green = (value) => color ? `\u001b[32m${value}\u001b[0m` : value;
|
|
16
|
+
let closed = false;
|
|
17
|
+
let currentStage = "";
|
|
18
|
+
let statusLine = false;
|
|
14
19
|
let lastDownload = 0;
|
|
20
|
+
let lastPlain = "";
|
|
15
21
|
const write = (text) => {
|
|
16
22
|
try {
|
|
17
23
|
stream.write(text);
|
|
@@ -20,57 +26,77 @@ export function createInstallProgress(stream, quiet) {
|
|
|
20
26
|
/* A display failure cannot alter installation. */
|
|
21
27
|
}
|
|
22
28
|
};
|
|
23
|
-
const
|
|
29
|
+
const clearStatus = (lineBreak) => {
|
|
30
|
+
if (!statusLine)
|
|
31
|
+
return;
|
|
32
|
+
write(`\r\u001b[2K${lineBreak ? "\n" : ""}`);
|
|
33
|
+
statusLine = false;
|
|
34
|
+
};
|
|
24
35
|
return {
|
|
25
36
|
update(event) {
|
|
26
37
|
if (quiet || closed)
|
|
27
38
|
return;
|
|
28
39
|
const pkg = event.package;
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
const
|
|
40
|
+
// Strip control characters as presentation defense for direct API
|
|
41
|
+
// callers and hostile registry metadata.
|
|
42
|
+
const packageLabel = pkg
|
|
32
43
|
? `${pkg.name}@${pkg.version}`.replace(/[\x00-\x1f\x7f-\x9f]/g, "")
|
|
33
44
|
: "";
|
|
34
45
|
if (pkg?.status === "linked") {
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
write(
|
|
46
|
+
if (tty)
|
|
47
|
+
clearStatus(true);
|
|
48
|
+
write(`${green("✓")} ${packageLabel} linked\n`);
|
|
38
49
|
return;
|
|
39
50
|
}
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
(downloading
|
|
47
|
-
? `Downloading ${label}: ${((pkg.bytes ?? 0) / 1024).toFixed(1)} KiB`
|
|
48
|
-
: labels[event.phase]) +
|
|
49
|
-
(event.total === undefined
|
|
50
|
-
? ""
|
|
51
|
-
: ` (${event.completed ?? 0}/${event.total})`) +
|
|
52
|
-
(event.reused === undefined
|
|
53
|
-
? ""
|
|
54
|
-
: ` — reused ${event.reused}, downloaded ${event.downloaded ?? 0}`);
|
|
55
|
-
if (stream.isTTY) {
|
|
56
|
-
render();
|
|
57
|
-
if (!timer) {
|
|
58
|
-
timer = setInterval(render, 100);
|
|
59
|
-
timer.unref();
|
|
51
|
+
const stage = labels[event.phase];
|
|
52
|
+
if (tty) {
|
|
53
|
+
if (stage !== "Installation complete" && stage !== currentStage) {
|
|
54
|
+
clearStatus(true);
|
|
55
|
+
write(`${dim(`› zyrk: ${stage}`)}\n`);
|
|
56
|
+
currentStage = stage;
|
|
60
57
|
}
|
|
58
|
+
if (pkg?.status === "downloading" || event.phase === "fetching") {
|
|
59
|
+
if (pkg?.status === "downloading" &&
|
|
60
|
+
pkg.bytes &&
|
|
61
|
+
Date.now() - lastDownload < 100)
|
|
62
|
+
return;
|
|
63
|
+
lastDownload = Date.now();
|
|
64
|
+
const status = pkg?.status === "downloading"
|
|
65
|
+
? ` Downloading ${packageLabel}: ${((pkg.bytes ?? 0) / 1024).toFixed(1)} KiB`
|
|
66
|
+
: ` Sources verified ${event.completed ?? 0}/${event.total ?? 0} · reused ${event.reused ?? 0} · downloaded ${event.downloaded ?? 0}`;
|
|
67
|
+
write(`\r\u001b[2K${dim(status)}`);
|
|
68
|
+
statusLine = true;
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
61
71
|
}
|
|
62
|
-
|
|
72
|
+
const current = (pkg?.status === "downloading"
|
|
73
|
+
? `Downloading ${packageLabel}: ${((pkg.bytes ?? 0) / 1024).toFixed(1)} KiB`
|
|
74
|
+
: stage) +
|
|
75
|
+
(event.total === undefined
|
|
76
|
+
? ""
|
|
77
|
+
: ` (${event.completed ?? 0}/${event.total})`) +
|
|
78
|
+
(event.reused === undefined
|
|
79
|
+
? ""
|
|
80
|
+
: ` — reused ${event.reused}, downloaded ${event.downloaded ?? 0}`);
|
|
81
|
+
if (current !== lastPlain)
|
|
63
82
|
write(`zyrk: ${current}\n`);
|
|
64
|
-
|
|
83
|
+
lastPlain = current;
|
|
65
84
|
},
|
|
66
|
-
close() {
|
|
85
|
+
close(completion) {
|
|
67
86
|
if (closed)
|
|
68
87
|
return;
|
|
69
88
|
closed = true;
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
if (
|
|
73
|
-
|
|
89
|
+
if (quiet)
|
|
90
|
+
return;
|
|
91
|
+
if (tty) {
|
|
92
|
+
clearStatus(true);
|
|
93
|
+
if (completion) {
|
|
94
|
+
write(`${dim("─".repeat(46))}\n`);
|
|
95
|
+
write(`${green("✓")} ${completion.title}\n`);
|
|
96
|
+
if (completion.detail)
|
|
97
|
+
write(`${dim(completion.detail)}\n`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
74
100
|
},
|
|
75
101
|
};
|
|
76
102
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type TerminalStyle = {
|
|
2
|
+
isTTY?: boolean;
|
|
3
|
+
color?: boolean;
|
|
4
|
+
};
|
|
5
|
+
/** Render command summaries for people while preserving redirected output. */
|
|
6
|
+
export declare function renderCommandOutput(command: string, output: string, style?: TerminalStyle): string;
|
|
7
|
+
/** Make stable CLI diagnostics easier to scan without changing their content. */
|
|
8
|
+
export declare function renderCommandError(error: string, style?: TerminalStyle): string;
|
|
9
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/cli/terminal.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAQjE,8EAA8E;AAC9E,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,aAAkB,GACxB,MAAM,CA0BR;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,aAAkB,GACxB,MAAM,CAUR"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
function paint(value, code, style) {
|
|
2
|
+
return style.isTTY && style.color !== false
|
|
3
|
+
? `\u001b[${code}m${value}\u001b[0m`
|
|
4
|
+
: value;
|
|
5
|
+
}
|
|
6
|
+
/** Render command summaries for people while preserving redirected output. */
|
|
7
|
+
export function renderCommandOutput(command, output, style = {}) {
|
|
8
|
+
if (!style.isTTY || output === "")
|
|
9
|
+
return output;
|
|
10
|
+
let value;
|
|
11
|
+
try {
|
|
12
|
+
value = JSON.parse(output);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
value = undefined;
|
|
16
|
+
}
|
|
17
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
18
|
+
const summary = { ...value };
|
|
19
|
+
delete summary.schemaVersion;
|
|
20
|
+
delete summary.status;
|
|
21
|
+
delete summary.command;
|
|
22
|
+
const body = JSON.stringify(summary, null, 2).replace(/^(\s*)"([^\"]+)":/gm, (_match, indent, key) => `${indent}${paint(`${key}:`, 2, style)}`);
|
|
23
|
+
return `${paint("✓", 32, style)} zyrk ${command}\n${body}\n`;
|
|
24
|
+
}
|
|
25
|
+
const lines = output.trimEnd().split("\n");
|
|
26
|
+
const first = lines.shift() ?? "";
|
|
27
|
+
const heading = first.startsWith("✓")
|
|
28
|
+
? `${paint("✓", 32, style)}${first.slice(1)}`
|
|
29
|
+
: `${paint("✓", 32, style)} ${first}`;
|
|
30
|
+
return `${heading}${lines.length ? `\n${lines.join("\n")}` : ""}\n`;
|
|
31
|
+
}
|
|
32
|
+
/** Make stable CLI diagnostics easier to scan without changing their content. */
|
|
33
|
+
export function renderCommandError(error, style = {}) {
|
|
34
|
+
if (!style.isTTY)
|
|
35
|
+
return error;
|
|
36
|
+
const match = /^zyrk: error ([A-Z0-9_]+): ([^\n]+)(?:\n([\s\S]*?))?\n?$/.exec(error);
|
|
37
|
+
if (!match)
|
|
38
|
+
return error;
|
|
39
|
+
const [, code, message, remedy] = match;
|
|
40
|
+
return `${paint("✖", 31, style)} zyrk ${code}\n ${message}${remedy ? `\n ${paint("↳", 33, style)} ${remedy}` : ""}\n`;
|
|
41
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAyEA,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AA8EF,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAoajB"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -10,6 +10,7 @@ import { validateNativeExport } from "./native-export.js";
|
|
|
10
10
|
import { workspaceRegistryOccurrences, workspaceContextId, } from "../install/workspace-graph.js";
|
|
11
11
|
import { findProjectBoundary, resolveStoreRoot } from "../config/paths.js";
|
|
12
12
|
import { ZyrkError } from "../errors.js";
|
|
13
|
+
import { renderCommandOutput } from "../cli/terminal.js";
|
|
13
14
|
import { lockedGraph } from "../install/lock.js";
|
|
14
15
|
import { loadProjectPatches } from "./patch.js";
|
|
15
16
|
import { currentPlatform } from "../resolve/resolver.js";
|
|
@@ -84,7 +85,12 @@ function output(options, result, human) {
|
|
|
84
85
|
command: options.command,
|
|
85
86
|
...result,
|
|
86
87
|
}) + "\n"
|
|
87
|
-
: human
|
|
88
|
+
: renderCommandOutput(options.command, `${human}\n`, {
|
|
89
|
+
...(options.stdout.isTTY === undefined
|
|
90
|
+
? {}
|
|
91
|
+
: { isTTY: options.stdout.isTTY }),
|
|
92
|
+
color: options.env.NO_COLOR === undefined && options.env.TERM !== "dumb",
|
|
93
|
+
}));
|
|
88
94
|
}
|
|
89
95
|
export async function runDeployCommand(options) {
|
|
90
96
|
const boundary = (await findWorkspaceRoot(options.cwd)) ??
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/commands/project.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/commands/project.ts"],"names":[],"mappings":"AA6DA,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAqMF,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAgRjB"}
|
package/dist/commands/project.js
CHANGED
|
@@ -21,6 +21,7 @@ import { randomId } from "../util/ids.js";
|
|
|
21
21
|
import { canonicalJson } from "../util/json.js";
|
|
22
22
|
import { sha512Hex } from "../util/hash.js";
|
|
23
23
|
import { CLI_VERSION } from "../version.js";
|
|
24
|
+
import { renderCommandOutput } from "../cli/terminal.js";
|
|
24
25
|
function object(value) {
|
|
25
26
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26
27
|
}
|
|
@@ -137,7 +138,12 @@ function emit(options, result, human) {
|
|
|
137
138
|
command: options.command,
|
|
138
139
|
...result,
|
|
139
140
|
}) + "\n"
|
|
140
|
-
: human
|
|
141
|
+
: renderCommandOutput(options.command, `${human}\n`, {
|
|
142
|
+
...(options.stdout.isTTY === undefined
|
|
143
|
+
? {}
|
|
144
|
+
: { isTTY: options.stdout.isTTY }),
|
|
145
|
+
color: options.env.NO_COLOR === undefined && options.env.TERM !== "dumb",
|
|
146
|
+
}));
|
|
141
147
|
}
|
|
142
148
|
export async function runProjectCommand(options) {
|
|
143
149
|
const selectors = [];
|