@visulima/vis 4.3.1 → 5.0.0
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/CHANGELOG.md +497 -0
- package/dist/bin.js +1 -1
- package/dist/binx.js +1 -1
- package/dist/config/index.d.ts +27 -2
- package/dist/packem_chunks/catalog.js +2 -2
- package/dist/packem_chunks/cli-exec.js +1 -1
- package/dist/packem_chunks/cli-main.js +126 -126
- package/dist/packem_chunks/handler.js +1 -1
- package/dist/packem_chunks/handler11.js +1 -1
- package/dist/packem_chunks/handler12.js +1 -1
- package/dist/packem_chunks/handler13.js +1 -1
- package/dist/packem_chunks/handler14.js +1 -1
- package/dist/packem_chunks/handler15.js +1 -1
- package/dist/packem_chunks/handler16.js +1 -1
- package/dist/packem_chunks/handler17.js +1 -1
- package/dist/packem_chunks/handler18.js +1 -1
- package/dist/packem_chunks/handler2.js +1 -1
- package/dist/packem_chunks/handler20.js +1 -1
- package/dist/packem_chunks/handler26.js +5 -5
- package/dist/packem_chunks/handler27.js +1 -1
- package/dist/packem_chunks/handler28.js +1 -1
- package/dist/packem_chunks/handler29.js +1 -1
- package/dist/packem_chunks/handler3.js +1 -1
- package/dist/packem_chunks/handler5.js +1 -1
- package/dist/packem_chunks/handler51.js +1 -1
- package/dist/packem_chunks/handler59.js +1 -1
- package/dist/packem_chunks/handler6.js +1 -1
- package/dist/packem_chunks/handler61.js +1 -1
- package/dist/packem_chunks/handler62.js +10 -10
- package/dist/packem_chunks/handler64.js +6 -3
- package/dist/packem_chunks/handler65.js +8 -6
- package/dist/packem_chunks/handler66.js +1 -1
- package/dist/packem_chunks/handler69.js +22 -153
- package/dist/packem_chunks/handler7.js +1 -1
- package/dist/packem_chunks/handler70.js +9 -9
- package/dist/packem_chunks/handler71.js +153 -22
- package/dist/packem_chunks/handler72.js +1 -1
- package/dist/packem_chunks/handler73.js +1 -1
- package/dist/packem_chunks/handler75.js +12 -12
- package/dist/packem_chunks/handler77.js +1 -1
- package/dist/packem_chunks/handler78.js +70 -68
- package/dist/packem_chunks/handler9.js +1 -1
- package/dist/packem_chunks/heal-accept.js +1 -1
- package/dist/packem_chunks/help-command.js +1 -1
- package/dist/packem_chunks/index6.js +1 -1
- package/dist/packem_chunks/list.js +1 -1
- package/dist/packem_chunks/loader.js +1 -1
- package/dist/packem_chunks/sync2.js +1 -1
- package/dist/packem_chunks/tar.js +1 -1
- package/dist/packem_chunks/tripwire.js +1 -1
- package/dist/packem_chunks/ts-loader.js +1 -1
- package/dist/packem_chunks/verify-lockfile.js +1 -1
- package/dist/packem_shared/{affected-selection-D4giBK2X.js → affected-selection-BJXJW_3Q.js} +1 -1
- package/dist/packem_shared/affected-shas-B_kfSKss.js +1 -0
- package/dist/packem_shared/{bin-C1XKj-O-.js → bin-Dx8mjl3g.js} +1 -1
- package/dist/packem_shared/{ecosystem-gate-ddru_hOg.js → ecosystem-gate-CeV20GSB.js} +1 -1
- package/dist/packem_shared/env-consistency-Dt_uDbSP.js +1 -0
- package/dist/packem_shared/git-source-DExWbfN0.js +2 -0
- package/dist/packem_shared/{index-DQ2GJzmy.js → index-C_ScJMpb.js} +1 -1
- package/dist/packem_shared/{index-Chje3u9v.js → index-nEyN71oX.js} +1 -1
- package/dist/packem_shared/{package-version-Dxirp-UO.js → package-version-CiRZecQu.js} +1 -1
- package/dist/packem_shared/{packument-BQv4je9m.js → packument-Df46y5MY.js} +1 -1
- package/dist/packem_shared/pm-runner-3iiQayy-.js +1 -0
- package/dist/packem_shared/{project-name-filter-D6tXD8gd.js → project-name-filter-CH8Ih7Qr.js} +1 -1
- package/dist/packem_shared/{provenance-DNyVMxNv.js → provenance-DKeR0Ig1.js} +1 -1
- package/dist/packem_shared/{resolve-explicit-BPsdmuty.js → resolve-explicit-BmV8YBE-.js} +1 -1
- package/dist/packem_shared/{s1ngularity-QD2LD1sO.js → s1ngularity-DZhkIqL4.js} +1 -1
- package/dist/packem_shared/{signatures-t8LbOaqr.js → signatures-BxTMck2l.js} +1 -1
- package/dist/packem_shared/task-env-DzR4RkOj.js +2 -0
- package/dist/packem_shared/{vis-user-error-75VtCwMv.js → vis-user-error-Dd7hwxlW.js} +1 -1
- package/dist/packem_shared/{watch-loop-qRn0IHPG.js → watch-loop-BBkg02-Q.js} +2 -2
- package/index.js +52 -52
- package/package.json +10 -10
- package/schemas/project.schema.json +44 -1
- package/schemas/vis-config.schema.json +122 -7
- package/skills/vis/SKILL.md +24 -12
- package/dist/packem_shared/affected-shas-B2V84O0g.js +0 -1
- package/dist/packem_shared/giget-D8Kwb0kD.js +0 -2
- package/dist/packem_shared/pm-runner-CMSml1Bj.js +0 -1
|
@@ -157,6 +157,13 @@
|
|
|
157
157
|
"description": "Default giget provider for `owner/repo` shorthand inputs.",
|
|
158
158
|
"default": "github"
|
|
159
159
|
},
|
|
160
|
+
"defaultTemplate": {
|
|
161
|
+
"type": "string",
|
|
162
|
+
"description": "Template used by a bare `vis create`. Accepts any template input, including an organization scope (`@acme` opens the `@acme/create` manifest picker, `@acme:app` selects one entry directly). In a terminal the usual prompts still run, minus the template step.",
|
|
163
|
+
"examples": [
|
|
164
|
+
"@acme"
|
|
165
|
+
]
|
|
166
|
+
},
|
|
160
167
|
"gitInit": {
|
|
161
168
|
"type": "boolean",
|
|
162
169
|
"description": "Initialize a git repository after scaffolding standalone projects.",
|
|
@@ -424,6 +431,9 @@
|
|
|
424
431
|
},
|
|
425
432
|
"stylelint": {
|
|
426
433
|
"$ref": "#/$defs/LintFmtAdapterOverride"
|
|
434
|
+
},
|
|
435
|
+
"typecheck": {
|
|
436
|
+
"$ref": "#/$defs/LintFmtAdapterOverride"
|
|
427
437
|
}
|
|
428
438
|
},
|
|
429
439
|
"additionalProperties": false,
|
|
@@ -2059,7 +2069,7 @@
|
|
|
2059
2069
|
},
|
|
2060
2070
|
"autoFingerprint": {
|
|
2061
2071
|
"type": "boolean",
|
|
2062
|
-
"description": "Enable auto-fingerprinting mode
|
|
2072
|
+
"description": "Enable auto-fingerprinting mode. When enabled, the task runner automatically tracks which files a task accesses during execution and uses that for cache invalidation instead of requiring manual input configuration.\n\nWhen the tracker observes no workspace access for a run, the run is keyed on the declared hash if the target declares `inputs` (see {@link TaskResult.hashSource } ). Otherwise it is not cached (see {@link TaskResult.emptyFingerprint } ).\n\nThis is the workspace-wide switch. To opt a single target into traced hashing without flipping it for the whole graph, set {@link TargetConfiguration.hashMode } to `\"trace\"` on that target instead.",
|
|
2063
2073
|
"default": false
|
|
2064
2074
|
},
|
|
2065
2075
|
"bail": {
|
|
@@ -2092,6 +2102,31 @@
|
|
|
2092
2102
|
"description": "Dry-run mode: compute hashes and check cache but don't execute tasks. Useful for debugging cache hits/misses.",
|
|
2093
2103
|
"default": false
|
|
2094
2104
|
},
|
|
2105
|
+
"env": {
|
|
2106
|
+
"type": "object",
|
|
2107
|
+
"properties": {
|
|
2108
|
+
"allow": {
|
|
2109
|
+
"type": "array",
|
|
2110
|
+
"items": {
|
|
2111
|
+
"type": "string"
|
|
2112
|
+
},
|
|
2113
|
+
"description": "Names and `*` wildcard patterns kept from the parent environment in `clean` mode. Ignored under `inherit`. Matching is case-insensitive on Windows, where environment names are case-insensitive."
|
|
2114
|
+
},
|
|
2115
|
+
"mode": {
|
|
2116
|
+
"type": "string",
|
|
2117
|
+
"enum": [
|
|
2118
|
+
"inherit",
|
|
2119
|
+
"clean"
|
|
2120
|
+
],
|
|
2121
|
+
"description": "Whether the child inherits the parent environment."
|
|
2122
|
+
}
|
|
2123
|
+
},
|
|
2124
|
+
"required": [
|
|
2125
|
+
"mode"
|
|
2126
|
+
],
|
|
2127
|
+
"additionalProperties": false,
|
|
2128
|
+
"description": "Workspace child-environment policy. `clean` gives every task a child with only the allow-listed parent variables, `PATH`, `HOME`, `TERM`, `CI`, the platform essentials, and whatever the executor injects. Default `inherit` (the whole parent environment).\n\nThe executor that spawns the task applies the policy. `vis run` does. The cache key follows it only when the runner context also carries a `childEnvPolicy` hook (see {@link TaskRunnerContext } ). Then a name the clean child cannot see hashes as unset. Without that hook every name is keyed as the parent sees it. Allow-listed names are not added to the key."
|
|
2129
|
+
},
|
|
2095
2130
|
"envVars": {
|
|
2096
2131
|
"type": "array",
|
|
2097
2132
|
"items": {
|
|
@@ -2104,7 +2139,7 @@
|
|
|
2104
2139
|
"items": {
|
|
2105
2140
|
"type": "string"
|
|
2106
2141
|
},
|
|
2107
|
-
"description": "Environment variable patterns to include in
|
|
2142
|
+
"description": "Environment variable patterns to include in the trace-mode fingerprint (`autoFingerprint` or a `hashMode: \"trace\"` target). Supports `*` wildcards anywhere in a pattern, e.g. \"VITE_*\" or \"*_TOKEN\". Per-target additions go in {@link TargetConfiguration.fingerprintEnv } ."
|
|
2108
2143
|
},
|
|
2109
2144
|
"frameworkInference": {
|
|
2110
2145
|
"type": "boolean",
|
|
@@ -2556,13 +2591,20 @@
|
|
|
2556
2591
|
"type": "string",
|
|
2557
2592
|
"description": "The executor/command to run"
|
|
2558
2593
|
},
|
|
2594
|
+
"fingerprintEnv": {
|
|
2595
|
+
"type": "array",
|
|
2596
|
+
"items": {
|
|
2597
|
+
"type": "string"
|
|
2598
|
+
},
|
|
2599
|
+
"description": "Env vars folded into this target's cache key, as names or `*` patterns (`\"VITE_*\"`). In `\"declared\"` mode each match becomes an env input, the same as `env://NAME`; in `\"trace\"` mode it extends {@link TaskRunnerOptions.fingerprintEnvPatterns } for this target."
|
|
2600
|
+
},
|
|
2559
2601
|
"hashMode": {
|
|
2560
2602
|
"type": "string",
|
|
2561
2603
|
"enum": [
|
|
2562
2604
|
"declared",
|
|
2563
2605
|
"trace"
|
|
2564
2606
|
],
|
|
2565
|
-
"description": "How this target's cache key is derived.\n\n- `\"declared\"` (default): the Nx-style path — the hash is built up-front from explicitly declared `inputs` (plus named/global inputs and the lockfile). Deterministic and portable across machines: two runners with the same workspace state produce the same key regardless of OS or syscall surface.\n- `\"trace\"`: the task is run under the file-access tracker (strace on Linux
|
|
2607
|
+
"description": "How this target's cache key is derived.\n\n- `\"declared\"` (default): the Nx-style path — the hash is built up-front from explicitly declared `inputs` (plus named/global inputs and the lockfile). Deterministic and portable across machines: two runners with the same workspace state produce the same key regardless of OS or syscall surface.\n- `\"trace\"`: the task is run under the file-access tracker (strace or seccomp on Linux; DYLD/IAT interposition on macOS and Windows for directly-executed commands; a Node preload otherwise) and the cache key is derived from the files it actually *read* during execution — no `inputs` declaration required. Mirrors the shipped `{ auto: true }` output capture, but for the input side. Use for compound or opaque commands whose real input set is impractical to enumerate.\n\nOpt-in per target precisely because trace mode trades reproducibility for convenience: the observed read set can differ across runners with different syscall surfaces (a static binary on a host without strace records nothing), so a trace key is **not** guaranteed portable between machines. Leave targets on `\"declared\"` whenever the input set can reasonably be listed.\n\nEquivalent to flipping {@link TaskRunnerOptions.autoFingerprint } on for this one target while every other target stays declared."
|
|
2566
2608
|
},
|
|
2567
2609
|
"inputs": {
|
|
2568
2610
|
"type": "array",
|
|
@@ -2704,6 +2746,17 @@
|
|
|
2704
2746
|
"type": "boolean",
|
|
2705
2747
|
"description": "Per-target PTY override. When `true`, every task spawned from this target runs inside a pseudo-terminal (so `isatty()` returns true and the child preserves color / progress UI). When `false`, the workspace-level PTY toggle is suppressed for this target. Useful when most targets are happy with piped stdio but one tool (vitest, prettier, a colorising linter) needs a real TTY, or vice versa.\n\nAbsent means \"follow the workspace default\" — the executor decides based on its own toggles."
|
|
2706
2748
|
},
|
|
2749
|
+
"splitCompound": {
|
|
2750
|
+
"type": "boolean",
|
|
2751
|
+
"description": "Split the target's command on top-level `&&` into one chained task per segment, each with its own cache key. Segment _n_ folds in the key of segment _n−1_, so changing a later segment re-runs only that segment and later ones, and a failing segment stops the chain. Works in declared and trace mode. A traced segment is tracked on its own command, and its trace key folds in the trace key of the segment before it.\n\nDeclared `outputs` attach to the last segment, so a cache hit on the whole chain restores them. A partial hit does not restore an earlier segment's files, so a later segment that reads a file written by an earlier segment needs that file to be a declared output of its own target. Opt-in. The split is refused, with a diagnostic and the target run whole, when the command contains a construct the splitter does not model (`;`, `||`, subshells, `cd`, `export`, `VAR=…` prefixes, command substitution, …), when an output is `{ auto: true }` (write tracking covers the whole target, not one segment), when it has a `when` condition, or when it is `always`."
|
|
2752
|
+
},
|
|
2753
|
+
"untrackedEnv": {
|
|
2754
|
+
"type": "array",
|
|
2755
|
+
"items": {
|
|
2756
|
+
"type": "string"
|
|
2757
|
+
},
|
|
2758
|
+
"description": "Env vars this target receives but keeps out of its cache key, as names or `*` patterns (`\"CI_*\"`). Applies on top of {@link TaskRunnerOptions.untrackedEnvVars } and wins over `fingerprintEnv`, `autoEnvVars`, framework inference and trace-mode fingerprint patterns. Explicit `env://` inputs and the workspace `envVars` / `globalEnv` lists are not affected."
|
|
2759
|
+
},
|
|
2707
2760
|
"warningPattern": {
|
|
2708
2761
|
"anyOf": [
|
|
2709
2762
|
{
|
|
@@ -2978,7 +3031,7 @@
|
|
|
2978
3031
|
"items": {
|
|
2979
3032
|
"type": "string"
|
|
2980
3033
|
},
|
|
2981
|
-
"description": "Environment variables that
|
|
3034
|
+
"description": "Environment variables that are passed to tasks but kept out of their cache key. Accepts names and `*` wildcard patterns (e.g. \"CI_*\"). Applies to the trace-mode fingerprint and to the implicit env sources of declared-mode hashing (`autoEnvVars`, framework inference). Explicit `env://` inputs and `envVars` / `globalEnv` are not affected. Per-target overrides go in {@link TargetConfiguration.untrackedEnv } ."
|
|
2982
3035
|
}
|
|
2983
3036
|
},
|
|
2984
3037
|
"additionalProperties": false,
|
|
@@ -3126,13 +3179,20 @@
|
|
|
3126
3179
|
"type": "string",
|
|
3127
3180
|
"description": "The executor/command to run"
|
|
3128
3181
|
},
|
|
3182
|
+
"fingerprintEnv": {
|
|
3183
|
+
"type": "array",
|
|
3184
|
+
"items": {
|
|
3185
|
+
"type": "string"
|
|
3186
|
+
},
|
|
3187
|
+
"description": "Env vars folded into this target's cache key, as names or `*` patterns (`\"VITE_*\"`). In `\"declared\"` mode each match becomes an env input, the same as `env://NAME`; in `\"trace\"` mode it extends {@link TaskRunnerOptions.fingerprintEnvPatterns } for this target."
|
|
3188
|
+
},
|
|
3129
3189
|
"hashMode": {
|
|
3130
3190
|
"type": "string",
|
|
3131
3191
|
"enum": [
|
|
3132
3192
|
"declared",
|
|
3133
3193
|
"trace"
|
|
3134
3194
|
],
|
|
3135
|
-
"description": "How this target's cache key is derived.\n\n- `\"declared\"` (default): the Nx-style path — the hash is built up-front from explicitly declared `inputs` (plus named/global inputs and the lockfile). Deterministic and portable across machines: two runners with the same workspace state produce the same key regardless of OS or syscall surface.\n- `\"trace\"`: the task is run under the file-access tracker (strace on Linux
|
|
3195
|
+
"description": "How this target's cache key is derived.\n\n- `\"declared\"` (default): the Nx-style path — the hash is built up-front from explicitly declared `inputs` (plus named/global inputs and the lockfile). Deterministic and portable across machines: two runners with the same workspace state produce the same key regardless of OS or syscall surface.\n- `\"trace\"`: the task is run under the file-access tracker (strace or seccomp on Linux; DYLD/IAT interposition on macOS and Windows for directly-executed commands; a Node preload otherwise) and the cache key is derived from the files it actually *read* during execution — no `inputs` declaration required. Mirrors the shipped `{ auto: true }` output capture, but for the input side. Use for compound or opaque commands whose real input set is impractical to enumerate.\n\nOpt-in per target precisely because trace mode trades reproducibility for convenience: the observed read set can differ across runners with different syscall surfaces (a static binary on a host without strace records nothing), so a trace key is **not** guaranteed portable between machines. Leave targets on `\"declared\"` whenever the input set can reasonably be listed.\n\nEquivalent to flipping {@link TaskRunnerOptions.autoFingerprint } on for this one target while every other target stays declared."
|
|
3136
3196
|
},
|
|
3137
3197
|
"inputs": {
|
|
3138
3198
|
"type": "array",
|
|
@@ -3269,6 +3329,17 @@
|
|
|
3269
3329
|
"type": "boolean",
|
|
3270
3330
|
"description": "Per-target PTY override. When `true`, every task spawned from this target runs inside a pseudo-terminal (so `isatty()` returns true and the child preserves color / progress UI). When `false`, the workspace-level PTY toggle is suppressed for this target. Useful when most targets are happy with piped stdio but one tool (vitest, prettier, a colorising linter) needs a real TTY, or vice versa.\n\nAbsent means \"follow the workspace default\" — the executor decides based on its own toggles."
|
|
3271
3331
|
},
|
|
3332
|
+
"splitCompound": {
|
|
3333
|
+
"type": "boolean",
|
|
3334
|
+
"description": "Split the target's command on top-level `&&` into one chained task per segment, each with its own cache key. Segment _n_ folds in the key of segment _n−1_, so changing a later segment re-runs only that segment and later ones, and a failing segment stops the chain. Works in declared and trace mode. A traced segment is tracked on its own command, and its trace key folds in the trace key of the segment before it.\n\nDeclared `outputs` attach to the last segment, so a cache hit on the whole chain restores them. A partial hit does not restore an earlier segment's files, so a later segment that reads a file written by an earlier segment needs that file to be a declared output of its own target. Opt-in. The split is refused, with a diagnostic and the target run whole, when the command contains a construct the splitter does not model (`;`, `||`, subshells, `cd`, `export`, `VAR=…` prefixes, command substitution, …), when an output is `{ auto: true }` (write tracking covers the whole target, not one segment), when it has a `when` condition, or when it is `always`."
|
|
3335
|
+
},
|
|
3336
|
+
"untrackedEnv": {
|
|
3337
|
+
"type": "array",
|
|
3338
|
+
"items": {
|
|
3339
|
+
"type": "string"
|
|
3340
|
+
},
|
|
3341
|
+
"description": "Env vars this target receives but keeps out of its cache key, as names or `*` patterns (`\"CI_*\"`). Applies on top of {@link TaskRunnerOptions.untrackedEnvVars } and wins over `fingerprintEnv`, `autoEnvVars`, framework inference and trace-mode fingerprint patterns. Explicit `env://` inputs and the workspace `envVars` / `globalEnv` lists are not affected."
|
|
3342
|
+
},
|
|
3272
3343
|
"warningPattern": {
|
|
3273
3344
|
"anyOf": [
|
|
3274
3345
|
{
|
|
@@ -3886,7 +3957,8 @@
|
|
|
3886
3957
|
"oxlint",
|
|
3887
3958
|
"ruff-check",
|
|
3888
3959
|
"shellcheck",
|
|
3889
|
-
"stylelint"
|
|
3960
|
+
"stylelint",
|
|
3961
|
+
"typecheck"
|
|
3890
3962
|
],
|
|
3891
3963
|
"description": "Adapter IDs that can lint (adapter `kind` is `\"lint\"` or `\"both\"`)."
|
|
3892
3964
|
},
|
|
@@ -5794,13 +5866,20 @@
|
|
|
5794
5866
|
"type": "string",
|
|
5795
5867
|
"description": "The executor/command to run"
|
|
5796
5868
|
},
|
|
5869
|
+
"fingerprintEnv": {
|
|
5870
|
+
"type": "array",
|
|
5871
|
+
"items": {
|
|
5872
|
+
"type": "string"
|
|
5873
|
+
},
|
|
5874
|
+
"description": "Env vars folded into this target's cache key, as names or `*` patterns (`\"VITE_*\"`). In `\"declared\"` mode each match becomes an env input, the same as `env://NAME`; in `\"trace\"` mode it extends {@link TaskRunnerOptions.fingerprintEnvPatterns } for this target."
|
|
5875
|
+
},
|
|
5797
5876
|
"hashMode": {
|
|
5798
5877
|
"type": "string",
|
|
5799
5878
|
"enum": [
|
|
5800
5879
|
"declared",
|
|
5801
5880
|
"trace"
|
|
5802
5881
|
],
|
|
5803
|
-
"description": "How this target's cache key is derived.\n\n- `\"declared\"` (default): the Nx-style path — the hash is built up-front from explicitly declared `inputs` (plus named/global inputs and the lockfile). Deterministic and portable across machines: two runners with the same workspace state produce the same key regardless of OS or syscall surface.\n- `\"trace\"`: the task is run under the file-access tracker (strace on Linux
|
|
5882
|
+
"description": "How this target's cache key is derived.\n\n- `\"declared\"` (default): the Nx-style path — the hash is built up-front from explicitly declared `inputs` (plus named/global inputs and the lockfile). Deterministic and portable across machines: two runners with the same workspace state produce the same key regardless of OS or syscall surface.\n- `\"trace\"`: the task is run under the file-access tracker (strace or seccomp on Linux; DYLD/IAT interposition on macOS and Windows for directly-executed commands; a Node preload otherwise) and the cache key is derived from the files it actually *read* during execution — no `inputs` declaration required. Mirrors the shipped `{ auto: true }` output capture, but for the input side. Use for compound or opaque commands whose real input set is impractical to enumerate.\n\nOpt-in per target precisely because trace mode trades reproducibility for convenience: the observed read set can differ across runners with different syscall surfaces (a static binary on a host without strace records nothing), so a trace key is **not** guaranteed portable between machines. Leave targets on `\"declared\"` whenever the input set can reasonably be listed.\n\nEquivalent to flipping {@link TaskRunnerOptions.autoFingerprint } on for this one target while every other target stays declared."
|
|
5804
5883
|
},
|
|
5805
5884
|
"inputs": {
|
|
5806
5885
|
"type": "array",
|
|
@@ -5937,6 +6016,17 @@
|
|
|
5937
6016
|
"type": "boolean",
|
|
5938
6017
|
"description": "Per-target PTY override. When `true`, every task spawned from this target runs inside a pseudo-terminal (so `isatty()` returns true and the child preserves color / progress UI). When `false`, the workspace-level PTY toggle is suppressed for this target. Useful when most targets are happy with piped stdio but one tool (vitest, prettier, a colorising linter) needs a real TTY, or vice versa.\n\nAbsent means \"follow the workspace default\" — the executor decides based on its own toggles."
|
|
5939
6018
|
},
|
|
6019
|
+
"splitCompound": {
|
|
6020
|
+
"type": "boolean",
|
|
6021
|
+
"description": "Split the target's command on top-level `&&` into one chained task per segment, each with its own cache key. Segment _n_ folds in the key of segment _n−1_, so changing a later segment re-runs only that segment and later ones, and a failing segment stops the chain. Works in declared and trace mode. A traced segment is tracked on its own command, and its trace key folds in the trace key of the segment before it.\n\nDeclared `outputs` attach to the last segment, so a cache hit on the whole chain restores them. A partial hit does not restore an earlier segment's files, so a later segment that reads a file written by an earlier segment needs that file to be a declared output of its own target. Opt-in. The split is refused, with a diagnostic and the target run whole, when the command contains a construct the splitter does not model (`;`, `||`, subshells, `cd`, `export`, `VAR=…` prefixes, command substitution, …), when an output is `{ auto: true }` (write tracking covers the whole target, not one segment), when it has a `when` condition, or when it is `always`."
|
|
6022
|
+
},
|
|
6023
|
+
"untrackedEnv": {
|
|
6024
|
+
"type": "array",
|
|
6025
|
+
"items": {
|
|
6026
|
+
"type": "string"
|
|
6027
|
+
},
|
|
6028
|
+
"description": "Env vars this target receives but keeps out of its cache key, as names or `*` patterns (`\"CI_*\"`). Applies on top of {@link TaskRunnerOptions.untrackedEnvVars } and wins over `fingerprintEnv`, `autoEnvVars`, framework inference and trace-mode fingerprint patterns. Explicit `env://` inputs and the workspace `envVars` / `globalEnv` lists are not affected."
|
|
6029
|
+
},
|
|
5940
6030
|
"warningPattern": {
|
|
5941
6031
|
"anyOf": [
|
|
5942
6032
|
{
|
|
@@ -6427,6 +6517,31 @@
|
|
|
6427
6517
|
"description": "How to forward affected files to the task process. Only used when invoked via `vis affected <target>`.",
|
|
6428
6518
|
"default": false
|
|
6429
6519
|
},
|
|
6520
|
+
"env": {
|
|
6521
|
+
"type": "object",
|
|
6522
|
+
"properties": {
|
|
6523
|
+
"allow": {
|
|
6524
|
+
"type": "array",
|
|
6525
|
+
"items": {
|
|
6526
|
+
"type": "string"
|
|
6527
|
+
},
|
|
6528
|
+
"description": "Names and `*` wildcard patterns kept from the parent environment in `clean` mode. Ignored under `inherit`. Matching is case-insensitive on Windows, where environment names are case-insensitive."
|
|
6529
|
+
},
|
|
6530
|
+
"mode": {
|
|
6531
|
+
"type": "string",
|
|
6532
|
+
"enum": [
|
|
6533
|
+
"inherit",
|
|
6534
|
+
"clean"
|
|
6535
|
+
],
|
|
6536
|
+
"description": "Whether the child inherits the parent environment."
|
|
6537
|
+
}
|
|
6538
|
+
},
|
|
6539
|
+
"required": [
|
|
6540
|
+
"mode"
|
|
6541
|
+
],
|
|
6542
|
+
"additionalProperties": false,
|
|
6543
|
+
"description": "Child-process environment for this target. Overrides the workspace `taskRunner.env`.\n- `mode: \"inherit\"`: the child gets the whole parent environment, even when the workspace is `clean`.\n- `mode: \"clean\"`: the child gets only the allow-listed names, `PATH`, `HOME`, `TERM`, `CI`, the platform essentials and what vis injects (`VIS_TASK_SLOTS`, `VIS_ARG_*`, `envFile` values, service env).\n- `allow`: names and `*` wildcard patterns kept under `clean`. Added to the workspace allow-list when the workspace is also `clean`.\n\nA traced target (`hashMode: \"trace\"`, or a workspace `autoFingerprint`) can be `clean` too: it gets the same environment plus the tracker's own variables, and the tracker then runs without its native backends. Without this option the workspace `taskRunner.env` applies, and that defaults to `inherit`."
|
|
6544
|
+
},
|
|
6430
6545
|
"envFile": {
|
|
6431
6546
|
"anyOf": [
|
|
6432
6547
|
{
|
package/skills/vis/SKILL.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vis
|
|
3
|
-
description: Use when the workspace contains a vis.config.ts (or vis.config.js/json) at the repo root, or when the user mentions "vis", "task-runner", or "@visulima/vis". This skill orchestrates the vis MCP server's
|
|
3
|
+
description: Use when the workspace contains a vis.config.ts (or vis.config.js/json) at the repo root, or when the user mentions "vis", "task-runner", or "@visulima/vis". This skill orchestrates the vis MCP server's thirteen read-only tools to inspect projects, plan task graphs, lint, and diagnose remote-cache rotations.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Working with the `vis` task runner
|
|
7
7
|
|
|
8
|
-
`vis` is the Visulima monorepo task runner — a Turborepo/Nx-class tool with a remote cache, REAPI gRPC backend, and project graph. When this skill is active you have the **`@visulima/vis-mcp` server** mounted, exposing
|
|
8
|
+
`vis` is the Visulima monorepo task runner — a Turborepo/Nx-class tool with a remote cache, REAPI gRPC backend, and project graph. When this skill is active you have the **`@visulima/vis-mcp` server** mounted, exposing thirteen read-only tools. Use them in preference to running `vis` shell commands yourself: the tools give you structured JSON and run faster.
|
|
9
9
|
|
|
10
10
|
The MCP server deliberately does NOT execute targets or scaffold templates — Nx-style "agent prepares, human executes". When the user wants to run `<project>:<target>` or `vis generate <template>`, prepare the command (use `list_targets`/`describe_template` to confirm it exists and capture required arguments) and ask the user to run it themselves; afterwards use `get_run_logs` to read the result of any task run.
|
|
11
11
|
|
|
@@ -18,9 +18,14 @@ The MCP server deliberately does NOT execute targets or scaffold templates — N
|
|
|
18
18
|
| `list_targets` | Per-target rows across the workspace, optionally narrowed to a single project |
|
|
19
19
|
| `list_templates` | Scaffolding templates discovered in `.vis/templates/`, `.moon/templates/`, and `vis.config.ts` `generator.templates` |
|
|
20
20
|
| `describe_template` | Variable schema, default destination, and description for a single template — required before suggesting a `vis generate` command |
|
|
21
|
-
| `
|
|
21
|
+
| `list_runs` | Recorded runs in `.vis/runs/`, newest first — the IDs feed `get_run_logs` and the cache tools |
|
|
22
|
+
| `get_run_logs` | Most recent run summary from `.vis/`, or a specific `runId`, optionally filtered to one task |
|
|
22
23
|
| `cache_why` | Diff a task's cache hash against the previous run — pinpoints what changed (command, nodes, runtime, implicit deps) |
|
|
23
|
-
| `cache_hash` | Recorded hash and per-input hash details for a task
|
|
24
|
+
| `cache_hash` | Recorded hash and per-input hash details for a task (trace-mode tasks: the tracked files and env instead) |
|
|
25
|
+
| `lint` | Check-only lint across the detected linters, merged findings (never applies fixes) |
|
|
26
|
+
| `fmt` | Check-only formatting: each finding is a file that would change (never writes) |
|
|
27
|
+
| `audit` | Vulnerability audit of installed packages; uses the offline advisory cache when one exists |
|
|
28
|
+
| `advisory_status` | Freshness of the local advisory database — check it before an offline `audit` |
|
|
24
29
|
|
|
25
30
|
## Workflow patterns
|
|
26
31
|
|
|
@@ -34,16 +39,23 @@ Default opening move when the user asks about the workspace:
|
|
|
34
39
|
### Plan a build
|
|
35
40
|
|
|
36
41
|
1. `list_targets` (optionally with `project: "@scope/name"`) to see what `build`/`test`/`lint`/etc. targets exist.
|
|
37
|
-
2. Tell the user the exact command (`vis run @scope/name:build`) and let them run it.
|
|
38
|
-
3. Use `get_run_logs` afterwards to
|
|
42
|
+
2. Tell the user the exact command (`vis run @scope/name:build`) and let them run it. `vis run` exits 1 when the target is missing, or when `--filter`, `--query` or `--tag` selects no project; `vis ci` and `vis affected` behave the same. Suggest `--if-present` (exit 0 with a one-line notice) only when an empty selection is acceptable, such as one script shared across repos that don't all define the target. An empty `--affected` set is not an error.
|
|
43
|
+
3. Use `get_run_logs` afterwards to read each task's `exitCode`, `cacheStatus`, and the run's `stats`.
|
|
44
|
+
|
|
45
|
+
### Check lint and formatting
|
|
46
|
+
|
|
47
|
+
1. `lint` and `fmt` are check-only: `lint` returns findings, `fmt` returns the files that would change. `files` narrows either one.
|
|
48
|
+
2. A clean `lint` does not mean the types check. The `typecheck` adapter (`tsc`) runs only when the workspace sets `lint.adapters.typecheck.enabled`, and then it checks the whole project, not just the listed files.
|
|
49
|
+
3. Hand the user `vis lint --fix` or `vis fmt` to apply changes.
|
|
39
50
|
|
|
40
51
|
### Investigate a cache miss
|
|
41
52
|
|
|
42
53
|
When a build that should have been cached re-ran:
|
|
43
54
|
|
|
44
|
-
1. `get_run_logs` (no args → latest summary) —
|
|
45
|
-
2. For
|
|
46
|
-
3. If `cache_why` shows the change but the user wants
|
|
55
|
+
1. `get_run_logs` (no args → latest summary) — each task carries `exitCode` and `cacheStatus` (`HIT`, `MISS`, `REMOTE_HIT`, `SKIPPED`).
|
|
56
|
+
2. For a task with `exitCode: 0` and `cacheStatus: "MISS"` that should have hit, call `cache_why` with that `taskId`. For a task with declared inputs it diffs `hashDetails` against the previous run and names the bucket that rotated (`command`, `nodes`, `runtime`, `implicitDeps`). A `hashMode: "trace"` task has no `hashDetails`; read `task.cacheMissReasons` instead. These are `{ type, detail }` entries such as `file-changed`, `env-changed`, or `tracker-changed` (the run used a different tracker than the stored trace). The field is `null` on a hit. `task.hashSource: "declared-fallback"` means the run was keyed on its declared inputs because the tracker saw no workspace access.
|
|
57
|
+
3. If `cache_why` shows the change but the user wants the raw inputs, `cache_hash` returns the per-input breakdown. For a trace-mode task it returns `trackedFingerprint` (the files, env names, and missing paths the run tracked) instead.
|
|
58
|
+
4. If `cache_why` shows nothing changed, the result was a hit, and it is still wrong, one possible cause is an env var the command reads that no cache key covers. Ask the user to run `vis doctor`: its Env Coverage section lists those variables per target, with the fixes (`fingerprintEnv`, `autoEnvVars`, or `untrackedEnv`). It is a warning; `vis doctor --exit-code --strict` turns it into a failure.
|
|
47
59
|
|
|
48
60
|
### Scaffold a new package or component
|
|
49
61
|
|
|
@@ -76,9 +88,9 @@ User: _"Scaffold a new React button component called PrimaryButton."_
|
|
|
76
88
|
|
|
77
89
|
### Diagnose a failed run
|
|
78
90
|
|
|
79
|
-
1. `get_run_logs` to see which task(s) failed.
|
|
80
|
-
2. `get_run_logs` with `taskId` set to the failing task — returns just that entry,
|
|
81
|
-
3. Decide: is it a code bug (read the project's source), a cache poisoning issue (`cache_why`), or environmental (
|
|
91
|
+
1. `get_run_logs` to see which task(s) failed; `stats.failed` counts them.
|
|
92
|
+
2. `get_run_logs` with `taskId` set to the failing task — returns just that entry. The summary records the exit code, cache status, and hash, not the task's output, so ask the user for the failing output if you need it.
|
|
93
|
+
3. Decide: is it a code bug (read the project's source), a cache poisoning issue (`cache_why`), or environmental (the summary's `environment` block gives platform, arch, and Node version)?
|
|
82
94
|
|
|
83
95
|
## Safety rules
|
|
84
96
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createRequire as l}from"node:module";import{z as g}from"./index-BzhrR_iC.js";import{y as b}from"./isAccessibleSync-DYKTrrvc-C-_5cgwu.js";let d;const E=e=>(d??=l(import.meta.url))(e),u=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,h=e=>{if(typeof u<"u"&&u.versions&&u.versions.node){const[t,r]=u.versions.node.split(".").map(Number);if(t>22||t===22&&r>=3||t===20&&r>=16)return u.getBuiltinModule(e)}return E(e)},{spawnSync:p}=h("node:child_process"),f="0000000000000000000000000000000000000000",A=e=>{if(b(e))try{const t=g(e);return JSON.parse(t)}catch{return}},I=(e,t)=>{const r=p("git",e,{cwd:t,encoding:"utf8"});if(!(r.error||typeof r.status!="number"||r.status!==0))return typeof r.stdout=="string"?r.stdout.trim():void 0},_=e=>typeof e=="string"&&e.length>0&&e!==f,R=(e,t,r)=>{const o=[],s=e.GITHUB_BASE_REF,i=e.GITHUB_SHA??"HEAD";if(s&&s.length>0)return o.push(`pull_request: $GITHUB_BASE_REF=${s}`),{base:`origin/${s}`,head:i,notes:o,provider:"github"};const c=e.GITHUB_EVENT_PATH,a=c?r(c):void 0;if(a){const n=typeof a.before=="string"?a.before:void 0;if(_(n))return o.push(`push: event.before=${n}`),{base:n,head:i,notes:o,provider:"github"}}return o.push(`fallback: origin/${t}`),{base:`origin/${t}`,head:i,notes:o,provider:"github"}},C=(e,t)=>{const r=[],o=e.CI_COMMIT_SHA??"HEAD";if(e.CI_PIPELINE_SOURCE==="merge_request_event"){const a=e.CI_MERGE_REQUEST_DIFF_BASE_SHA;if(_(a))return r.push(`merge_request: $CI_MERGE_REQUEST_DIFF_BASE_SHA=${a}`),{base:a,head:o,notes:r,provider:"gitlab"};const n=e.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;if(n&&n.length>0)return r.push(`merge_request: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME=${n}`),{base:`origin/${n}`,head:o,notes:r,provider:"gitlab"}}const i=e.CI_COMMIT_BEFORE_SHA;if(_(i))return r.push(`push: $CI_COMMIT_BEFORE_SHA=${i}`),{base:i,head:o,notes:r,provider:"gitlab"};const c=e.CI_DEFAULT_BRANCH??t;return r.push(`fallback: origin/${c}`),{base:`origin/${c}`,head:o,notes:r,provider:"gitlab"}},S=(e,t)=>{const r=[],o=e.BUILDKITE_COMMIT??"HEAD",s=e.BUILDKITE_PULL_REQUEST_BASE_BRANCH;return s&&s.length>0?(r.push(`pull_request: $BUILDKITE_PULL_REQUEST_BASE_BRANCH=${s}`),{base:`origin/${s}`,head:o,notes:r,provider:"buildkite"}):(r.push(`fallback: origin/${t} (buildkite has no canonical previous-build SHA env)`),{base:`origin/${t}`,head:o,notes:r,provider:"buildkite"})},B=(e,t)=>{const r=[],o=e.CIRCLE_SHA1??"HEAD",s=e.CIRCLE_PR_BASE_BRANCH;return s&&s.length>0?(r.push(`pull_request: $CIRCLE_PR_BASE_BRANCH=${s}`),{base:`origin/${s}`,head:o,notes:r,provider:"circleci"}):(r.push(`fallback: origin/${t} (circleci has no canonical previous-build SHA env)`),{base:`origin/${t}`,head:o,notes:r,provider:"circleci"})},v=(e,t,r)=>{const o=[],s=t(["merge-base","HEAD",`origin/${e}`],r);return s&&s.length>0?(o.push(`local: git merge-base HEAD origin/${e}=${s}`),{base:s,head:"HEAD",notes:o,provider:"local"}):(o.push(`local fallback: origin/${e} (no merge-base available)`),{base:`origin/${e}`,head:"HEAD",notes:o,provider:"local"})},m=e=>{const t=e?.env??process.env,r=e?.defaultBase??"main",o=e?.readEventPayload??A,s=e?.runGit??I,i=e?.workspaceRoot??process.cwd();return t.GITHUB_ACTIONS==="true"?R(t,r,o):t.GITLAB_CI==="true"?C(t,r):t.BUILDKITE==="true"?S(t,r):t.CIRCLECI==="true"?B(t,r):v(r,s,i)};export{m as r};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createRequire as le}from"node:module";let ue;const de=t=>(ue??=le(import.meta.url))(t),y=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,v=t=>{if(typeof y<"u"&&y.versions&&y.versions.node){const[e,r]=y.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return y.getBuiltinModule(t)}return de(t)},{existsSync:g,openSync:he,readSync:fe,closeSync:pe,statSync:me,createWriteStream:V,readdirSync:ge,renameSync:we}=v("node:fs"),{readFile:X,mkdir:O,rm:x,writeFile:ve,mkdtemp:be}=v("node:fs/promises"),{PassThrough:q,Readable:I,pipeline:_e}=v("node:stream"),{pipeline:J}=v("node:stream/promises"),{spawn:Y}=v("node:child_process"),{basename:$e,normalize:ye,delimiter:T,resolve:K,dirname:M,join:j}=v("node:path"),{cwd:Z}=y,ke=v("node:readline"),{homedir:Ee,tmpdir:Q}=v("node:os"),{promisify:xe}=v("node:util");var F=Object.defineProperty,Te=(t,e)=>{let r={};for(var n in t)F(r,n,{get:t[n],enumerable:!0});return F(r,Symbol.toStringTag,{value:"Module"}),r};const Ce=/^[A-Za-z]:\//;function C(t=""){return t&&t.replace(/\\/g,"/").replace(Ce,e=>e.toUpperCase())}const Ae=/^[/\\]{2}/,Se=/^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/,ee=/^[A-Za-z]:$/,te=function(t){if(t.length===0)return".";t=C(t);let e=t.match(Ae),r=k(t),n=t[t.length-1]==="/";return t=re(t,!r),t.length===0?r?"/":n?"./":".":(n&&(t+="/"),ee.test(t)&&(t+="/"),e?r?`//${t}`:`//./${t}`:r&&!k(t)?`/${t}`:t)},D=function(...t){let e="";for(let r of t)if(r)if(e.length>0){let n=e[e.length-1]==="/",s=r[0]==="/";n&&s?e+=r.slice(1):e+=n||s?r:`/${r}`}else e+=r;return te(e)};function Oe(){return typeof process.cwd=="function"?process.cwd().replace(/\\/g,"/"):"/"}const m=function(...t){t=t.map(n=>C(n));let e="",r=!1;for(let n=t.length-1;n>=-1&&!r;n--){let s=n>=0?t[n]:Oe();!s||s.length===0||(e=`${s}/${e}`,r=k(s))}return e=re(e,!r),r&&!k(e)?`/${e}`:e.length>0?e:"."};function re(t,e){let r="",n=0,s=-1,i=0,o=null;for(let a=0;a<=t.length;++a){if(a<t.length)o=t[a];else{if(o==="/")break;o="/"}if(o==="/"){if(s!==a-1&&i!==1)if(i===2){if(r.length<2||n!==2||r[r.length-1]!=="."||r[r.length-2]!=="."){if(r.length>2){let c=r.lastIndexOf("/");c===-1?(r="",n=0):(r=r.slice(0,c),n=r.length-1-r.lastIndexOf("/")),s=a,i=0;continue}else if(r.length>0){r="",n=0,s=a,i=0;continue}}e&&(r+=r.length>0?"/..":"..",n=2)}else r.length>0?r+=`/${t.slice(s+1,a)}`:r=t.slice(s+1,a),n=a-s-1;s=a,i=0}else o==="."&&i!==-1?++i:i=-1}return r}const k=function(t){return Se.test(t)},ne=function(t){let e=C(t).replace(/\/$/,"").split("/").slice(0,-1);return e.length===1&&ee.test(e[0])&&(e[0]+="/"),e.join("/")||(k(t)?"/":".")},se=function(t,e){let r=C(t).split("/"),n="";for(let s=r.length-1;s>=0;s--){let i=r[s];if(i){n=i;break}}return n},ze=/^path$/i,P={key:"PATH",value:""};function ie(t){for(let e in t){if(!Object.prototype.hasOwnProperty.call(t,e)||!ze.test(e))continue;let r=t[e];return r?{key:e,value:r}:P}return P}function Ie(t,e){let r=e.value.split(T),n=[],s=t,i;do n.push(K(s,"node_modules",".bin")),i=s,s=M(s);while(s!==i);n.push(M(process.execPath));let o=n.concat(r).join(T);return{key:e.key,value:o}}function Me(t,e,r=!0){let n={...process.env,...e};if(!r)return n;let s=Ie(t,ie(n));return n[s.key]=s.value,n}const je=t=>{let e=t.length,r=new q,n=()=>{--e===0&&r.end()};for(let s of t)J(s,r,{end:!1}).then(n).catch(n);return r},S=/([()\][%!^"`<>&|;, *?])/g,Fe=/^#!\s*(.+)/,De=/\.(?:com|exe)$/i,Pe=/node_modules[\\/]\.bin[\\/][^\\/]+\.cmd$/i,Ge=process.platform==="win32",Re=[".EXE",".CMD",".BAT",".COM"];function Be(t,e=[],r={}){if(r.shell===!0||!Ge)return{command:t,args:e,options:r};let n=G(t,r),s=null;if(n!==null){let i=Buffer.alloc(150),o=null;try{o=he(n,"r"),fe(o,i,0,150,0)}catch{}finally{o!==null&&pe(o)}let a=i.toString().match(Fe);if(a!==null){let c=a[1].trim(),d=c.indexOf(" "),l=d===-1?c:c.slice(0,d),f=d===-1?"":c.slice(d+1),h=$e(l);s=h==="env"?f||null:h}}if(s!==null&&n!==null&&(e=[n,...e],t=s,n=G(t,r)),n===null||!De.test(n)){let i=n!==null&&Pe.test(n);t=ye(t),t=t.replace(S,"^$1"),e=e.map(o=>(o=o.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),o=o.replace(/(?=(\\+?)?)\1$/,"$1$1"),o=`"${o}"`,o=o.replace(S,"^$1"),i&&(o=o.replace(S,"^$1")),o)),e=["/d","/s","/c",`"${[t,...e].join(" ")}"`],t=r.env?.comspec??"cmd.exe",r={...r,windowsVerbatimArguments:!0}}return{command:t,args:e,options:r}}function G(t,e){let r=(e.cwd??Z()).toString(),n=e.env??process.env,s=ie(n).value,i=t.includes("/")||t.includes("\\")?[""]:[r,...s.split(T)],o=n.PATHEXT?n.PATHEXT.split(T):Re;t.includes(".")&&o[0]!==""&&o.unshift("");for(let a of i){let c=K(r,a.startsWith('"')&&a.endsWith('"')&&a.length>1?a.slice(1,-1):a,t);for(let d of o){let l=c+d;try{if(me(l).isFile())return l}catch{}}}return null}var R=class extends Error{result;output;get exitCode(){if(this.result.exitCode!==null)return this.result.exitCode}constructor(t,e){super(`Process exited with non-zero status (${t.exitCode})`),this.result=t,this.output=e}};const Ue={timeout:void 0,persist:!1},He={windowsHide:!0};function Ne(t){let e=new AbortController;for(let r of t){if(r.aborted)return e.abort(),r;r.addEventListener("abort",()=>{e.abort(r.reason)},{signal:e.signal})}return e.signal}async function B(t){let e="";try{for await(let r of t)e+=r.toString()}catch{}return e}var Le=class{_process;_aborted=!1;_options;_command;_args;_resolveClose;_processClosed;_thrownError;get process(){return this._process}get pid(){return this._process?.pid}get exitCode(){if(this._process&&this._process.exitCode!==null)return this._process.exitCode}constructor(t,e,r){this._options={...Ue,...r},this._command=t,this._args=e??[],this._processClosed=new Promise(n=>{this._resolveClose=n})}kill(t){return this._process?.kill(t)===!0}get aborted(){return this._aborted}get killed(){return this._process?.killed===!0}pipe(t,e,r){return We(t,e,{...r,stdin:this})}async*[Symbol.asyncIterator](){let t=this._process;if(!t)return;let e=[];this._streamErr&&e.push(this._streamErr),this._streamOut&&e.push(this._streamOut);let r=je(e),n=ke.createInterface({input:r});for await(let s of n)yield s.toString();if(await this._processClosed,t.removeAllListeners(),this._thrownError)throw this._thrownError;if(this._options?.throwOnError&&this.exitCode!==0&&this.exitCode!==void 0)throw new R(this)}async _waitForOutput(){let t=this._process;if(!t)throw Error("No process was started");let[e,r]=await Promise.all([this._streamOut?B(this._streamOut):"",this._streamErr?B(this._streamErr):""]);await this._processClosed;let{stdin:n}=this._options;if(n&&typeof n!="string"&&await n,t.removeAllListeners(),this._thrownError)throw this._thrownError;let s={stderr:r,stdout:e,exitCode:this.exitCode};if(this._options.throwOnError&&this.exitCode!==0&&this.exitCode!==void 0)throw new R(this,s);return s}then(t,e){return this._waitForOutput().then(t,e)}_streamOut;_streamErr;spawn(){let t=Z(),e=this._options,r={...He,...e.nodeOptions},n=[];this._resetState(),e.timeout!==void 0&&n.push(AbortSignal.timeout(e.timeout)),e.signal!==void 0&&n.push(e.signal),e.persist===!0&&(r.detached=!0),n.length>0&&(r.signal=Ne(n)),r.env=Me(t,r.env,e.nodePath);let s=Be(this._command,this._args,r),i=Y(s.command,s.args,s.options);if(i.stderr&&(this._streamErr=i.stderr),i.stdout&&(this._streamOut=i.stdout),this._process=i,i.once("error",this._onError),i.once("close",this._onClose),i.stdin){let{stdin:o}=e;typeof o=="string"?i.stdin.end(o):o?.process?.stdout?.pipe(i.stdin)}}_resetState(){this._aborted=!1,this._processClosed=new Promise(t=>{this._resolveClose=t}),this._thrownError=void 0}_onError=t=>{if(t.name==="AbortError"&&(!(t.cause instanceof Error)||t.cause.name!=="TimeoutError")){this._aborted=!0;return}this._thrownError=t};_onClose=()=>{this._resolveClose&&this._resolveClose()}};const z=(t,e,r)=>{let n=new Le(t,e,r);return n.spawn(),n},We=z;var Ve=Te({detectPackageManager:()=>ae,installDependencies:()=>et,packageManagers:()=>w});async function Xe(t,e,r={}){let n=te(t).split("/");for(;n.length>0;){let s=await e(n.join("/")||"/");if(s||!r.includeParentDirs)return s;n.pop()}}function qe(t){let e;return()=>(e===void 0&&(e=t().then(r=>(e=r,e))),e)}const Je=qe(async()=>{if(globalThis.process?.versions?.webcontainer)return!1;try{let{exitCode:t}=await z("corepack",["--version"]);return t===0}catch{return!1}});async function Ye(t,e,r={}){let n=t!=="npm"&&t!=="bun"&&t!=="deno"&&t!=="aube"&&t!=="nub"&&r.corepack!==!1&&await Je()?["corepack",[t,...e]]:[t,e],{exitCode:s,stdout:i,stderr:o}=await z(n[0],n[1],{nodeOptions:{cwd:m(r.cwd||process.cwd()),env:r.env,stdio:r.silent?"pipe":"inherit"}});if(s!==0)throw Error(`\`${n.flat().join(" ")}\` failed.${r.silent?["",i,o].join(`
|
|
2
|
-
`):""}`)}async function Ke(t={}){let e=t.cwd||process.cwd(),r={...process.env,...t.env},n=(typeof t.packageManager=="string"?w.find(s=>s.name===t.packageManager):t.packageManager)||await ae(t.cwd||process.cwd());if(!n)throw Error("No package manager auto-detected.");return{cwd:e,env:r,silent:t.silent??!1,packageManager:n,dev:t.dev??!1,workspace:t.workspace,global:t.global??!1,dry:t.dry??!1,corepack:t.corepack??!0}}const oe=/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;function Ze(t){let[e,r]=(t||"").split("@"),[n,s]=r?.split("+")||[];if(e&&e!=="-"&&oe.test(e))return{name:e,version:n,buildMeta:s};let i=(e||"").replace(/\W+/g,"");return{name:i,version:n,buildMeta:s,warnings:[`Abnormal characters found in \`packageManager\` field, sanitizing from \`${e}\` to \`${i}\``]}}function Qe(t){let e=t?.packageManager,r=Array.isArray(e)?e[0]:e,n=typeof r?.name=="string"?r.name:void 0,s=typeof r?.version=="string"?r.version:void 0;if(!n)return{};if(!oe.test(n)){let i=n.replace(/\W+/g,"");return{name:i,version:s,warnings:[`Abnormal characters found in \`devEngines.packageManager\` field, sanitizing from \`${n}\` to \`${i}\``]}}return{name:n,version:s}}const w=[{name:"npm",command:"npm",lockFile:"package-lock.json"},{name:"aube",command:"aube",lockFile:"aube-lock.yaml"},{name:"nub",command:"nub"},{name:"pnpm",command:"pnpm",lockFile:"pnpm-lock.yaml",files:["pnpm-workspace.yaml"]},{name:"bun",command:"bun",lockFile:["bun.lockb","bun.lock"]},{name:"yarn",command:"yarn",lockFile:"yarn.lock",files:[".yarnrc.yml"]},{name:"deno",command:"deno",lockFile:"deno.lock",files:["deno.json"]}];async function ae(t,e={}){let r=await Xe(m(t||"."),async n=>{if(!e.ignorePackageJSON){let s=D(n,"package.json");if(g(s)){let i=JSON.parse(await X(s,"utf8"));if(i?.packageManager){let{name:a,version:c="0.0.0",buildMeta:d,warnings:l}=Ze(i.packageManager);if(a){let f=c.split(".")[0],h=w.find(p=>p.name===a&&p.majorVersion===f)||w.find(p=>p.name===a);return{name:a,command:a,version:c,majorVersion:f,buildMeta:d,warnings:l,files:h?.files,lockFile:h?.lockFile}}}let o=Qe(i?.devEngines);if(o.name){let{name:a,version:c,warnings:d}=o,l=c?.match(/\d+/)?.[0],f=w.find(h=>h.name===a&&h.majorVersion===l)||w.find(h=>h.name===a);return{name:a,command:a,version:c,majorVersion:l,warnings:d,files:f?.files,lockFile:f?.lockFile}}}if(g(D(n,"deno.json")))return w.find(i=>i.name==="deno")}if(!e.ignoreLockFile){for(let s of w)if([s.lockFile,s.files].flat().filter(Boolean).some(i=>g(m(n,i))))return{...s}}},{includeParentDirs:e.includeParentDirs??!0});if(!r&&!e.ignoreArgv){let n=process.argv[1];if(n){for(let s of w)if(RegExp(`[/\\\\]\\.?${s.command}`).test(n))return s}}return r}async function et(t={}){let e=await Ke(t),r=t.frozenLockFile?{npm:["ci"],yarn:["install","--immutable"],bun:["install","--frozen-lockfile"],pnpm:["install","--frozen-lockfile"],deno:["install","--frozen"],aube:["install","--frozen-lockfile"],nub:["install","--frozen-lockfile"]}[e.packageManager.name]:["install"];return t.ignoreWorkspace&&e.packageManager.name==="pnpm"&&r.push("--ignore-workspace"),e.dry||await Ye(e.packageManager.command,r,{cwd:e.cwd,silent:e.silent,corepack:e.corepack}),{exec:{command:e.packageManager.command,args:r}}}const tt=Object.defineProperty({__proto__:null,basename:se,dirname:ne,dist_exports:Ve,resolve:m},Symbol.toStringTag,{value:"Module"});async function rt(t,e,r={}){const n=e+".json",s=JSON.parse(await X(n,"utf8").catch(()=>"{}")),i=(await E(t,{method:"HEAD",headers:r.headers}).catch(()=>{}))?.headers.get("etag");if(s.etag===i&&g(e))return;typeof i=="string"&&(s.etag=i);const o=await E(t,{headers:r.headers});if(o.status>=400)throw new Error(`Failed to download ${t}: ${o.status} ${o.statusText}`);const a=V(e);await xe(_e)(o.body,a),await ve(n,JSON.stringify(s),"utf8")}const nt=/^(?<repo>[-\w.]+\/[-\w.]+)(?<subdir>[^#]+)?(?<ref>#[-\w./@]+)?/,st=/^(?<repo>[-\w.]+(?:\/[-\w.]+)+?)(?:::(?<subdir>[^#]*))?(?<ref>#[-\w./@]+)?$/;function A(t,e){const r=e?.expandRepo||t.includes("::"),n=t.match(r?st:nt)?.groups||{},s=r?n.subdir?"/"+n.subdir:"/":n.subdir||"/";return{repo:n.repo||"",subdir:s,ref:n.ref?n.ref.slice(1):"main"}}function b(...t){process.env.DEBUG&&console.debug("[giget]",...t)}async function E(t,e={}){e.headers?.["sec-fetch-mode"]&&(e.mode=e.headers["sec-fetch-mode"]);const r=await fetch(t,{...e,headers:ce(e.headers)}).catch(n=>{throw new Error(`Failed to download ${t}: ${n}`,{cause:n})});if(e.validateStatus&&r.status>=400)throw new Error(`Failed to fetch ${t}: ${r.status} ${r.statusText}`);return r}function it(){const t=process.env.XDG_CACHE_HOME?m(process.env.XDG_CACHE_HOME,"giget"):m(Ee(),".cache/giget");if(process.platform==="win32"){const e=m(Q(),"giget");if(!g(e)&&g(t))try{we(t,e)}catch{}return e}return t}function ce(t={}){const e={};for(const[r,n]of Object.entries(t))n&&(e[r.toLowerCase()]=n);return e}const ot=(t,e)=>{const r=at(t);return{name:r.name,version:r.subdir?`${r.version||"default"}-${r.subdir.replaceAll("/","-")}`:r.version,tar:({auth:n}={})=>ct(r,n??e.auth)}};function at(t,e={}){const r=e.cwd??process.cwd();let n=t.replace(/#.*$/,""),s;if(/^[./]/.test(t))n=m(r,n);else if(/^https?:\/\//.test(n)){const l=/^(https?:\/\/[^/]+)\/([\w.-]+\/[\w.-]+?)(?:\.git)?(?:\/(.+))?$/.exec(n);if(l){const[,f,h,p]=l;n=`${f}/${h}`,p&&(s=p)}}else if(n.includes("@")){const l=/^(.*?:[\w.-]+\/[\w.-]+?)(?:\.git)?(?:\/(.+))?$/.exec(n);if(l){const[,f,h]=l;n=f,h&&(s=h)}}else{const l={"github:":"https://github.com/","gh:":"https://github.com/","gitlab:":"https://gitlab.com/","bitbucket:":"https://bitbucket.org/","sourcehut:":"https://git.sr.ht/~"},f=/^(.+?:)/.exec(n)?.at(1);f&&l[f]?n=n.replace(f,l[f]):f||(n=`${(process.env.GIGET_GIT_HOST||"https://github.com/").replace(/\/$/,"")}/${n}`);const h=/^(https?:\/\/[^/]+\/~?[\w.-]+\/[\w.-]+?)(?:\.git)?(?:\/(.+))?$/.exec(n);if(h){const[,p,u]=h;n=p,u&&(s=u)}}const i=n.replace(/^https?:\/\//,"").replace(/^.+@/,"").replace(/(\.git)?(#.*)?$/,"").replace(/^\W+/,"").replaceAll(/[:/]/g,"-"),[o,a]=/#(.+)$/.exec(t)?.at(1)?.split(":")??[],c=o||void 0,d=a||s;return{uri:n,name:i,...c&&{version:c},...d&&{subdir:d}}}async function ct(t,e){const r=await be(j(Q(),"giget-git-"));if(e&&/[\r\n]/.test(e))throw new Error("Auth token must not contain newline characters");const n={...process.env,GIT_TERMINAL_PROMPT:"0"};e&&(n.GIT_CONFIG_COUNT="1",n.GIT_CONFIG_KEY_0="http.extraHeader",n.GIT_CONFIG_VALUE_0=`Authorization: Bearer ${e}`);const s={env:n,timeout:6e4},i=lt(),o=c=>H(c,s,i),a=c=>H(c,{...s,cwd:r},i);try{const c=["clone","--progress","--depth","1"];t.subdir&&c.push("--filter=blob:none","--sparse","--no-checkout"),t.version&&c.push("--branch",t.version),c.push("--",t.uri,r);try{i.update("Cloning..."),await o(c),i.update("Cloned.")}catch(u){if(!t.version)throw u;b("Shallow clone failed, falling back to full clone:",u),i.update("Shallow clone failed, cloning..."),await x(r,{recursive:!0,force:!0}),await O(r,{recursive:!0}),await a(["init"]),await a(["remote","add","origin",t.uri]),await a(["fetch","origin"]),await a(["checkout",t.version]),i.update("Fetched.")}t.subdir&&(i.update(`Sparse checkout ${t.subdir}...`),await a(["sparse-checkout","set",t.subdir]),await a(["checkout"])),i.update("Packing...");const d=t.subdir?j(r,t.subdir):r,{create:l}=await import("../packem_chunks/tar.js").then(u=>u.index_min_exports);i.done();const f=l({gzip:!0,cwd:d,filter:u=>!u.startsWith(".git/")&&u!==".git"&&!u.startsWith("./.git/")&&u!=="./.git"},["."]).pipe(new q);let h=!1;const p=()=>{h||(h=!0,x(r,{recursive:!0,force:!0}))};return f.on("end",p),f.on("error",p),f.on("close",p),f}catch(c){throw i.done(),await x(r,{recursive:!0,force:!0}),c}}const U=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function H(t,e,r){return new Promise((n,s)=>{const i=Y("git",t,{...e,stdio:["ignore","pipe","pipe"]});i.stdout.resume();let o="";i.stderr?.on("data",a=>{const c=a.toString();for(const d of c.split(/[\r\n]/)){const l=d.trim();l&&(o=l)}r&&r.update(o)}),i.on("close",a=>{a===0?n(o):s(new Error(`git ${t[0]} exited with code ${a}. Is git installed?`))}),i.on("error",a=>{a.code==="ENOENT"?s(new Error("git is not installed or not found in PATH")):s(a)})})}function lt(){if(!process.stderr.isTTY)return{update(s){},done(){}};let t="",e=0;const r=()=>{const s=U[e%U.length];e++,process.stderr.write(`\x1B[2K\r\x1B[2m${s} ${t}\x1B[0m`)},n=setInterval(r,80);return{update(s){t=s,r()},done(){clearInterval(n),process.stderr.write("\x1B[2K\r")}}}const N=async(t,e)=>{if(t.endsWith(".json"))return await L(t,e);const r=new URL(t);let n=se(r.pathname);try{const s=await E(r.href,{method:"HEAD",validateStatus:!0,headers:{authorization:e.auth?`Bearer ${e.auth}`:void 0}});if((s.headers.get("content-type")||"").includes("application/json"))return await L(t,e);const i=s.headers.get("content-disposition")?.match(/filename="?(.+)"?/)?.[1];i&&(n=i.split(".")[0])}catch(s){b(`Failed to fetch HEAD for ${r.href}:`,s)}return{name:`${n}-${r.href.slice(0,8)}`,version:"",subdir:"",tar:r.href,defaultDir:n,headers:{Authorization:e.auth?`Bearer ${e.auth}`:void 0}}},L=async(t,e)=>{const r=await(await E(t,{validateStatus:!0,headers:{authorization:e.auth?`Bearer ${e.auth}`:void 0}})).json();if(!r.tar||!r.name)throw new Error(`Invalid template info from ${t}. name or tar fields are missing!`);return r},W=(t,e)=>{const r=A(t),n=process.env.GIGET_GITHUB_URL||"https://api.github.com";return{name:r.repo.replace("/","-"),version:r.ref,subdir:r.subdir,headers:{Authorization:e.auth?`Bearer ${e.auth}`:void 0,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28"},url:`${n.replace("api.github.com","github.com")}/${r.repo}/tree/${r.ref}${r.subdir}`,tar:`${n}/repos/${r.repo}/tarball/${r.ref}`}},ut=(t,e)=>{const r=A(t,{expandRepo:!0}),n=process.env.GIGET_GITLAB_URL||"https://gitlab.com";return{name:r.repo.replace("/","-"),version:r.ref,subdir:r.subdir,headers:{authorization:e.auth?`Bearer ${e.auth}`:void 0,"sec-fetch-mode":"same-origin"},url:`${n}/${r.repo}/tree/${r.ref}${r.subdir}`,tar:`${n}/${r.repo}/-/archive/${r.ref}.tar.gz`}},dt=(t,e)=>{const r=A(t);return{name:r.repo.replace("/","-"),version:r.ref,subdir:r.subdir,headers:{authorization:e.auth?`Bearer ${e.auth}`:void 0},url:`https://bitbucket.com/${r.repo}/src/${r.ref}${r.subdir}`,tar:`https://bitbucket.org/${r.repo}/get/${r.ref}.tar.gz`}},ht=(t,e)=>{const r=A(t);return{name:r.repo.replace("/","-"),version:r.ref,subdir:r.subdir,headers:{authorization:e.auth?`Bearer ${e.auth}`:void 0},url:`https://git.sr.ht/~${r.repo}/tree/${r.ref}/item${r.subdir}`,tar:`https://git.sr.ht/~${r.repo}/archive/${r.ref}.tar.gz`}},ft={http:N,https:N,git:ot,github:W,gh:W,gitlab:ut,bitbucket:dt,sourcehut:ht},pt="https://raw.githubusercontent.com/unjs/giget/main/templates",mt=(t=pt,e={})=>(async r=>{const n=Date.now(),s=`${t}/${r}.json`,i=await E(s,{headers:{authorization:e.auth?`Bearer ${e.auth}`:void 0}});if(i.status>=400)throw new Error(`Failed to download ${r} template info from ${s}: ${i.status} ${i.statusText}`);const o=await i.json();if(!o.tar||!o.name)throw new Error(`Invalid template info from ${s}. name or tar fields are missing!`);return b(`Fetched ${r} template info from ${s} in ${Date.now()-n}ms`),o}),gt=/^([\w+-.]+):/;function wt(t){if(!t)return;if(typeof t=="function")return t;const e=globalThis.process.getBuiltinModule?.("node:path")?.matchesGlob;if(typeof e!="function")throw new TypeError("Ignore patterns require `path.matchesGlob` which is supported in Node.js v22.5.0, v20.17.0 or later.");return r=>t.some(n=>e(r,n))}async function bt(t,e={}){const r=wt(e.ignore);e.registry=process.env.GIGET_REGISTRY??e.registry,e.auth=process.env.GIGET_AUTH??e.auth;const n=e.registry===!1?void 0:mt(e.registry,{auth:e.auth});let s=e.provider||(n?"registry":"github"),i=t;const o=t.match(gt);o&&(s=o[1],i=t.slice(o[0].length),(s==="http"||s==="https")&&(i=t)),s.endsWith("+git")&&(i=`${s.slice(0,-4)}:${i}`,s="git");const a=e.providers?.[s]||ft[s]||n;if(!a)throw new Error(`Unsupported provider: ${s}`);const c=await Promise.resolve().then(()=>a(i,{auth:e.auth})).catch(u=>{throw new Error(`Failed to download template from ${s}: ${u.message}`)});if(!c)throw new Error(`Failed to resolve template from ${s}`);c.name=(c.name||"template").replace(/[^\da-z-]/gi,"-"),c.defaultDir=(c.defaultDir||c.name).replace(/[^\da-z-]/gi,"-");const d=m(m(it(),s,c.name),(c.version||c.name)+".tar.gz");if(e.preferOffline&&g(d)&&(e.offline=!0),!e.offline){await O(ne(d),{recursive:!0});const u=Date.now();if(typeof c.tar=="function"){const _=c.tar;await(async()=>{const $=await _({auth:e.auth});await J($ instanceof I?$:I.fromWeb($),V(d))})().catch($=>{if(!g(d))throw $;b("Download error. Using cached version:",$),e.offline=!0})}else await rt(c.tar,d,{headers:{Authorization:e.auth?`Bearer ${e.auth}`:void 0,...ce(c.headers)}}).catch(_=>{if(!g(d))throw _;b("Download error. Using cached version:",_),e.offline=!0});b(`Downloaded to ${d} in ${Date.now()-u}ms`)}if(!g(d))throw new Error(`Tarball not found: ${d} (offline: ${e.offline})`);const l=m(m(e.cwd||"."),e.dir||c.defaultDir);if(e.forceClean&&await x(l,{recursive:!0,force:!0}),!e.force&&g(l)&&ge(l).length>0)throw new Error(`Destination ${l} already exists.`);await O(l,{recursive:!0});const f=Date.now(),h=c.subdir?.replace(/^\//,"")||"",{extract:p}=await import("../packem_chunks/tar.js").then(u=>u.index_min_exports);if(await p({file:d,cwd:l,onReadEntry(u){u.path=u.path.split("/").splice(1).join("/"),h&&(u.path.startsWith(h+"/")?u.path=u.path.slice(h.length):u.path=""),r&&u.path&&r(u.path.replace(/^\//,""))&&(u.path="")}}),b(`Extracted to ${l} in ${Date.now()-f}ms`),e.install){b("Installing dependencies...");const{installDependencies:u}=await Promise.resolve().then(()=>tt).then(_=>_.dist_exports);await u({cwd:l,silent:e.silent,...typeof e.install=="object"?e.install:{}})}return{...c,source:i,dir:l}}export{Te as _,bt as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createRequire as U}from"node:module";import{e as y,m as O,b as S,z as J}from"./index-BzhrR_iC.js";import{withEnhancedPath as Y,collectNodeModulesBinDirs as z}from"@visulima/task-runner";import{s as j}from"./index-B4AjSxHU.js";import{detectPackageManager as G,resolveAdd as H,resolveRemove as V,whichBin as X,resolveUnlink as K,resolveInstall as Q,execPmCommandInteractive as Z,resolveDlx as ee,resolveExec as ne,resolveDedupe as re,resolveWhy as se,resolveLink as ae,resolvePmCommand as ie}from"#native";import{y as R}from"./isAccessibleSync-DYKTrrvc-C-_5cgwu.js";let T;const x=e=>(T??=U(import.meta.url))(e),k=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,q=e=>{if(typeof k<"u"&&k.versions&&k.versions.node){const[n,r]=k.versions.node.split(".").map(Number);if(n>22||n===22&&r>=3||n===20&&r>=16)return k.getBuiltinModule(e)}return x(e)},{spawn:F,spawnSync:E}=q("node:child_process"),p=(e,n,r,s)=>{for(const a of n)e.push("--filter",a);r&&e.push("--recursive"),s&&e.push("--workspace-root")},te=e=>{const n=[],r=[];return p(n,e.filter,e.recursive,e.workspaceRoot),e.silent&&n.push("--silent"),e.frozenLockfile&&n.push("--frozen-lockfile"),n.push("install"),e.dev&&n.push("--dev"),e.prod&&n.push("--prod"),e.force&&n.push("--force"),e.ignoreScripts&&n.push("--ignore-scripts"),e.lockfileOnly&&n.push("--lockfile-only"),e.noOptional&&n.push("--no-optional"),e.offline&&n.push("--offline"),{args:n,bin:"aube",warnings:r}},oe=e=>{const n=[],r=[];return p(n,e.filter,!1,!1),n.push("add"),e.saveDev&&n.push("--save-dev"),e.exact&&n.push("--save-exact"),e.global&&n.push("--global"),e.optional&&n.push("--save-optional"),e.peer&&n.push("--save-peer"),e.workspace&&r.push("aube has no flag for the `workspace:` protocol; it auto-detects local workspace members during add. Ignoring --workspace."),e.workspaceRoot&&n.push("--workspace"),n.push(...e.packages),{args:n,bin:"aube",warnings:r}},ue=e=>{const n=[];return p(n,e.filter,e.recursive,!1),n.push("remove"),e.saveDev&&n.push("--save-dev"),e.global&&n.push("--global"),e.workspaceRoot&&n.push("--workspace"),n.push(...e.packages),{args:n,bin:"aube",warnings:[]}},ce=e=>{const n=["dedupe"];return e&&n.push("--check"),{args:n,bin:"aube",warnings:[]}},le=e=>{const n=[],r=[];p(n,e.filter,e.recursive,!1),n.push("why"),e.dev&&n.push("--dev"),e.prod&&n.push("--prod"),e.json&&n.push("--json"),e.long&&n.push("--long"),e.parseable&&n.push("--parseable"),e.depth!==void 0&&r.push("aube why does not accept --depth; ignoring."),e.noOptional&&r.push("aube why does not accept --no-optional; ignoring."),e.global&&r.push("aube why does not accept --global; ignoring.");const[s,...a]=e.packages;return s===void 0?r.push("aube why requires a package name; none provided."):(a.length>0&&r.push("aube why takes a single package; using the first."),n.push(s)),{args:n,bin:"aube",warnings:r}},fe=e=>{const n=[];e.silent&&n.push("--silent"),n.push("dlx");for(const r of e.additionalPackages)n.push("--package",r);return e.shellMode&&n.push("--shell-mode"),n.push(e.package),n.push(...e.args),{args:n,bin:"aube",warnings:[]}},de=e=>{const n=[];return p(n,e.filter,e.recursive,e.workspaceRoot),n.push("exec"),e.parallel&&n.push("--parallel"),e.reverse&&n.push("--reverse"),e.shellMode&&n.push("--shell-mode"),n.push(e.command),n.push(...e.args),{args:n,bin:"aube",warnings:[]}},he=e=>{const n=["link"];return e!==null&&n.push(e),{args:n,bin:"aube",warnings:[]}},pe=(e,n)=>{const r=[],s=[];return n&&r.push("--recursive"),r.push("unlink"),e.length>1&&s.push("aube unlink takes a single package; using the first."),e.length>0&&r.push(e[0]),{args:r,bin:"aube",warnings:s}},ge=e=>{const n=["view","--",e.package],r=[],[s,...a]=e.fields;return s!==void 0?(a.length>0&&r.push("aube view only supports a single field; using the first."),e.json&&r.push("aube view does not support --json with a field selector; printing the field without --json."),n.push(s)):e.json&&n.push("--json"),{args:n,bin:"aube",warnings:r}},Ye=e=>{const n=[],r=[];return p(n,e.filters,e.recursive,e.workspaceRoot),n.push("update"),e.dev&&n.push("--dev"),e.prod&&n.push("--prod"),e.global&&n.push("--global"),e.interactive&&n.push("--interactive"),e.latest&&n.push("--latest"),e.noOptional&&n.push("--no-optional"),e.noSave&&n.push("--no-save"),n.push(...e.packages),{args:n,bin:"aube",warnings:r}},be=new Set(["fund","ping","search","token"]),ke=(e,n)=>be.has(e)?{args:[e,...n],bin:"npm",warnings:[`'${e}' is not natively supported by aube. Delegating to npm.`]}:{args:[e,...n],bin:"aube",warnings:[]},w=256*1024,we=e=>{const n=e?{...process.env,...e}:{...process.env};return process.stderr.isTTY&&n.FORCE_COLOR===void 0&&n.NO_COLOR===void 0&&(n.FORCE_COLOR="1"),n},I=e=>e!==""&&!/[\s"&()<>^|%!]/u.test(e)?e:`"${e.replaceAll(/(\\*)"/gu,String.raw`$1$1\"`).replace(/(\\+)$/u,"$1$1").replaceAll(/[&()<>^|%!]/gu,String.raw`^$&`)}"`,ve=async(e,n,r)=>new Promise((s,a)=>{const i=process.platform==="win32",t=F(i?I(e):e,i?n.map(o=>I(o)):[...n],{cwd:r.cwd,env:we(r.env),shell:i,stdio:["inherit","pipe","pipe"],windowsHide:!0});let c=[],f=0;const d=o=>{if(c.push(o),f+=o.length,!(f<=w)){for(;c.length>1&&f-c[0].length>w;)f-=c.shift().length;if(c.length===1&&f>w){const h=c[0];c[0]=h.subarray(h.length-w),f=w}}},b=()=>Buffer.concat(c).toString("utf8");t.stdout?.on("data",o=>{process.stdout.write(o),d(o)}),t.stderr?.on("data",o=>{process.stderr.write(o),d(o)}),t.on("error",a),t.on("close",o=>{const h=b();c=[],s({code:o??1,output:h})})}),v=e=>{const n=j.coerce(e);return n?j.gte(n,"11.0.0"):!1},l=e=>e.name==="yarn"&&!e.version.startsWith("1."),$=e=>e.name==="yarn"&&e.version.startsWith("1."),ye=e=>e[0]==="rm"?["remove",...e.slice(1)]:e,me=(e,n,r)=>{switch(n){case"audit":return l(e)?{args:["npm","audit",...r],bin:"yarn",kind:"rewrite"}:{kind:"passthrough"};case"config":{if(l(e)){const[s,...a]=r;return s==="delete"?{args:["config","unset",...a],bin:"yarn",kind:"rewrite",warning:"yarn berry uses `config unset`, not `config delete`."}:{kind:"passthrough"}}return e.name==="bun"?{kind:"skip",warning:"bun has no `config` CLI. Edit bunfig.toml or .npmrc directly."}:e.name==="deno"?{kind:"skip",warning:"deno has no registry-config CLI. Edit deno.json directly."}:{kind:"passthrough"}}case"dist-tag":return $(e)?{args:["tag",...r],bin:"yarn",kind:"rewrite",warning:"yarn 1 has no `dist-tag`; using `yarn tag`."}:l(e)?{args:["npm","tag",...ye(r)],bin:"yarn",kind:"rewrite"}:e.name==="bun"||e.name==="deno"?{kind:"skip",warning:`${e.name} has no \`dist-tag\`. Use \`npm dist-tag\` instead.`}:{kind:"passthrough"};case"login":case"logout":return l(e)?{args:["npm",n,...r],bin:"yarn",kind:"rewrite"}:e.name==="bun"?{args:[n,...r],bin:"npm",kind:"rewrite",warning:`bun has no \`${n}\`; falling back to \`npm ${n}\` (writes ~/.npmrc, which bun reads).`}:e.name==="deno"?{kind:"skip",warning:`deno has no \`${n}\`. JSR uses browser OAuth via \`deno publish\`.`}:{kind:"passthrough"};case"owner":return e.name==="pnpm"&&v(e.version)?{args:["owner",...r],bin:"npm",kind:"rewrite",warning:"pnpm 11 removed `owner`; falling back to `npm owner`."}:l(e)?{args:["owner",...r],bin:"npm",kind:"rewrite",warning:"yarn berry has no `owner` (not in `yarn npm`); falling back to `npm owner`."}:e.name==="bun"?{args:["owner",...r],bin:"npm",kind:"rewrite",warning:"bun has no `owner`; falling back to `npm owner`."}:e.name==="deno"?{kind:"skip",warning:"deno has no `owner`. JSR uses scope-member roles via the web UI."}:{kind:"passthrough"};case"ping":return e.name==="pnpm"&&v(e.version)?{args:["ping",...r],bin:"npm",kind:"rewrite",warning:"pnpm 11 removed `ping`; falling back to `npm ping`."}:{kind:"passthrough"};case"plugin":return l(e)?{kind:"passthrough"}:{kind:"skip",warning:`${e.name} does not support yarn-style plugins. Skipping (no-op).`};case"prune":return $(e)?{kind:"skip",warning:"yarn 1 has no `prune`. Use `yarn install --production` for a prod-only tree."}:l(e)?{kind:"skip",warning:"yarn berry has no `prune`. Use `yarn workspaces focus --production` instead."}:e.name==="bun"||e.name==="deno"?{kind:"skip",warning:`${e.name} has no \`prune\`. Pruning happens automatically on install.`}:{kind:"passthrough"};case"publish":return l(e)?{args:["npm","publish",...r],bin:"yarn",kind:"rewrite"}:{kind:"passthrough"};case"rebuild":return $(e)?{kind:"skip",warning:"yarn 1 has no `rebuild`. Re-install instead."}:e.name==="bun"?{kind:"skip",warning:"bun has no `rebuild`. Use `bun install --force` instead."}:e.name==="deno"?{kind:"skip",warning:"deno has no `rebuild`."}:{kind:"passthrough"};case"search":return e.name==="pnpm"&&v(e.version)?{args:["search",...r],bin:"npm",kind:"rewrite",warning:"pnpm 11 removed `search`; falling back to `npm search`."}:{kind:"passthrough"};case"token":return e.name==="pnpm"&&v(e.version)?{args:["token",...r],bin:"npm",kind:"rewrite",warning:"pnpm 11 removed `token`; falling back to `npm token`."}:{kind:"passthrough"};case"whoami":return e.name==="pnpm"&&v(e.version)?{args:["whoami",...r],bin:"npm",kind:"rewrite",warning:"pnpm 11 removed `whoami`; falling back to `npm whoami`."}:l(e)?{args:["npm","whoami",...r],bin:"yarn",kind:"rewrite"}:e.name==="bun"?{args:["pm","whoami",...r],bin:"bun",kind:"rewrite"}:e.name==="deno"?{kind:"skip",warning:"deno has no `whoami`. JSR uses browser auth."}:{kind:"passthrough"};default:return{kind:"passthrough"}}},A=e=>X(e)!==null,je=e=>{const n=[["pnpm-lock.yaml","pnpm"],["yarn.lock","yarn"],["package-lock.json","npm"],["npm-shrinkwrap.json","npm"],["bun.lock","bun"],["bun.lockb","bun"],["deno.lock","deno"]];let r=e;for(;;){for(const[a,i]of n)if(R(y(r,a)))return i;const s=O(r);if(s===r||S(r).root===r)return;r=s}},ze=(e,n)=>{if(n.name!=="aube")return;const r=je(e);if(r!==void 0)return`Resolved installer is aube but the workspace has a ${r} lockfile. Aube reads and writes ${r}'s lockfile format in place, but its byte output may differ subtly — expect a one-time churn diff on the first install, and ongoing drift if your team mixes tools on the same lockfile. To pin the choice across the team, set \`install.backend\` in vis.config; to bypass aube for this run, pass --no-aube.`},C=e=>{if(R(e))try{return JSON.parse(J(e,{buffer:!1}))}catch{return}},Re=e=>{let n=e;for(;;){const r=y(n,"package.json"),s=C(r);if(s&&typeof s.packageManager=="string"&&s.packageManager.length>0)return s.packageManager;const a=O(n);if(a===n||S(n).root===n)return;n=a}},M=new Set(["npm","pnpm","yarn"]),P=(e,n,r)=>r===!1||!M.has(n)||!A("corepack")?!1:r===!0?!0:Re(e)!==void 0,Ge=(e,n)=>{const r=n.backend,s=process.env.VIS_INSTALLER,a=r??s??n.configBackend,i=n.configCorepack??"auto";if(a&&a!=="auto"){if(a==="aube"&&!A("aube"))throw new Error('install.backend is set to "aube" but the `aube` binary is not on PATH. Install it via `npm i -g @endevco/aube`, `mise use -g aube`, or `brew install endevco/tap/aube`.');return{name:a,useCorepack:P(e,a,i),version:"latest"}}if(A("aube"))return{name:"aube",useCorepack:!1,version:"latest"};const t=$e(e);return{...t,useCorepack:P(e,t.name,i)}},$e=e=>{if(!R(e))throw new Error(`Could not detect package manager in ${e}. Directory does not exist.`);const n=G(e);return{name:n.name,version:n.version||"latest"}},L=(e,n)=>n.useCorepack!==!0||!M.has(n.name)||e.bin==="corepack"||e.bin!==n.name?e:{...e,args:[n.name,...e.args],bin:"corepack"},Ae=(e,n,r)=>{if(r===void 0)return Z(e.bin,e.args,n);const s=E(e.bin,e.args,{cwd:n,env:{...process.env,...r},stdio:"inherit"});if(s.error)throw s.error;return s.status??1},u=(e,n,r,s,a={})=>{const i=L(n,e);for(const t of i.warnings)s.warn(`warning: ${t}`);return a.dry?(s.log(`[dry-run] ${i.bin} ${i.args.join(" ")}`),0):Ae(i,r,a.env)},g=(e,n,r,s,a={})=>u(e,n(),r,s,a),Oe=(e,n)=>n==="aube"||n==="deno"?e:{...e,args:[...e.args,"--prefer-offline"]},Se=(e,n,r)=>n!=="yarn"||r.startsWith("1.")||!e.args.includes("--immutable")||e.args.includes("--immutable-cache")?e:{...e,args:[...e.args,"--immutable-cache"]},W=(e,n,r)=>{let s=e.name==="aube"?te(n):Q(e.name,e.version,{...n,silent:n.silent||r.silent===!0});return r.preferOffline&&(s=Oe(s,e.name)),r.ciMode&&(s=Se(s,e.name,e.version)),s},He=(e,n,r,s,a={})=>{const i=W(e,n,a);return D(e,i,r,s,{dry:a.dry,env:a.env})},Ve=async(e,n,r,s,a={})=>{const i=L(W(e,n,a),e);for(const t of i.warnings)s.warn(`warning: ${t}`);return a.dry?(s.log(`[dry-run] ${i.bin} ${i.args.join(" ")}`),{code:0,output:""}):ve(i.bin,i.args,{cwd:r,env:a.env?{...process.env,...a.env}:process.env})},N=(e,n)=>{const r=n==="deno"?"--quiet":"--silent";return{...e,args:[...e.args,r]}},Ce=(e,n)=>n==="yarn"||n==="aube"?null:{...e,args:[...e.args,"--dry-run"]},D=(e,n,r,s,a)=>{if(a.dry!==!0)return u(e,n,r,s,a);const i=Ce(n,e.name);return i===null?u(e,n,r,s,a):u(e,i,r,s,{env:a.env})},De=(e,n)=>n==="aube"?{...e,args:[...e.args,"--ignore-scripts"]}:n==="deno"?e:{...e,args:[...e.args,"--ignore-scripts"]},_e=(e,n,r,s,a={})=>{let i=e.name==="aube"?oe(n):H(e.name,e.version,n);a.ignoreScripts&&(i=De(i,e.name)),a.silent&&(i=N(i,e.name));const t=D(e,i,r,s,{dry:a.dry,env:a.env});return t===0&&a.autoInstallPeers&&Me(e,n,r,s,a),t},Ie=e=>{if(e.startsWith("@")){const r=e.indexOf("/");if(r===-1)return e;const s=e.indexOf("@",r);return s===-1?e:e.slice(0,s)}const n=e.indexOf("@");return n===-1?e:e.slice(0,n)},Pe=(e,n)=>{let r=e;for(;;){const s=y(r,"node_modules",n,"package.json"),a=C(s);if(a)return a;const i=O(r);if(i===r||S(r).root===r)return;r=i}},Ee=e=>{const n=C(y(e,"package.json")),r=new Set;if(!n)return r;for(const s of["dependencies","devDependencies","peerDependencies","optionalDependencies"]){const a=n[s];if(a)for(const i of Object.keys(a))r.add(i)}return r},Me=(e,n,r,s,a)=>{if(e.name==="deno")return;const i=Ee(r),t=new Map;for(const d of n.packages){const b=Ie(d),o=Pe(r,b);if(!o?.peerDependencies)continue;const h=o.peerDependenciesMeta??{};for(const[m,B]of Object.entries(o.peerDependencies))h[m]?.optional||i.has(m)||t.has(m)||t.set(m,B)}if(t.size===0)return;const c=[...t.entries()].map(([d,b])=>`${d}@${b}`);s.log(`auto-installing peer dependencies: ${c.join(", ")}`);const f={exact:!1,filter:n.filter,global:!1,optional:!1,packages:c,peer:!1,saveDev:n.saveDev,workspace:!1,workspaceRoot:n.workspaceRoot};_e(e,f,r,s,{ignoreScripts:a.ignoreScripts})},Xe=(e,n,r,s,a={})=>{let i=e.name==="aube"?ue(n):V(e.name,e.version,n);return a.silent&&(i=N(i,e.name)),D(e,i,r,s,{dry:a.dry,env:a.env})},Ke=(e,n,r,s,a={})=>e.name==="aube"?u(e,ce(n),r,s,a):g(e,()=>re(e.name,e.version,n),r,s,a),Qe=(e,n,r,s,a={})=>e.name==="aube"?u(e,le(n),r,s,a):g(e,()=>se(e.name,e.version,n),r,s,a),Le=(e,n)=>{if(e.name==="aube")return ge(n);const r=[],s=[],a=e.name;switch(e.name){case"bun":{const i=j.coerce(e.version);i&&j.lt(i,"1.3.0")&&s.push(`bun ${e.version} does not support \`bun pm view\` (added in bun 1.3). Upgrade bun, or run \`npm view ${n.package}\` instead.`),r.push("pm","view","--",n.package,...n.fields),n.json&&r.push("--json");break}case"deno":{const i=n.package.startsWith("npm:")||n.package.startsWith("jsr:")||n.package.startsWith("https://")||n.package.startsWith("http://")||n.package.startsWith("file:")?n.package:`npm:${n.package}`;r.push("info","--",i),n.json&&r.push("--json"),n.fields.length>0&&s.push("deno info does not accept field selectors; ignoring.");break}case"npm":case"pnpm":{r.push("view","--",n.package,...n.fields),n.json&&r.push("--json");break}case"yarn":{if(e.version.startsWith("1.")){r.push("info","--",n.package);const[i,...t]=n.fields;i!==void 0&&(t.length>0&&s.push("yarn v1 only supports querying one field at a time; using the first."),r.push(i)),n.json&&r.push("--json")}else r.push("npm","info","--",n.package),n.fields.length>0&&s.push("yarn berry does not support field arguments to 'npm info'; ignoring."),n.json&&r.push("--json");break}default:{const i=e.name;throw new Error(`Unsupported package manager: ${i}`)}}return{args:r,bin:a,warnings:s}},Ze=(e,n,r,s,a={})=>u(e,Le(e,n),r,s,a),en=(e,n,r,s,a={})=>e.name==="aube"?u(e,he(n),r,s,a):g(e,()=>ae(e.name,e.version,n),r,s,a),nn=(e,n,r,s,a,i={})=>e.name==="aube"?u(e,pe(n,r),s,a,i):g(e,()=>K(e.name,e.version,n,r),s,a,i),We=(e,n,r)=>{if(e.args.includes("--offline")||e.args.includes("--cached-only"))return e;const s=(a,i)=>{const t=[...e.args];return t.splice(i,0,a),{...e,args:t}};switch(n){case"aube":case"pnpm":return s("--offline",1);case"bun":return{...e,warnings:[...e.warnings,"bun x does not support --offline. Pre-install the package via `vis install` so bun x resolves from the local cache."]};case"deno":return s("--cached-only",1);case"npm":return s("--offline",1);case"yarn":return r.startsWith("1.")?s("--offline",0):{...e,warnings:[...e.warnings,"yarn berry has no --offline flag for dlx. Configure `enableNetwork: false` in .yarnrc.yml or set `enableMirror: true` for offline-first behavior."]};default:{const a=n;return{...e,warnings:[...e.warnings,`applyDlxOffline: unsupported pm ${String(a)}`]}}}},rn=(e,n,r,s,a={})=>{let i=e.name==="aube"?fe(n):ee(e.name,e.version,n);return a.offline&&(i=We(i,e.name,e.version)),u(e,i,r,s,{dry:a.dry,env:a.env})},_=process.platform==="win32",Ne=_?[".exe",".cmd",".bat",".ps1",""]:[""],Be=(e,n)=>{if(!(e.includes("/")||e.includes("\\")))for(const r of z(n))for(const s of Ne){const a=y(r,`${e}${s}`);if(R(a))return _?a.replaceAll("/","\\"):a}},sn=(e,n,r)=>{const s=Be(e,r);if(s===void 0||_&&!s.toLowerCase().endsWith(".exe"))return null;const a=E(s,n,{cwd:r,env:Y({...process.env},r),stdio:"inherit"});if(a.error)throw a.error;return a.status??1},an=(e,n,r,s,a={})=>e.name==="aube"?u(e,de(n),r,s,a):g(e,()=>ne(e.name,e.version,n),r,s,a),tn=(e,n,r,s,a,i={})=>{if(e.name==="aube")return u(e,ke(n,r),s,a,i);const t=me(e,n,r);return t.kind==="skip"?(a.warn(`warning: ${t.warning}`),0):t.kind==="rewrite"?u(e,{args:t.args,bin:t.bin,warnings:t.warning?[t.warning]:[]},s,a,i):g(e,()=>ie(e.name,e.version,n,r),s,a,i)};export{Ge as a,an as b,_e as c,$e as d,Ke as e,Ze as f,ze as g,Ve as h,en as i,tn as j,Xe as k,nn as l,Qe as m,He as n,rn as o,Ye as p,sn as r,ve as s};
|