@visulima/vis 1.0.0-alpha.2 → 1.0.0-alpha.4

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 (103) hide show
  1. package/CHANGELOG.md +136 -14
  2. package/LICENSE.md +27 -0
  3. package/README.md +15 -9
  4. package/dist/audit-config.d.ts +24 -0
  5. package/dist/bin.js +777 -70
  6. package/dist/catalog.d.ts +16 -8
  7. package/dist/commands/add.d.ts +3 -0
  8. package/dist/commands/approve-builds.d.ts +3 -0
  9. package/dist/commands/audit.d.ts +23 -0
  10. package/dist/commands/clean.d.ts +3 -0
  11. package/dist/commands/create/discovery.d.ts +42 -0
  12. package/dist/commands/create/index.d.ts +13 -0
  13. package/dist/commands/create/prompts.d.ts +31 -0
  14. package/dist/commands/create/random-name.d.ts +15 -0
  15. package/dist/commands/create/templates/builtin.d.ts +15 -0
  16. package/dist/commands/create/templates/generator.d.ts +14 -0
  17. package/dist/commands/create/templates/index.d.ts +13 -0
  18. package/dist/commands/create/templates/monorepo.d.ts +16 -0
  19. package/dist/commands/create/templates/remote.d.ts +41 -0
  20. package/dist/commands/create/templates/types.d.ts +46 -0
  21. package/dist/commands/create/utils.d.ts +42 -0
  22. package/dist/commands/dedupe.d.ts +3 -0
  23. package/dist/commands/devcontainer.d.ts +3 -0
  24. package/dist/commands/dlx.d.ts +3 -0
  25. package/dist/commands/doctor.d.ts +15 -0
  26. package/dist/commands/exec.d.ts +3 -0
  27. package/dist/commands/implode.d.ts +3 -0
  28. package/dist/commands/init.d.ts +14 -0
  29. package/dist/commands/install.d.ts +3 -0
  30. package/dist/commands/link.d.ts +3 -0
  31. package/dist/commands/optimize.d.ts +38 -0
  32. package/dist/commands/pm.d.ts +3 -0
  33. package/dist/commands/remove.d.ts +3 -0
  34. package/dist/commands/sort-package-json.d.ts +3 -0
  35. package/dist/commands/unlink.d.ts +3 -0
  36. package/dist/commands/upgrade.d.ts +3 -0
  37. package/dist/commands/why.d.ts +3 -0
  38. package/dist/config.d.ts +38 -11
  39. package/dist/config.js +1 -1
  40. package/dist/native-binding.d.ts +151 -0
  41. package/dist/output.d.ts +40 -0
  42. package/dist/overrides.d.ts +82 -0
  43. package/dist/plugins/config-loader.d.ts +3 -0
  44. package/dist/plugins/post-command.d.ts +3 -0
  45. package/dist/plugins/security-enforcement.d.ts +3 -0
  46. package/dist/pm-runner.d.ts +23 -0
  47. package/dist/security.d.ts +64 -0
  48. package/dist/socket-security.d.ts +129 -0
  49. package/dist/tips.d.ts +41 -0
  50. package/dist/tui/components/CheckProgressApp.d.ts +6 -0
  51. package/dist/tui/components/CommandSummary.d.ts +17 -0
  52. package/dist/tui/components/Header.d.ts +13 -0
  53. package/dist/tui/components/OutputPanel.d.ts +16 -0
  54. package/dist/tui/components/QuitDialog.d.ts +15 -0
  55. package/dist/tui/components/TaskListPanel.d.ts +19 -0
  56. package/dist/tui/components/TaskRow.d.ts +12 -0
  57. package/dist/tui/components/TaskStore.d.ts +80 -0
  58. package/dist/tui/components/VisTaskRunnerApp.d.ts +17 -0
  59. package/dist/tui/components/devcontainer/DevcontainerStore.d.ts +66 -0
  60. package/dist/tui/components/devcontainer/VisDevcontainerApp.d.ts +9 -0
  61. package/dist/tui/components/devcontainer/catalogs/extensions.d.ts +8 -0
  62. package/dist/tui/components/devcontainer/catalogs/features.d.ts +8 -0
  63. package/dist/tui/components/devcontainer/catalogs/filters.d.ts +4 -0
  64. package/dist/tui/components/devcontainer/catalogs/mount-suggestions.d.ts +19 -0
  65. package/dist/tui/components/devcontainer/catalogs/templates.d.ts +8 -0
  66. package/dist/tui/components/devcontainer/devcontainer-io.d.ts +14 -0
  67. package/dist/tui/components/devcontainer/sections/DockerComposeSection.d.ts +11 -0
  68. package/dist/tui/components/devcontainer/sections/EnvironmentSection.d.ts +16 -0
  69. package/dist/tui/components/devcontainer/sections/ExtensionsSection.d.ts +11 -0
  70. package/dist/tui/components/devcontainer/sections/FeaturesSection.d.ts +11 -0
  71. package/dist/tui/components/devcontainer/sections/GeneralSection.d.ts +12 -0
  72. package/dist/tui/components/devcontainer/sections/LifecycleSection.d.ts +13 -0
  73. package/dist/tui/components/devcontainer/sections/MountsSection.d.ts +16 -0
  74. package/dist/tui/components/devcontainer/sections/PortsSection.d.ts +10 -0
  75. package/dist/tui/components/devcontainer/sections/PreviewPanel.d.ts +11 -0
  76. package/dist/tui/components/devcontainer/types.d.ts +53 -0
  77. package/dist/tui/components/devcontainer/validate.d.ts +16 -0
  78. package/dist/tui/components/graph/GraphStore.d.ts +42 -0
  79. package/dist/tui/components/graph/ProjectDetailPanel.d.ts +10 -0
  80. package/dist/tui/components/graph/ProjectListPanel.d.ts +20 -0
  81. package/dist/tui/components/graph/VisGraphApp.d.ts +8 -0
  82. package/dist/tui/components/optimize/OptimizeDetailPanel.d.ts +9 -0
  83. package/dist/tui/components/optimize/OptimizeListPanel.d.ts +16 -0
  84. package/dist/tui/components/optimize/OptimizeStore.d.ts +50 -0
  85. package/dist/tui/components/optimize/VisOptimizeApp.d.ts +8 -0
  86. package/dist/tui/components/optimize/constants.d.ts +7 -0
  87. package/dist/tui/components/update/PackageDetailPanel.d.ts +12 -0
  88. package/dist/tui/components/update/PackageListPanel.d.ts +18 -0
  89. package/dist/tui/components/update/UpdateStore.d.ts +62 -0
  90. package/dist/tui/components/update/VisUpdateApp.d.ts +11 -0
  91. package/dist/tui/dynamic-life-cycle.d.ts +21 -0
  92. package/dist/tui/formatting-utils.d.ts +17 -0
  93. package/dist/tui/pretty-time.d.ts +8 -0
  94. package/dist/tui/static-life-cycle.d.ts +22 -0
  95. package/dist/tui/status-utils.d.ts +20 -0
  96. package/dist/tui/symbols.d.ts +7 -0
  97. package/dist/tui/types.d.ts +11 -0
  98. package/dist/typosquats.d.ts +70 -0
  99. package/dist/upgrade-check.d.ts +30 -0
  100. package/dist/utils.d.ts +22 -0
  101. package/dist/workspace.d.ts +262 -5
  102. package/index.js +600 -0
  103. package/package.json +34 -11
package/dist/catalog.d.ts CHANGED
@@ -1,28 +1,29 @@
1
+ import type { AcceptedRisk, PackageReportData, SocketSecurityOptions } from "./socket-security.d.ts";
1
2
  type UpdateTarget = "latest" | "minor" | "patch";
2
- interface ParsedVersion {
3
- major: number;
4
- minor: number;
5
- patch: number;
6
- prerelease: string;
7
- }
8
3
  interface SecurityVulnerability {
4
+ /** Alternate identifiers (CVE-*, GHSA-*, etc.) from the OSV database. */
5
+ aliases?: string[];
9
6
  cvssScore?: number;
10
7
  fixedVersions: string[];
11
8
  id: string;
12
9
  severity: "CRITICAL" | "HIGH" | "LOW" | "MODERATE" | "UNKNOWN";
13
10
  summary: string;
14
11
  }
12
+ type SocketReport = Pick<PackageReportData, "alerts" | "license" | "score">;
15
13
  interface OutdatedEntry {
14
+ acceptedRisk?: AcceptedRisk;
16
15
  catalogName: string;
17
16
  currentRange: string;
18
17
  newRange: string;
19
18
  packageName: string;
19
+ socketReport?: SocketReport;
20
20
  targetVersion: string;
21
21
  updateType: "major" | "minor" | "patch";
22
22
  vulnerabilities?: SecurityVulnerability[];
23
23
  }
24
24
  interface CatalogCheckOptions {
25
25
  exclude: string[];
26
+ ignore: string[];
26
27
  include: string[];
27
28
  includePrerelease: boolean;
28
29
  security?: boolean;
@@ -32,6 +33,12 @@ interface ReadCatalogOptions {
32
33
  dev?: boolean;
33
34
  prod?: boolean;
34
35
  }
36
+ interface ParsedVersion {
37
+ major: number;
38
+ minor: number;
39
+ patch: number;
40
+ prerelease: string;
41
+ }
35
42
  declare const parseVersion: (input: string) => ParsedVersion | undefined;
36
43
  declare const extractPrefix: (range: string) => string;
37
44
  declare const getUpdateType: (current: ParsedVersion, target: ParsedVersion) => "major" | "minor" | "none" | "patch";
@@ -83,9 +90,10 @@ declare const fetchVulnerabilities: (packages: {
83
90
  declare const findTargetVersion: (versions: string[], latest: string, currentRange: string, target: UpdateTarget, includePrerelease: boolean) => string | undefined;
84
91
  interface CheckOutdatedResult {
85
92
  failed: string[];
93
+ ignored: string[];
86
94
  outdated: OutdatedEntry[];
87
95
  }
88
- declare const checkOutdated: (catalogs: Map<string, Map<string, string>>, options: CatalogCheckOptions, npmrcConfig?: NpmrcConfig, onProgress?: (current: number, total: number) => void) => Promise<CheckOutdatedResult>;
96
+ declare const checkOutdated: (catalogs: Map<string, Map<string, string>>, options: CatalogCheckOptions, npmrcConfig?: NpmrcConfig, onProgress?: (current: number, total: number) => void, workspaceRoot?: string, socketOptions?: SocketSecurityOptions, acceptedRisks?: Record<string, AcceptedRisk>) => Promise<CheckOutdatedResult>;
89
97
  declare const createBackup: (workspaceRoot: string, packageManager?: string, updates?: OutdatedEntry[]) => string | undefined;
90
98
  declare const restoreFromBackup: (workspaceRoot: string, packageManager?: string) => boolean;
91
99
  declare const hasBackup: (workspaceRoot: string, packageManager?: string) => boolean;
@@ -106,5 +114,5 @@ interface ChangelogInfo {
106
114
  repoUrl?: string;
107
115
  }
108
116
  declare const fetchChangelogInfo: (packages: OutdatedEntry[], timeoutMs?: number) => Promise<ChangelogInfo[]>;
109
- export type { CatalogCheckOptions, CatalogProvider, ChangelogInfo, CheckOutdatedResult, NpmrcConfig, OutdatedEntry, OutputFormat, ParsedVersion, ReadCatalogOptions, SecurityVulnerability, UpdateTarget, };
117
+ export type { CatalogCheckOptions, CatalogProvider, ChangelogInfo, CheckOutdatedResult, NpmrcConfig, OutdatedEntry, OutputFormat, ReadCatalogOptions, SecurityVulnerability, SocketReport, UpdateTarget, };
110
118
  export { applyCatalogUpdates, applyPackageJsonUpdates, checkOutdated, createBackup, detectJsonIndent, extractPrefix, fetchChangelogInfo, fetchPackageVersions, fetchVulnerabilities, findTargetVersion, formatOutdatedJson, formatOutdatedMinimal, formatOutdatedTable, formatSummary, getRegistryForPackage, getUpdateType, groupByCatalog, hasBackup, hasCatalogs, hasPackageJsonDeps, isNewer, loadNpmrc, matchesFilters, matchesPattern, parseBunCatalogs, parseCatalogsFromYaml, parseCompositeCatalogName, parseNpmrc, parseVersion, promptPackageSelection, readCatalogs, readPackageJsonDeps, restoreFromBackup, toFilterArray, };
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const add: Command;
3
+ export default add;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const approveBuilds: Command;
3
+ export default approveBuilds;
@@ -0,0 +1,23 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ interface InstalledPackage {
3
+ isDev: boolean;
4
+ name: string;
5
+ version: string;
6
+ }
7
+ /** A package installed in multiple versions. */
8
+ interface DuplicatePackage {
9
+ /** The package name. */
10
+ name: string;
11
+ /** Each installed version. */
12
+ versions: string[];
13
+ }
14
+ declare const scanInstalledPackages: (workspaceRoot: string) => InstalledPackage[];
15
+ /**
16
+ * Finds packages with multiple installed versions by parsing the lockfile
17
+ * via `lockparse`. Passes `package.json` for accuracy (especially yarn).
18
+ */
19
+ declare const findDuplicateDependencies: (workspaceRoot: string, pmName: string) => Promise<DuplicatePackage[]>;
20
+ declare const audit: Command;
21
+ export default audit;
22
+ export type { DuplicatePackage, InstalledPackage };
23
+ export { findDuplicateDependencies, scanInstalledPackages };
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const clean: Command;
3
+ export default clean;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Template discovery — identifies and resolves template sources from user input.
3
+ *
4
+ * Supports:
5
+ * - Built-in templates prefixed with `vis:` (app, library, monorepo, generator)
6
+ * - npm `create-*` packages (with shorthand expansion)
7
+ * - Git repositories from GitHub, GitLab, Bitbucket, and Sourcehut (all URL formats)
8
+ * - Direct tarball/registry URLs via giget's http/https providers
9
+ */
10
+ import type { TemplateConfig, TemplateType } from "./templates/types.d.ts";
11
+ /**
12
+ * Check if the input looks like a git/tarball URL that giget can handle.
13
+ * @param input Raw user input string.
14
+ * @returns `true` when the input matches a known git host, provider prefix, or URL scheme.
15
+ */
16
+ export declare const isGitUrl: (input: string) => boolean;
17
+ /**
18
+ * Expand shorthand npm create names following the `npm create` convention:
19
+ *
20
+ * - `vite` → `create-vite`
21
+ * - `@scope/foo` → `@scope/create-foo`
22
+ * - `create-vue` → `create-vue` (already expanded)
23
+ * - `sv` → `sv` (direct-package initialiser, not expanded)
24
+ * @param name Bare package name or scoped package name.
25
+ * @returns Expanded package name suitable for `dlx`.
26
+ */
27
+ export declare const expandCreateShorthand: (name: string) => string;
28
+ /**
29
+ * Given the raw template string from the user, determine what kind of
30
+ * template it is and return a resolved {@link TemplateConfig}.
31
+ * @param input Raw template string (e.g., "vis:app", "vite", "user/repo").
32
+ * @param extraArgs Additional CLI arguments to forward to the template runner.
33
+ * @returns Resolved template configuration with type, source, and args.
34
+ */
35
+ export declare const discoverTemplate: (input: string, extraArgs?: string[]) => TemplateConfig;
36
+ /**
37
+ * Suggest the most appropriate parent directory for a new project based on
38
+ * the template type.
39
+ * @param type The resolved template type.
40
+ * @returns Suggested parent directory name ("apps", "packages", or ".").
41
+ */
42
+ export declare const inferParentDir: (type: TemplateType) => string;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `vis create` — full-featured project scaffolding command.
3
+ *
4
+ * Supports built-in templates (monorepo, app, library, generator),
5
+ * remote npm create-* packages, and git repository templates
6
+ * (GitHub, GitLab, Bitbucket, Sourcehut) via giget.
7
+ *
8
+ * Interactive mode guides users through template selection, naming,
9
+ * directory choice, and post-creation setup.
10
+ */
11
+ import type { Command } from "@visulima/cerebro";
12
+ declare const create: Command;
13
+ export default create;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Interactive prompts for `vis create`.
3
+ *
4
+ * Uses `node:readline` (same pattern as `vis init`) to keep dependencies minimal.
5
+ */
6
+ export interface PromptResult {
7
+ editor?: "vscode" | undefined;
8
+ gitInit: boolean;
9
+ /** Whether the user confirmed overwriting an existing non-empty directory. */
10
+ overwrite: boolean;
11
+ pm?: "bun" | "npm" | "pnpm" | "yarn" | undefined;
12
+ projectName: string;
13
+ targetDir: string;
14
+ template: string;
15
+ }
16
+ /**
17
+ * Run the full interactive prompt flow and return the collected answers.
18
+ * @param options.cwd Working directory for resolving paths.
19
+ * @param options.defaultPm Pre-selected package manager (skips PM prompt when set).
20
+ * @param options.defaultGitInit Default for the git-init prompt (from vis.config.ts).
21
+ * @param options.defaultEditor Default for the editor prompt (from vis.config.ts).
22
+ * @param options.inMonorepo Whether we are inside an existing monorepo workspace.
23
+ * @returns Collected answers including template, name, directory, PM, and flags.
24
+ */
25
+ export declare const runInteractivePrompts: (options: {
26
+ cwd: string;
27
+ defaultEditor?: "vscode";
28
+ defaultGitInit?: boolean;
29
+ defaultPm?: string;
30
+ inMonorepo: boolean;
31
+ }) => Promise<PromptResult>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Random project name generator — produces friendly `word-word` names
3
+ * used as default project name suggestions in interactive mode.
4
+ *
5
+ * Uses @nkzw/safe-word-list for a curated set of ~2700 safe English words.
6
+ */
7
+ /**
8
+ * Generate a random `word-word` project name from the safe word list.
9
+ * @example
10
+ * ```ts
11
+ * randomName(); // "swift-ember"
12
+ * randomName(); // "bold-prism"
13
+ * ```
14
+ */
15
+ export declare const randomName: () => string;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Built-in template executor — routes `vis:app` and `vis:library`
3
+ * to appropriate scaffolding strategies.
4
+ *
5
+ * - `vis:app` delegates to `create-vite` via dlx
6
+ * - `vis:library` scaffolds a minimal TypeScript library package
7
+ */
8
+ import type { ExecutionContext, TemplateConfig } from "./types.d.ts";
9
+ /**
10
+ * Execute a built-in template (vis:app or vis:library).
11
+ * @param config Resolved template config with type and extra args.
12
+ * @param context Runtime context with PM info, target dir, and project name.
13
+ * @returns Exit code — 0 on success, non-zero on failure.
14
+ */
15
+ export declare const executeBuiltin: (config: TemplateConfig, context: ExecutionContext) => number;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Built-in generator template — scaffolds a code generator package
3
+ * inside an existing monorepo workspace.
4
+ *
5
+ * Creates a minimal Node.js CLI package with a bin entry point.
6
+ */
7
+ import type { ExecutionContext } from "./types.d.ts";
8
+ /**
9
+ * Scaffold a code generator package with a bin entry point.
10
+ * @param context Runtime context with project name and target directory.
11
+ * @param description Optional generator description for package.json.
12
+ * @returns Exit code — 0 on success.
13
+ */
14
+ export declare const executeGeneratorTemplate: (context: ExecutionContext, description?: string) => number;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Template executor router — dispatches to the correct executor
3
+ * based on the resolved template type.
4
+ */
5
+ import type { ExecutionContext, TemplateConfig } from "./types.d.ts";
6
+ /**
7
+ * Execute a template given its resolved configuration and runtime context.
8
+ * @param config Resolved template info (type, source, extra args).
9
+ * @param context Runtime context (cwd, PM, project name, target dir, config).
10
+ * @returns Exit code — 0 on success, non-zero on failure.
11
+ */
12
+ export declare const executeTemplate: (config: TemplateConfig, context: ExecutionContext) => Promise<number>;
13
+ export type { ExecutionContext, TemplateConfig } from "./types.d.ts";
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Built-in monorepo template — scaffolds a complete pnpm workspace.
3
+ *
4
+ * Creates:
5
+ * - Root package.json with workspace scripts
6
+ * - pnpm-workspace.yaml
7
+ * - .gitignore, .editorconfig
8
+ * - apps/ and packages/ directories
9
+ */
10
+ import type { ExecutionContext } from "./types.d.ts";
11
+ /**
12
+ * Scaffold a pnpm monorepo workspace with apps/ and packages/ directories.
13
+ * @param context Execution context with project name, target directory, and PM info.
14
+ * @returns Exit code (0 = success).
15
+ */
16
+ export declare const executeMonorepoTemplate: (context: ExecutionContext) => number;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Remote template executors:
3
+ *
4
+ * - `executeRemoteNpm` — runs npm `create-*` packages via `dlx`
5
+ * - `executeRemoteGit` — downloads git repositories using giget
6
+ * (GitHub, GitLab, Bitbucket, Sourcehut — tarballs with caching)
7
+ *
8
+ * Includes auto-fix rules for popular tools that need extra flags
9
+ * to play nicely with monorepo setups.
10
+ */
11
+ import type { ExecutionContext, TemplateConfig } from "./types.d.ts";
12
+ /**
13
+ * Execute an npm `create-*` package via the package manager's `dlx` command.
14
+ *
15
+ * Injects the target directory as the first positional argument if not
16
+ * already present, since most `create-*` packages expect the output
17
+ * directory as the first arg (e.g., `create-vite my-app`).
18
+ *
19
+ * Auto-fix rules are applied for known tools that need extra flags.
20
+ * @param config Resolved template config with source package name and extra args.
21
+ * @param context Runtime context with PM, cwd, target dir, and monorepo flag.
22
+ * @returns Exit code — 0 on success, non-zero on failure.
23
+ */
24
+ export declare const executeRemoteNpm: (config: TemplateConfig, context: ExecutionContext) => number;
25
+ /**
26
+ * Download a git repository template using giget.
27
+ *
28
+ * Supports GitHub, GitLab, Bitbucket, and Sourcehut — with tarball
29
+ * downloads, disk caching, offline support, subdirectory extraction,
30
+ * and private repo auth via tokens.
31
+ *
32
+ * Source format follows giget conventions:
33
+ * - `provider:owner/repo[/subpath][#ref]`
34
+ * - `owner/repo` (defaults to GitHub)
35
+ * - Full HTTPS URLs
36
+ * - `git:` prefix for raw git clone
37
+ * @param config Resolved template config with giget source string and extra args.
38
+ * @param context Runtime context with target dir and createConfig (auth, registry, etc.).
39
+ * @returns Exit code — 0 on success, 1 on failure.
40
+ */
41
+ export declare const executeRemoteGit: (config: TemplateConfig, context: ExecutionContext) => Promise<number>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Core type definitions for the `vis create` scaffolding system.
3
+ */
4
+ /** The kind of template being scaffolded. */
5
+ export type TemplateType = "builtin:app" | "builtin:generator" | "builtin:library" | "builtin:monorepo" | "remote:git" | "remote:npm";
6
+ /** Resolved information about a template after discovery. */
7
+ export interface TemplateConfig {
8
+ /** Extra CLI arguments forwarded to the template runner. */
9
+ args: string[];
10
+ /** The npm package name (for remote:npm) or git URL (for remote:git). */
11
+ source: string;
12
+ /** What kind of template this is. */
13
+ type: TemplateType;
14
+ }
15
+ /** Create config from vis.config.ts — full shape matching VisConfig.create. */
16
+ export interface CreateConfig {
17
+ auth?: string;
18
+ defaultEditor?: "vscode";
19
+ defaultPm?: "bun" | "npm" | "pnpm" | "yarn";
20
+ defaultProvider?: "bitbucket" | "github" | "gitlab" | "sourcehut";
21
+ gitInit?: boolean;
22
+ install?: boolean;
23
+ preferOffline?: boolean;
24
+ registry?: false | string;
25
+ templates?: Record<string, string>;
26
+ }
27
+ /** Runtime context passed to every template executor. */
28
+ export interface ExecutionContext {
29
+ /** Create config from vis.config.ts. */
30
+ createConfig?: CreateConfig;
31
+ /** Working directory (workspace root or cwd). */
32
+ cwd: string;
33
+ /** Whether we are inside an existing monorepo workspace. */
34
+ inMonorepo: boolean;
35
+ /** Console-compatible logger from Cerebro toolbox. */
36
+ logger: Console;
37
+ /** Detected package manager. */
38
+ pm: {
39
+ name: "bun" | "npm" | "pnpm" | "yarn";
40
+ version: string;
41
+ };
42
+ /** The validated npm-safe project name. */
43
+ projectName: string;
44
+ /** Absolute path to the target directory. */
45
+ targetDir: string;
46
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Utility helpers for the `vis create` command.
3
+ *
4
+ * - Package name validation & sanitisation
5
+ * - Directory emptiness / conflict checks
6
+ * - Target directory resolution
7
+ */
8
+ /**
9
+ * Validate an npm package name using the official `validate-npm-package-name` library.
10
+ * Handles blacklisted names, core module conflicts, length limits, etc.
11
+ * @param name Package name to validate.
12
+ * @returns `true` when `name` is valid for new npm packages.
13
+ */
14
+ export declare const isValidPackageName: (name: string) => boolean;
15
+ /**
16
+ * Sanitise an arbitrary string into a valid npm package name.
17
+ * @param raw Arbitrary string to sanitise.
18
+ * @returns Lowercased, hyphen-separated name with special chars stripped.
19
+ */
20
+ export declare const toValidPackageName: (raw: string) => string;
21
+ /**
22
+ * Check if a directory is empty or contains only ignored files (.DS_Store, .git, etc.).
23
+ * @param dir Absolute path to check.
24
+ * @returns `true` when `dir` does not exist or contains only ignored files.
25
+ */
26
+ export declare const isEmptyDir: (dir: string) => boolean;
27
+ /**
28
+ * Resolve `projectName` relative to `cwd` into an absolute target directory path.
29
+ * @param projectName Project name or relative path.
30
+ * @param cwd Base directory to resolve from.
31
+ * @returns Object with absolute `targetDir` and sanitised `packageName`.
32
+ */
33
+ export declare const resolveTargetDir: (projectName: string, cwd: string) => {
34
+ packageName: string;
35
+ targetDir: string;
36
+ };
37
+ /**
38
+ * Check whether scaffolding can proceed without overwriting user files.
39
+ * @param dir Absolute path to the target directory.
40
+ * @returns `true` when the directory is safe to write into (empty or non-existent).
41
+ */
42
+ export declare const canSafelyOverwrite: (dir: string) => boolean;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const dedupe: Command;
3
+ export default dedupe;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const devcontainer: Command;
3
+ export default devcontainer;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const dlx: Command;
3
+ export default dlx;
@@ -0,0 +1,15 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ /**
3
+ * `vis doctor` — unified project health check.
4
+ *
5
+ * Runs all diagnostic scans in parallel (outdated, vulnerabilities,
6
+ * Socket.dev scores, duplicates, optimization opportunities) and
7
+ * displays a single dashboard with actionable next steps.
8
+ * @example
9
+ * ```sh
10
+ * vis doctor # full health check
11
+ * vis doctor --json # machine-readable output
12
+ * ```
13
+ */
14
+ declare const doctor: Command;
15
+ export default doctor;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const exec: Command;
3
+ export default exec;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const implode: Command;
3
+ export default implode;
@@ -0,0 +1,14 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ /**
3
+ * `vis init` — initialize vis configuration with secure defaults.
4
+ *
5
+ * In interactive mode (`--interactive` or TTY default), guides the user through:
6
+ * 1. Socket.dev security scanning (opt-in)
7
+ * 2. Build script approval (scans node_modules)
8
+ * 3. Git hooks / lint-staged setup
9
+ * 4. Native PM config sync
10
+ *
11
+ * In non-interactive mode (CI, piped), creates a minimal config with secure defaults.
12
+ */
13
+ declare const init: Command;
14
+ export default init;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const install: Command;
3
+ export default install;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const link: Command;
3
+ export default link;
@@ -0,0 +1,38 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ import type { PmInfo } from "../overrides.d.ts";
3
+ import type { OptimizeEntry } from "../tui/components/optimize/OptimizeStore.d.ts";
4
+ /** Collects dependency names from a `package.json`. */
5
+ declare const collectDepsFromPkgJson: (pkgJsonPath: string, productionOnly: boolean) => Set<string>;
6
+ /** Discovers workspace package directories. */
7
+ declare const discoverWorkspacePackages: (workspaceRoot: string) => string[];
8
+ /** Scans deps against e18e module-replacements manifests. */
9
+ declare const buildE18eEntries: (allDeps: Set<string>) => OptimizeEntry[];
10
+ /** Scans deps against @socketregistry manifest. */
11
+ declare const buildSocketEntries: (allDeps: Set<string>, lockText: string, pm: PmInfo, pin: boolean) => OptimizeEntry[];
12
+ /** Marks e18e entries that have codemods available. */
13
+ declare const markCodemodAvailability: (entries: OptimizeEntry[]) => Promise<void>;
14
+ interface CodemodResult {
15
+ filesChanged: number;
16
+ packageName: string;
17
+ }
18
+ /**
19
+ * Runs a codemod for a single package across all source files in the project.
20
+ * Returns the number of files modified.
21
+ */
22
+ declare const runCodemod: (workspaceRoot: string, packageName: string) => Promise<CodemodResult>;
23
+ /**
24
+ * `vis optimize` — two-phase dependency optimization with interactive TUI.
25
+ *
26
+ * **Phase 1 (e18e):** Identifies packages replaceable with native builtins or lighter
27
+ * alternatives using `module-replacements` manifests. Runs source code codemods via
28
+ * `module-replacements-codemods` for selected entries.
29
+ *
30
+ * **Phase 2 (Socket.dev):** Writes override/resolution entries for packages that have
31
+ * security-hardened `@socketregistry` alternatives.
32
+ *
33
+ * In TTY mode, presents an interactive TUI (like `vis update`) where users select
34
+ * which optimizations to apply. In non-TTY/CI mode, outputs a static report.
35
+ */
36
+ declare const optimize: Command;
37
+ export default optimize;
38
+ export { buildE18eEntries, buildSocketEntries, collectDepsFromPkgJson, discoverWorkspacePackages, markCodemodAvailability, runCodemod };
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const pm: Command;
3
+ export default pm;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const remove: Command;
3
+ export default remove;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const sortPackageJson: Command;
3
+ export default sortPackageJson;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const unlink: Command;
3
+ export default unlink;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const upgrade: Command;
3
+ export default upgrade;
@@ -0,0 +1,3 @@
1
+ import type { Command } from "@visulima/cerebro";
2
+ declare const why: Command;
3
+ export default why;
package/dist/config.d.ts CHANGED
@@ -1,6 +1,19 @@
1
1
  import type { VisConfig } from "./workspace.d.ts";
2
2
  /** Supported config file names, checked in order. */
3
3
  declare const CONFIG_FILES: string[];
4
+ /**
5
+ * Secure-by-default security settings based on npm supply chain best practices.
6
+ *
7
+ * These defaults are applied automatically when using `defineConfig()` or `loadVisConfig()`.
8
+ * Users can override any value — their settings always take precedence.
9
+ * @see https://github.com/lirantal/awesome-npm-security-best-practices
10
+ */
11
+ declare const SECURITY_DEFAULTS: Required<Pick<NonNullable<VisConfig["security"]>, "blockExoticSubdeps" | "minimumReleaseAge" | "strictDepBuilds" | "trustPolicy" | "trustPolicyIgnoreAfter">>;
12
+ /**
13
+ * Apply secure defaults to a raw config object.
14
+ * Merges `SECURITY_DEFAULTS` into `config.security`, preserving all user overrides.
15
+ */
16
+ declare const applyDefaults: (config: VisConfig) => VisConfig;
4
17
  /**
5
18
  * Find the vis config file in a directory.
6
19
  * @param directory The directory to search in.
@@ -10,31 +23,45 @@ declare const findVisConfigFile: (directory: string) => string | undefined;
10
23
  /**
11
24
  * Load the vis configuration from a `vis.config.ts` (or `.js`, `.mjs`, `.cjs`, `.mts`, `.cts`) file.
12
25
  *
13
- * Uses jiti for runtime TypeScript support no build step needed for config files.
14
- * Falls back to an empty config if no config file is found.
26
+ * Uses a file-hash based cache to avoid repeated jiti compilations.
27
+ * Falls back to secure defaults if no config file is found.
15
28
  * @param workspaceRoot The workspace root directory to search for the config file.
16
- * @returns The loaded and resolved configuration.
29
+ * @returns The loaded and resolved configuration with secure defaults applied.
17
30
  */
18
31
  declare const loadVisConfig: (workspaceRoot: string) => Promise<VisConfig>;
19
32
  /**
20
33
  * Type-safe helper for defining vis configuration.
21
34
  * Provides full TypeScript autocomplete when used in `vis.config.ts`.
35
+ *
36
+ * Secure defaults are applied automatically — you only need to specify overrides.
37
+ * To see the active defaults, run `vis check --security-config`.
22
38
  * @example
23
39
  * ```typescript
24
- * // vis.config.ts
40
+ * // vis.config.ts — minimal config, fully secured by defaults
25
41
  * import { defineConfig } from "@visulima/vis/config";
26
42
  *
27
43
  * export default defineConfig({
28
- * update: {
29
- * target: "minor",
30
- * exclude: ["@types/*"],
31
- * security: true,
44
+ * security: {
45
+ * allowBuilds: {
46
+ * esbuild: true,
47
+ * "@prisma/client": true,
48
+ * },
32
49
  * },
33
- * ai: {
34
- * provider: "claude",
50
+ * });
51
+ * ```
52
+ * @example
53
+ * ```typescript
54
+ * // vis.config.ts — override a default
55
+ * import { defineConfig } from "@visulima/vis/config";
56
+ *
57
+ * export default defineConfig({
58
+ * security: {
59
+ * // Relax cooldown to 24 hours instead of the default 14 days
60
+ * minimumReleaseAge: 1440,
61
+ * allowBuilds: { esbuild: true },
35
62
  * },
36
63
  * });
37
64
  * ```
38
65
  */
39
66
  declare const defineConfig: (config: VisConfig) => VisConfig;
40
- export { CONFIG_FILES, defineConfig, findVisConfigFile, loadVisConfig };
67
+ export { applyDefaults, CONFIG_FILES, defineConfig, findVisConfigFile, loadVisConfig, SECURITY_DEFAULTS };
package/dist/config.js CHANGED
@@ -1 +1 @@
1
- var r=Object.defineProperty;var n=(e,i)=>r(e,"name",{value:i,configurable:!0});import{createRequire as f}from"node:module";import{join as g}from"@visulima/path";import{createJiti as d}from"jiti";const c=f(import.meta.url),s=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,a=n(e=>{if(typeof s<"u"&&s.versions&&s.versions.node){const[i,o]=s.versions.node.split(".").map(Number);if(i>22||i===22&&o>=3||i===20&&o>=16)return s.getBuiltinModule(e)}return c(e)},"__cjs_getBuiltinModule"),{existsSync:u}=a("node:fs");var l=Object.defineProperty,t=n((e,i)=>l(e,"name",{value:i,configurable:!0}),"o");const m=["vis.config.ts","vis.config.mts","vis.config.cts","vis.config.js","vis.config.mjs","vis.config.cjs"],p=t(e=>{for(const i of m){const o=g(e,i);if(u(o))return o}},"findVisConfigFile"),C=t(async e=>{const i=p(e);if(!i)return{};const o=await d(e).import(i,{default:!0,try:!0})??{};return typeof o=="function"?await o():o},"loadVisConfig"),b=t(e=>e,"defineConfig");export{m as CONFIG_FILES,b as defineConfig,p as findVisConfigFile,C as loadVisConfig};
1
+ var h=Object.defineProperty;var u=(e,t)=>h(e,"name",{value:t,configurable:!0});import{createRequire as C}from"node:module";import{findCacheDirSync as w}from"@visulima/find-cache-dir";import{ensureDirSync as p,isAccessibleSync as D,readJsonSync as I,writeJsonSync as x}from"@visulima/fs";import{join as o,dirname as E}from"@visulima/path";import{createJiti as P}from"jiti";const v=C(import.meta.url),r=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,d=u(e=>{if(typeof r<"u"&&r.versions&&r.versions.node){const[t,s]=r.versions.node.split(".").map(Number);if(t>22||t===22&&s>=3||t===20&&s>=16)return r.getBuiltinModule(e)}return v(e)},"__cjs_getBuiltinModule"),{createHash:_}=d("node:crypto"),{existsSync:y,readFileSync:S,copyFileSync:j,unlinkSync:b}=d("node:fs"),{tmpdir:F}=d("node:os");var T=Object.defineProperty,i=u((e,t)=>T(e,"name",{value:t,configurable:!0}),"e");const A=["vis.config.ts","vis.config.mts","vis.config.cts","vis.config.js","vis.config.mjs","vis.config.cjs"],J={blockExoticSubdeps:!0,minimumReleaseAge:20160,strictDepBuilds:!0,trustPolicy:"no-downgrade",trustPolicyIgnoreAfter:43200},R=i(e=>({...J,...e}),"mergeSecurityDefaults"),l=i(e=>({...e,security:R(e.security),update:{security:!0,target:"minor",...e.update}}),"applyDefaults"),V=i(e=>{for(const t of A){const s=o(e,t);if(y(s))return s}},"findVisConfigFile"),k=i(e=>_("sha256").update(S(e)).digest("hex"),"hashFileContents"),q=i(e=>{const t=o(e,"node_modules");if(y(t)){const n=o(t,".cache","vis");return p(n),o(n,"vis-config-cache.json")}const s=w("vis",{create:!0,cwd:e});return s?o(s,"vis-config-cache.json"):void 0},"getConfigCachePath"),B=i((e,t)=>{if(D(e))try{const s=I(e);if(s.hash===t)return s.config}catch{}},"readConfigCache"),N=i((e,t,s)=>{try{p(E(e)),x(e,{config:s,hash:t})}catch{}},"writeConfigCache"),H=i(async e=>{const t=V(e);if(!t)return l({});const s=k(t),n=q(e);if(n){const g=B(n,s);if(g)return g}const m=t.slice(t.lastIndexOf(".")),a=o(F(),`vis-config-${s}${m}`);j(t,a);let c;try{c=await P(e,{fsCache:!1,moduleCache:!1}).import(a,{default:!0,try:!0})??{}}finally{try{b(a)}catch{}}let f;return f=l(typeof c=="function"?await c()??{}:c),n&&N(n,s,f),f},"loadVisConfig"),Y=i(e=>l(e),"defineConfig");export{A as CONFIG_FILES,J as SECURITY_DEFAULTS,l as applyDefaults,Y as defineConfig,V as findVisConfigFile,H as loadVisConfig};