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

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 +101 -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,206 +1,20 @@
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
- execSync
22
- } = __cjs_getBuiltinModule("node:child_process");
23
- const {
24
- createInterface
25
- } = __cjs_getBuiltinModule("node:readline");
26
- import { isAccessibleSync, writeFileSync } from '@visulima/fs';
27
- import { join } from '@visulima/path';
28
- import { findVisConfigFile } from './applyDefaults.js';
29
- import { c as detectPm, p as pail, s as scanUnapprovedBuildScripts, e as syncAllowBuildsToNativeConfig } from './bin.js';
30
-
31
- const detectExistingTools = (cwd) => {
32
- const found = [];
33
- if (isAccessibleSync(join(cwd, "turbo.json"))) {
34
- found.push("turborepo");
35
- }
36
- if (isAccessibleSync(join(cwd, "nx.json"))) {
37
- found.push("nx");
38
- }
39
- if (isAccessibleSync(join(cwd, ".moon"))) {
40
- found.push("moon");
41
- }
42
- return found;
43
- };
44
- const ask = (rl, question) => new Promise((resolve) => {
45
- rl.question(question, (answer) => {
46
- resolve(answer.trim());
47
- });
48
- });
49
- const confirm = async (rl, question, defaultYes = true) => {
50
- const hint = defaultYes ? "[Y/n]" : "[y/N]";
51
- const answer = await ask(rl, `${question} ${hint} `);
52
- if (answer === "") {
53
- return defaultYes;
54
- }
55
- return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
56
- };
57
- const generateConfigContent = (_pm, options) => {
58
- const sections = [];
59
- const allowBuildsEntries = Object.entries(options.allowBuilds).filter(([, v]) => v).map(([k]) => ` "${k}": true,`).join("\n");
60
- const allowBuildsBlock = allowBuildsEntries ? `{
61
- ${allowBuildsEntries}
62
- }` : "{}";
63
- let securityBlock = ` allowBuilds: ${allowBuildsBlock},`;
64
- if (options.enableSocket) {
65
- securityBlock += `
66
- socket: { enabled: true },`;
67
- }
68
- sections.push(` security: {
69
- ${securityBlock}
70
- },`);
71
- if (options.staged) {
72
- sections.push(` staged: {
1
+ var _=Object.defineProperty;var $=(s,e)=>_(s,"name",{value:e,configurable:!0});import{createRequire as C}from"node:module";import{isAccessibleSync as g,writeFileSync as b}from"@visulima/fs";import{join as h}from"@visulima/path";import{findVisConfigFile as B}from"./applyDefaults.js";import{p as t,I as E,T as x,A as R}from"./bin.js";const I=C(import.meta.url),p=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,j=$(s=>{if(typeof p<"u"&&p.versions&&p.versions.node){const[e,o]=p.versions.node.split(".").map(Number);if(e>22||e===22&&o>=3||e===20&&o>=16)return p.getBuiltinModule(s)}return I(s)},"__cjs_getBuiltinModule"),{execFileSync:T}=j("node:child_process"),{createInterface:O}=j("node:readline");var N=Object.defineProperty,u=$((s,e)=>N(s,"name",{value:e,configurable:!0}),"f");const M=u(s=>{const e=[];return g(h(s,"turbo.json"))&&e.push("turborepo"),g(h(s,"nx.json"))&&e.push("nx"),g(h(s,".moon"))&&e.push("moon"),e},"detectExistingTools"),P=u((s,e)=>new Promise(o=>{s.question(e,n=>{o(n.trim())})}),"ask"),d=u(async(s,e,o=!0)=>{const n=await P(s,`${e} ${o?"[Y/n]":"[y/N]"} `);return n===""?o:n.toLowerCase()==="y"||n.toLowerCase()==="yes"},"confirm"),w=u((s,e)=>{const o=[],n=Object.entries(e.allowBuilds).filter(([,r])=>r).map(([r])=>` "${r}": true,`).join(`
2
+ `);let i=` allowBuilds: ${n?`{
3
+ ${n}
4
+ }`:"{}"},`;return e.enableSocket&&(i+=`
5
+ socket: { enabled: true },`),o.push(` security: {
6
+ ${i}
7
+ },`),e.staged&&o.push(` staged: {
73
8
  "*.{ts,tsx}": "eslint --fix",
74
9
  "*.{ts,tsx,js,jsx,json,md}": "prettier --write",
75
- },`);
76
- }
77
- return `import { defineConfig } from "@visulima/vis/config";
10
+ },`),`import { defineConfig } from "@visulima/vis/config";
78
11
 
79
12
  export default defineConfig({
80
- ${sections.join("\n\n")}
81
- });
82
- `;
83
- };
84
- const runInteractiveInit = async (cwd, pm, configPath) => {
85
- const rl = createInterface({ input: process.stdin, output: process.stdout });
86
- pail.info("\n vis init — interactive setup\n");
87
- const enableSocket = await confirm(rl, " Enable Socket.dev security scanning?");
88
- if (enableSocket) {
89
- pail.success(" Socket.dev enabled — scores, alerts, and supply chain data active.");
90
- if (!process.env.VIS_SOCKET_TOKEN) {
91
- pail.notice(" Set VIS_SOCKET_TOKEN for a custom API token (optional).");
92
- }
93
- }
94
- pail.info("");
95
- const scanBuilds = await confirm(rl, " Scan for packages with build scripts?");
96
- const allowBuilds = {};
97
- if (scanBuilds) {
98
- pail.info(" Scanning node_modules...");
99
- const unapproved = scanUnapprovedBuildScripts(cwd, {});
100
- if (unapproved.length > 0) {
101
- pail.info(` Found ${String(unapproved.length)} package${unapproved.length === 1 ? "" : "s"} with build scripts:
102
- `);
103
- for (const pkg of unapproved) {
104
- const answer = await confirm(rl, ` Allow ${pkg}?`, false);
105
- const pkgName = pkg.split(" (")[0] ?? pkg;
106
- allowBuilds[pkgName] = answer;
107
- if (answer) {
108
- pail.success(` ✓ ${pkgName} approved`);
109
- }
110
- }
111
- } else {
112
- pail.info(" No packages with build scripts found.");
113
- }
114
- }
115
- pail.info("");
116
- const setupStaged = await confirm(rl, " Set up pre-commit hooks (lint-staged)?", false);
117
- let syncNative = false;
118
- if (pm.name === "pnpm" || pm.name === "yarn" || pm.name === "npm" || pm.name === "bun") {
119
- pail.info("");
120
- syncNative = await confirm(rl, ` Sync security settings to ${pm.name} config?`);
121
- }
122
- const existingTools = detectExistingTools(cwd);
123
- if (existingTools.length > 0) {
124
- pail.info("");
125
- pail.info(` Detected existing tools: ${existingTools.join(", ")}`);
126
- const shouldMigrate = await confirm(rl, ` Run \`vis migrate\` for ${existingTools.join(", ")}?`, false);
127
- if (shouldMigrate) {
128
- rl.close();
129
- const execPrefix = pm.name === "pnpm" ? "pnpm exec" : pm.name === "yarn" ? "yarn exec" : pm.name === "bun" ? "bunx" : "npx";
130
- for (const tool of existingTools) {
131
- pail.info(` Migrating from ${tool}...`);
132
- try {
133
- execSync(`${execPrefix} vis migrate ${tool}`, {
134
- cwd,
135
- stdio: "inherit"
136
- });
137
- } catch {
138
- pail.warn(` Migration from ${tool} had issues — run \`vis migrate ${tool}\` manually.`);
139
- }
140
- }
141
- if (isAccessibleSync(configPath)) {
142
- pail.success(`Migrated config written to ${configPath}`);
143
- } else {
144
- const content2 = generateConfigContent(pm.name, { allowBuilds, enableSocket, staged: setupStaged });
145
- writeFileSync(configPath, content2);
146
- pail.success(`Created ${configPath}`);
147
- }
148
- pail.notice(" Run 'vis doctor' to see your project's full health status.");
149
- return;
150
- }
151
- }
152
- rl.close();
153
- pail.info("");
154
- const content = generateConfigContent(pm.name, { allowBuilds, enableSocket, staged: setupStaged });
155
- writeFileSync(configPath, content);
156
- pail.success(`Created ${configPath}`);
157
- if (syncNative) {
158
- const approvedBuilds = Object.fromEntries(Object.entries(allowBuilds).filter(([, v]) => v));
159
- const actions = syncAllowBuildsToNativeConfig(pm.name, cwd, approvedBuilds);
160
- for (const action of actions) {
161
- pail.success(` ${action}`);
162
- }
163
- }
164
- pail.info("");
165
- pail.info(" Setup complete. Your config:");
166
- pail.info(` Security: ${enableSocket ? "Socket.dev enabled" : "defaults only"}`);
167
- pail.info(` Build scripts: ${Object.values(allowBuilds).filter(Boolean).length} approved`);
168
- pail.info(` Git hooks: ${setupStaged ? "lint-staged configured" : "not configured"}`);
169
- pail.info(` PM sync: ${syncNative ? "done" : "skipped"}`);
170
- pail.info("");
171
- pail.notice(" Run 'vis doctor' to see your project's full health status.");
172
- pail.info("");
173
- };
174
- const runStaticInit = (cwd, pm, options, configPath) => {
175
- const content = generateConfigContent(pm.name, { allowBuilds: {}, enableSocket: false, staged: false });
176
- writeFileSync(configPath, content);
177
- pail.success(`Created ${configPath}`);
178
- pail.info(" Secure defaults applied automatically by defineConfig().");
179
- if (options.syncNative) {
180
- const actions = syncAllowBuildsToNativeConfig(pm.name, cwd, {});
181
- for (const action of actions) {
182
- pail.success(` ${action}`);
183
- }
184
- }
185
- pail.info("");
186
- pail.notice("Run 'vis doctor' for a full health check, or 'vis init' in a terminal for guided setup.");
187
- };
188
- const execute = async ({ options, workspaceRoot: wsRoot }) => {
189
- const cwd = wsRoot ?? process.cwd();
190
- const pm = detectPm(cwd);
191
- const existingConfig = findVisConfigFile(cwd);
192
- if (existingConfig && !options.force) {
193
- pail.warn(`Config already exists: ${existingConfig}`);
194
- pail.notice("Use --force to overwrite, or edit the existing file.");
195
- return;
196
- }
197
- const configPath = existingConfig ?? join(cwd, "vis.config.ts");
198
- const isTTY = Boolean(process.stdin.isTTY) && options.interactive !== false;
199
- if (isTTY && !options.noInteractive) {
200
- await runInteractiveInit(cwd, pm, configPath);
201
- } else {
202
- runStaticInit(cwd, pm, options, configPath);
203
- }
204
- };
13
+ ${o.join(`
205
14
 
206
- export { execute as default };
15
+ `)}
16
+ });
17
+ `},"generateConfigContent"),q=u(async(s,e,o)=>{const n=O({input:process.stdin,output:process.stdout});t.info(`
18
+ vis init — interactive setup
19
+ `);const i=await d(n," Enable Socket.dev security scanning?");i&&(t.success(" Socket.dev enabled — scores, alerts, and supply chain data active."),process.env.VIS_SOCKET_TOKEN||t.notice(" Set VIS_SOCKET_TOKEN for a custom API token (optional).")),t.info("");const r=await d(n," Scan for packages with build scripts?"),l={};if(r){t.info(" Scanning node_modules...");const c=E(s,{});if(c.length>0){t.info(` Found ${String(c.length)} package${c.length===1?"":"s"} with build scripts:
20
+ `);for(const f of c){const a=await d(n,` Allow ${f}?`,!1),S=f.split(" (")[0]??f;l[S]=a,a&&t.success(` ✓ ${S} approved`)}}else t.info(" No packages with build scripts found.")}t.info("");const v=await d(n," Set up pre-commit hooks (lint-staged)?",!1);let y=!1;(e.name==="pnpm"||e.name==="yarn"||e.name==="npm"||e.name==="bun")&&(t.info(""),y=await d(n,` Sync security settings to ${e.name} config?`));const m=M(s);if(m.length>0&&(t.info(""),t.info(` Detected existing tools: ${m.join(", ")}`),await d(n,` Run \`vis migrate\` for ${m.join(", ")}?`,!1))){n.close();const[c,...f]=e.name==="pnpm"?["pnpm","exec"]:e.name==="yarn"?["yarn","exec"]:e.name==="bun"?["bunx"]:["npx"];for(const a of m){t.info(` Migrating from ${a}...`);try{T(c,[...f,"vis","migrate",a],{cwd:s,stdio:"inherit"})}catch{t.warn(` Migration from ${a} had issues — run \`vis migrate ${a}\` manually.`)}}if(g(o))t.success(`Migrated config written to ${o}`);else{const a=w(e.name,{allowBuilds:l,enableSocket:i,staged:v});b(o,a),t.success(`Created ${o}`)}t.notice(" Run 'vis doctor' to see your project's full health status.");return}n.close(),t.info("");const k=w(e.name,{allowBuilds:l,enableSocket:i,staged:v});if(b(o,k),t.success(`Created ${o}`),y){const c=Object.fromEntries(Object.entries(l).filter(([,a])=>a)),f=x(e.name,s,c);for(const a of f)t.success(` ${a}`)}t.info(""),t.info(" Setup complete. Your config:"),t.info(` Security: ${i?"Socket.dev enabled":"defaults only"}`),t.info(` Build scripts: ${Object.values(l).filter(Boolean).length} approved`),t.info(` Git hooks: ${v?"lint-staged configured":"not configured"}`),t.info(` PM sync: ${y?"done":"skipped"}`),t.info(""),t.notice(" Run 'vis doctor' to see your project's full health status."),t.info("")},"runInteractiveInit"),A=u((s,e,o,n)=>{const i=w(e.name,{allowBuilds:{},enableSocket:!1,staged:!1});if(b(n,i),t.success(`Created ${n}`),t.info(" Secure defaults applied automatically by defineConfig()."),o.syncNative){const r=x(e.name,s,{});for(const l of r)t.success(` ${l}`)}t.info(""),t.notice("Run 'vis doctor' for a full health check, or 'vis init' in a terminal for guided setup.")},"runStaticInit"),G=u(async({options:s,workspaceRoot:e})=>{const o=e??process.cwd(),n=R(o),i=B(o);if(i&&!s.force){t.warn(`Config already exists: ${i}`),t.notice("Use --force to overwrite, or edit the existing file.");return}const r=i??h(o,"vis.config.ts");process.stdin.isTTY&&s.interactive!==!1&&!s.noInteractive?await q(o,n,r):A(o,n,s,r)},"execute");export{G as default};
@@ -1,124 +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
- rmSync
22
- } = __cjs_getBuiltinModule("node:fs");
23
- import { isAccessibleSync } from '@visulima/fs';
24
- import { join, dirname, parse } from '@visulima/path';
25
- import { p as pail, c as detectPm, r as resolveInstaller, w as detectLockfileDrift, x as runInstall } from './bin.js';
26
- import { s as scanDepsForTyposquats } from '../packem_shared/typosquats-C-bCh3PX.js';
27
- import { t as toStringArray } from '../packem_shared/utils-CthVdBPS.js';
28
-
29
- const LOCKFILE_NAMES = ["pnpm-lock.yaml", "yarn.lock", "package-lock.json", "npm-shrinkwrap.json", "bun.lock", "bun.lockb"];
30
- const hasLockfile = (start) => {
31
- let dir = start;
32
- while (true) {
33
- for (const name of LOCKFILE_NAMES) {
34
- if (isAccessibleSync(join(dir, name))) {
35
- return true;
36
- }
37
- }
38
- const parent = dirname(dir);
39
- if (parent === dir || parse(dir).root === dir) {
40
- return false;
41
- }
42
- dir = parent;
43
- }
44
- };
45
- const ALLOWED_BACKENDS = /* @__PURE__ */ new Set(["aube", "auto", "bun", "npm", "pnpm", "yarn"]);
46
- const execute = async ({ logger, options, visConfig, workspaceRoot: wsRoot }) => {
47
- const cwd = wsRoot ?? process.cwd();
48
- if (!options.noTyposquatCheck) {
49
- const shouldContinue = await scanDepsForTyposquats(cwd, visConfig?.security?.typosquatAllowlist);
50
- if (!shouldContinue) {
51
- process.exitCode = 1;
52
- return;
53
- }
54
- }
55
- const flagBackendRaw = options.installer;
56
- if (flagBackendRaw && !ALLOWED_BACKENDS.has(flagBackendRaw)) {
57
- pail.error(`Invalid --installer value: "${flagBackendRaw}". Expected one of: ${[...ALLOWED_BACKENDS].join(", ")}.`);
58
- process.exitCode = 1;
59
- return;
60
- }
61
- const flagBackend = flagBackendRaw;
62
- const noAube = options.noAube || false;
63
- let pm;
64
- try {
65
- pm = noAube ? detectPm(cwd) : resolveInstaller(cwd, { backend: flagBackend, configBackend: visConfig?.install?.backend });
66
- } catch (error) {
67
- pail.error(error instanceof Error ? error.message : String(error));
68
- process.exitCode = 1;
69
- return;
70
- }
71
- const driftWarning = detectLockfileDrift(cwd, pm);
72
- if (driftWarning) {
73
- pail.warn(driftWarning);
74
- }
75
- const filters = toStringArray(options.filter);
76
- const ciMode = options.ci || false;
77
- const explicitFrozen = options.frozenLockfile || ciMode;
78
- const optedOutOfFrozen = options.noFrozenLockfile || options.force || options.lockfileOnly;
79
- const lockfilePresent = hasLockfile(cwd);
80
- const shouldFreeze = explicitFrozen || !optedOutOfFrozen && lockfilePresent;
81
- if (!explicitFrozen && shouldFreeze && !options.silent) {
82
- pail.info("Defaulting to frozen lockfile (pass --no-frozen-lockfile to allow lockfile updates).");
83
- }
84
- if (ciMode) {
85
- pail.info("Clean install: removing node_modules...");
86
- try {
87
- rmSync(join(cwd, "node_modules"), { force: true, recursive: true });
88
- } catch (error) {
89
- pail.error(`Failed to remove node_modules: ${error instanceof Error ? error.message : String(error)}`);
90
- process.exitCode = 1;
91
- return;
92
- }
93
- }
94
- const code = runInstall(
95
- pm,
96
- {
97
- dev: options.dev || false,
98
- filter: filters,
99
- force: options.force || false,
100
- frozenLockfile: shouldFreeze,
101
- // Block-by-default lifecycle scripts (mirrors pnpm v10).
102
- // Allowlisted packages from `security.allowBuilds` are executed
103
- // post-install by the `security-enforcement` plugin's
104
- // afterCommand hook (`runApprovedScripts`). The escape hatch
105
- // is `--run-scripts`, which restores the PM's native behavior.
106
- ignoreScripts: !options.runScripts,
107
- lockfileOnly: options.lockfileOnly || false,
108
- noOptional: options.noOptional || false,
109
- offline: options.offline || false,
110
- prod: options.prod || false,
111
- recursive: options.recursive || false,
112
- silent: options.silent || false,
113
- workspaceRoot: options.workspaceRoot || false
114
- },
115
- cwd,
116
- logger,
117
- { preferOffline: options.preferOffline || false }
118
- );
119
- if (code !== 0) {
120
- process.exitCode = code;
121
- }
122
- };
123
-
124
- export { execute as default };
1
+ var C=Object.defineProperty;var f=(o,e)=>C(o,"name",{value:e,configurable:!0});import{createRequire as x}from"node:module";import{isAccessibleSync as R}from"@visulima/fs";import{join as y,dirname as T,parse as z}from"@visulima/path";import{p as t,A,m as L,f as $,h as B}from"./bin.js";import{s as D}from"../packem_shared/typosquats-CcZl99B1.js";import{o as E}from"../packem_shared/utils-DrNg0XTR.js";const O=x(import.meta.url),i=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,S=f(o=>{if(typeof i<"u"&&i.versions&&i.versions.node){const[e,r]=i.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return i.getBuiltinModule(o)}return O(o)},"__cjs_getBuiltinModule"),{rmSync:q}=S("node:fs");var F=Object.defineProperty,b=f((o,e)=>F(o,"name",{value:e,configurable:!0}),"f");const M=["pnpm-lock.yaml","yarn.lock","package-lock.json","npm-shrinkwrap.json","bun.lock","bun.lockb"],P=b(o=>{let e=o;for(;;){for(const c of M)if(R(y(e,c)))return!0;const r=T(e);if(r===e||z(e).root===e)return!1;e=r}},"hasLockfile"),g=new Set(["aube","auto","bun","npm","pnpm","yarn"]),U=b(async({logger:o,options:e,visConfig:r,workspaceRoot:c})=>{const s=c??process.cwd();if(!e.noTyposquatCheck&&!await D(s,r?.security?.typosquatAllowlist)){process.exitCode=1;return}const l=e.installer;if(l&&!g.has(l)){t.error(`Invalid --installer value: "${l}". Expected one of: ${[...g].join(", ")}.`),process.exitCode=1;return}const v=l,_=e.noAube||!1;let a;try{a=_?A(s):L(s,{backend:v,configBackend:r?.install?.backend,configCorepack:r?.install?.corepack})}catch(n){t.error(n instanceof Error?n.message:String(n)),process.exitCode=1;return}const p=$(s,a);p&&t.warn(p);const w=E(e.filter),u=e.ci||!1,d=e.frozenLockfile||u,h=e.noFrozenLockfile||e.force||e.lockfileOnly,j=P(s),m=d||!h&&j;if(!d&&m&&!e.silent&&t.info("Defaulting to frozen lockfile (pass --no-frozen-lockfile to allow lockfile updates)."),u){t.info("Clean install: removing node_modules...");try{q(y(s,"node_modules"),{force:!0,recursive:!0})}catch(n){t.error(`Failed to remove node_modules: ${n instanceof Error?n.message:String(n)}`),process.exitCode=1;return}}const k=B(a,{dev:e.dev||!1,filter:w,force:e.force||!1,frozenLockfile:m,ignoreScripts:!e.runScripts,lockfileOnly:e.lockfileOnly||!1,noOptional:e.noOptional||!1,offline:e.offline||!1,prod:e.prod||!1,recursive:e.recursive||!1,silent:e.silent||!1,workspaceRoot:e.workspaceRoot||!1},s,o,{preferOffline:e.preferOffline||!1});k!==0&&(process.exitCode=k)},"execute");export{U as default};
@@ -1,13 +1 @@
1
- import { r as resolveInstaller, y as runLink } from './bin.js';
2
-
3
- const execute = async ({ argument, logger, visConfig, workspaceRoot: wsRoot }) => {
4
- const target = argument?.[0] ?? null;
5
- const cwd = wsRoot ?? process.cwd();
6
- const pm = resolveInstaller(cwd, { configBackend: visConfig?.install?.backend });
7
- const code = runLink(pm, target, cwd, logger);
8
- if (code !== 0) {
9
- process.exitCode = code;
10
- }
11
- };
12
-
13
- export { execute as default };
1
+ var i=Object.defineProperty;var n=(e,a)=>i(e,"name",{value:a,configurable:!0});import{m as p,l as f}from"./bin.js";var g=Object.defineProperty,m=n((e,a)=>g(e,"name",{value:a,configurable:!0}),"s");const k=m(async({argument:e,logger:a,visConfig:o,workspaceRoot:s})=>{const t=e?.[0]??null,r=s??process.cwd(),l=p(r,{configBackend:o?.install?.backend,configCorepack:o?.install?.corepack}),c=f(l,t,r,a);c!==0&&(process.exitCode=c)},"execute");export{k as default};
@@ -1,106 +1 @@
1
- import { d as discoverWorkspace } from './bin.js';
2
- import { f as filterProjectsByQuery } from '../packem_shared/selectors-SM69TfqC.js';
3
-
4
- const execute = async ({ logger, options, visConfig, workspaceRoot: wsRoot }) => {
5
- if (!wsRoot) {
6
- throw new Error("Could not determine workspace root.");
7
- }
8
- const { projectOptions, workspace } = discoverWorkspace(wsRoot, visConfig);
9
- let projectNames = Object.keys(workspace.projects).sort();
10
- if (options.query) {
11
- projectNames = filterProjectsByQuery(projectNames, workspace, options.query);
12
- }
13
- if (projectNames.length === 0) {
14
- logger.info("No projects found.");
15
- return;
16
- }
17
- const inferredOnly = options.inferred === true;
18
- const showTargets = options.targets === true || inferredOnly;
19
- if (options.json) {
20
- const data = projectNames.map((name) => {
21
- const project = workspace.projects[name];
22
- const visTargets = projectOptions.get(name) ?? {};
23
- const targets = Object.entries(project.targets ?? {}).map(([targetName]) => {
24
- const visTarget = visTargets[targetName];
25
- const isInferred = visTarget?.inferred === true;
26
- return {
27
- aliases: visTarget?.aliases ?? [],
28
- command: visTarget?.command,
29
- description: visTarget?.description,
30
- // Only emit the field when it's true — keeps the JSON
31
- // shape additive instead of breaking downstream
32
- // consumers that didn't know about `inferred` yet.
33
- ...isInferred ? { inferred: true } : {},
34
- name: targetName,
35
- type: visTarget?.type
36
- };
37
- }).filter((target) => !inferredOnly || target.inferred === true);
38
- return {
39
- language: project.language,
40
- layer: project.layer,
41
- name,
42
- root: project.root,
43
- stack: project.stack,
44
- tags: project.tags ?? [],
45
- targets,
46
- type: project.projectType ?? "library"
47
- };
48
- });
49
- logger.info(JSON.stringify(data, null, 2));
50
- return;
51
- }
52
- const renderTable = (header2, rows2) => {
53
- const widths = header2.map((h, i) => {
54
- const maxData = rows2.reduce((max, row) => Math.max(max, (row[i] ?? "").length), 0);
55
- return Math.max(h.length, maxData);
56
- });
57
- const pad = (str, w) => str.padEnd(w);
58
- logger.info(header2.map((h, i) => pad(h, widths[i])).join(" "));
59
- logger.info(widths.map((w) => "─".repeat(w)).join("──"));
60
- for (const row of rows2) {
61
- logger.info(row.map((cell, i) => pad(cell, widths[i])).join(" "));
62
- }
63
- };
64
- if (showTargets) {
65
- const targetRows = [];
66
- for (const name of projectNames) {
67
- const project = workspace.projects[name];
68
- const visTargets = projectOptions.get(name) ?? {};
69
- for (const targetName of Object.keys(project.targets ?? {}).sort()) {
70
- const visTarget = visTargets[targetName];
71
- const isInferred = visTarget?.inferred === true;
72
- if (inferredOnly && !isInferred) {
73
- continue;
74
- }
75
- const targetConfig = project.targets?.[targetName];
76
- const cache = targetConfig?.cache === false ? "no" : targetConfig?.cache === true ? "yes" : "default";
77
- targetRows.push([name, targetName, visTarget?.type ?? "—", cache, isInferred ? "yes" : "no", visTarget?.description ?? "—"]);
78
- }
79
- }
80
- if (targetRows.length === 0) {
81
- logger.info(inferredOnly ? "No inferred targets found." : "No targets found.");
82
- return;
83
- }
84
- renderTable(["Project", "Target", "Type", "Cache", "Inferred", "Description"], targetRows);
85
- logger.info("");
86
- logger.info(`${String(targetRows.length)} target(s) across ${String(projectNames.length)} project(s)`);
87
- return;
88
- }
89
- const header = ["Project", "Type", "Layer", "Tags", "Targets"];
90
- const rows = projectNames.map((name) => {
91
- const project = workspace.projects[name];
92
- const targets = Object.keys(project.targets ?? {});
93
- return [
94
- name,
95
- project.projectType ?? "library",
96
- project.layer ?? "—",
97
- (project.tags ?? []).join(", ") || "—",
98
- targets.length > 4 ? `${targets.slice(0, 4).join(", ")}… (${String(targets.length)})` : targets.join(", ") || "—"
99
- ];
100
- });
101
- renderTable(header, rows);
102
- logger.info("");
103
- logger.info(`${String(projectNames.length)} project(s)`);
104
- };
105
-
106
- export { execute as default };
1
+ var d=Object.defineProperty;var t=(e,o)=>d(e,"name",{value:o,configurable:!0});import{m as g,x as u}from"./bin.js";var f=Object.defineProperty,m=t((e,o)=>f(e,"name",{value:o,configurable:!0}),"n");const w=m(async({argument:e,logger:o,visConfig:c,workspaceRoot:r})=>{const a=e;if(!a||a.length===0)throw new Error("No subcommand specified. Available: cache, publish, audit, list, view, config, whoami, login, logout, pack, owner, dist-tag, search, fund, ping, token, deprecate, rebuild, prune");const[s,...l]=a,n=r??process.cwd(),p=g(n,{configBackend:c?.install?.backend,configCorepack:c?.install?.corepack}),i=u(p,s,l,n,o);i!==0&&(process.exitCode=i)},"execute");export{w as default};
@@ -1,19 +1 @@
1
- import { r as resolveInstaller, z as runPmSubcommand } from './bin.js';
2
-
3
- const execute = async ({ argument, logger, visConfig, workspaceRoot: wsRoot }) => {
4
- const args = argument;
5
- if (!args || args.length === 0) {
6
- throw new Error(
7
- "No subcommand specified. Available: cache, publish, audit, list, view, config, whoami, login, logout, pack, owner, dist-tag, search, fund, ping, token, deprecate, rebuild, prune"
8
- );
9
- }
10
- const [subcommand, ...rest] = args;
11
- const cwd = wsRoot ?? process.cwd();
12
- const pm = resolveInstaller(cwd, { configBackend: visConfig?.install?.backend });
13
- const code = runPmSubcommand(pm, subcommand, rest, cwd, logger);
14
- if (code !== 0) {
15
- process.exitCode = code;
16
- }
17
- };
18
-
19
- export { execute as default };
1
+ var f=Object.defineProperty;var i=(e,o)=>f(e,"name",{value:o,configurable:!0});import{m as p,n as g}from"./bin.js";import{o as v}from"../packem_shared/utils-DrNg0XTR.js";var k=Object.defineProperty,m=i((e,o)=>k(e,"name",{value:o,configurable:!0}),"l");const b=m(async({argument:e,logger:o,options:a,visConfig:s,workspaceRoot:l})=>{const r=e;if(!r||r.length===0)throw new Error("No packages specified. Usage: vis remove <packages...>");const c=process.cwd(),n=p(l??c,{configBackend:s?.install?.backend,configCorepack:s?.install?.corepack}),t=g(n,{filter:v(a.filter),global:a.global||!1,packages:r,recursive:a.recursive||!1,saveDev:a.saveDev||!1,workspaceRoot:a.workspaceRoot||!1},c,o);t!==0&&(process.exitCode=t)},"execute");export{b as default};
@@ -1,75 +1,2 @@
1
- import { getAffectedProjects } from '@visulima/task-runner';
2
- import { d as discoverWorkspace, b as buildProjectGraph } from './bin.js';
3
- import { f as filterProjectsByQuery } from '../packem_shared/selectors-SM69TfqC.js';
4
-
5
- const execute = async ({ argument, logger, options, runtime, visConfig, workspaceRoot: wsRoot }) => {
6
- const target = argument[0];
7
- if (!target) {
8
- throw new Error("Missing target. Usage: vis affected <target>");
9
- }
10
- if (!wsRoot) {
11
- throw new Error("Could not determine workspace root. Run this command inside a monorepo.");
12
- }
13
- const workspaceRoot = wsRoot;
14
- const { packageJsons, workspace } = discoverWorkspace(workspaceRoot, visConfig);
15
- const projectGraph = buildProjectGraph(workspaceRoot, workspace, packageJsons);
16
- const validScopes = /* @__PURE__ */ new Set(["deep", "direct", "none"]);
17
- const downstreamValue = options.downstream ?? "deep";
18
- const upstreamValue = options.upstream ?? "none";
19
- if (!validScopes.has(downstreamValue)) {
20
- throw new Error(`Invalid --downstream value: "${downstreamValue}". Must be "none", "direct", or "deep".`);
21
- }
22
- if (!validScopes.has(upstreamValue)) {
23
- throw new Error(`Invalid --upstream value: "${upstreamValue}". Must be "none", "direct", or "deep".`);
24
- }
25
- const affectedOptions = {
26
- base: options.base,
27
- downstream: downstreamValue,
28
- head: options.head,
29
- projectGraph,
30
- projects: workspace.projects,
31
- upstream: upstreamValue,
32
- workspaceRoot
33
- };
34
- const result = await getAffectedProjects(affectedOptions);
35
- if (result.changedFiles.length === 0) {
36
- logger.info("No files changed. Nothing to run.");
37
- return;
38
- }
39
- if (result.affectedProjects.length === 0) {
40
- logger.info("No projects affected by the changes.");
41
- return;
42
- }
43
- let { affectedProjects } = result;
44
- if (options.query) {
45
- affectedProjects = filterProjectsByQuery(affectedProjects, workspace, options.query);
46
- if (affectedProjects.length === 0) {
47
- logger.info(`Query "${String(options.query)}" matched no affected projects.`);
48
- return;
49
- }
50
- }
51
- logger.info(`Affected projects: ${affectedProjects.join(", ")}`);
52
- if (result.changedFiles.length > 0) {
53
- process.env["VIS_AFFECTED_FILES"] = result.changedFiles.join("\n");
54
- }
55
- const argv = [target, `--projects=${affectedProjects.join(",")}`];
56
- if (options.parallel !== void 0) {
57
- argv.push(`--parallel=${String(options.parallel)}`);
58
- }
59
- if (!options.cache) {
60
- argv.push("--no-cache");
61
- }
62
- if (options.dryRun) {
63
- argv.push("--dry-run");
64
- }
65
- if (options.partition) {
66
- argv.push(`--partition=${String(options.partition)}`);
67
- }
68
- try {
69
- await runtime.runCommand("run", { argv });
70
- } finally {
71
- delete process.env["VIS_AFFECTED_FILES"];
72
- }
73
- };
74
-
75
- export { execute as default };
1
+ var j=Object.defineProperty;var g=(n,r)=>j(n,"name",{value:r,configurable:!0});import{getAffectedProjects as v}from"@visulima/task-runner";import{k as E,y as F}from"./bin.js";import{f as b}from"../packem_shared/selectors-BylODRiM.js";var S=Object.defineProperty,$=g((n,r)=>S(n,"name",{value:r,configurable:!0}),"m");const T=$(async({argument:n,logger:r,options:e,runtime:l,visConfig:h,workspaceRoot:u})=>{const f=n[0];if(!f)throw new Error("Missing target. Usage: vis affected <target>");if(!u)throw new Error("Could not determine workspace root. Run this command inside a monorepo.");const s=u,{packageJsons:m,workspace:i}=E(s,h),w=F(s,i,m),d=new Set(["deep","direct","none"]),c=e.downstream??"deep",p=e.upstream??"none";if(!d.has(c))throw new Error(`Invalid --downstream value: "${c}". Must be "none", "direct", or "deep".`);if(!d.has(p))throw new Error(`Invalid --upstream value: "${p}". Must be "none", "direct", or "deep".`);const y={base:e.base,downstream:c,head:e.head,projectGraph:w,projects:i.projects,upstream:p,workspaceRoot:s},o=await v(y);if(o.changedFiles.length===0){r.info("No files changed. Nothing to run.");return}if(o.affectedProjects.length===0){r.info("No projects affected by the changes.");return}let{affectedProjects:a}=o;if(e.query&&(a=b(a,i,e.query),a.length===0)){r.info(`Query "${String(e.query)}" matched no affected projects.`);return}r.info(`Affected projects: ${a.join(", ")}`),o.changedFiles.length>0&&(process.env.VIS_AFFECTED_FILES=o.changedFiles.join(`
2
+ `));const t=[f,`--projects=${a.join(",")}`];e.parallel!==void 0&&t.push(`--parallel=${String(e.parallel)}`),e.cache||t.push("--no-cache"),e.dryRun&&t.push("--dry-run"),e.partition&&t.push(`--partition=${String(e.partition)}`),e.reverse&&t.push("--reverse"),typeof e.runnerTags=="string"&&e.runnerTags!==""&&t.push(`--runner-tags=${e.runnerTags}`);try{await l.runCommand("run",{argv:t})}finally{delete process.env.VIS_AFFECTED_FILES}},"execute");export{T as default};
@@ -1,29 +1,5 @@
1
- import { r as resolveInstaller, A as runRemove } from './bin.js';
2
- import { t as toStringArray } from '../packem_shared/utils-CthVdBPS.js';
3
-
4
- const execute = async ({ argument, logger, options, visConfig, workspaceRoot: wsRoot }) => {
5
- const packages = argument;
6
- if (!packages || packages.length === 0) {
7
- throw new Error("No packages specified. Usage: vis remove <packages...>");
8
- }
9
- const cwd = process.cwd();
10
- const pm = resolveInstaller(wsRoot ?? cwd, { configBackend: visConfig?.install?.backend });
11
- const code = runRemove(
12
- pm,
13
- {
14
- filter: toStringArray(options.filter),
15
- global: options.global || false,
16
- packages,
17
- recursive: options.recursive || false,
18
- saveDev: options.saveDev || false,
19
- workspaceRoot: options.workspaceRoot || false
20
- },
21
- cwd,
22
- logger
23
- );
24
- if (code !== 0) {
25
- process.exitCode = code;
26
- }
27
- };
28
-
29
- export { execute as default };
1
+ var k=Object.defineProperty;var p=(t,e)=>k(t,"name",{value:e,configurable:!0});import{readLastRunSummary as S}from"@visulima/task-runner";import{p as m}from"./bin.js";import{r as g,l as v}from"../packem_shared/run-summary-utils-BfBvjzhY.js";var x=Object.defineProperty,o=p((t,e)=>x(t,"name",{value:e,configurable:!0}),"s");const I=new Set(["json","table"]),y=o(t=>t??process.cwd(),"resolveWorkspaceRoot"),c=o(t=>t===void 0?"-":t<1e3?`${String(t)}ms`:`${(t/1e3).toFixed(2)}s`,"formatDuration"),l=o(t=>t.exitCode===void 0?t.cacheStatus:t.exitCode===0?t.cacheStatus==="MISS"?"OK":t.cacheStatus:`FAIL(${String(t.exitCode)})`,"formatStatus"),n=o((t,e)=>t.length>=e?t:t+" ".repeat(e-t.length),"padCell"),w=o(t=>t.exitCode!==void 0&&t.exitCode!==0,"isFailedTask"),$=o((t,e)=>{e.info(`Run ${t.id}`),e.info(` start: ${t.startTime}`),e.info(` end: ${t.endTime}`),e.info(` duration: ${c(t.duration)}`),e.info(` totals: ${String(t.stats.total)} total · ${String(t.stats.succeeded)} ok · ${String(t.stats.cached)} cached · ${String(t.stats.skipped)} skipped · ${String(t.stats.failed)} failed`),e.info(` env: node ${t.environment.nodeVersion} · ${t.environment.platform}/${t.environment.arch}`),e.info("")},"renderRunHeader"),T=o((t,e)=>{if(t.length===0){e.info("(no tasks match the current filter)");return}const a=t.map(r=>({duration:c(r.duration),hash:r.hash?r.hash.slice(0,12):"-",status:l(r),taskId:r.taskId})),s={duration:Math.max(8,...a.map(r=>r.duration.length)),hash:Math.max(4,...a.map(r=>r.hash.length)),status:Math.max(6,...a.map(r=>r.status.length)),taskId:Math.max(4,...a.map(r=>r.taskId.length))};e.info(` ${n("task",s.taskId)} ${n("status",s.status)} ${n("duration",s.duration)} ${n("hash",s.hash)}`),e.info(` ${"-".repeat(s.taskId)} ${"-".repeat(s.status)} ${"-".repeat(s.duration)} ${"-".repeat(s.hash)}`);for(const r of a)e.info(` ${n(r.taskId,s.taskId)} ${n(r.status,s.status)} ${n(r.duration,s.duration)} ${n(r.hash,s.hash)}`)},"renderTaskTable"),C=o((t,e,a)=>{$(t,a),a.info(`Task ${e.taskId}`),a.info(` status: ${l(e)}`),a.info(` cache: ${e.cacheStatus}`),a.info(` duration: ${c(e.duration)}`),a.info(` exit: ${e.exitCode===void 0?"-":String(e.exitCode)}`),a.info(` hash: ${e.hash??"(none)"}`),a.info(` start: ${e.startTime??"-"}`),a.info(` end: ${e.endTime??"-"}`),e.dependencies.length>0&&a.info(` deps: ${e.dependencies.join(", ")}`),a.info(""),m.info(`Drill into hash inputs with: vis cache why ${e.taskId} --run ${t.id}`)},"renderTaskDetail"),R=o(t=>{process.stdout.write(`${JSON.stringify(t.map(e=>({id:e.id,mtime:new Date(e.mtimeMs).toISOString(),path:e.path})),void 0,2)}
2
+ `)},"renderListJson"),j=o((t,e)=>{if(t.length===0){m.info("No recorded runs found in .task-runner/runs/. Run with --summarize to record a run.");return}const a={id:Math.max(2,...t.map(s=>s.id.length)),mtime:24};e.info(` ${n("id",a.id)} ${n("mtime",a.mtime)}`),e.info(` ${"-".repeat(a.id)} ${"-".repeat(a.mtime)}`);for(const s of t)e.info(` ${n(s.id,a.id)} ${new Date(s.mtimeMs).toISOString()}`)},"renderListTable"),O=o((t,e)=>{let{tasks:a}=t;return e.task!==void 0&&(a=a.filter(s=>s.taskId===e.task)),e.failed&&(a=a.filter(s=>w(s))),a},"filterTasks"),b=o(async(t,e)=>{const{failed:a,format:s,runId:r,task:d,workspaceRoot:h}=t,i=r===void 0?await S(h):await g(h,r);if(!i){if(s==="json"){process.stdout.write(`${JSON.stringify({error:"no-summary",runId:r??null},void 0,2)}
3
+ `),process.exitCode=1;return}r===void 0?m.error("No previous run summary found. Run a task first to populate `.task-runner/last-summary.json`."):m.error(`Run summary "${r}" not found in .task-runner/runs/.`),process.exitCode=1;return}const f=O(i,{failed:a,task:d});if(d!==void 0&&f.length===0){if(s==="json"){process.stdout.write(`${JSON.stringify({error:"task-not-in-summary",runId:i.id,taskId:d},void 0,2)}
4
+ `),process.exitCode=1;return}m.error(`Task "${d}" was not part of run ${i.id}.`),process.exitCode=1;return}if(i.stats.failed>0&&(process.exitCode=1),s==="json"){process.stdout.write(`${JSON.stringify({duration:i.duration,endTime:i.endTime,environment:i.environment,runId:i.id,startTime:i.startTime,stats:i.stats,tasks:f.map(u=>({cacheStatus:u.cacheStatus,dependencies:u.dependencies,duration:u.duration,endTime:u.endTime,exitCode:u.exitCode,hash:u.hash??null,startTime:u.startTime,taskId:u.taskId}))},void 0,2)}
5
+ `);return}if(d!==void 0){C(i,f[0],e);return}$(i,e),T(f,e)},"runReplay"),L=o(async({logger:t,options:e,workspaceRoot:a})=>{const s=y(a),r=e.format??"table";if(!I.has(r)){m.error(`Invalid --format: ${r}. Expected "table" or "json".`),process.exitCode=1;return}if(e.list===!0){const d=await v(s);if(r==="json"){R(d);return}j(d,t);return}await b({failed:e.failed===!0,format:r,runId:e.run,task:e.task,workspaceRoot:s},t)},"replayExecute");export{L as default,L as replayExecute,b as runReplay};