@visulima/vis 1.0.0-alpha.11 → 1.0.0-alpha.12

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 (116) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/LICENSE.md +559 -186
  3. package/README.md +18 -0
  4. package/dist/bin.js +1 -9
  5. package/dist/config/index.d.ts +477 -556
  6. package/dist/config/index.js +1 -2
  7. package/dist/generate/index.js +1 -3
  8. package/dist/packem_chunks/applyDefaults.js +2 -336
  9. package/dist/packem_chunks/bin.js +234 -9552
  10. package/dist/packem_chunks/doctor-probe.js +2 -112
  11. package/dist/packem_chunks/fix.js +11 -234
  12. package/dist/packem_chunks/handler.js +1 -99
  13. package/dist/packem_chunks/handler10.js +2 -53
  14. package/dist/packem_chunks/handler11.js +1 -32
  15. package/dist/packem_chunks/handler12.js +5 -100
  16. package/dist/packem_chunks/handler13.js +1 -25
  17. package/dist/packem_chunks/handler14.js +18 -916
  18. package/dist/packem_chunks/handler15.js +15 -201
  19. package/dist/packem_chunks/handler16.js +1 -124
  20. package/dist/packem_chunks/handler17.js +1 -13
  21. package/dist/packem_chunks/handler18.js +1 -106
  22. package/dist/packem_chunks/handler19.js +1 -19
  23. package/dist/packem_chunks/handler2.js +2 -75
  24. package/dist/packem_chunks/handler20.js +5 -29
  25. package/dist/packem_chunks/handler21.js +1 -222
  26. package/dist/packem_chunks/handler22.js +1 -237
  27. package/dist/packem_chunks/handler23.js +5 -101
  28. package/dist/packem_chunks/handler24.js +1 -110
  29. package/dist/packem_chunks/handler25.js +3 -402
  30. package/dist/packem_chunks/handler26.js +1 -13
  31. package/dist/packem_chunks/handler27.js +1 -63
  32. package/dist/packem_chunks/handler28.js +7 -34
  33. package/dist/packem_chunks/handler29.js +21 -456
  34. package/dist/packem_chunks/handler3.js +4 -95
  35. package/dist/packem_chunks/handler30.js +3 -170
  36. package/dist/packem_chunks/handler31.js +1 -530
  37. package/dist/packem_chunks/handler32.js +2 -214
  38. package/dist/packem_chunks/handler33.js +25 -119
  39. package/dist/packem_chunks/handler34.js +2 -630
  40. package/dist/packem_chunks/handler35.js +3 -283
  41. package/dist/packem_chunks/handler36.js +22 -542
  42. package/dist/packem_chunks/handler37.js +410 -744
  43. package/dist/packem_chunks/handler38.js +22 -989
  44. package/dist/packem_chunks/handler39.js +22 -574
  45. package/dist/packem_chunks/handler4.js +2 -90
  46. package/dist/packem_chunks/handler40.js +22 -1685
  47. package/dist/packem_chunks/handler41.js +6 -1088
  48. package/dist/packem_chunks/handler42.js +5 -797
  49. package/dist/packem_chunks/handler43.js +10 -2658
  50. package/dist/packem_chunks/handler44.js +51 -3784
  51. package/dist/packem_chunks/handler45.js +25 -2574
  52. package/dist/packem_chunks/handler46.js +3 -3769
  53. package/dist/packem_chunks/handler47.js +21 -1485
  54. package/dist/packem_chunks/handler48.js +42 -0
  55. package/dist/packem_chunks/handler5.js +8 -174
  56. package/dist/packem_chunks/handler6.js +1 -95
  57. package/dist/packem_chunks/handler7.js +1 -115
  58. package/dist/packem_chunks/handler8.js +1 -12
  59. package/dist/packem_chunks/handler9.js +1 -29
  60. package/dist/packem_chunks/heal-accept.js +10 -522
  61. package/dist/packem_chunks/heal.js +14 -673
  62. package/dist/packem_chunks/index.js +7 -873
  63. package/dist/packem_chunks/loader.js +1 -23
  64. package/dist/packem_chunks/tar.js +3 -0
  65. package/dist/packem_shared/ai-analysis-hm8d2W7z.js +67 -0
  66. package/dist/packem_shared/ai-cache-DoiF80AR.js +1 -0
  67. package/dist/packem_shared/ai-fix-nn4zOE95.js +43 -0
  68. package/dist/packem_shared/cache-directory-CwHlJhgx.js +1 -0
  69. package/dist/packem_shared/dependency-scan-COr5n63B.js +2 -0
  70. package/dist/packem_shared/docker-D6OGr5_S.js +2 -0
  71. package/dist/packem_shared/failure-log-iUVLf6ts.js +2 -0
  72. package/dist/packem_shared/flakiness-D9wf0t56.js +1 -0
  73. package/dist/packem_shared/giget-CcEy_Elm.js +2 -0
  74. package/dist/packem_shared/index-DH-5hsrC.js +1 -0
  75. package/dist/packem_shared/otel-DxDUPJJH.js +6 -0
  76. package/dist/packem_shared/otelPlugin-CQq6poq8.js +1 -0
  77. package/dist/packem_shared/registry-CkubDdiY.js +2 -0
  78. package/dist/packem_shared/run-summary-utils-BfBvjzhY.js +1 -0
  79. package/dist/packem_shared/runtime-check-BXZ43CBW.js +1 -0
  80. package/dist/packem_shared/selectors-BylODRiM.js +3 -0
  81. package/dist/packem_shared/symbols-CQmER5MT.js +1 -0
  82. package/dist/packem_shared/toolchain-BgBOUHII.js +5 -0
  83. package/dist/packem_shared/typosquats-CcZl99B1.js +1 -0
  84. package/dist/packem_shared/use-measured-height-DjYgUOKk.js +1 -0
  85. package/dist/packem_shared/utils-DrNg0XTR.js +1 -0
  86. package/dist/packem_shared/verify-Baj5mFJ7.js +1 -0
  87. package/dist/packem_shared/vis-update-app-D1jl0UZZ.js +1 -0
  88. package/dist/packem_shared/xxh3-DrAUNq4n.js +1 -0
  89. package/index.js +556 -727
  90. package/package.json +19 -29
  91. package/schemas/project.schema.json +739 -297
  92. package/schemas/vis-config.schema.json +3365 -384
  93. package/templates/buildkite-ci/template.yml +20 -20
  94. package/dist/packem_shared/VisUpdateApp-D-Yz_wvg.js +0 -1316
  95. package/dist/packem_shared/_commonjsHelpers-BqLXS_qQ.js +0 -5
  96. package/dist/packem_shared/ai-analysis-CHeB1joD.js +0 -367
  97. package/dist/packem_shared/ai-cache-Be_jexe4.js +0 -142
  98. package/dist/packem_shared/ai-fix-B9iQVcD2.js +0 -379
  99. package/dist/packem_shared/cache-directory-2qvs4goY.js +0 -98
  100. package/dist/packem_shared/catalog-BJTtyi-O.js +0 -1371
  101. package/dist/packem_shared/dependency-scan-A0KSklpG.js +0 -188
  102. package/dist/packem_shared/docker-2iZzc280.js +0 -181
  103. package/dist/packem_shared/failure-log-Cz3Z4SKL.js +0 -100
  104. package/dist/packem_shared/flakiness-goTxXuCX.js +0 -180
  105. package/dist/packem_shared/otel-DCvqCTz_.js +0 -158
  106. package/dist/packem_shared/otelPlugin-DFaLDvJf.js +0 -3
  107. package/dist/packem_shared/registry-CbqXI0rc.js +0 -272
  108. package/dist/packem_shared/run-summary-utils-PVMl4aIh.js +0 -130
  109. package/dist/packem_shared/runtime-check-Cobi3p6l.js +0 -127
  110. package/dist/packem_shared/selectors-SM69TfqC.js +0 -194
  111. package/dist/packem_shared/symbols-Ta7g2nU-.js +0 -14
  112. package/dist/packem_shared/toolchain-BdZd9eBi.js +0 -975
  113. package/dist/packem_shared/typosquats-C-bCh3PX.js +0 -1210
  114. package/dist/packem_shared/use-measured-height-CNP0vT4M.js +0 -20
  115. package/dist/packem_shared/utils-CthVdBPS.js +0 -40
  116. package/dist/packem_shared/xxh3-Ck8mXNg1.js +0 -239
@@ -1,222 +1 @@
1
- import { readLastRunSummary } from '@visulima/task-runner';
2
- import { p as pail } from './bin.js';
3
- import { l as listRunSummaries, r as readRunSummaryById } from '../packem_shared/run-summary-utils-PVMl4aIh.js';
4
-
5
- const VALID_FORMATS = /* @__PURE__ */ new Set(["json", "table"]);
6
- const resolveWorkspaceRoot = (workspaceRoot) => workspaceRoot ?? process.cwd();
7
- const formatDuration = (ms) => {
8
- if (ms === void 0) {
9
- return "-";
10
- }
11
- if (ms < 1e3) {
12
- return `${String(ms)}ms`;
13
- }
14
- return `${(ms / 1e3).toFixed(2)}s`;
15
- };
16
- const formatStatus = (task) => {
17
- if (task.exitCode === void 0) {
18
- return task.cacheStatus;
19
- }
20
- if (task.exitCode === 0) {
21
- return task.cacheStatus === "MISS" ? "OK" : task.cacheStatus;
22
- }
23
- return `FAIL(${String(task.exitCode)})`;
24
- };
25
- const padCell = (value, width) => {
26
- if (value.length >= width) {
27
- return value;
28
- }
29
- return value + " ".repeat(width - value.length);
30
- };
31
- const isFailedTask = (task) => task.exitCode !== void 0 && task.exitCode !== 0;
32
- const renderRunHeader = (summary, logger) => {
33
- logger.info(`Run ${summary.id}`);
34
- logger.info(` start: ${summary.startTime}`);
35
- logger.info(` end: ${summary.endTime}`);
36
- logger.info(` duration: ${formatDuration(summary.duration)}`);
37
- logger.info(
38
- ` totals: ${String(summary.stats.total)} total · ${String(summary.stats.succeeded)} ok · ${String(summary.stats.cached)} cached · ${String(summary.stats.skipped)} skipped · ${String(summary.stats.failed)} failed`
39
- );
40
- logger.info(` env: node ${summary.environment.nodeVersion} · ${summary.environment.platform}/${summary.environment.arch}`);
41
- logger.info("");
42
- };
43
- const renderTaskTable = (tasks, logger) => {
44
- if (tasks.length === 0) {
45
- logger.info("(no tasks match the current filter)");
46
- return;
47
- }
48
- const rows = tasks.map((task) => ({
49
- duration: formatDuration(task.duration),
50
- hash: task.hash ? task.hash.slice(0, 12) : "-",
51
- status: formatStatus(task),
52
- taskId: task.taskId
53
- }));
54
- const widths = {
55
- duration: Math.max("duration".length, ...rows.map((r) => r.duration.length)),
56
- hash: Math.max("hash".length, ...rows.map((r) => r.hash.length)),
57
- status: Math.max("status".length, ...rows.map((r) => r.status.length)),
58
- taskId: Math.max("task".length, ...rows.map((r) => r.taskId.length))
59
- };
60
- logger.info(
61
- ` ${padCell("task", widths.taskId)} ${padCell("status", widths.status)} ${padCell("duration", widths.duration)} ${padCell("hash", widths.hash)}`
62
- );
63
- logger.info(` ${"-".repeat(widths.taskId)} ${"-".repeat(widths.status)} ${"-".repeat(widths.duration)} ${"-".repeat(widths.hash)}`);
64
- for (const row of rows) {
65
- logger.info(
66
- ` ${padCell(row.taskId, widths.taskId)} ${padCell(row.status, widths.status)} ${padCell(row.duration, widths.duration)} ${padCell(row.hash, widths.hash)}`
67
- );
68
- }
69
- };
70
- const renderTaskDetail = (summary, task, logger) => {
71
- renderRunHeader(summary, logger);
72
- logger.info(`Task ${task.taskId}`);
73
- logger.info(` status: ${formatStatus(task)}`);
74
- logger.info(` cache: ${task.cacheStatus}`);
75
- logger.info(` duration: ${formatDuration(task.duration)}`);
76
- logger.info(` exit: ${task.exitCode === void 0 ? "-" : String(task.exitCode)}`);
77
- logger.info(` hash: ${task.hash ?? "(none)"}`);
78
- logger.info(` start: ${task.startTime ?? "-"}`);
79
- logger.info(` end: ${task.endTime ?? "-"}`);
80
- if (task.dependencies.length > 0) {
81
- logger.info(` deps: ${task.dependencies.join(", ")}`);
82
- }
83
- logger.info("");
84
- pail.info(`Drill into hash inputs with: vis cache why ${task.taskId} --run ${summary.id}`);
85
- };
86
- const renderListJson = (entries) => {
87
- process.stdout.write(
88
- `${JSON.stringify(
89
- entries.map((entry) => ({
90
- id: entry.id,
91
- mtime: new Date(entry.mtimeMs).toISOString(),
92
- path: entry.path
93
- })),
94
- void 0,
95
- 2
96
- )}
97
- `
98
- );
99
- };
100
- const renderListTable = (entries, logger) => {
101
- if (entries.length === 0) {
102
- pail.info("No recorded runs found in .task-runner/runs/. Run with --summarize to record a run.");
103
- return;
104
- }
105
- const widths = {
106
- id: Math.max("id".length, ...entries.map((entry) => entry.id.length)),
107
- mtime: 24
108
- };
109
- logger.info(` ${padCell("id", widths.id)} ${padCell("mtime", widths.mtime)}`);
110
- logger.info(` ${"-".repeat(widths.id)} ${"-".repeat(widths.mtime)}`);
111
- for (const entry of entries) {
112
- logger.info(` ${padCell(entry.id, widths.id)} ${new Date(entry.mtimeMs).toISOString()}`);
113
- }
114
- };
115
- const filterTasks = (summary, options) => {
116
- let tasks = summary.tasks;
117
- if (options.task !== void 0) {
118
- tasks = tasks.filter((t) => t.taskId === options.task);
119
- }
120
- if (options.failed) {
121
- tasks = tasks.filter((t) => isFailedTask(t));
122
- }
123
- return tasks;
124
- };
125
- const runReplay = async (options, logger) => {
126
- const { failed, format, runId, task: taskFilter, workspaceRoot } = options;
127
- const summary = runId === void 0 ? await readLastRunSummary(workspaceRoot) : await readRunSummaryById(workspaceRoot, runId);
128
- if (!summary) {
129
- if (format === "json") {
130
- process.stdout.write(`${JSON.stringify({ error: "no-summary", runId: runId ?? null }, void 0, 2)}
131
- `);
132
- process.exitCode = 1;
133
- return;
134
- }
135
- if (runId === void 0) {
136
- pail.error("No previous run summary found. Run a task first to populate `.task-runner/last-summary.json`.");
137
- } else {
138
- pail.error(`Run summary "${runId}" not found in .task-runner/runs/.`);
139
- }
140
- process.exitCode = 1;
141
- return;
142
- }
143
- const filteredTasks = filterTasks(summary, { failed, task: taskFilter });
144
- if (taskFilter !== void 0 && filteredTasks.length === 0) {
145
- if (format === "json") {
146
- process.stdout.write(`${JSON.stringify({ error: "task-not-in-summary", runId: summary.id, taskId: taskFilter }, void 0, 2)}
147
- `);
148
- process.exitCode = 1;
149
- return;
150
- }
151
- pail.error(`Task "${taskFilter}" was not part of run ${summary.id}.`);
152
- process.exitCode = 1;
153
- return;
154
- }
155
- if (summary.stats.failed > 0) {
156
- process.exitCode = 1;
157
- }
158
- if (format === "json") {
159
- process.stdout.write(
160
- `${JSON.stringify(
161
- {
162
- duration: summary.duration,
163
- endTime: summary.endTime,
164
- environment: summary.environment,
165
- runId: summary.id,
166
- startTime: summary.startTime,
167
- stats: summary.stats,
168
- tasks: filteredTasks.map((t) => ({
169
- cacheStatus: t.cacheStatus,
170
- dependencies: t.dependencies,
171
- duration: t.duration,
172
- endTime: t.endTime,
173
- exitCode: t.exitCode,
174
- hash: t.hash ?? null,
175
- startTime: t.startTime,
176
- taskId: t.taskId
177
- }))
178
- },
179
- void 0,
180
- 2
181
- )}
182
- `
183
- );
184
- return;
185
- }
186
- if (taskFilter !== void 0) {
187
- renderTaskDetail(summary, filteredTasks[0], logger);
188
- return;
189
- }
190
- renderRunHeader(summary, logger);
191
- renderTaskTable(filteredTasks, logger);
192
- };
193
- const replayExecute = async ({ logger, options, workspaceRoot: wsRoot }) => {
194
- const workspaceRoot = resolveWorkspaceRoot(wsRoot);
195
- const format = options.format ?? "table";
196
- if (!VALID_FORMATS.has(format)) {
197
- pail.error(`Invalid --format: ${format}. Expected "table" or "json".`);
198
- process.exitCode = 1;
199
- return;
200
- }
201
- if (options.list === true) {
202
- const entries = await listRunSummaries(workspaceRoot);
203
- if (format === "json") {
204
- renderListJson(entries);
205
- return;
206
- }
207
- renderListTable(entries, logger);
208
- return;
209
- }
210
- await runReplay(
211
- {
212
- failed: options.failed === true,
213
- format,
214
- runId: options.run,
215
- task: options.task,
216
- workspaceRoot
217
- },
218
- logger
219
- );
220
- };
221
-
222
- export { replayExecute as default, replayExecute, runReplay };
1
+ var T=Object.defineProperty;var y=(e,t)=>T(e,"name",{value:t,configurable:!0});import{createRequire as C}from"node:module";import{green as f,red as v,dim as J,yellow as _}from"@visulima/colorize";import{isAccessibleSync as M,readJsonSync as P}from"@visulima/fs";import{join as b}from"@visulima/path";import{enforceProjectConstraints as V}from"@visulima/task-runner";import{k as z,y as A}from"./bin.js";import{a as B}from"../packem_shared/flakiness-D9wf0t56.js";import{c as I}from"../packem_shared/runtime-check-BXZ43CBW.js";const q=C(import.meta.url),n=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,x=y(e=>{if(typeof n<"u"&&n.versions&&n.versions.node){const[t,i]=n.versions.node.split(".").map(Number);if(t>22||t===22&&i>=3||t===20&&i>=16)return n.getBuiltinModule(e)}return q(e)},"__cjs_getBuiltinModule"),{readdirSync:F}=x("node:fs");var K=Object.defineProperty,O=y((e,t)=>K(e,"name",{value:t,configurable:!0}),"h");const r=O(e=>e?f("✓"):v("✗"),"icon"),X=O(async({logger:e,options:t,visConfig:i,workspaceRoot:o})=>{if(!o)throw new Error("Could not determine workspace root.");const{config:j,packageJsons:w,workspace:u}=z(o,i),R=A(o,u,w),k=Object.keys(u.projects).length,$=new Set(Object.values(u.projects).flatMap(p=>Object.keys(p.targets??{}))).size,a=I(o);let s=0;j.constraints&&(s=V(R,j.constraints).length);const c=B(o,{minRuns:2});let l;const g=b(o,".task-runner","runs");if(M(g)){const p=F(g).filter(d=>d.endsWith(".json")).sort();let m=0,S=0;for(const d of p.slice(-20))try{const h=P(b(g,d));h.stats&&(m+=h.stats.total??0,S+=h.stats.cached??0)}catch{continue}m>0&&(l=`${(S/m*100).toFixed(0)}%`)}if(t.json){e.info(JSON.stringify({cacheHitRate:l??null,constraintViolations:s,flakyTasks:c.length,projects:k,runtimeIssues:a.length,targets:$},null,2));return}e.info(""),e.info(` ${J("VIS STATUS")}`),e.info(""),e.info(` ${r(!0)} ${String(k)} projects · ${String($)} unique targets`),e.info(` ${r(a.length===0)} Runtime: ${a.length===0?f("OK"):_(`${String(a.length)} issue(s)`)}`),e.info(` ${r(s===0)} Constraints: ${s===0?f("OK"):v(`${String(s)} violation(s)`)}`),e.info(` ${r(c.length===0)} Flaky tasks: ${c.length===0?f("none"):_(String(c.length))}`),l&&e.info(` ${r(!0)} Cache hit rate: ${l} (last 20 runs)`),e.info("")},"execute");export{X as default};
@@ -1,237 +1 @@
1
- import { createRequire as __cjs_createRequire } from "node:module";
2
-
3
- const __cjs_require = __cjs_createRequire(import.meta.url);
4
-
5
- const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
6
-
7
- const __cjs_getBuiltinModule = (module) => {
8
- // Check if we're in Node.js and version supports getBuiltinModule
9
- if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
10
- const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
11
- // Node.js 20.16.0+ and 22.3.0+
12
- if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
13
- return __cjs_getProcess.getBuiltinModule(module);
14
- }
15
- }
16
- // Fallback to createRequire
17
- return __cjs_require(module);
18
- };
19
-
20
- const {
21
- writeFileSync
22
- } = __cjs_getBuiltinModule("node:fs");
23
- import { readFileSync, isAccessibleSync } from '@visulima/fs';
24
- import { join, relative, basename, resolve } from '@visulima/path';
25
- import zeptomatch from 'zeptomatch';
26
- import { sortPackageJsonStringWithOptions } from '#native';
27
- import { p as pail, q as readPnpmWorkspacePatterns, o as resolveWorkspacePatterns } from './bin.js';
28
- import { e as errorMessage } from '../packem_shared/utils-CthVdBPS.js';
29
-
30
- const findPackageJsonFiles = (root) => {
31
- const seen = /* @__PURE__ */ new Set();
32
- const results = [];
33
- const addFile = (filePath) => {
34
- const resolved = resolve(filePath);
35
- if (!seen.has(resolved) && isAccessibleSync(resolved)) {
36
- seen.add(resolved);
37
- results.push(resolved);
38
- }
39
- };
40
- addFile(join(root, "package.json"));
41
- const pnpmPatterns = readPnpmWorkspacePatterns(root);
42
- if (pnpmPatterns) {
43
- const projectDirectories = resolveWorkspacePatterns(root, pnpmPatterns);
44
- for (const dir of projectDirectories) {
45
- addFile(join(root, dir, "package.json"));
46
- }
47
- } else {
48
- const rootPkgPath = join(root, "package.json");
49
- if (isAccessibleSync(rootPkgPath)) {
50
- const rootPkg = JSON.parse(readFileSync(rootPkgPath));
51
- const patterns = Array.isArray(rootPkg.workspaces) ? rootPkg.workspaces : rootPkg.workspaces?.packages;
52
- if (patterns) {
53
- const projectDirectories = resolveWorkspacePatterns(root, patterns);
54
- for (const dir of projectDirectories) {
55
- addFile(join(root, dir, "package.json"));
56
- }
57
- }
58
- }
59
- }
60
- return results;
61
- };
62
- const detectIndent = (contents) => {
63
- const match = /\n([ \t]+)/.exec(contents);
64
- return match?.[1] ?? " ";
65
- };
66
- const resolveIndentOverride = (raw) => {
67
- if (raw === void 0 || raw === "") {
68
- return void 0;
69
- }
70
- if (raw === "tab" || raw === String.raw`\t`) {
71
- return " ";
72
- }
73
- if (/^\d+$/.test(raw)) {
74
- return " ".repeat(Number.parseInt(raw, 10));
75
- }
76
- return raw;
77
- };
78
- const splitList = (raw) => {
79
- if (raw === void 0) {
80
- return [];
81
- }
82
- const items = Array.isArray(raw) ? raw : [raw];
83
- return items.flatMap((item) => item.split(",")).map((item) => item.trim()).filter((item) => item.length > 0);
84
- };
85
- const detectLineEnding = (contents) => contents.includes("\r\n") ? "crlf" : "lf";
86
- const ALLOWED_LINE_ENDINGS = /* @__PURE__ */ new Set(["auto", "crlf", "lf"]);
87
- const validateLineEnding = (raw) => {
88
- if (raw === void 0 || raw === "") {
89
- return "auto";
90
- }
91
- if (ALLOWED_LINE_ENDINGS.has(raw)) {
92
- return raw;
93
- }
94
- pail.error(`--line-ending must be one of: auto, lf, crlf (got "${raw}")`);
95
- process.exit(2);
96
- };
97
- const filterByIgnore = (files, patterns, cwd) => {
98
- if (patterns.length === 0) {
99
- return files;
100
- }
101
- return files.filter((absolute) => {
102
- const relPath = relative(cwd, absolute);
103
- const base = basename(absolute);
104
- return !patterns.some((pattern) => {
105
- const target = pattern.includes("/") ? relPath : base;
106
- return zeptomatch(pattern, target);
107
- });
108
- });
109
- };
110
- const applySortOrder = (object, sortOrder) => {
111
- if (sortOrder.length === 0) {
112
- return object;
113
- }
114
- const result = {};
115
- const consumed = /* @__PURE__ */ new Set();
116
- for (const key of sortOrder) {
117
- if (Object.hasOwn(object, key)) {
118
- result[key] = object[key];
119
- consumed.add(key);
120
- }
121
- }
122
- for (const key of Object.keys(object)) {
123
- if (!consumed.has(key)) {
124
- result[key] = object[key];
125
- }
126
- }
127
- return result;
128
- };
129
- const restoreUnsortedSections = (sorted, original, unsorted) => {
130
- if (unsorted.length === 0) {
131
- return sorted;
132
- }
133
- const result = { ...sorted };
134
- for (const key of unsorted) {
135
- if (Object.hasOwn(original, key)) {
136
- result[key] = original[key];
137
- }
138
- }
139
- return result;
140
- };
141
- const sortContents = (contents, config) => {
142
- const indent = config.indent ?? detectIndent(contents);
143
- const lineEnding = config.lineEnding === "auto" ? detectLineEnding(contents) : config.lineEnding;
144
- const compact = sortPackageJsonStringWithOptions(contents, {
145
- pretty: false,
146
- sortScripts: config.sortScripts
147
- });
148
- let parsed = JSON.parse(compact);
149
- if (config.unsorted.length > 0) {
150
- const original = JSON.parse(contents);
151
- parsed = restoreUnsortedSections(parsed, original, config.unsorted);
152
- }
153
- parsed = applySortOrder(parsed, config.sortOrder);
154
- let output = JSON.stringify(parsed, null, indent);
155
- if (config.finalNewline) {
156
- output += "\n";
157
- }
158
- if (lineEnding === "crlf") {
159
- output = output.replaceAll("\n", "\r\n");
160
- }
161
- return output;
162
- };
163
- const execute = async ({ options, visConfig, workspaceRoot: wsRoot }) => {
164
- const cwd = wsRoot ?? process.cwd();
165
- const config = visConfig?.["sortPackageJson"];
166
- const check = options.check || false;
167
- const normalized = {
168
- finalNewline: options.finalNewline ?? config?.finalNewline ?? true,
169
- ignore: [...splitList(options.ignore), ...config?.ignore ?? []],
170
- indent: resolveIndentOverride(options.indent ?? config?.indent),
171
- lineEnding: validateLineEnding(options.lineEnding ?? config?.lineEnding),
172
- sortOrder: [...splitList(options.sortOrder), ...config?.sortOrder ?? []],
173
- sortScripts: options.sortScripts || config?.sortScripts || false,
174
- unsorted: [...splitList(options.unsorted), ...config?.unsorted ?? []]
175
- };
176
- const allFiles = findPackageJsonFiles(cwd);
177
- const files = filterByIgnore(allFiles, normalized.ignore, cwd);
178
- if (files.length === 0) {
179
- pail.info(allFiles.length === 0 ? "No package.json files found." : "All package.json files were excluded by --ignore.");
180
- return;
181
- }
182
- let unsortedCount = 0;
183
- let sortedCount = 0;
184
- let errorCount = 0;
185
- for (const filePath of files) {
186
- try {
187
- const contents = readFileSync(filePath);
188
- let sorted;
189
- try {
190
- sorted = sortContents(contents, normalized);
191
- } catch (error) {
192
- pail.error(`${filePath}: ${errorMessage(error)}`);
193
- errorCount++;
194
- continue;
195
- }
196
- if (contents === sorted) {
197
- sortedCount++;
198
- continue;
199
- }
200
- unsortedCount++;
201
- if (check) {
202
- pail.warn(`${filePath} is not sorted`);
203
- } else {
204
- writeFileSync(filePath, sorted, "utf8");
205
- pail.success(`Sorted ${filePath}`);
206
- }
207
- } catch (error) {
208
- pail.error(`${filePath}: ${errorMessage(error)}`);
209
- errorCount++;
210
- }
211
- }
212
- if (check) {
213
- if (unsortedCount > 0) {
214
- pail.info(`${unsortedCount} file${unsortedCount === 1 ? "" : "s"} not sorted, ${sortedCount} already sorted`);
215
- process.exitCode = 1;
216
- } else {
217
- pail.info(`All ${sortedCount} package.json file${sortedCount === 1 ? " is" : "s are"} sorted`);
218
- }
219
- } else {
220
- const parts = [];
221
- if (unsortedCount > 0) {
222
- parts.push(`sorted ${unsortedCount} file${unsortedCount === 1 ? "" : "s"}`);
223
- }
224
- if (sortedCount > 0) {
225
- parts.push(`${sortedCount} already sorted`);
226
- }
227
- if (errorCount > 0) {
228
- parts.push(`${errorCount} error${errorCount === 1 ? "" : "s"}`);
229
- }
230
- pail.info(parts.join(", "));
231
- }
232
- if (errorCount > 0) {
233
- process.exitCode = 1;
234
- }
235
- };
236
-
237
- export { execute as default };
1
+ var y=Object.defineProperty;var j=(t,e)=>y(t,"name",{value:e,configurable:!0});import{createTaskGraph as b}from"@visulima/task-runner";import{k as v,y as E}from"./bin.js";var T=Object.defineProperty,u=j((t,e)=>T(t,"name",{value:e,configurable:!0}),"h");const O=u((t,e)=>{const s=new Map;for(const[i,r]of Object.entries(t.dependencies))for(const f of r){const c=s.get(f)??[];c.push(i),s.set(f,c)}if(!t.tasks[e])return;const a=new Set([e]),o=[{node:e,path:[e]}];for(;o.length>0;){const i=o.shift();if(t.roots.includes(i.node))return i.path;for(const r of s.get(i.node)??[])a.has(r)||(a.add(r),o.push({node:r,path:[r,...i.path]}))}return[e]},"findShortestPathToRoot"),x=u((t,e)=>{const s=[];for(const[a,o]of Object.entries(t.dependencies))o.includes(e)&&s.push(a);return s.sort()},"collectParents"),I=u(async({argument:t,logger:e,visConfig:s,workspaceRoot:a})=>{if(!a)throw new Error("Could not determine workspace root.");const o=t[0];if(!o)throw new Error("No task ID specified. Usage: vis task-why <project>:<target>");if(!o.includes(":"))throw new Error(`Invalid task ID "${o}" — expected format "project:target".`);const{packageJsons:i,workspace:r}=v(a,s),f=E(a,r,i),[c,w]=o.split(":",2),$=r.projects[c];if(!$)throw new Error(`Unknown project "${c}".`);if(!$.targets?.[w])throw new Error(`Project "${c}" has no target "${w}".`);const m=Object.entries(r.projects).flatMap(([n,k])=>Object.keys(k.targets??{}).map(h=>({id:`${n}:${h}`,outputs:[],overrides:{},target:{project:n,target:h}}))),p=b(m,{projectGraph:f,workspace:r});if(!p.tasks[o])throw new Error(`Task "${o}" is not reachable in the graph.`);const d=O(p,o),g=x(p,o);if(e.info(""),e.info(`Why ${o}?`),e.info(""),d&&d.length>1){e.info("Shortest path from a root to this task:");for(const[n,k]of d.entries()){const h=n===0?" ":`${" ".repeat(n+1)}└─ `;e.info(`${h}${k}`)}e.info("")}else e.info(" This task is itself a root — nothing upstream depends on it."),e.info("");if(g.length>0){e.info(`Directly depended on by ${g.length} task(s):`);for(const n of g)e.info(` - ${n}`);e.info("")}const l=p.dependencies[o]??[];if(l.length>0){e.info(`This task depends on ${l.length} task(s):`);for(const n of[...l].sort())e.info(` - ${n}`);e.info("")}},"execute");export{I as default};
@@ -1,101 +1,5 @@
1
- import { createRequire as __cjs_createRequire } from "node:module";
2
-
3
- const __cjs_require = __cjs_createRequire(import.meta.url);
4
-
5
- const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
6
-
7
- const __cjs_getBuiltinModule = (module) => {
8
- // Check if we're in Node.js and version supports getBuiltinModule
9
- if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
10
- const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
11
- // Node.js 20.16.0+ and 22.3.0+
12
- if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
13
- return __cjs_getProcess.getBuiltinModule(module);
14
- }
15
- }
16
- // Fallback to createRequire
17
- return __cjs_require(module);
18
- };
19
-
20
- const {
21
- readdirSync
22
- } = __cjs_getBuiltinModule("node:fs");
23
- import { dim, green, yellow, red } from '@visulima/colorize';
24
- import { isAccessibleSync, readJsonSync } from '@visulima/fs';
25
- import { join } from '@visulima/path';
26
- import { enforceProjectConstraints } from '@visulima/task-runner';
27
- import { d as discoverWorkspace, b as buildProjectGraph } from './bin.js';
28
- import { a as analyzeFlakiness } from '../packem_shared/flakiness-goTxXuCX.js';
29
- import { c as checkRuntimeVersions } from '../packem_shared/runtime-check-Cobi3p6l.js';
30
-
31
- const icon = (ok) => ok ? green("✓") : red("✗");
32
- const execute = async ({ logger, options, visConfig, workspaceRoot: wsRoot }) => {
33
- if (!wsRoot) {
34
- throw new Error("Could not determine workspace root.");
35
- }
36
- const { config, packageJsons, workspace } = discoverWorkspace(wsRoot, visConfig);
37
- const projectGraph = buildProjectGraph(wsRoot, workspace, packageJsons);
38
- const projectCount = Object.keys(workspace.projects).length;
39
- const targetCount = new Set(Object.values(workspace.projects).flatMap((p) => Object.keys(p.targets ?? {}))).size;
40
- const runtimeFindings = checkRuntimeVersions(wsRoot);
41
- let constraintViolations = 0;
42
- if (config.constraints) {
43
- constraintViolations = enforceProjectConstraints(projectGraph, config.constraints).length;
44
- }
45
- const flakyStats = analyzeFlakiness(wsRoot, { minRuns: 2 });
46
- let cacheHitRate;
47
- const runsDir = join(wsRoot, ".task-runner", "runs");
48
- if (isAccessibleSync(runsDir)) {
49
- const files = readdirSync(runsDir).filter((f) => f.endsWith(".json")).sort();
50
- let totalTasks = 0;
51
- let cachedTasks = 0;
52
- for (const file of files.slice(-20)) {
53
- try {
54
- const data = readJsonSync(join(runsDir, file));
55
- if (data.stats) {
56
- totalTasks += data.stats.total ?? 0;
57
- cachedTasks += data.stats.cached ?? 0;
58
- }
59
- } catch {
60
- continue;
61
- }
62
- }
63
- if (totalTasks > 0) {
64
- cacheHitRate = `${(cachedTasks / totalTasks * 100).toFixed(0)}%`;
65
- }
66
- }
67
- if (options.json) {
68
- logger.info(
69
- JSON.stringify(
70
- {
71
- cacheHitRate: cacheHitRate ?? null,
72
- constraintViolations,
73
- flakyTasks: flakyStats.length,
74
- projects: projectCount,
75
- runtimeIssues: runtimeFindings.length,
76
- targets: targetCount
77
- },
78
- null,
79
- 2
80
- )
81
- );
82
- return;
83
- }
84
- logger.info("");
85
- logger.info(` ${dim("VIS STATUS")}`);
86
- logger.info("");
87
- logger.info(` ${icon(true)} ${String(projectCount)} projects · ${String(targetCount)} unique targets`);
88
- logger.info(
89
- ` ${icon(runtimeFindings.length === 0)} Runtime: ${runtimeFindings.length === 0 ? green("OK") : yellow(`${String(runtimeFindings.length)} issue(s)`)}`
90
- );
91
- logger.info(
92
- ` ${icon(constraintViolations === 0)} Constraints: ${constraintViolations === 0 ? green("OK") : red(`${String(constraintViolations)} violation(s)`)}`
93
- );
94
- logger.info(` ${icon(flakyStats.length === 0)} Flaky tasks: ${flakyStats.length === 0 ? green("none") : yellow(String(flakyStats.length))}`);
95
- if (cacheHitRate) {
96
- logger.info(` ${icon(true)} Cache hit rate: ${cacheHitRate} (last 20 runs)`);
97
- }
98
- logger.info("");
99
- };
100
-
101
- export { execute as default };
1
+ var P=Object.defineProperty;var v=(e,n)=>P(e,"name",{value:n,configurable:!0});import{createRequire as R}from"node:module";import{green as S,red as W,yellow as A,dim as d}from"@visulima/colorize";import{join as N}from"@visulima/path";import{p as o}from"./bin.js";import{S as w,g as C,w as j,b as B,p as q,f as k,a as M,c as H,u as y,d as K,e as O,h as D}from"../packem_shared/toolchain-BgBOUHII.js";const I=R(import.meta.url),$=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,b=v(e=>{if(typeof $<"u"&&$.versions&&$.versions.node){const[n,r]=$.versions.node.split(".").map(Number);if(n>22||n===22&&r>=3||n===20&&r>=16)return $.getBuiltinModule(e)}return I(e)},"__cjs_getBuiltinModule"),{spawnSync:U}=b("node:child_process"),{writeFileSync:F}=b("node:fs");var L=Object.defineProperty,f=v((e,n)=>L(e,"name",{value:n,configurable:!0}),"d");const x=["bun","deno","go","node","npm","pnpm","python","ruby","rust","yarn"],G=f(e=>x.includes(e),"isKnownTool"),p=f(e=>e?S("✓"):W("✗"),"icon"),T=A("⚠"),J=f(e=>{if(e.installed){const n=e.version?` v${e.version}`:"",r=e.configFiles.length>0?` (${e.configFiles.join(", ")})`:"";return`${p(!0)} ${e.name}${n}${r}`}return`${T} ${e.name} — referenced by ${e.configFiles.join(", ")} but not installed`},"renderManagerLine"),z=f(e=>{if(e.matches)return"";const{manager:n}=e;return n.name==="none"?d("→ (no manager)"):n.name==="self-activate"?"":n.installed?d(`→ ${n.name}`):d(`→ ${n.name} (missing)`)},"renderToolManager"),Q=f(e=>e.matches?p(!0):e.actual?T:p(!1),"toolIcon"),V=f(e=>{if(o.info(""),o.info(d("── Toolchain ───────────────────────")),e.detected.length===0)o.info(` ${p(!1)} No version manager detected`),o.notice(` Install one of: ${w.join(", ")}`);else for(const n of e.detected)o.info(` ${J(n)}`);if(o.info(""),e.tools.length===0){o.info(` ${d("No tool pins found — add engines.node, .nvmrc, or a manager config file.")}`);return}o.info(d("── Tools ───────────────────────────"));for(const n of e.tools){const r=`${n.expected.tool} ${n.expected.version}`,i=n.actual?`actual ${n.actual}`:"not installed",t=n.matches?"":d(` [${n.expected.source}]`),s=z(n),u=s===""?"":` ${s}`;o.info(` ${Q(n)} ${r} — ${i}${t}${u}`),n.manager.note&&o.notice(` ${n.manager.note}`)}},"printStatus"),X=f((e,n,r)=>{const i=C(e,n);if(r.json){process.stdout.write(`${JSON.stringify({detected:i.detected.map(s=>({binPath:s.binPath??null,configFiles:s.configFiles,installed:s.installed,name:s.name,version:s.version??null})),tools:i.tools.map(s=>({actual:s.actual??null,expected:s.expected.version,manager:s.manager.name,managerInstalled:s.manager.installed,matches:s.matches,note:s.manager.note??null,source:s.expected.source,tool:s.expected.tool}))},void 0,2)}
2
+ `);return}V(i);const t=i.tools.filter(s=>!s.matches);t.length>0&&(o.info(""),o.notice(" Run `vis toolchain install` to install pinned versions.")),r.exitCode&&t.length>0&&(process.exitCode=1)},"executeStatus"),Y=f(e=>{const n=new Map;for(const r of e){const i=n.get(r.manager.name);i?i.push(r):n.set(r.manager.name,[r])}return n},"groupByManager"),_=f((e,n,r)=>U(e,n,{cwd:r,stdio:"inherit"}).status??1,"runInvocation"),Z=f((e,n,r)=>{const i=C(e,n),t=i.tools.filter(c=>!c.matches);if(t.length===0){o.success("Everything already matches — nothing to install.");return}const s=t.some(c=>c.manager.name!=="self-activate"&&c.manager.name!=="none");if(i.detected.length===0&&s){o.error(`No version manager detected. Install one of: ${w.join(", ")}.`),process.exitCode=1;return}const u=Y(t);let l=!1,g=0;for(const[c,m]of u){if(c==="self-activate"){for(const{expected:a}of m){if(a.source==="packageManager")o.info(`${d("$")} (${a.tool} will self-activate from packageManager on next invocation)`);else if(o.info(`${d("$")} Writing packageManager=${a.tool}@${a.version}`),r.dryRun)l=!0;else try{j(e,a),l=!0}catch(h){o.error(h.message),g=1}o.notice(` ${a.tool} ${a.version} — no install needed`)}continue}if(c==="none"){for(const{expected:a}of m)o.warn(`Cannot install ${a.tool} ${a.version} — no manager can handle it.`);g=1;continue}if(!i.detected.find(a=>a.name===c)?.installed){o.error(`${c} is referenced but not on PATH — install it first, then rerun \`vis toolchain install\`.`),g=1;continue}const E=m.map(a=>B(c,a.expected)).filter(Boolean);for(const a of E){if(!a)continue;if(a.bin==="nvm"&&a.args.length===0){o.error("nvm is a shell function — run `nvm install` in your shell, then rerun `vis toolchain install`."),a.hint&&o.notice(` ${a.hint}`),g=1;continue}if(o.info(`${d("$")} ${a.bin} ${a.args.join(" ")}`),a.hint&&o.notice(` ${a.hint}`),r.dryRun){l=!0;continue}const h=_(a.bin,a.args,e);if(l=!0,h!==0){g=h;break}}}if(g!==0){process.exitCode=g;return}l&&o.success("Toolchain installed.")},"executeInstall"),ee=f((e,n,r,i)=>{if(!r)throw new Error("Usage: vis toolchain use <tool>@<version> (e.g. vis toolchain use node@22.13.0)");const t=q(r);if(!t)throw new Error(`Could not parse "${r}". Expected "<tool>@<version>" where <tool> is one of ${x.join(", ")}.`);const s=k(e),u=M(t,s,n);if(u.name==="none"){o.error(`No manager can pin ${t.tool}. Install one of: ${w.join(", ")}.`),process.exitCode=1;return}if(!u.installed){o.error(`The best manager for ${t.tool} (${u.name}) is not on PATH. ${u.note??""}`),process.exitCode=1;return}const l=H(u.name,t);if(!l){o.error(`${u.name} cannot pin ${t.tool}. Use a different manager, or set \`toolchain.tools.${t.tool}\` in vis.config.ts.`),process.exitCode=1;return}if(u.name==="self-activate"){if(o.info(`${d("→")} Writing packageManager field to package.json...`),i.dryRun){o.notice(` Would set packageManager: "${t.tool}@${t.version}"`);return}try{const c=j(e,t);if(!c){o.error(`Refusing to pin non-package-manager tool ${t.tool} via the packageManager field.`),process.exitCode=1;return}if(o.success(`Set packageManager: "${c}" — ${t.tool} will activate this version on next invocation.`),i.engines!==!1){const m=y(e,t);m&&o.success(`Updated package.json engines.${t.tool} → ${m}.`)}}catch(c){o.error(c.message),process.exitCode=1}return}if(l.args.length===0&&u.name==="nvm"&&t.tool==="node"){const c=N(e,".nvmrc");if(o.info(`${d("→")} Writing ${c}...`),i.dryRun){o.notice(` Would write ${t.version} to .nvmrc`);return}try{F(c,`${t.version}
3
+ `)}catch(m){o.error(`Failed to write .nvmrc: ${m.message}`),process.exitCode=1;return}o.success(`Wrote ${t.version} to .nvmrc.`),o.notice(" nvm is a shell function — run `nvm use` to activate it in this shell.");return}if(l.args.length===0){o.error(`${u.name} cannot pin ${t.tool} from a subprocess. ${l.configChange?.hint??""}`),l.configChange&&o.notice(` Edit ${l.configChange.file} by hand and rerun \`vis toolchain status\` to verify.`),process.exitCode=1;return}if(o.info(`${d("$")} ${l.bin} ${l.args.join(" ")}`),l.configChange&&o.notice(` Will update ${l.configChange.file} — ${l.configChange.hint}`),i.dryRun)return;const g=_(l.bin,l.args,e);if(g!==0){process.exitCode=g;return}if(o.success(`Pinned ${t.tool} to ${t.version}.`),i.engines!==!1)try{const c=y(e,t);c&&o.success(`Updated package.json engines.${t.tool} → ${c}.`)}catch(c){o.warn(`Could not update engines.${t.tool}: ${c.message}`)}},"executeUse"),ne=f((e,n,r)=>{if(!r)throw new Error("Usage: vis toolchain which <tool> (e.g. vis toolchain which node)");const i=r.toLowerCase();if(!G(i))throw new Error(`Unknown tool "${r}". Known: ${x.join(", ")}.`);const t=k(e),s=M({source:"vis.config.ts",tool:i,version:"*"},t,n),u=s.installed&&s.name!=="self-activate"&&s.name!=="none"?t.find(g=>g.name===s.name):void 0,l=u?K(u,i):O(i);if(!l){o.error(`${r} not found in PATH${u?` or via ${u.name}`:""}.`),process.exitCode=1;return}process.stdout.write(`${l}
4
+ `)},"executeWhich"),oe=f((e,n)=>{const r=D(e,n);process.stdout.write(`${r.name}
5
+ `)},"executeDetect"),le=f(async({argument:e,options:n,visConfig:r,workspaceRoot:i})=>{if(!i)throw new Error("Could not determine workspace root. Run inside a monorepo.");const t=e[0]??"status",s=r?.toolchain;switch(t){case"detect":{oe(i,s);return}case"install":{Z(i,s,n);return}case"status":{X(i,s,n);return}case"use":{ee(i,s,e[1],n);return}case"which":{ne(i,s,e[1]);return}default:throw new Error(`Unknown toolchain action "${t}". Known: status, detect, install, use, which.`)}},"execute");export{le as default};