@visulima/vis 1.0.0-alpha.15 → 1.0.0-alpha.16

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 (101) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/LICENSE.md +44 -233
  3. package/dist/bin.js +1 -1
  4. package/dist/config/index.d.ts +121 -94
  5. package/dist/config/index.js +1 -1
  6. package/dist/packem_chunks/bin.js +271 -271
  7. package/dist/packem_chunks/config.js +18 -0
  8. package/dist/packem_chunks/fix.js +1 -1
  9. package/dist/packem_chunks/handler.js +1 -1
  10. package/dist/packem_chunks/handler10.js +1 -1
  11. package/dist/packem_chunks/handler11.js +1 -1
  12. package/dist/packem_chunks/handler12.js +1 -1
  13. package/dist/packem_chunks/handler13.js +1 -1
  14. package/dist/packem_chunks/handler14.js +4 -4
  15. package/dist/packem_chunks/handler15.js +1 -1
  16. package/dist/packem_chunks/handler16.js +1 -1
  17. package/dist/packem_chunks/handler17.js +1 -1
  18. package/dist/packem_chunks/handler18.js +1 -1
  19. package/dist/packem_chunks/handler19.js +5 -5
  20. package/dist/packem_chunks/handler2.js +1 -1
  21. package/dist/packem_chunks/handler20.js +2 -1
  22. package/dist/packem_chunks/handler21.js +18 -1
  23. package/dist/packem_chunks/handler22.js +1 -5
  24. package/dist/packem_chunks/handler23.js +1 -1
  25. package/dist/packem_chunks/handler24.js +5 -3
  26. package/dist/packem_chunks/handler25.js +1 -1
  27. package/dist/packem_chunks/handler26.js +3 -1
  28. package/dist/packem_chunks/handler27.js +1 -7
  29. package/dist/packem_chunks/handler28.js +1 -23
  30. package/dist/packem_chunks/handler29.js +7 -3
  31. package/dist/packem_chunks/handler3.js +1 -1
  32. package/dist/packem_chunks/handler30.js +23 -18
  33. package/dist/packem_chunks/handler31.js +3 -1
  34. package/dist/packem_chunks/handler32.js +1 -2
  35. package/dist/packem_chunks/handler33.js +2 -25
  36. package/dist/packem_chunks/handler34.js +25 -2
  37. package/dist/packem_chunks/handler35.js +2 -2
  38. package/dist/packem_chunks/handler36.js +8 -8
  39. package/dist/packem_chunks/handler37.js +3 -3
  40. package/dist/packem_chunks/handler38.js +4 -4
  41. package/dist/packem_chunks/handler39.js +6 -6
  42. package/dist/packem_chunks/handler40.js +5 -5
  43. package/dist/packem_chunks/handler41.js +9 -9
  44. package/dist/packem_chunks/handler42.js +10 -10
  45. package/dist/packem_chunks/handler43.js +1 -1
  46. package/dist/packem_chunks/handler44.js +5 -5
  47. package/dist/packem_chunks/handler45.js +3 -3
  48. package/dist/packem_chunks/handler46.js +9 -9
  49. package/dist/packem_chunks/handler47.js +161 -36
  50. package/dist/packem_chunks/handler48.js +1 -1
  51. package/dist/packem_chunks/handler5.js +5 -5
  52. package/dist/packem_chunks/handler6.js +1 -1
  53. package/dist/packem_chunks/handler7.js +1 -1
  54. package/dist/packem_chunks/handler8.js +1 -1
  55. package/dist/packem_chunks/handler9.js +1 -1
  56. package/dist/packem_chunks/heal-accept.js +2 -2
  57. package/dist/packem_chunks/heal.js +1 -1
  58. package/dist/packem_chunks/help-command.js +16 -16
  59. package/dist/packem_chunks/index.js +1 -1
  60. package/dist/packem_chunks/loader.js +1 -1
  61. package/dist/packem_shared/{ai-analysis-CGVjqwdc.js → ai-analysis-C_GpXikx.js} +3 -3
  62. package/dist/packem_shared/ai-cache-DrCLD4gc.js +1 -0
  63. package/dist/packem_shared/ai-fix-CWOz12Om.js +43 -0
  64. package/dist/packem_shared/applyDefaults-DLY94gWA.js +1 -0
  65. package/dist/packem_shared/cache-directory-C_U1qsIw.js +1 -0
  66. package/dist/packem_shared/definePlugin-CWm4Dv_t.js +1 -0
  67. package/dist/packem_shared/dependency-scan-YdgNVvoz.js +2 -0
  68. package/dist/packem_shared/docker-Dl0AoVTZ.js +60 -0
  69. package/dist/packem_shared/failure-log-CSC6KfcO.js +2 -0
  70. package/dist/packem_shared/flakiness-Dzz-I3dB.js +1 -0
  71. package/dist/packem_shared/lifecycle-BC6Nst6i.js +2 -0
  72. package/dist/packem_shared/{lockfile-B7JJzxnL.js → lockfile-i-qvq_k8.js} +1 -1
  73. package/dist/packem_shared/otelPlugin-CJR2T_lk.js +1 -0
  74. package/dist/packem_shared/{readTomlSync-1fKo0R52-DAKNI1Me.js → readTomlSync-1fKo0R52-DtxWULlF.js} +1 -1
  75. package/dist/packem_shared/run-summary-utils-CJv75pla.js +1 -0
  76. package/dist/packem_shared/runtime-check-CBU6W8qG.js +1 -0
  77. package/dist/packem_shared/{selectors-Sem2CTYA.js → selectors-B2ISH581.js} +1 -1
  78. package/dist/packem_shared/toolchain-B7dckBQ1.js +5 -0
  79. package/dist/packem_shared/typosquats-B3A38-qx.js +1 -0
  80. package/dist/packem_shared/verify-WDStBFvK.js +1 -0
  81. package/dist/packem_shared/vis-update-app-D0uL3eO5.js +1 -0
  82. package/package.json +13 -13
  83. package/schemas/project.schema.json +12 -2
  84. package/schemas/vis-config.schema.json +248 -3
  85. package/dist/packem_chunks/applyDefaults.js +0 -2
  86. package/dist/packem_shared/ai-cache-BdPgSfg2.js +0 -1
  87. package/dist/packem_shared/ai-fix-iHtGLkJS.js +0 -43
  88. package/dist/packem_shared/cache-directory-DTfMSzT9.js +0 -1
  89. package/dist/packem_shared/dependency-scan-SQeRzrpJ.js +0 -2
  90. package/dist/packem_shared/docker-D5p9mRPU.js +0 -2
  91. package/dist/packem_shared/failure-log-CElcbnb9.js +0 -2
  92. package/dist/packem_shared/flakiness-C4t4_NoA.js +0 -1
  93. package/dist/packem_shared/otel-CO8UEfTa.js +0 -17
  94. package/dist/packem_shared/otelPlugin-DTynZDWh.js +0 -1
  95. package/dist/packem_shared/registry-D04iOQ5H.js +0 -2
  96. package/dist/packem_shared/run-summary-utils-BPraMTcm.js +0 -1
  97. package/dist/packem_shared/runtime-check-l4qFpo08.js +0 -1
  98. package/dist/packem_shared/toolchain-BhZNts--.js +0 -5
  99. package/dist/packem_shared/typosquats-Dr7VIL2B.js +0 -1
  100. package/dist/packem_shared/verify-C6NNOhTA.js +0 -1
  101. package/dist/packem_shared/vis-update-app-DGiMc5kb.js +0 -1
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "noProductionDependencyOnApplication": {
51
51
  "type": "boolean",
52
- "description": "When true, production `dependencies` must not point to \"application\" type projects. devDependencies on applications are allowed (e.g., for testing).",
52
+ "description": "When true, production `dependencies` must not point to deployment-target projects — `application`, `service`, or `tool`. devDependencies on those are allowed (e.g., for testing).",
53
53
  "default": false
54
54
  }
55
55
  },
@@ -86,7 +86,7 @@
86
86
  },
87
87
  "enforceApplicationBoundary": {
88
88
  "type": "boolean",
89
- "description": "When true, no project may depend on an \"application\" type project. Applications are typically deployment targets, not libraries.",
89
+ "description": "When true, no project may depend on a deployment target — projects of type `application`, `service`, or `tool`. Deployment targets are standalone artefacts, not reusable libraries.",
90
90
  "default": true
91
91
  }
92
92
  },
@@ -470,6 +470,59 @@
470
470
  "additionalProperties": false,
471
471
  "description": "Tweak the custom-types lint that flags drift in `engines.{node,pnpm,...}`, `packageManager`, `volta.{node,pnpm,yarn}`, and the proposed `devEngines.{runtime,packageManager}` array form.\n\nEach (customType × name) cluster is tracked independently — `engines.node` and `volta.node` don't cross-couple here. Use a versionGroup once that lands if you need to enforce they agree."
472
472
  },
473
+ "deadWorkspacePatterns": {
474
+ "type": "object",
475
+ "properties": {
476
+ "autofix": {
477
+ "anyOf": [
478
+ {
479
+ "type": "string",
480
+ "const": "prompt"
481
+ },
482
+ {
483
+ "type": "boolean"
484
+ }
485
+ ],
486
+ "description": "Three-state autofix opt-out. See `workspaceProtocol.autofix` for the contract — applied here to dropping unmatched patterns from the workspace config file.",
487
+ "default": true
488
+ }
489
+ },
490
+ "additionalProperties": false,
491
+ "description": "Tweak the dead-workspace-patterns lint that flags entries in `pnpm-workspace.yaml#packages` / `package.json#workspaces` which resolve to zero on-disk directories."
492
+ },
493
+ "emptyDeps": {
494
+ "type": "object",
495
+ "properties": {
496
+ "autofix": {
497
+ "anyOf": [
498
+ {
499
+ "type": "string",
500
+ "const": "prompt"
501
+ },
502
+ {
503
+ "type": "boolean"
504
+ }
505
+ ],
506
+ "description": "Three-state autofix opt-out. See `workspaceProtocol.autofix` for the contract — applied here to removing the empty key.",
507
+ "default": true
508
+ },
509
+ "ignoreBlocks": {
510
+ "type": "array",
511
+ "items": {
512
+ "type": "string",
513
+ "enum": [
514
+ "dependencies",
515
+ "devDependencies",
516
+ "optionalDependencies",
517
+ "peerDependencies"
518
+ ]
519
+ },
520
+ "description": "Block names exempt from the rule (e.g. `[\"peerDependencies\"]` to keep the key around as a marker even when empty)."
521
+ }
522
+ },
523
+ "additionalProperties": false,
524
+ "description": "Tweak the empty-deps lint that flags empty `dependencies` / `devDependencies` / `peerDependencies` / `optionalDependencies` blocks across the workspace."
525
+ },
473
526
  "redefineRoot": {
474
527
  "type": "object",
475
528
  "properties": {
@@ -484,6 +537,121 @@
484
537
  "additionalProperties": false,
485
538
  "description": "Tweak the redefine-root lint that flags non-root packages duplicating deps already pinned at the workspace root."
486
539
  },
540
+ "rootDeps": {
541
+ "type": "object",
542
+ "properties": {
543
+ "autofix": {
544
+ "anyOf": [
545
+ {
546
+ "type": "string",
547
+ "const": "prompt"
548
+ },
549
+ {
550
+ "type": "boolean"
551
+ }
552
+ ],
553
+ "description": "Three-state autofix opt-out. See `workspaceProtocol.autofix` for the contract — applied here to moving entries from `dependencies` to `devDependencies` on the root package.json.",
554
+ "default": true
555
+ }
556
+ },
557
+ "additionalProperties": false,
558
+ "description": "Tweak the root-deps lint that flags runtime `dependencies` declared on the private workspace root (they should live in `devDependencies`)."
559
+ },
560
+ "rootPackageManager": {
561
+ "type": "object",
562
+ "properties": {
563
+ "autofix": {
564
+ "anyOf": [
565
+ {
566
+ "type": "string",
567
+ "const": "prompt"
568
+ },
569
+ {
570
+ "type": "boolean"
571
+ }
572
+ ],
573
+ "description": "Three-state autofix opt-out. See `workspaceProtocol.autofix` for the contract. `--fix` only writes when `suggested` is set — a missing `packageManager` field has no canonical default.",
574
+ "default": true
575
+ },
576
+ "suggested": {
577
+ "type": "string",
578
+ "description": "Canonical specifier (`name@version`) to write when `--fix` runs and the field is absent. Required to enable autofix — vis won't guess the workspace's preferred manager.",
579
+ "examples": [
580
+ "pnpm@10.32.1"
581
+ ]
582
+ }
583
+ },
584
+ "additionalProperties": false,
585
+ "description": "Tweak the root-package-manager lint that flags a missing or malformed `packageManager` field on the workspace root."
586
+ },
587
+ "rootPrivate": {
588
+ "type": "object",
589
+ "properties": {
590
+ "autofix": {
591
+ "anyOf": [
592
+ {
593
+ "type": "string",
594
+ "const": "prompt"
595
+ },
596
+ {
597
+ "type": "boolean"
598
+ }
599
+ ],
600
+ "description": "Three-state autofix opt-out. See `workspaceProtocol.autofix` for the contract — applied here to inserting `\"private\": true`.",
601
+ "default": true
602
+ }
603
+ },
604
+ "additionalProperties": false,
605
+ "description": "Tweak the root-private lint that flags a workspace root package.json missing `\"private\": true`. Only fires when the root looks like a workspace (npm/yarn/bun `workspaces` field or `pnpm-workspace.yaml`)."
606
+ },
607
+ "similarDeps": {
608
+ "type": "object",
609
+ "properties": {
610
+ "extraFamilies": {
611
+ "type": "array",
612
+ "items": {
613
+ "$ref": "#/$defs/SimilarDepFamily"
614
+ },
615
+ "description": "Additional families merged with the built-ins. Same `id` wins → user override fully replaces the built-in entry."
616
+ },
617
+ "ignoreFamilies": {
618
+ "type": "array",
619
+ "items": {
620
+ "type": "string"
621
+ },
622
+ "description": "Family ids to skip entirely (matches `SimilarDepFamily.id`)."
623
+ }
624
+ },
625
+ "additionalProperties": false,
626
+ "description": "Tweak the similar-deps lint that flags drift across related dep families (e.g. `react` and `react-dom`, all of `@babel/*`).\n\nThe lint is report-only — aligning a family requires picking a single canonical specifier across heterogeneous range syntaxes (`^`, `~`, exact), which is too lossy without user input."
627
+ },
628
+ "typesInDeps": {
629
+ "type": "object",
630
+ "properties": {
631
+ "autofix": {
632
+ "anyOf": [
633
+ {
634
+ "type": "string",
635
+ "const": "prompt"
636
+ },
637
+ {
638
+ "type": "boolean"
639
+ }
640
+ ],
641
+ "description": "Three-state autofix opt-out. See `workspaceProtocol.autofix` for the contract — applied here to moving the entry to `devDependencies`. Existing dev pins are preserved on conflict.",
642
+ "default": true
643
+ },
644
+ "ignore": {
645
+ "type": "array",
646
+ "items": {
647
+ "type": "string"
648
+ },
649
+ "description": "Dep names exempt from the rule (exact match, e.g. `@types/node`)."
650
+ }
651
+ },
652
+ "additionalProperties": false,
653
+ "description": "Tweak the types-in-deps lint that flags `@types/*` declared in `dependencies` on a private package (they belong in `devDependencies` since the package never ships)."
654
+ },
487
655
  "workspaceProtocol": {
488
656
  "type": "object",
489
657
  "properties": {
@@ -848,6 +1016,18 @@
848
1016
  "additionalProperties": false,
849
1017
  "description": "sort-package-json command defaults"
850
1018
  },
1019
+ "sponsor": {
1020
+ "type": "object",
1021
+ "properties": {
1022
+ "enabled": {
1023
+ "type": "boolean",
1024
+ "description": "Show the sponsor notice on successful command completion.",
1025
+ "default": true
1026
+ }
1027
+ },
1028
+ "additionalProperties": false,
1029
+ "description": "Sponsorship notice shown after successful commands.\n\nvis prints a one-line \"consider sponsoring visulima\" notice at most once every 14 days (skipped in CI, non-TTY, and when `VIS_NO_SPONSOR=1` is set). Set `enabled: false` to silence it permanently for this workspace."
1030
+ },
851
1031
  "staged": {
852
1032
  "$ref": "#/$defs/StagedConfig",
853
1033
  "description": "Staged file patterns and commands (replaces lint-staged).\n\nAccepts all lint-staged config forms:\n- `string` or `string[]` commands\n- Sync/async functions returning `string | string[]`\n- `{ title, task }` objects for named side-effect tasks\n- Mixed arrays of strings and functions\n- A top-level generate-task function"
@@ -929,6 +1109,10 @@
929
1109
  },
930
1110
  "description": "Named configurations (e.g., \"production\", \"development\")"
931
1111
  },
1112
+ "concurrencyGroup": {
1113
+ "type": "string",
1114
+ "description": "Workspace-level concurrency group this target opts into. The scheduler caps the *combined* in-flight count of every task whose target carries the same group name to the value declared in {@link TaskRunnerOptions.concurrencyGroups } . Use this when several targets share an external resource (a single Postgres, a developer's Docker daemon, an account-wide deploy lock) so the cap follows the resource, not any single target name.\n\nTargets that name a group not declared in `concurrencyGroups` run uncapped — a typo shouldn't deadlock the graph. Caps don't apply to tasks marked `always: true`; those run in a separate finalisation phase outside the scheduler."
1115
+ },
932
1116
  "dependsOn": {
933
1117
  "type": "array",
934
1118
  "items": {
@@ -1082,6 +1266,10 @@
1082
1266
  },
1083
1267
  "description": "Input patterns for cache invalidation"
1084
1268
  },
1269
+ "maxConcurrent": {
1270
+ "type": "number",
1271
+ "description": "Maximum number of in-flight instances of this target across the whole graph. When set, the scheduler refuses to start an additional task whose `target.target` equals this target's name once the running count reaches `maxConcurrent`. Independent of `--parallel`: the global cap still bounds total in-flight tasks, and `maxConcurrent` further bounds the per-target subset.\n\nUse for tests/deploys that share an external resource (DB, port, mock server). Set to `1` to serialize. Values `<= 0` are ignored.\n\nIf multiple projects declare different values for the same target name, the runner uses the smallest declared cap. Caps don't apply to tasks marked `always: true`; those run in a separate finalisation phase outside the scheduler."
1272
+ },
1085
1273
  "outputs": {
1086
1274
  "type": "array",
1087
1275
  "items": {
@@ -1488,6 +1676,13 @@
1488
1676
  "description": "When `true`, file hashes are cached in a persistent mtime+size indexed snapshot under `node_modules/.cache/task-runner/`. On subsequent runs, unchanged files skip content re-reads — cuts cold-cache fingerprint time dramatically on large workspaces.\n\nChanged or new files still get full content hashing. Safe to leave on by default; overhead when nothing matches is a single `stat` call per file.",
1489
1677
  "default": false
1490
1678
  },
1679
+ "concurrencyGroups": {
1680
+ "type": "object",
1681
+ "additionalProperties": {
1682
+ "type": "number"
1683
+ },
1684
+ "description": "Workspace-level concurrency group caps. Maps a group name to the maximum number of in-flight tasks across every target whose `concurrencyGroup` field equals the same name. Independent of `parallel`: the global cap still bounds total tasks, and group caps further bound the named subset.\n\nCommon shape — one cap per shared resource:\n\n ```ts concurrencyGroups: { \"db-bound\": 2, // any target hitting the local Postgres \"deploy-lock\": 1, // any deploy target } ```\n\nTargets opt in via {@link TargetConfiguration.concurrencyGroup } . Values `<= 0` are ignored."
1685
+ },
1491
1686
  "maxCacheAge": {
1492
1687
  "type": "number",
1493
1688
  "description": "Maximum age of cache entries in milliseconds"
@@ -1757,6 +1952,10 @@
1757
1952
  },
1758
1953
  "description": "Named configurations (e.g., \"production\", \"development\")"
1759
1954
  },
1955
+ "concurrencyGroup": {
1956
+ "type": "string",
1957
+ "description": "Workspace-level concurrency group this target opts into. The scheduler caps the *combined* in-flight count of every task whose target carries the same group name to the value declared in {@link TaskRunnerOptions.concurrencyGroups } . Use this when several targets share an external resource (a single Postgres, a developer's Docker daemon, an account-wide deploy lock) so the cap follows the resource, not any single target name.\n\nTargets that name a group not declared in `concurrencyGroups` run uncapped — a typo shouldn't deadlock the graph. Caps don't apply to tasks marked `always: true`; those run in a separate finalisation phase outside the scheduler."
1958
+ },
1760
1959
  "dependsOn": {
1761
1960
  "type": "array",
1762
1961
  "items": {
@@ -1915,6 +2114,10 @@
1915
2114
  "additionalProperties": {},
1916
2115
  "description": "Options passed to the executor"
1917
2116
  },
2117
+ "maxConcurrent": {
2118
+ "type": "number",
2119
+ "description": "Maximum number of in-flight instances of this target across the whole graph. When set, the scheduler refuses to start an additional task whose `target.target` equals this target's name once the running count reaches `maxConcurrent`. Independent of `--parallel`: the global cap still bounds total in-flight tasks, and `maxConcurrent` further bounds the per-target subset.\n\nUse for tests/deploys that share an external resource (DB, port, mock server). Set to `1` to serialize. Values `<= 0` are ignored.\n\nIf multiple projects declare different values for the same target name, the runner uses the smallest declared cap. Caps don't apply to tasks marked `always: true`; those run in a separate finalisation phase outside the scheduler."
2120
+ },
1918
2121
  "outputs": {
1919
2122
  "type": "array",
1920
2123
  "items": {
@@ -2571,6 +2774,38 @@
2571
2774
  "additionalProperties": false,
2572
2775
  "description": "One user-declared customTypes entry. See `policy.customTypes.extraTypes` for the full contract — this is just the row shape."
2573
2776
  },
2777
+ "SimilarDepFamily": {
2778
+ "type": "object",
2779
+ "properties": {
2780
+ "id": {
2781
+ "type": "string",
2782
+ "description": "Stable id; used in report output and config overrides."
2783
+ },
2784
+ "label": {
2785
+ "type": "string",
2786
+ "description": "Pretty label for the report. Defaults to `id` when omitted."
2787
+ },
2788
+ "members": {
2789
+ "type": "array",
2790
+ "items": {
2791
+ "type": "string"
2792
+ },
2793
+ "description": "Dep names that belong to this family verbatim."
2794
+ },
2795
+ "prefixes": {
2796
+ "type": "array",
2797
+ "items": {
2798
+ "type": "string"
2799
+ },
2800
+ "description": "Dep-name prefixes (literal, no glob). Match if `depName.startsWith(prefix)`."
2801
+ }
2802
+ },
2803
+ "required": [
2804
+ "id"
2805
+ ],
2806
+ "additionalProperties": false,
2807
+ "description": "One family of upstream-coupled packages.\n\n`members` is an exact-match list. `prefixes` accept any dep whose name starts with the prefix — useful for monorepos that ship many subpackages under one scope (e.g. `@babel/`, `@storybook/`, `@nx/`). A family can use either or both; a dep matching either list belongs to the family."
2808
+ },
2574
2809
  "StagedConfig": {
2575
2810
  "type": "object",
2576
2811
  "additionalProperties": {
@@ -2903,6 +3138,10 @@
2903
3138
  },
2904
3139
  "description": "Named configurations (e.g., \"production\", \"development\")"
2905
3140
  },
3141
+ "concurrencyGroup": {
3142
+ "type": "string",
3143
+ "description": "Workspace-level concurrency group this target opts into. The scheduler caps the *combined* in-flight count of every task whose target carries the same group name to the value declared in {@link TaskRunnerOptions.concurrencyGroups } . Use this when several targets share an external resource (a single Postgres, a developer's Docker daemon, an account-wide deploy lock) so the cap follows the resource, not any single target name.\n\nTargets that name a group not declared in `concurrencyGroups` run uncapped — a typo shouldn't deadlock the graph. Caps don't apply to tasks marked `always: true`; those run in a separate finalisation phase outside the scheduler."
3144
+ },
2906
3145
  "dependsOn": {
2907
3146
  "type": "array",
2908
3147
  "items": {
@@ -3056,6 +3295,10 @@
3056
3295
  },
3057
3296
  "description": "Input patterns for cache invalidation"
3058
3297
  },
3298
+ "maxConcurrent": {
3299
+ "type": "number",
3300
+ "description": "Maximum number of in-flight instances of this target across the whole graph. When set, the scheduler refuses to start an additional task whose `target.target` equals this target's name once the running count reaches `maxConcurrent`. Independent of `--parallel`: the global cap still bounds total in-flight tasks, and `maxConcurrent` further bounds the per-target subset.\n\nUse for tests/deploys that share an external resource (DB, port, mock server). Set to `1` to serialize. Values `<= 0` are ignored.\n\nIf multiple projects declare different values for the same target name, the runner uses the smallest declared cap. Caps don't apply to tasks marked `always: true`; those run in a separate finalisation phase outside the scheduler."
3301
+ },
3059
3302
  "outputs": {
3060
3303
  "type": "array",
3061
3304
  "items": {
@@ -3416,7 +3659,9 @@
3416
3659
  "type": "string",
3417
3660
  "enum": [
3418
3661
  "application",
3419
- "library"
3662
+ "library",
3663
+ "service",
3664
+ "tool"
3420
3665
  ],
3421
3666
  "description": "Match on project type."
3422
3667
  },
@@ -1,2 +0,0 @@
1
- var E=Object.defineProperty;var C=(e,t)=>E(e,"name",{value:t,configurable:!0});import{createRequire as R}from"node:module";import{M as c,O as V,i as d,V as B,h as y,K as T,n as x,m as L,a as m,w as P,b as _,c as k}from"../packem_shared/otel-CO8UEfTa.js";import{o as me}from"../packem_shared/otel-CO8UEfTa.js";import{createJiti as O}from"jiti";const I=R(import.meta.url),h=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,p=C(e=>{if(typeof h<"u"&&h.versions&&h.versions.node){const[t,s]=h.versions.node.split(".").map(Number);if(t>22||t===22&&s>=3||t===20&&s>=16)return h.getBuiltinModule(e)}return I(e)},"__cjs_getBuiltinModule"),{createHash:S}=p("node:crypto"),{readdirSync:D,readFileSync:A,copyFileSync:M,unlinkSync:q}=p("node:fs"),{createRequire:K}=p("node:module"),{tmpdir:N}=p("node:os");var U=Object.defineProperty,a=C((e,t)=>U(e,"name",{value:t,configurable:!0}),"r");const b=["vis.config.ts","vis.config.mts","vis.config.cts","vis.config.js","vis.config.mjs","vis.config.cjs"],W=new Set(b),F=["vis.task.ts","vis.task.mts","vis.task.cts","vis.task.js","vis.task.mjs","vis.task.cjs"],z=new Set(F),H={blockExoticSubdeps:!0,strictDepBuilds:!0,trustPolicy:"no-downgrade",trustPolicyIgnoreAfter:43200},Y=a(e=>({...H,...e}),"mergeSecurityDefaults"),w=a(e=>({...e,security:Y(e.security),update:{security:!0,target:"minor",...e.update}}),"applyDefaults"),J=a(e=>{let t;try{t=D(e)}catch{return}const s=new Set(t.filter(i=>W.has(i)));for(const i of b)if(s.has(i))return c(e,i)},"findVisConfigFile"),Q=a(e=>{let t;try{t=D(e)}catch{return}const s=new Set(t.filter(i=>z.has(i)));for(const i of F)if(s.has(i))return c(e,i)},"findVisTaskConfigFile"),v=a(e=>S("sha256").update(A(e)).digest("hex"),"hashFileContents"),X=a(e=>{const t=S("sha256"),s=[...e].sort();for(const i of s)t.update(i),t.update(":"),t.update(v(i)),t.update(`
2
- `);return t.digest("hex")},"hashConfigChain"),Z=a(e=>{const t=c(e,"node_modules");if(d(t)){const i=c(t,".cache","vis");return y(i),c(i,"vis-config-cache.json")}const s=T("vis",{create:!0,cwd:e});return s?c(s,"vis-config-cache.json"):void 0},"getConfigCachePath"),ee=a((e,t)=>{if(d(e))try{const s=x(e);if(s.hash===t)return s.config}catch{}},"readConfigCache"),te=a((e,t,s)=>{try{y(m(e)),P(e,{config:s,hash:t})}catch{}},"writeConfigCache"),se=a(e=>e===void 0?[]:Array.isArray(e)?e:[e],"normalizeExtends"),ie=a((e,t,s)=>{if(V(e))throw new k(e,[...s,t],["Absolute paths in `extends` are not supported. Use a relative path or an npm package name."]);const i=[];if(e.startsWith("./")||e.startsWith("../")){const o=m(t),n=c(o,e);if(i.push(n),d(n))return n;throw new k(e,[...s,t],i)}try{return K(t).resolve(e)}catch{throw i.push(`require.resolve("${e}") from ${t}`),new k(e,[...s,t],i)}},"resolveExtendsSpecifier"),$=a(async(e,t,s)=>{const i=v(t),o=t.slice(t.lastIndexOf(".")),n=c(N(),`vis-config-${i}${o}`);M(t,n);let r;try{r=await e.import(n,{default:!0,try:!0})??{}}catch(f){throw new _(t,s,f)}finally{try{q(n)}catch{}}try{return(typeof r=="function"?await r()??{}:r)??{}}catch(f){throw new _(t,s,f)}},"loadRawConfig"),ne=a((e,t)=>{const s={...e,...t};if(e.targetDefaults||t.targetDefaults){const i=new Set([...Object.keys(e.targetDefaults??{}),...Object.keys(t.targetDefaults??{})]),o={};for(const n of i)o[n]=L(e.targetDefaults?.[n],t.targetDefaults?.[n]);s.targetDefaults=o}return(e.taskDefaults||t.taskDefaults)&&(s.taskDefaults=[...e.taskDefaults??[],...t.taskDefaults??[]]),(e.fileGroups||t.fileGroups)&&(s.fileGroups={...e.fileGroups,...t.fileGroups}),(e.taskGroups||t.taskGroups)&&(s.taskGroups={...e.taskGroups,...t.taskGroups}),(e.security||t.security)&&(s.security={...e.security,...t.security}),(e.update||t.update)&&(s.update={...e.update,...t.update}),(e.taskRunnerOptions||t.taskRunnerOptions)&&(s.taskRunnerOptions={...e.taskRunnerOptions,...t.taskRunnerOptions}),delete s.extends,s},"mergeVisConfigs"),G=a(async(e,t,s,i,o,n)=>{if(i.has(t))throw new B(t,s);if(!o.has(t)){i.add(t);try{const r=await $(e,t,s),f=se(r.extends);for(const u of f){const g=ie(u,t,s);await G(e,g,[...s,t],i,o,n)}o.set(t,r),n.push(t)}finally{i.delete(t)}}},"resolveConfigChain"),ge=a(async(e,t)=>{let s;if(t?.explicitConfigPath){const l=V(t.explicitConfigPath)?t.explicitConfigPath:c(e,t.explicitConfigPath);if(!d(l))throw new Error(`Cannot find config file at ${l}`);s=l}else s=J(e);if(!s)return w({});const i=O(e,{fsCache:!1,moduleCache:!1}),o=new Set,n=new Map,r=[];await G(i,s,[],o,n,r);const f=X(r),u=Z(e);if(u){const l=ee(u,f);if(l)return l}let g={};for(const l of r)g=ne(g,n.get(l));const j=w(g);return u&&te(u,f,j),j},"loadVisConfig"),ae=a(e=>e.replaceAll(/[^\w.-]+/g,"_"),"sanitizeProjectName"),oe=a((e,t)=>{const s=c(e,"node_modules"),i=ae(t);if(d(s)){const n=c(s,".cache","vis","task-configs");return y(n),c(n,`${i}.json`)}const o=T("vis",{create:!0,cwd:e});return o?c(o,"task-configs",`${i}.json`):void 0},"getVisTaskCachePath"),re=a((e,t)=>{if(d(e))try{const s=x(e);if(s.hash===t)return s.config}catch{}},"readVisTaskCache"),ce=a((e,t,s)=>{try{y(m(e)),P(e,{config:s,hash:t})}catch{}},"writeVisTaskCache"),he=a(async(e,t,s)=>{const i=Q(t);if(!i)return;const o=v(i),n=oe(e,s);if(n){const u=re(n,o);if(u)return u}const r=O(t,{fsCache:!1,moduleCache:!1}),f=await $(r,i,[]);return n&&ce(n,o,f),f},"loadVisTaskConfig"),pe=a(e=>e,"defineTaskConfig"),ye=a(e=>w(e),"defineConfig"),Ce=a(e=>e,"definePlugin");export{b as CONFIG_FILES,H as SECURITY_DEFAULTS,F as TASK_CONFIG_FILES,w as applyDefaults,ye as defineConfig,Ce as definePlugin,pe as defineTaskConfig,J as findVisConfigFile,Q as findVisTaskConfigFile,ge as loadVisConfig,he as loadVisTaskConfig,me as otelPlugin};
@@ -1 +0,0 @@
1
- var S=Object.defineProperty;var g=(t,e)=>S(t,"name",{value:e,configurable:!0});import{createRequire as _}from"node:module";import{X as v}from"./xxh3-DrAUNq4n.js";import{M as c,h as w,i as d,n as j}from"./otel-CO8UEfTa.js";import{n as A}from"../packem_chunks/bin.js";const M=_(import.meta.url),u=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,b=g(t=>{if(typeof u<"u"&&u.versions&&u.versions.node){const[e,r]=u.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return u.getBuiltinModule(t)}return M(t)},"__cjs_getBuiltinModule"),{rmSync:f,writeFileSync:h,readdirSync:p,statSync:D}=b("node:fs");var B=Object.defineProperty,n=g((t,e)=>B(t,"name",{value:e,configurable:!0}),"r");const a=n(()=>c(A(),"ai"),"getCacheDirectory"),J=3600*1e3,N=1800*1e3,C=n(()=>{w(a())},"ensureCacheDirectory"),k=n((t,e,r)=>{const s=r.map(i=>({currentRange:i.currentRange,name:i.packageName,targetVersion:i.targetVersion})).toSorted((i,y)=>i.name.localeCompare(y.name)),o=JSON.stringify({analysisType:e,packages:s,provider:t});return v(Buffer.from(o))},"buildCacheKey"),q=n(t=>{const e=c(a(),`${t}.json`);if(d(e))try{const r=j(e);if(Date.now()-r.createdAt>r.ttlMs){f(e,{force:!0});return}return r.result}catch{f(e,{force:!0});return}},"getCachedAnalysis"),z=n((t,e,r)=>{C();const s=a(),o={createdAt:Date.now(),result:e,ttlMs:r};h(c(s,`${t}.json`),JSON.stringify(o,void 0,2),"utf8")},"setCachedAnalysis"),V=n((t,e)=>e!==void 0&&e>0?e:t==="security"?N:J,"getTtlForAnalysisType"),F=n(()=>{const t=a();if(!d(t))return{entries:0,newestEntry:void 0,oldestEntry:void 0,totalSizeBytes:0};const e=p(t).filter(i=>i.endsWith(".json"));let r=0,s,o;for(const i of e){const y=c(t,i),m=D(y);r+=m.size;const{mtimeMs:l}=m;(s===void 0||l<s)&&(s=l),(o===void 0||l>o)&&(o=l)}return{entries:e.length,newestEntry:o,oldestEntry:s,totalSizeBytes:r}},"getCacheStats"),K=n(t=>v(Buffer.from(JSON.stringify(t))),"buildHashCacheKey"),P=n(t=>{const e=c(a(),`${t}.json`);if(d(e))try{const r=j(e);if(Date.now()-r.createdAt>r.ttlMs){f(e,{force:!0});return}return r.result}catch{f(e,{force:!0});return}},"getCachedJson"),W=n((t,e,r)=>{C();const s=a(),o={createdAt:Date.now(),result:e,ttlMs:r};h(c(s,`${t}.json`),JSON.stringify(o,void 0,2),"utf8")},"setCachedJson"),x=n(()=>{const t=a();if(!d(t))return 0;const e=p(t).filter(r=>r.endsWith(".json"));for(const r of e)f(c(t,r),{force:!0});return e.length},"clearCache");export{x as B,F as J,K as M,P as N,W as O,z as R,q as T,V as j,k};
@@ -1,43 +0,0 @@
1
- var O=Object.defineProperty;var f=(e,t)=>O(e,"name",{value:t,configurable:!0});import{createRequire as F}from"node:module";import{readLastRunSummary as T}from"@visulima/task-runner";import{a as j}from"./failure-log-CElcbnb9.js";import{r as k,f as y,a as D,d as _}from"./run-summary-utils-BPraMTcm.js";import{O as $,C as b,M as R,z as A}from"./otel-CO8UEfTa.js";import{w as E,b as B,r as H}from"./ai-analysis-CGVjqwdc.js";import{M as q,N as W,O as L}from"./ai-cache-BdPgSfg2.js";const C=F(import.meta.url),d=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,I=f(e=>{if(typeof d<"u"&&d.versions&&d.versions.node){const[t,a]=d.versions.node.split(".").map(Number);if(t>22||t===22&&a>=3||t===20&&a>=16)return d.getBuiltinModule(e)}return C(e)},"__cjs_getBuiltinModule"),{readFile:N,writeFile:M}=I("node:fs/promises");var Y=Object.defineProperty,m=f((e,t)=>Y(e,"name",{value:t,configurable:!0}),"u");const z=32*1024,J=m((e,t)=>{if(e.length<=t)return e;const a=e.slice(-t),o=e.length-a.length;return`[…${String(o)} bytes truncated from head…]
2
- ${a}`},"truncateHead"),K=m(async(e,t)=>t===void 0?T(e):k(e,t),"loadSummary"),ge=m(async(e,t,a={})=>{const o=a.terminalOutputLimit??z,[r,n]=await Promise.all([j(e,t),K(e,a.runId)]),i=n?y(n,t):void 0;if(!r&&!i)return;let s,c;if(n&&i){const l=await D(e,n.id),g=l?y(l,t):void 0;s=_(i.hashDetails,g?.hashDetails),c=l?.id}const h=r?.terminalOutput??"";return{command:r?.command??void 0,cwd:r?.cwd??void 0,dependencies:i?.dependencies??[],duration:i?.duration,exitCode:r?.exitCode??i?.exitCode,hash:i?.hash??r?.hash,hashDetails:i?.hashDetails,hashDiff:s,previousRunId:c,project:i?.target.project,runId:n?.id??r?.runId,status:r?.status??(i?U(i):void 0),target:i?.target.target,taskId:t,terminalOutput:J(h,o),terminalOutputCaptured:!!r,timestamp:r?.timestamp??i?.endTime??i?.startTime}},"aggregateFailureContext"),U=m(e=>{if(e.exitCode!==void 0&&e.exitCode!==0)return"failure";switch(e.cacheStatus){case"HIT":return"local-cache";case"REMOTE_HIT":return"remote-cache";case"SKIPPED":return"skipped";default:return e.exitCode===0?"success":void 0}},"mapCacheStatusToTaskStatus");var G=Object.defineProperty,u=f((e,t)=>G(e,"name",{value:t,configurable:!0}),"a");const Q=3600*1e3,S=80,V=new Set(["high","low","medium"]),X=u(()=>`You are an expert software engineer helping fix a failing build/test/lint task.
3
-
4
- You will be given:
5
- - The terminal output (stdout/stderr) from the failed task.
6
- - Optional metadata: command, working directory, project, task hash, and a diff describing what changed in the task's hash inputs since the previous run that did not fail.
7
-
8
- Your job:
9
- 1. Identify the root cause from the terminal output.
10
- 2. Propose a minimal set of source-file patches that fix the cause.
11
- 3. If you cannot determine a safe fix, set "cannotFix" with a clear, actionable explanation.
12
-
13
- Constraints:
14
- - Patches MUST be exact string replacements. The "oldString" must appear verbatim in the named file. Paths are relative to the working directory.
15
- - Each "oldString" must be unique within its file. Include surrounding context so the match is unambiguous.
16
- - Do NOT include unrelated cleanup, formatting changes, or speculative refactors.
17
- - If the failure is environmental (missing tool, network) or requires running commands, prefer "cannotFix" over a guess.
18
- - Keep "explanation" short (1-3 sentences). Reserve "reason" on each patch for why that specific edit fixes the cause.
19
-
20
- Respond ONLY with valid JSON in this exact structure:
21
- {
22
- "explanation": "Brief root-cause analysis and what the fix does.",
23
- "confidence": "low|medium|high",
24
- "patches": [
25
- {
26
- "file": "path/relative/to/cwd.ts",
27
- "oldString": "exact text to find",
28
- "newString": "exact replacement text",
29
- "reason": "why this change fixes it"
30
- }
31
- ],
32
- "cannotFix": "optional — set when no safe patch can be proposed"
33
- }`,"buildSystemPrompt"),v=u((e,t)=>{const a=[];if(t.added.length>0&&a.push(` added: ${t.added.join(", ")}`),t.changed.length>0&&a.push(` changed: ${t.changed.join(", ")}`),t.removed.length>0&&a.push(` removed: ${t.removed.join(", ")}`),a.length!==0)return`- ${e}:
34
- ${a.join(`
35
- `)}`},"formatBucket"),Z=u(e=>{if(!e.hashDiff)return"No hash-diff available — there is no previous run to compare against.";const t=[];e.hashDiff.commandChanged&&t.push("- command line changed since previous run");const a=v("file inputs",e.hashDiff.nodes),o=v("implicit deps",e.hashDiff.implicitDeps),r=v("runtime/env",e.hashDiff.runtime);return a&&t.push(a),o&&t.push(o),r&&t.push(r),t.length===0?"No detectable changes between this run and the previous run.":t.join(`
36
- `)},"buildHashDiffSummary"),ee=u(e=>{const t=[`Task: ${e.taskId}`];return e.project&&t.push(`Project: ${e.project}`),e.target&&t.push(`Target: ${e.target}`),e.command&&t.push(`Command: ${e.command}`),e.cwd&&t.push(`CWD: ${e.cwd}`),e.exitCode!==void 0&&t.push(`Exit code: ${String(e.exitCode)}`),e.hash&&t.push(`Task hash: ${e.hash}`),t.push("","Hash-diff since previous run:",Z(e),""),e.terminalOutputCaptured?t.push("Terminal output:","```",e.terminalOutput,"```"):t.push("Terminal output: <no failure log was captured for this task>",'Set "cannotFix" and tell the user to re-run with `vis run` so logs can be captured.'),t.join(`
37
- `)},"buildUserPrompt"),te=u(e=>`${X()}
38
-
39
- ${ee(e)}`,"buildFixPrompt"),ae=u((e,t)=>{const a=Array.isArray(e.patches)?e.patches:[],o=[];for(const n of a)typeof n.file!="string"||n.file.length===0||typeof n.oldString!="string"||n.oldString.length===0||typeof n.newString=="string"&&o.push({file:n.file,newString:n.newString,oldString:n.oldString,reason:typeof n.reason=="string"&&n.reason.length>0?n.reason:void 0});const r=typeof e.cannotFix=="string"&&e.cannotFix.length>0?e.cannotFix:void 0;return{cannotFix:r,confidence:V.has(e.confidence)?e.confidence:"low",explanation:typeof e.explanation=="string"?e.explanation:"",patches:r?[]:o,provider:t}},"normalizeFixProposal"),ie=u((e,t)=>{const a=E(e);return!a||typeof a!="object"?{cannotFix:"AI response was not valid JSON.",confidence:"low",explanation:"Failed to parse AI response.",patches:[],provider:t}:ae(a,t)},"parseFixResponse"),ne=u((e,t)=>q({cwd:t.cwd??null,flow:"ai-fix",hash:t.hash??null,provider:e,taskId:t.taskId,terminalOutput:t.terminalOutput,terminalOutputCaptured:t.terminalOutputCaptured}),"buildFixCacheKey"),ve=u(async(e,t,a={})=>{const o=B(a.config);if(!o){t.warn(`No AI provider available — install one of: claude, gemini, copilot, codex.
40
- `);return}const r=a.cache!==!1,n=ne(o.name,e);if(r){const i=W(n);if(i)return t.info(`Using cached fix proposal from ${i.provider}.
41
- `),i}t.info(`Generating fix proposal with ${o.name}...
42
- `);try{const i=await H(o,te(e)),s=ie(i,o.name);return r&&s.patches.length>0&&!s.cannotFix&&L(n,s,Q),s}catch(i){const s=i instanceof Error?i.message:String(i);t.warn(`AI fix proposal failed (${s}).
43
- `);return}},"runFixAnalysis"),re=u((e,t,a)=>$(a)?b(a):b(R(t??e,a)),"resolvePatchPath"),se=u((e,t)=>{const a=A(e,t);return a===""?!0:!a.startsWith("..")&&!$(a)},"isInsideWorkspace"),oe=u((e,t,a)=>{const o=e.indexOf(t),r=Math.max(0,o-S),n=Math.min(e.length,o+t.length+S),i=e.slice(r,n);return{previewAfter:`${e.slice(r,o)}${a}${e.slice(o+t.length,n)}`,previewBefore:i}},"buildPreview"),xe=u(async(e,t,a,o={})=>{const r=o.dryRun===!0,n=new Map,i=[];for(const s of a.patches){const c=re(e,t,s.file);if(!se(e,c)){i.push({absolutePath:c,patch:s,status:"outside-workspace"});continue}let h=n.get(c);if(h===void 0){try{h=await N(c,"utf8")}catch(p){const w=p.code;i.push({absolutePath:c,error:w==="ENOENT"?void 0:p.message,patch:s,status:w==="ENOENT"?"missing-file":"error"});continue}n.set(c,h)}const l=h.indexOf(s.oldString);if(l===-1){i.push({absolutePath:c,patch:s,status:"no-match"});continue}if(h.indexOf(s.oldString,l+s.oldString.length)!==-1){i.push({absolutePath:c,patch:s,status:"ambiguous-match"});continue}const{previewAfter:g,previewBefore:P}=oe(h,s.oldString,s.newString),x=`${h.slice(0,l)}${s.newString}${h.slice(l+s.oldString.length)}`;if(!r)try{await M(c,x,"utf8")}catch(p){n.delete(c),i.push({absolutePath:c,error:p.message,patch:s,status:"error"});continue}n.set(c,x),i.push({absolutePath:c,patch:s,previewAfter:g,previewBefore:P,status:"applied"})}return i},"applyFixProposal");export{ge as a,ve as b,xe as c,re as r};
@@ -1 +0,0 @@
1
- var h=Object.defineProperty;var l=(e,r)=>h(e,"name",{value:r,configurable:!0});import{createRequire as d}from"node:module";import{O as p,C as a,z as m}from"./otel-CO8UEfTa.js";import{DEFAULT_CACHE_DIRECTORY_NAME as u,getMainWorktreeRoot as v}from"@visulima/task-runner";const f=d(import.meta.url),i=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,g=l(e=>{if(typeof i<"u"&&i.versions&&i.versions.node){const[r,t]=i.versions.node.split(".").map(Number);if(r>22||r===22&&t>=3||r===20&&t>=16)return i.getBuiltinModule(e)}return f(e)},"__cjs_getBuiltinModule"),{execFileSync:_}=g("node:child_process");var C=Object.defineProperty,s=l((e,r)=>C(e,"name",{value:r,configurable:!0}),"s");const y=s((e,r,t)=>{const n=s(c=>p(c)?c:a(e,c),"normalize");if(r&&r.length>0)return n(r);if(t&&t.length>0)return n(t);const o=process.env.VIS_CACHE_DIRECTORY;return o&&o.length>0?n(o):a(e,u)},"resolveCacheDirectory"),E=s((e,r)=>r===!1?e:v(e)??e,"resolveSharedCacheRoot"),I=s((e,r,t,n)=>{const o=r??t??process.env.VIS_CACHE_DIRECTORY;if(o&&o.length>0)return y(e,r,t);const c=E(e,n);return a(c,u)},"resolveSharedCacheDirectory"),R=/[^\w.-]+/g,S=/^-+|-+$/g,b=s(e=>e.trim().replaceAll(R,"-").replaceAll(S,"").slice(0,64),"sanitizeBranchSegment"),A=s(e=>{try{const r=_("git",["rev-parse","--abbrev-ref","HEAD"],{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();return!r||r==="HEAD"?void 0:r}catch{return}},"detectGitBranch"),z=s((e,r,t)=>{if(t!==!0)return e;const n=A(r);if(!n)return e;const o=b(n);return o.length===0?e:a(e,"branches",o)},"applyBranchScope"),H=s((e,r)=>{const t=m(r,e);return t.length===0?!1:t!==".."&&!t.startsWith("../")&&!p(t)},"isCacheDirectoryInsideWorkspace");export{I as E,z as a,H as m};
@@ -1,2 +0,0 @@
1
- var j=Object.defineProperty;var b=(t,e)=>j(t,"name",{value:e,configurable:!0});import{e as E,aw as h,E as w,c as M,d as O,s as R}from"../packem_chunks/bin.js";import{Box as g,Text as d,Spinner as A,render as I}from"@visulima/tui";import k from"react";import{jsx as i,jsxs as v}from"react/jsx-runtime";import{D as S,W as Y,T as B,C as G}from"./symbols-CQmER5MT.js";import{$ as T,M as D}from"./otel-CO8UEfTa.js";import{F as P}from"./lockfile-B7JJzxnL.js";var N=Object.defineProperty,W=b((t,e)=>N(t,"name",{value:e,configurable:!0}),"l$1");const $=W(({rows:t})=>i(g,{flexDirection:"column",children:t.map(e=>{let r;switch(e.status){case"error":{r=i(d,{color:"red",children:G});break}case"ok":{r=i(d,{color:"green",children:B});break}case"running":{r=i(d,{color:"white",children:i(A,{type:"dots"})});break}case"warn":{r=i(d,{color:"yellow",children:Y});break}default:{r=i(d,{dimColor:!0,children:S});break}}return v(g,{children:[i(g,{width:3,children:r}),i(g,{flexGrow:1,children:i(d,{children:e.label})}),e.summary?i(g,{children:v(d,{dimColor:!0,children:[S," ",e.summary]})}):null]},e.id)})}),"ScanProgressApp");var z=Object.defineProperty,l=b((t,e)=>z(t,"name",{value:e,configurable:!0}),"e");const F={error:O(h.failure),ok:M(h.success),pending:w(h.dash),skip:w(h.dash),warn:E(h.warning)},H=l((t,e,r)=>{const u=r?`${t} ${w(`— ${r}`)}`:t;return` ${F[e]} ${u}
2
- `},"formatStaticRow"),_=l((t,e={})=>{const r=e.stream??process.stderr,u=typeof r.isTTY=="boolean"&&r.isTTY&&!R,p=e.live??u,n=new Map;for(const a of t)n.set(a.id,{id:a.id,label:a.label,status:"pending"});if(!p||t.length===0)return{finish:l((a,c,y)=>{const f=n.get(a);f&&(n.set(a,{...f,status:c,summary:y}),r.write(H(f.label,c,y)))},"finish"),start:l(a=>{const c=n.get(a);c&&n.set(a,{...c,status:"running"})},"start"),stop:l(()=>{},"stop")};const m=l(()=>t.map(a=>n.get(a.id)),"buildRows");let s=I(k.createElement($,{rows:m()}),{interactive:!0,patchConsole:!1});const o=l(()=>{s?.rerender(k.createElement($,{rows:m()}))},"rerender");return{finish:l((a,c,y)=>{const f=n.get(a);f&&(n.set(a,{...f,status:c,summary:y}),o())},"finish"),start:l(a=>{const c=n.get(a);c&&(n.set(a,{...c,status:"running"}),o())},"start"),stop:l(()=>{s&&(o(),s.unmount(),s=void 0)},"stop")}},"startScanProgress");var K=Object.defineProperty,x=b((t,e)=>K(t,"name",{value:e,configurable:!0}),"l");const C={bun:{file:"bun.lock",type:"bun"},npm:{file:"package-lock.json",type:"npm"},pnpm:{file:"pnpm-lock.yaml",type:"pnpm"},yarn:{file:"yarn.lock",type:"yarn"}},ee=x((t,e)=>{const r=C[e];if(!r)return[];let u;try{u=T(D(t,r.file))}catch{return[]}const p=P(u,r.type);if(p.length===0)return[];const n=new Set,m=[];for(const s of p){const o=`${s.name}@${s.version}`;n.has(o)||(n.add(o),m.push({isDev:!1,name:s.name,version:s.version}))}return m},"lockedPackages"),re=x((t,e)=>{const r=C[e];if(!r)return[];let u;try{u=T(D(t,r.file))}catch{return[]}const p=P(u,r.type);if(p.length===0)return[];const n=new Map;for(const s of p)n.has(s.name)||n.set(s.name,new Set),n.get(s.name).add(s.version);const m=[];for(const[s,o]of n)o.size<=1||m.push({name:s,versions:[...o]});return m.sort((s,o)=>s.name.localeCompare(o.name))},"findDuplicateDependencies");export{re as f,ee as l,_ as s};
@@ -1,2 +0,0 @@
1
- var E=Object.defineProperty;var v=(e,o)=>E(e,"name",{value:o,configurable:!0});import{createRequire as T}from"node:module";import{h as C,a as b,M as c,B as F,i as M,n as $,z as O}from"./otel-CO8UEfTa.js";const x=T(import.meta.url),m=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,D=v(e=>{if(typeof m<"u"&&m.versions&&m.versions.node){const[o,r]=m.versions.node.split(".").map(Number);if(o>22||o===22&&r>=3||o===20&&r>=16)return m.getBuiltinModule(e)}return x(e)},"__cjs_getBuiltinModule"),{cpSync:_,lstatSync:N,readdirSync:R,rmSync:y}=D("node:fs");var P=Object.defineProperty,l=v((e,o)=>P(e,"name",{value:o,configurable:!0}),"p");const A=l((e,o)=>{const r=new Set,t=[e],a=new Set([e]);for(;t.length>0;){const n=t.shift(),f=o.dependencies[n]??[];for(const i of f)a.has(i.target)||(a.add(i.target),r.add(i.target),t.push(i.target))}return r},"collectTransitiveProjectDeps"),k="vis-docker-manifest.json",I=["package.json","project.json"],q=["package.json","pnpm-workspace.yaml","pnpm-lock.yaml","package-lock.json","yarn.lock","bun.lock","bun.lockb",".npmrc","vis.config.ts","vis.config.mts","vis.config.cts","vis.config.js","vis.config.mjs","vis.config.cjs"],B=l((e,o)=>{const r=new Set(e);for(const t of e){const a=A(t,o);for(const n of a)r.add(n)}return r},"resolveFocusProjects"),g=l(e=>{C(e)},"ensureDir"),w=l((e,o)=>{try{return g(b(o)),_(e,o),!0}catch(r){if(r.code==="ENOENT")return!1;throw r}},"copyFileIfExists"),S=l((e,o)=>{let r;try{r=N(e)}catch{return}if(!r.isSymbolicLink()){if(r.isFile()){g(b(o)),_(e,o);return}g(o);for(const t of R(e,{withFileTypes:!0}))t.name==="node_modules"||t.name===".git"||t.isSymbolicLink()||S(c(e,t.name),c(o,t.name))}},"copyTreeExcludingNodeModules"),G=l(e=>{const{focus:o,includeSources:r=!1,outDir:t,projectGraph:a,workspace:n,workspaceRoot:f}=e,i=o.filter(s=>n.projects[s]===void 0);if(i.length>0)throw new Error(`Unknown focus project(s): ${i.join(", ")}. Check project names in your workspace.`);const j=B(o,a),u=c(t,"workspace"),d=c(t,"sources");y(u,{force:!0,recursive:!0}),y(d,{force:!0,recursive:!0}),g(u);for(const s of q)w(c(f,s),c(u,s));for(const s of j){const p=n.projects[s];if(p?.root)for(const h of I)w(c(f,p.root,h),c(u,p.root,h))}if(r){g(d);for(const s of o){const p=n.projects[s];p?.root&&S(c(f,p.root),c(d,p.root))}}return F(c(t,k),`${JSON.stringify({focus:o,projects:[...j].sort()},null,2)}
2
- `),{projects:[...j]}},"scaffoldDockerContext"),J=l(e=>{const{contextRoot:o,workspace:r,workspaceRoot:t}=e,a=c(o,k);if(!M(a))throw new Error(`No ${k} at ${o}. Run \`vis docker scaffold\` first.`);const n=$(a);if(!Array.isArray(n.projects))throw new TypeError(`Invalid ${k}: "projects" must be an array.`);const f=new Set(n.projects),i=[];for(const[j,u]of Object.entries(r.projects)){if(f.has(j)||!u.root)continue;const d=c(t,u.root),s=O(t,d);s===""||s==="."||s.startsWith("..")||(y(d,{force:!0,recursive:!0}),i.push(s))}return{removed:i}},"pruneDockerContext");export{J as p,B as r,G as s};
@@ -1,2 +0,0 @@
1
- var h=Object.defineProperty;var a=(t,e)=>h(t,"name",{value:e,configurable:!0});import{createRequire as m}from"node:module";import{M as l}from"./otel-CO8UEfTa.js";const y=m(import.meta.url),s=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,u=a(t=>{if(typeof s<"u"&&s.versions&&s.versions.node){const[e,r]=s.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return s.getBuiltinModule(t)}return y(t)},"__cjs_getBuiltinModule"),{mkdirSync:F,writeFileSync:L,readdirSync:_}=u("node:fs"),{readFile:v}=u("node:fs/promises");var j=Object.defineProperty,i=a((t,e)=>j(t,"name",{value:e,configurable:!0}),"i");const S="last-failures",c=i(t=>l(t,".task-runner",S),"getFailureLogDirectory"),d=i((t,e)=>l(c(t),`${encodeURIComponent(e)}.json`),"getFailureLogPath");class I{static{a(this,"FailureLogLifeCycle")}static{i(this,"FailureLogLifeCycle")}#e;#t;constructor(e,r){this.#e=e,this.#t=r}printTaskTerminalOutput(e,r,o){if(r!=="failure")return;const n=c(this.#e);try{F(n,{recursive:!0})}catch{return}const f=e.overrides.command,g=e.projectRoot,p={command:f,cwd:g,exitCode:void 0,hash:e.hash,runId:this.#t,status:r,taskId:e.id,terminalOutput:o,timestamp:new Date().toISOString()};try{L(d(this.#e,e.id),`${JSON.stringify(p,void 0,2)}
2
- `,"utf8")}catch{}}}const R=i(async(t,e)=>{const r=d(t,e);try{const o=await v(r,"utf8");return JSON.parse(o)}catch{return}},"loadFailureLog"),T=i(t=>{const e=c(t);let r;try{r=_(e)}catch{return[]}const o=[];for(const n of r)if(n.endsWith(".json"))try{o.push(decodeURIComponent(n.slice(0,-5)))}catch{}return o},"listFailureLogs");export{I as F,R as a,T as l};
@@ -1 +0,0 @@
1
- var k=Object.defineProperty;var f=(a,s)=>k(a,"name",{value:s,configurable:!0});import{createRequire as R}from"node:module";import{M as p,i as T,n as v}from"./otel-CO8UEfTa.js";const b=R(import.meta.url),l=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,j=f(a=>{if(typeof l<"u"&&l.versions&&l.versions.node){const[s,o]=l.versions.node.split(".").map(Number);if(s>22||s===22&&o>=3||s===20&&o>=16)return l.getBuiltinModule(a)}return b(a)},"__cjs_getBuiltinModule"),{readdirSync:y}=j("node:fs");var S=Object.defineProperty,d=f((a,s)=>S(a,"name",{value:s,configurable:!0}),"i");const $=d((a,s)=>{let o=0,n=0,r=0;for(const[,t]of a)switch(t.status){case"failure":{r+=1;break}case"local-cache":case"local-cache-kept-existing":case"remote-cache":{n+=1;break}case"success":{o+=1;break}}const i=[];o>0&&i.push(`${String(o)} succeeded`),n>0&&i.push(`${String(n)} cached`),r>0&&i.push(`${String(r)} failed`);const c=(s/1e3).toFixed(1);return i.push(`${c}s`),i.join(" · ")},"formatTimingSummary"),g=d(a=>{const s=p(a,".task-runner","runs");if(!T(s))return[];const o=y(s).filter(r=>r.endsWith(".json")),n=[];for(const r of o)try{n.push(v(p(s,r)))}catch{}return n},"loadRunSummaries"),I=d((a,s,o)=>{const n=o??g(a);if(n.length<2)return;let r=0,i=0;for(const e of n)typeof e.duration=="number"&&e.duration>0&&(r+=e.duration,i+=1);if(i<2)return;const c=r/i-s,t=Math.abs(c/1e3).toFixed(1);return Math.abs(c)<500?"(about average)":c>0?`(${t}s faster than avg)`:`(${t}s slower than avg)`},"compareDuration");var F=Object.defineProperty,m=f((a,s)=>F(a,"name",{value:s,configurable:!0}),"l");const P=m((a,s={},o)=>{const n=o??g(a);if(n.length===0)return[];const r=new Map;for(const t of n)if(!(s.since&&(t.startTime===void 0||t.startTime<s.since))&&Array.isArray(t.tasks))for(const e of t.tasks){if(e.cacheStatus==="HIT"||e.cacheStatus==="REMOTE_HIT"||e.cacheStatus==="SKIPPED")continue;const u=r.get(e.taskId)??{failures:0,project:e.target.project,successes:0,target:e.target.target,totalRuns:0};u.totalRuns+=1,e.exitCode!==void 0&&e.exitCode!==0?(u.failures+=1,u.lastFailure=e.startTime??t.startTime):u.successes+=1,r.set(e.taskId,u)}const i=s.minRuns??2,c=[];for(const[t,e]of r)e.totalRuns<i||e.failures!==0&&c.push({failures:e.failures,flakinessRate:e.failures/e.totalRuns,lastFailure:e.lastFailure,project:e.project,successes:e.successes,target:e.target,taskId:t,totalRuns:e.totalRuns});return c.sort((t,e)=>e.flakinessRate-t.flakinessRate),c},"analyzeFlakiness"),E=m(a=>{if(a.length===0)return["No flaky tasks detected."];const s=["Task","Runs","Failures","Rate","Last Failure"],o=a.map(t=>[t.taskId,String(t.totalRuns),String(t.failures),`${(t.flakinessRate*100).toFixed(1)}%`,t.lastFailure??"—"]),n=s.map((t,e)=>{let u=0;for(const h of o)u=Math.max(u,(h[e]??"").length);return Math.max(t.length,u)}),r=m((t,e)=>t.padEnd(e),"pad"),i=n.map(t=>"─".repeat(t)).join("──"),c=[s.map((t,e)=>r(t,n[e])).join(" "),i];for(const t of o)c.push(t.map((e,u)=>r(e,n[u])).join(" "));return c},"formatFlakinessTable");export{P as a,E as b,I as c,$ as f,g as l};