zyrk 0.8.4 → 0.8.6
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 -0
- package/VERSION +1 -1
- package/dist/cli/terminal.d.ts +9 -0
- package/dist/cli/terminal.d.ts.map +1 -1
- package/dist/cli/terminal.js +94 -0
- package/dist/commands/project.d.ts.map +1 -1
- package/dist/commands/project.js +3 -1
- package/dist/lockfile/write.d.ts.map +1 -1
- package/dist/lockfile/write.js +10 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -191,6 +191,12 @@ paths. Older platform-pruned locks need an intentional non-frozen refresh; incom
|
|
|
191
191
|
npm locks must be freshly resolved before portable adoption. macOS, Windows, and
|
|
192
192
|
broad framework compatibility have not passed their release gates.
|
|
193
193
|
|
|
194
|
+
Zyrk writes the npm-compatible lock layout alongside its portable graph. Peer
|
|
195
|
+
dependencies are placed beside or above their consumers, as npm requires. If
|
|
196
|
+
an older Zyrk lock makes `npm ci` report missing peer packages, run
|
|
197
|
+
`zyrk install --lockfile-only` with the updated CLI to refresh that layout
|
|
198
|
+
without installing dependencies or running lifecycle scripts.
|
|
199
|
+
|
|
194
200
|
### Workspaces
|
|
195
201
|
|
|
196
202
|
Standard `package.json` workspaces use one root lock and a recoverable transaction
|
|
@@ -528,3 +534,12 @@ and runs real pinned React, Vite, Vitest, and Tailwind builds and HTTP asset
|
|
|
528
534
|
checks. It uses native zyrk installation with default deny policy. Recorded
|
|
529
535
|
results describe the exact tested versions and platform, without a universal
|
|
530
536
|
framework or cold-install performance claim.
|
|
537
|
+
|
|
538
|
+
### Inspection output
|
|
539
|
+
|
|
540
|
+
Interactive `doctor`, store status/verification, and collection commands use
|
|
541
|
+
command-specific summaries. A failed doctor result is marked as a failure;
|
|
542
|
+
an unavailable audit result is attention, never a clean audit. Store collection
|
|
543
|
+
previews distinguish eligible, retained, removed, and grace-period entries and
|
|
544
|
+
keep physical reclamation explicitly unavailable when it cannot be measured.
|
|
545
|
+
Redirected output and `--json` preserve their existing data contracts.
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v0.8.
|
|
1
|
+
v0.8.6
|
package/dist/cli/terminal.d.ts
CHANGED
|
@@ -2,6 +2,15 @@ export type TerminalStyle = {
|
|
|
2
2
|
isTTY?: boolean;
|
|
3
3
|
color?: boolean;
|
|
4
4
|
};
|
|
5
|
+
export type HumanSummary = {
|
|
6
|
+
tone: "success" | "attention" | "failure" | "status";
|
|
7
|
+
heading: string;
|
|
8
|
+
facts: string[];
|
|
9
|
+
next?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function renderSummary(summary: HumanSummary, style: TerminalStyle): string;
|
|
12
|
+
/** Command facts stay separate from their terminal presentation and JSON data. */
|
|
13
|
+
export declare function commandSummary(command: string, value: Record<string, unknown>): HumanSummary | undefined;
|
|
5
14
|
/** Render command summaries for people while preserving redirected output. */
|
|
6
15
|
export declare function renderCommandOutput(command: string, output: string, style?: TerminalStyle): string;
|
|
7
16
|
/** Make stable CLI diagnostics easier to scan without changing their content. */
|
|
@@ -1 +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;
|
|
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;AAEjE,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,aAAa,CAC3B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,aAAa,GACnB,MAAM,CAQR;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,YAAY,GAAG,SAAS,CAgG1B;AAQD,8EAA8E;AAC9E,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,aAAkB,GACxB,MAAM,CA4BR;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,aAAkB,GACxB,MAAM,CAUR"}
|
package/dist/cli/terminal.js
CHANGED
|
@@ -1,3 +1,94 @@
|
|
|
1
|
+
export function renderSummary(summary, style) {
|
|
2
|
+
const marker = { success: "✓", attention: "!", failure: "✖", status: "›" }[summary.tone];
|
|
3
|
+
const color = { success: 32, attention: 33, failure: 31, status: 2 }[summary.tone];
|
|
4
|
+
return `${paint(marker, color, style)} ${summary.heading}\n${summary.facts.map((fact) => ` ${fact}\n`).join("")}${summary.next ? ` Next: ${summary.next}\n` : ""}`;
|
|
5
|
+
}
|
|
6
|
+
/** Command facts stay separate from their terminal presentation and JSON data. */
|
|
7
|
+
export function commandSummary(command, value) {
|
|
8
|
+
if (command === "doctor" &&
|
|
9
|
+
typeof value.ok === "boolean" &&
|
|
10
|
+
Array.isArray(value.diagnostics)) {
|
|
11
|
+
const diagnostics = value.diagnostics;
|
|
12
|
+
return {
|
|
13
|
+
tone: !value.ok
|
|
14
|
+
? "failure"
|
|
15
|
+
: diagnostics.length
|
|
16
|
+
? "attention"
|
|
17
|
+
: "success",
|
|
18
|
+
heading: !value.ok
|
|
19
|
+
? "Project needs attention"
|
|
20
|
+
: diagnostics.length
|
|
21
|
+
? "Project checks passed with warnings"
|
|
22
|
+
: "Project checks passed",
|
|
23
|
+
facts: diagnostics.length
|
|
24
|
+
? diagnostics.map((d) => `${d.severity}: ${d.code}: ${d.message}`)
|
|
25
|
+
: ["Lock, links, build readiness, and store safety checked."],
|
|
26
|
+
...(!value.ok
|
|
27
|
+
? {
|
|
28
|
+
next: "Review these diagnostics before choosing install or repair.",
|
|
29
|
+
}
|
|
30
|
+
: {}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (command.startsWith("store") && typeof value.initialized === "boolean") {
|
|
34
|
+
return {
|
|
35
|
+
tone: "status",
|
|
36
|
+
heading: value.initialized
|
|
37
|
+
? "Shared store status"
|
|
38
|
+
: "Shared store is not initialized",
|
|
39
|
+
facts: value.initialized
|
|
40
|
+
? [
|
|
41
|
+
`Retention roots: ${value.retentionRoots ?? "unavailable"}`,
|
|
42
|
+
`Logical bytes: ${value.logicalBytes ?? "unavailable"}`,
|
|
43
|
+
`Allocated bytes estimate: ${value.allocatedBytesEstimate ?? "unavailable"}`,
|
|
44
|
+
String(value.allocationMethod ??
|
|
45
|
+
"Physical allocation measurement unavailable."),
|
|
46
|
+
"Private builds, fetch caches, and exclusive reclaimable bytes are not measured here.",
|
|
47
|
+
]
|
|
48
|
+
: ["No store content has been inspected."],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (command.startsWith("store") && value.verified === true)
|
|
52
|
+
return {
|
|
53
|
+
tone: "success",
|
|
54
|
+
heading: "Shared store verification passed",
|
|
55
|
+
facts: [
|
|
56
|
+
`Sources: ${value.sources}; objects: ${value.objects}; realizations: ${value.realizations}`,
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
if (command.startsWith("store") &&
|
|
60
|
+
typeof value.dryRun === "boolean" &&
|
|
61
|
+
Array.isArray(value.candidates))
|
|
62
|
+
return {
|
|
63
|
+
tone: "status",
|
|
64
|
+
heading: value.dryRun
|
|
65
|
+
? "Store collection preview"
|
|
66
|
+
: "Store collection complete",
|
|
67
|
+
facts: [
|
|
68
|
+
`Eligible entries: ${value.candidates.length}; removed: ${value.removed}; retained: ${value.retained}`,
|
|
69
|
+
`Within grace period: ${value.graceRetained}`,
|
|
70
|
+
`Selected logical bytes: ${value.logicalBytesSelected}; physical bytes reclaimed: ${value.physicalBytesReclaimed}`,
|
|
71
|
+
...(Array.isArray(value.retentionReasons)
|
|
72
|
+
? value.retentionReasons.map(String)
|
|
73
|
+
: []),
|
|
74
|
+
],
|
|
75
|
+
...(value.dryRun
|
|
76
|
+
? { next: "Review eligibility; run zyrk store gc to apply collection." }
|
|
77
|
+
: {}),
|
|
78
|
+
};
|
|
79
|
+
if (value.status === "unavailable")
|
|
80
|
+
return {
|
|
81
|
+
tone: "attention",
|
|
82
|
+
heading: `${command} is unavailable`,
|
|
83
|
+
facts: [
|
|
84
|
+
"No clean result can be established.",
|
|
85
|
+
...Object.entries(value)
|
|
86
|
+
.filter(([key]) => !["schemaVersion", "status", "command"].includes(key))
|
|
87
|
+
.map(([key, item]) => `${key}: ${JSON.stringify(item)}`),
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
1
92
|
function paint(value, code, style) {
|
|
2
93
|
return style.isTTY && style.color !== false
|
|
3
94
|
? `\u001b[${code}m${value}\u001b[0m`
|
|
@@ -15,6 +106,9 @@ export function renderCommandOutput(command, output, style = {}) {
|
|
|
15
106
|
value = undefined;
|
|
16
107
|
}
|
|
17
108
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
109
|
+
const semantic = commandSummary(command, value);
|
|
110
|
+
if (semantic)
|
|
111
|
+
return renderSummary(semantic, style);
|
|
18
112
|
const summary = { ...value };
|
|
19
113
|
delete summary.schemaVersion;
|
|
20
114
|
delete summary.status;
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AA2MF,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAgRjB"}
|
package/dist/commands/project.js
CHANGED
|
@@ -138,7 +138,9 @@ function emit(options, result, human) {
|
|
|
138
138
|
command: options.command,
|
|
139
139
|
...result,
|
|
140
140
|
}) + "\n"
|
|
141
|
-
: renderCommandOutput(options.command,
|
|
141
|
+
: renderCommandOutput(options.command, options.command === "doctor" && options.stdout.isTTY
|
|
142
|
+
? JSON.stringify(result)
|
|
143
|
+
: `${human}\n`, {
|
|
142
144
|
...(options.stdout.isTTY === undefined
|
|
143
145
|
? {}
|
|
144
146
|
: { isTTY: options.stdout.isTTY }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/lockfile/write.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGjE,OAAO,EAGL,KAAK,UAAU,EAGhB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,mBAAmB,CAAC;IAChC,YAAY,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,eAAe,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACzB,CAAC;AAEF,wBAAsB,aAAa,CACjC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/lockfile/write.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGjE,OAAO,EAGL,KAAK,UAAU,EAGhB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,mBAAmB,CAAC;IAChC,YAAY,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,eAAe,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACzB,CAAC;AAEF,wBAAsB,aAAa,CACjC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAiQrB"}
|
package/dist/lockfile/write.js
CHANGED
|
@@ -123,13 +123,19 @@ export async function writeLockfile(options) {
|
|
|
123
123
|
...node.platform,
|
|
124
124
|
...(node.engines === undefined ? {} : { engines: node.engines }),
|
|
125
125
|
};
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
// Establish peers before descending into ordinary children. A peer must be
|
|
127
|
+
// visible beside or above its consumer; its own node_modules is invalid to
|
|
128
|
+
// npm even if that directory already contains the requested version.
|
|
129
|
+
const placementEdges = [...node.edges].sort((a, b) => Number(b.kind === "peer") - Number(a.kind === "peer"));
|
|
130
|
+
for (const edge of placementEdges) {
|
|
131
|
+
const base = edge.kind === "peer"
|
|
132
|
+
? location.slice(0, Math.max(0, location.lastIndexOf("/node_modules/")))
|
|
133
|
+
: location;
|
|
134
|
+
const found = lookup(base, edge.name);
|
|
128
135
|
if (found !== undefined && placements.get(found) === edge.target)
|
|
129
136
|
continue;
|
|
130
137
|
if (edge.kind === "peer") {
|
|
131
|
-
|
|
132
|
-
populate(`${parent}node_modules/${edge.name}`, edge.target);
|
|
138
|
+
populate(`${base ? `${base}/` : ""}node_modules/${edge.name}`, edge.target);
|
|
133
139
|
}
|
|
134
140
|
else {
|
|
135
141
|
populate(`${location}/node_modules/${edge.name}`, edge.target);
|