@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.
- package/CHANGELOG.md +136 -14
- package/LICENSE.md +27 -0
- package/README.md +15 -9
- package/dist/audit-config.d.ts +24 -0
- package/dist/bin.js +777 -70
- package/dist/catalog.d.ts +16 -8
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/approve-builds.d.ts +3 -0
- package/dist/commands/audit.d.ts +23 -0
- package/dist/commands/clean.d.ts +3 -0
- package/dist/commands/create/discovery.d.ts +42 -0
- package/dist/commands/create/index.d.ts +13 -0
- package/dist/commands/create/prompts.d.ts +31 -0
- package/dist/commands/create/random-name.d.ts +15 -0
- package/dist/commands/create/templates/builtin.d.ts +15 -0
- package/dist/commands/create/templates/generator.d.ts +14 -0
- package/dist/commands/create/templates/index.d.ts +13 -0
- package/dist/commands/create/templates/monorepo.d.ts +16 -0
- package/dist/commands/create/templates/remote.d.ts +41 -0
- package/dist/commands/create/templates/types.d.ts +46 -0
- package/dist/commands/create/utils.d.ts +42 -0
- package/dist/commands/dedupe.d.ts +3 -0
- package/dist/commands/devcontainer.d.ts +3 -0
- package/dist/commands/dlx.d.ts +3 -0
- package/dist/commands/doctor.d.ts +15 -0
- package/dist/commands/exec.d.ts +3 -0
- package/dist/commands/implode.d.ts +3 -0
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/install.d.ts +3 -0
- package/dist/commands/link.d.ts +3 -0
- package/dist/commands/optimize.d.ts +38 -0
- package/dist/commands/pm.d.ts +3 -0
- package/dist/commands/remove.d.ts +3 -0
- package/dist/commands/sort-package-json.d.ts +3 -0
- package/dist/commands/unlink.d.ts +3 -0
- package/dist/commands/upgrade.d.ts +3 -0
- package/dist/commands/why.d.ts +3 -0
- package/dist/config.d.ts +38 -11
- package/dist/config.js +1 -1
- package/dist/native-binding.d.ts +151 -0
- package/dist/output.d.ts +40 -0
- package/dist/overrides.d.ts +82 -0
- package/dist/plugins/config-loader.d.ts +3 -0
- package/dist/plugins/post-command.d.ts +3 -0
- package/dist/plugins/security-enforcement.d.ts +3 -0
- package/dist/pm-runner.d.ts +23 -0
- package/dist/security.d.ts +64 -0
- package/dist/socket-security.d.ts +129 -0
- package/dist/tips.d.ts +41 -0
- package/dist/tui/components/CheckProgressApp.d.ts +6 -0
- package/dist/tui/components/CommandSummary.d.ts +17 -0
- package/dist/tui/components/Header.d.ts +13 -0
- package/dist/tui/components/OutputPanel.d.ts +16 -0
- package/dist/tui/components/QuitDialog.d.ts +15 -0
- package/dist/tui/components/TaskListPanel.d.ts +19 -0
- package/dist/tui/components/TaskRow.d.ts +12 -0
- package/dist/tui/components/TaskStore.d.ts +80 -0
- package/dist/tui/components/VisTaskRunnerApp.d.ts +17 -0
- package/dist/tui/components/devcontainer/DevcontainerStore.d.ts +66 -0
- package/dist/tui/components/devcontainer/VisDevcontainerApp.d.ts +9 -0
- package/dist/tui/components/devcontainer/catalogs/extensions.d.ts +8 -0
- package/dist/tui/components/devcontainer/catalogs/features.d.ts +8 -0
- package/dist/tui/components/devcontainer/catalogs/filters.d.ts +4 -0
- package/dist/tui/components/devcontainer/catalogs/mount-suggestions.d.ts +19 -0
- package/dist/tui/components/devcontainer/catalogs/templates.d.ts +8 -0
- package/dist/tui/components/devcontainer/devcontainer-io.d.ts +14 -0
- package/dist/tui/components/devcontainer/sections/DockerComposeSection.d.ts +11 -0
- package/dist/tui/components/devcontainer/sections/EnvironmentSection.d.ts +16 -0
- package/dist/tui/components/devcontainer/sections/ExtensionsSection.d.ts +11 -0
- package/dist/tui/components/devcontainer/sections/FeaturesSection.d.ts +11 -0
- package/dist/tui/components/devcontainer/sections/GeneralSection.d.ts +12 -0
- package/dist/tui/components/devcontainer/sections/LifecycleSection.d.ts +13 -0
- package/dist/tui/components/devcontainer/sections/MountsSection.d.ts +16 -0
- package/dist/tui/components/devcontainer/sections/PortsSection.d.ts +10 -0
- package/dist/tui/components/devcontainer/sections/PreviewPanel.d.ts +11 -0
- package/dist/tui/components/devcontainer/types.d.ts +53 -0
- package/dist/tui/components/devcontainer/validate.d.ts +16 -0
- package/dist/tui/components/graph/GraphStore.d.ts +42 -0
- package/dist/tui/components/graph/ProjectDetailPanel.d.ts +10 -0
- package/dist/tui/components/graph/ProjectListPanel.d.ts +20 -0
- package/dist/tui/components/graph/VisGraphApp.d.ts +8 -0
- package/dist/tui/components/optimize/OptimizeDetailPanel.d.ts +9 -0
- package/dist/tui/components/optimize/OptimizeListPanel.d.ts +16 -0
- package/dist/tui/components/optimize/OptimizeStore.d.ts +50 -0
- package/dist/tui/components/optimize/VisOptimizeApp.d.ts +8 -0
- package/dist/tui/components/optimize/constants.d.ts +7 -0
- package/dist/tui/components/update/PackageDetailPanel.d.ts +12 -0
- package/dist/tui/components/update/PackageListPanel.d.ts +18 -0
- package/dist/tui/components/update/UpdateStore.d.ts +62 -0
- package/dist/tui/components/update/VisUpdateApp.d.ts +11 -0
- package/dist/tui/dynamic-life-cycle.d.ts +21 -0
- package/dist/tui/formatting-utils.d.ts +17 -0
- package/dist/tui/pretty-time.d.ts +8 -0
- package/dist/tui/static-life-cycle.d.ts +22 -0
- package/dist/tui/status-utils.d.ts +20 -0
- package/dist/tui/symbols.d.ts +7 -0
- package/dist/tui/types.d.ts +11 -0
- package/dist/typosquats.d.ts +70 -0
- package/dist/upgrade-check.d.ts +30 -0
- package/dist/utils.d.ts +22 -0
- package/dist/workspace.d.ts +262 -5
- package/index.js +600 -0
- package/package.json +34 -11
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Task, TaskResult } from "@visulima/task-runner";
|
|
2
|
+
import type { TaskRowData } from "./TaskRow.d.ts";
|
|
3
|
+
export interface TaskState {
|
|
4
|
+
/** Auto-exit countdown in seconds. null = not counting. */
|
|
5
|
+
autoExitCountdown: number | null;
|
|
6
|
+
/** Number of tasks completed from cache. */
|
|
7
|
+
cached: number;
|
|
8
|
+
/** Total completed tasks. */
|
|
9
|
+
completed: number;
|
|
10
|
+
/** All tasks finished — triggers summary/countdown. */
|
|
11
|
+
done: boolean;
|
|
12
|
+
/** Timestamp when all tasks completed (Date.now). null while running. */
|
|
13
|
+
endTime: number | null;
|
|
14
|
+
/** Number of failed tasks. */
|
|
15
|
+
failed: number;
|
|
16
|
+
/** Whether the filter input bar is active. */
|
|
17
|
+
filterActive: boolean;
|
|
18
|
+
/** Current filter text (empty = no filter). */
|
|
19
|
+
filterText: string;
|
|
20
|
+
/** Which panel currently has keyboard focus. */
|
|
21
|
+
focusedPanel: "output" | "tasks";
|
|
22
|
+
/** Whether interactive input mode is active for the current task. */
|
|
23
|
+
interactiveMode: boolean;
|
|
24
|
+
/** Accumulated terminal output per task. */
|
|
25
|
+
outputs: Map<string, string>;
|
|
26
|
+
/** Up to 2 pinned task IDs for output panes. */
|
|
27
|
+
pinnedTaskIds: [string | null, string | null];
|
|
28
|
+
/** Whether a rerun has been requested by the user. */
|
|
29
|
+
rerunRequested: boolean;
|
|
30
|
+
/** Task ID requested for single-task retry (null = none). */
|
|
31
|
+
retryTaskId: string | null;
|
|
32
|
+
/** All task rows with current status. */
|
|
33
|
+
rows: TaskRowData[];
|
|
34
|
+
/** Currently highlighted task index in the list. */
|
|
35
|
+
selectedIndex: number;
|
|
36
|
+
/** Command start timestamp (Date.now). */
|
|
37
|
+
startTime: number;
|
|
38
|
+
/** Status filter for task list: "all", "failed", "running", "passed". */
|
|
39
|
+
statusFilter: "all" | "failed" | "passed" | "running";
|
|
40
|
+
/** Number of successfully completed tasks. */
|
|
41
|
+
succeeded: number;
|
|
42
|
+
/** Current view mode: list (full width), split (list + output), fullscreen (output only). */
|
|
43
|
+
viewMode: "fullscreen" | "list" | "split";
|
|
44
|
+
}
|
|
45
|
+
type Listener = () => void;
|
|
46
|
+
export declare class TaskStore {
|
|
47
|
+
#private;
|
|
48
|
+
constructor(tasks: Task[]);
|
|
49
|
+
getSnapshot: () => TaskState;
|
|
50
|
+
subscribe: (listener: Listener) => () => void;
|
|
51
|
+
startTasks(started: Task[]): void;
|
|
52
|
+
endTasks(results: TaskResult[]): void;
|
|
53
|
+
addOutput(taskId: string, output: string): void;
|
|
54
|
+
/** Replace the full output for a task (used by PTY mode where ANSI sequences update in place). */
|
|
55
|
+
setOutput(taskId: string, content: string): void;
|
|
56
|
+
markDone(): void;
|
|
57
|
+
/** Update elapsed times for running tasks. Called every 100ms. */
|
|
58
|
+
tick(): void;
|
|
59
|
+
setSelectedIndex(index: number): void;
|
|
60
|
+
setFocusedPanel(panel: "output" | "tasks"): void;
|
|
61
|
+
setFilter(text: string): void;
|
|
62
|
+
setFilterActive(active: boolean): void;
|
|
63
|
+
pinTask(slot: 0 | 1, taskId: string | null): void;
|
|
64
|
+
clearPins(): void;
|
|
65
|
+
/** Request retry of a single failed task. */
|
|
66
|
+
requestRetry(taskId: string): void;
|
|
67
|
+
/** Acknowledge the retry request (called by lifecycle after re-launching). */
|
|
68
|
+
acknowledgeRetry(): string | null;
|
|
69
|
+
/** Toggle interactive input mode for the current task. */
|
|
70
|
+
setInteractiveMode(active: boolean): void;
|
|
71
|
+
/** Set the current view mode. */
|
|
72
|
+
setViewMode(mode: "fullscreen" | "list" | "split"): void;
|
|
73
|
+
/** Set status filter for the task list. */
|
|
74
|
+
setStatusFilter(filter: "all" | "failed" | "passed" | "running"): void;
|
|
75
|
+
/** Request a rerun — resets all task state back to pending. */
|
|
76
|
+
requestRerun(): void;
|
|
77
|
+
/** Acknowledge the rerun request (called by lifecycle after re-launching tasks). */
|
|
78
|
+
acknowledgeRerun(): void;
|
|
79
|
+
}
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Task } from "@visulima/task-runner";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import type { StdinEntry } from "../types.d.ts";
|
|
4
|
+
import type { TaskStore } from "./TaskStore.d.ts";
|
|
5
|
+
interface VisTaskRunnerAppProps {
|
|
6
|
+
/** 0 = no auto-exit (default), >0 = countdown seconds */
|
|
7
|
+
autoExitSeconds: number;
|
|
8
|
+
parallelSlots: number;
|
|
9
|
+
projectNames: string[];
|
|
10
|
+
/** Registry of stdin entries keyed by task ID, for interactive input. */
|
|
11
|
+
stdinRegistry: Map<string, StdinEntry>;
|
|
12
|
+
store: TaskStore;
|
|
13
|
+
targets: string[];
|
|
14
|
+
tasks: Task[];
|
|
15
|
+
}
|
|
16
|
+
declare const VisTaskRunnerApp: ({ autoExitSeconds, parallelSlots, projectNames, stdinRegistry, store, targets, tasks }: VisTaskRunnerAppProps) => React.JSX.Element;
|
|
17
|
+
export default VisTaskRunnerApp;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { PackageManager } from "./catalogs/mount-suggestions.d.ts";
|
|
2
|
+
import type { DevcontainerConfig, MountEntry, SectionId } from "./types.d.ts";
|
|
3
|
+
export interface DevcontainerState {
|
|
4
|
+
/** The configuration being edited. */
|
|
5
|
+
config: DevcontainerConfig;
|
|
6
|
+
/** Detected package manager from the workspace. */
|
|
7
|
+
detectedPm: PackageManager | null;
|
|
8
|
+
/** Search text for extensions section. */
|
|
9
|
+
extensionSearch: string;
|
|
10
|
+
/** Search text for features section. */
|
|
11
|
+
featureSearch: string;
|
|
12
|
+
/** Whether any field is being actively edited via TextInput. */
|
|
13
|
+
fieldEditing: boolean;
|
|
14
|
+
/** Which field is focused within the current section. */
|
|
15
|
+
fieldIndex: number;
|
|
16
|
+
/** Whether the original file contained JSONC comments (warning on save). */
|
|
17
|
+
hadComments: boolean;
|
|
18
|
+
/** Whether config has been changed since load/save. */
|
|
19
|
+
isDirty: boolean;
|
|
20
|
+
/** Create or edit mode. */
|
|
21
|
+
mode: "create" | "edit";
|
|
22
|
+
/** Original config for diffing (null in create mode). */
|
|
23
|
+
originalConfig: DevcontainerConfig | null;
|
|
24
|
+
/** Currently active tab/section. */
|
|
25
|
+
section: SectionId;
|
|
26
|
+
/** Whether to show the template selector dialog. */
|
|
27
|
+
showTemplateSelector: boolean;
|
|
28
|
+
/** Suggested mounts based on PM and features. */
|
|
29
|
+
suggestedMounts: MountEntry[];
|
|
30
|
+
/** Selected template index in the selector. */
|
|
31
|
+
templateIndex: number;
|
|
32
|
+
}
|
|
33
|
+
type Listener = () => void;
|
|
34
|
+
export declare class DevcontainerStore {
|
|
35
|
+
#private;
|
|
36
|
+
constructor(config: DevcontainerConfig | null, hadComments: boolean, detectedPm?: PackageManager | null);
|
|
37
|
+
getSnapshot: () => DevcontainerState;
|
|
38
|
+
subscribe: (listener: Listener) => () => void;
|
|
39
|
+
setSection(section: SectionId): void;
|
|
40
|
+
nextSection(): void;
|
|
41
|
+
previousSection(): void;
|
|
42
|
+
setFieldIndex(index: number): void;
|
|
43
|
+
setFieldEditing(editing: boolean): void;
|
|
44
|
+
setTemplateIndex(index: number): void;
|
|
45
|
+
applyTemplate(templateId: string): void;
|
|
46
|
+
dismissTemplateSelector(): void;
|
|
47
|
+
updateConfig(partial: Partial<DevcontainerConfig>): void;
|
|
48
|
+
toggleFeature(featureId: string): void;
|
|
49
|
+
setFeatureSearch(search: string): void;
|
|
50
|
+
addPort(port: number | string): void;
|
|
51
|
+
removePort(index: number): void;
|
|
52
|
+
toggleExtension(extensionId: string): void;
|
|
53
|
+
setExtensionSearch(search: string): void;
|
|
54
|
+
addEnvVar(target: "container" | "remote", key: string, value: string): void;
|
|
55
|
+
removeEnvVar(target: "container" | "remote", key: string): void;
|
|
56
|
+
addMount(mount: MountEntry): void;
|
|
57
|
+
removeMount(index: number): void;
|
|
58
|
+
/** Add all currently suggested mounts to the config. */
|
|
59
|
+
applySuggestedMounts(): void;
|
|
60
|
+
setLifecycleCommand(hook: "onCreateCommand" | "postAttachCommand" | "postCreateCommand" | "postStartCommand", command: string): void;
|
|
61
|
+
markClean(): void;
|
|
62
|
+
getJsonPreview(): string;
|
|
63
|
+
/** Return a cleaned config with empty/undefined fields stripped. */
|
|
64
|
+
cleanConfig(): DevcontainerConfig;
|
|
65
|
+
}
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DevcontainerStore } from "./DevcontainerStore.d.ts";
|
|
3
|
+
import type { DevcontainerConfig } from "./types.d.ts";
|
|
4
|
+
interface VisDevcontainerAppProps {
|
|
5
|
+
readonly onSave: (config: DevcontainerConfig) => void;
|
|
6
|
+
readonly store: DevcontainerStore;
|
|
7
|
+
}
|
|
8
|
+
declare const VisDevcontainerApp: ({ onSave, store }: VisDevcontainerAppProps) => React.JSX.Element;
|
|
9
|
+
export default VisDevcontainerApp;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type ExtensionCategory = "debugging" | "formatting" | "git" | "language" | "linting" | "other" | "testing";
|
|
2
|
+
export interface ExtensionCatalogEntry {
|
|
3
|
+
category: ExtensionCategory;
|
|
4
|
+
description: string;
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const EXTENSION_CATALOG: ExtensionCatalogEntry[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type FeatureCategory = "cloud" | "database" | "language" | "other" | "tool";
|
|
2
|
+
export interface FeatureCatalogEntry {
|
|
3
|
+
category: FeatureCategory;
|
|
4
|
+
description: string;
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const FEATURE_CATALOG: FeatureCatalogEntry[];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ExtensionCatalogEntry } from "./extensions.d.ts";
|
|
2
|
+
import type { FeatureCatalogEntry } from "./features.d.ts";
|
|
3
|
+
export declare const filterFeatures: (searchText: string) => FeatureCatalogEntry[];
|
|
4
|
+
export declare const filterExtensions: (searchText: string) => ExtensionCatalogEntry[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { MountEntry } from "../types.d.ts";
|
|
2
|
+
export type PackageManager = "bun" | "npm" | "pnpm" | "yarn";
|
|
3
|
+
/**
|
|
4
|
+
* Suggested mounts based on detected package manager.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PM_MOUNTS: Record<PackageManager, MountEntry[]>;
|
|
7
|
+
/**
|
|
8
|
+
* Feature-specific mount suggestions.
|
|
9
|
+
* Key is a substring of the feature ID to match.
|
|
10
|
+
*/
|
|
11
|
+
export declare const FEATURE_MOUNTS: {
|
|
12
|
+
featureMatch: string;
|
|
13
|
+
mounts: MountEntry[];
|
|
14
|
+
}[];
|
|
15
|
+
/**
|
|
16
|
+
* Get suggested mounts based on the package manager and enabled features.
|
|
17
|
+
* Returns only mounts that are not already in the current config.
|
|
18
|
+
*/
|
|
19
|
+
export declare const getSuggestedMounts: (pm: PackageManager | null, enabledFeatures: Record<string, Record<string, unknown> | string>, currentMounts: Array<MountEntry | string>) => MountEntry[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DevcontainerConfig } from "./types.d.ts";
|
|
2
|
+
export interface ReadResult {
|
|
3
|
+
config: DevcontainerConfig;
|
|
4
|
+
hadComments: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Read and parse .devcontainer/devcontainer.json with JSONC support.
|
|
8
|
+
* Returns null if the file doesn't exist.
|
|
9
|
+
*/
|
|
10
|
+
export declare const readDevcontainerJson: (workspaceRoot: string) => ReadResult | null;
|
|
11
|
+
/**
|
|
12
|
+
* Write devcontainer.json to disk, creating the directory if needed.
|
|
13
|
+
*/
|
|
14
|
+
export declare const writeDevcontainerJson: (workspaceRoot: string, config: DevcontainerConfig, outputPath?: string) => void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DevcontainerConfig } from "../types.d.ts";
|
|
3
|
+
interface DockerComposeSectionProps {
|
|
4
|
+
readonly config: DevcontainerConfig;
|
|
5
|
+
readonly fieldEditing: boolean;
|
|
6
|
+
readonly fieldIndex: number;
|
|
7
|
+
readonly onUpdate: (partial: Partial<DevcontainerConfig>) => void;
|
|
8
|
+
}
|
|
9
|
+
declare const DockerComposeSection: ({ config, fieldEditing, fieldIndex, onUpdate }: DockerComposeSectionProps) => React.JSX.Element;
|
|
10
|
+
export declare const COMPOSE_FIELD_COUNT: number;
|
|
11
|
+
export default DockerComposeSection;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DevcontainerConfig } from "../types.d.ts";
|
|
3
|
+
interface EnvironmentSectionProps {
|
|
4
|
+
readonly config: DevcontainerConfig;
|
|
5
|
+
readonly fieldIndex: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Layout:
|
|
9
|
+
* fieldIndex 0..containerCount-1 → containerEnv entries
|
|
10
|
+
* fieldIndex containerCount → "+ Add container env..." row
|
|
11
|
+
* fieldIndex containerCount+1.. → remoteEnv entries
|
|
12
|
+
* fieldIndex last → "+ Add remote env..." row
|
|
13
|
+
*/
|
|
14
|
+
declare const EnvironmentSection: ({ config, fieldIndex }: EnvironmentSectionProps) => React.JSX.Element;
|
|
15
|
+
export declare const getEnvFieldCount: (config: DevcontainerConfig) => number;
|
|
16
|
+
export default EnvironmentSection;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DevcontainerConfig } from "../types.d.ts";
|
|
3
|
+
interface ExtensionsSectionProps {
|
|
4
|
+
readonly config: DevcontainerConfig;
|
|
5
|
+
readonly fieldIndex: number;
|
|
6
|
+
readonly scrollOffset: number;
|
|
7
|
+
readonly searchText: string;
|
|
8
|
+
readonly viewportHeight: number;
|
|
9
|
+
}
|
|
10
|
+
declare const ExtensionsSection: ({ config, fieldIndex, scrollOffset, searchText, viewportHeight }: ExtensionsSectionProps) => React.JSX.Element;
|
|
11
|
+
export default ExtensionsSection;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DevcontainerConfig } from "../types.d.ts";
|
|
3
|
+
interface FeaturesSectionProps {
|
|
4
|
+
readonly config: DevcontainerConfig;
|
|
5
|
+
readonly fieldIndex: number;
|
|
6
|
+
readonly scrollOffset: number;
|
|
7
|
+
readonly searchText: string;
|
|
8
|
+
readonly viewportHeight: number;
|
|
9
|
+
}
|
|
10
|
+
declare const FeaturesSection: ({ config, fieldIndex, scrollOffset, searchText, viewportHeight }: FeaturesSectionProps) => React.JSX.Element;
|
|
11
|
+
export default FeaturesSection;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DevcontainerConfig } from "../types.d.ts";
|
|
3
|
+
interface GeneralSectionProps {
|
|
4
|
+
readonly config: DevcontainerConfig;
|
|
5
|
+
readonly fieldEditing: boolean;
|
|
6
|
+
readonly fieldIndex: number;
|
|
7
|
+
readonly onUpdate: (partial: Partial<DevcontainerConfig>) => void;
|
|
8
|
+
}
|
|
9
|
+
declare const GeneralSection: ({ config, fieldEditing, fieldIndex, onUpdate }: GeneralSectionProps) => React.JSX.Element;
|
|
10
|
+
export declare const GENERAL_FIELD_COUNT: number;
|
|
11
|
+
export declare const GENERAL_BOOLEAN_FIELDS: readonly ("privileged" | "overrideCommand")[];
|
|
12
|
+
export default GeneralSection;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DevcontainerConfig } from "../types.d.ts";
|
|
3
|
+
declare const HOOKS: readonly ["postCreateCommand", "postStartCommand", "postAttachCommand", "onCreateCommand"];
|
|
4
|
+
type LifecycleHook = (typeof HOOKS)[number];
|
|
5
|
+
interface LifecycleSectionProps {
|
|
6
|
+
readonly config: DevcontainerConfig;
|
|
7
|
+
readonly fieldEditing: boolean;
|
|
8
|
+
readonly fieldIndex: number;
|
|
9
|
+
readonly onSetCommand: (hook: LifecycleHook, command: string) => void;
|
|
10
|
+
}
|
|
11
|
+
declare const LifecycleSection: ({ config, fieldEditing, fieldIndex, onSetCommand }: LifecycleSectionProps) => React.JSX.Element;
|
|
12
|
+
export declare const LIFECYCLE_FIELD_COUNT: number;
|
|
13
|
+
export default LifecycleSection;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { PackageManager } from "../catalogs/mount-suggestions.d.ts";
|
|
3
|
+
import type { DevcontainerConfig, MountEntry } from "../types.d.ts";
|
|
4
|
+
interface MountsSectionProps {
|
|
5
|
+
readonly addingMount: boolean;
|
|
6
|
+
readonly config: DevcontainerConfig;
|
|
7
|
+
readonly detectedPm: PackageManager | null;
|
|
8
|
+
readonly fieldIndex: number;
|
|
9
|
+
readonly mountPhase: "source" | "target" | "type";
|
|
10
|
+
readonly mountSource: string;
|
|
11
|
+
readonly mountTarget: string;
|
|
12
|
+
readonly mountType: "bind" | "tmpfs" | "volume";
|
|
13
|
+
readonly suggestedMounts: MountEntry[];
|
|
14
|
+
}
|
|
15
|
+
declare const MountsSection: ({ addingMount, config, detectedPm, fieldIndex, mountPhase, mountSource, mountTarget, mountType, suggestedMounts, }: MountsSectionProps) => React.JSX.Element;
|
|
16
|
+
export default MountsSection;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DevcontainerConfig } from "../types.d.ts";
|
|
3
|
+
interface PortsSectionProps {
|
|
4
|
+
readonly addingPort: boolean;
|
|
5
|
+
readonly addPortValue: string;
|
|
6
|
+
readonly config: DevcontainerConfig;
|
|
7
|
+
readonly fieldIndex: number;
|
|
8
|
+
}
|
|
9
|
+
declare const PortsSection: ({ addingPort, addPortValue, config, fieldIndex }: PortsSectionProps) => React.JSX.Element;
|
|
10
|
+
export default PortsSection;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ScrollViewRef } from "@visulima/tui";
|
|
2
|
+
import React from "react";
|
|
3
|
+
interface PreviewPanelProps {
|
|
4
|
+
readonly focused: boolean;
|
|
5
|
+
readonly hadComments: boolean;
|
|
6
|
+
readonly jsonPreview: string;
|
|
7
|
+
readonly mode: "create" | "edit";
|
|
8
|
+
readonly scrollRef: React.RefObject<ScrollViewRef>;
|
|
9
|
+
}
|
|
10
|
+
declare const PreviewPanel: ({ focused, hadComments, jsonPreview, mode, scrollRef }: PreviewPanelProps) => React.JSX.Element;
|
|
11
|
+
export default PreviewPanel;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface DevcontainerBuild {
|
|
2
|
+
args?: Record<string, string>;
|
|
3
|
+
context?: string;
|
|
4
|
+
dockerfile?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PortAttributes {
|
|
7
|
+
label?: string;
|
|
8
|
+
onAutoForward?: "ignore" | "notify" | "openBrowser" | "openPreview" | "silent";
|
|
9
|
+
protocol?: "http" | "https";
|
|
10
|
+
}
|
|
11
|
+
export interface MountEntry {
|
|
12
|
+
source: string;
|
|
13
|
+
target: string;
|
|
14
|
+
type: "bind" | "tmpfs" | "volume";
|
|
15
|
+
}
|
|
16
|
+
export interface DevcontainerConfig {
|
|
17
|
+
build?: DevcontainerBuild;
|
|
18
|
+
capAdd?: string[];
|
|
19
|
+
containerEnv?: Record<string, string>;
|
|
20
|
+
containerUser?: string;
|
|
21
|
+
customizations?: {
|
|
22
|
+
jetbrains?: {
|
|
23
|
+
plugins?: string[];
|
|
24
|
+
};
|
|
25
|
+
vscode?: {
|
|
26
|
+
extensions?: string[];
|
|
27
|
+
settings?: Record<string, unknown>;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
dockerComposeFile?: string | string[];
|
|
31
|
+
features?: Record<string, Record<string, unknown> | string>;
|
|
32
|
+
forwardPorts?: Array<number | string>;
|
|
33
|
+
image?: string;
|
|
34
|
+
mounts?: Array<MountEntry | string>;
|
|
35
|
+
name?: string;
|
|
36
|
+
onCreateCommand?: string | string[];
|
|
37
|
+
overrideCommand?: boolean;
|
|
38
|
+
postAttachCommand?: string | string[];
|
|
39
|
+
postCreateCommand?: string | string[];
|
|
40
|
+
postStartCommand?: string | string[];
|
|
41
|
+
portsAttributes?: Record<string, PortAttributes>;
|
|
42
|
+
privileged?: boolean;
|
|
43
|
+
remoteEnv?: Record<string, string>;
|
|
44
|
+
remoteUser?: string;
|
|
45
|
+
runServices?: string[];
|
|
46
|
+
securityOpt?: string[];
|
|
47
|
+
service?: string;
|
|
48
|
+
shutdownAction?: string;
|
|
49
|
+
workspaceFolder?: string;
|
|
50
|
+
workspaceMount?: string;
|
|
51
|
+
}
|
|
52
|
+
export type SectionId = "compose" | "environment" | "extensions" | "features" | "general" | "lifecycle" | "mounts" | "ports";
|
|
53
|
+
export declare const SECTION_ORDER: readonly SectionId[];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DevcontainerConfig } from "./types.d.ts";
|
|
2
|
+
export interface ValidationIssue {
|
|
3
|
+
field: string;
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ValidationResult {
|
|
7
|
+
errors: ValidationIssue[];
|
|
8
|
+
suggestions: ValidationIssue[];
|
|
9
|
+
valid: boolean;
|
|
10
|
+
warnings: ValidationIssue[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Validate a devcontainer.json configuration.
|
|
14
|
+
* Returns errors (invalid config), warnings (deprecated/suspicious), and suggestions.
|
|
15
|
+
*/
|
|
16
|
+
export declare const validateConfig: (config: DevcontainerConfig) => ValidationResult;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProjectGraph, ProjectGraphDependency } from "@visulima/task-runner";
|
|
2
|
+
export type GraphFilterType = "all" | "app" | "lib";
|
|
3
|
+
export interface GraphNode {
|
|
4
|
+
deps: ProjectGraphDependency[];
|
|
5
|
+
name: string;
|
|
6
|
+
reverseDeps: string[];
|
|
7
|
+
type: string;
|
|
8
|
+
}
|
|
9
|
+
export interface GraphState {
|
|
10
|
+
/** All nodes. */
|
|
11
|
+
allNodes: GraphNode[];
|
|
12
|
+
/** Whether the text filter input is active. */
|
|
13
|
+
filterActive: boolean;
|
|
14
|
+
/** Current filter text. */
|
|
15
|
+
filterText: string;
|
|
16
|
+
/** Filter by project type. */
|
|
17
|
+
filterType: GraphFilterType;
|
|
18
|
+
/** Which panel has keyboard focus. */
|
|
19
|
+
focusedPanel: "detail" | "list";
|
|
20
|
+
/** Currently highlighted entry index in the filtered list. */
|
|
21
|
+
selectedIndex: number;
|
|
22
|
+
}
|
|
23
|
+
type Listener = () => void;
|
|
24
|
+
export declare class GraphStore {
|
|
25
|
+
#private;
|
|
26
|
+
constructor(projectGraph: ProjectGraph);
|
|
27
|
+
getSnapshot: () => GraphState;
|
|
28
|
+
subscribe: (listener: Listener) => () => void;
|
|
29
|
+
getFilteredNodes(): GraphNode[];
|
|
30
|
+
getStats(): {
|
|
31
|
+
apps: number;
|
|
32
|
+
deps: number;
|
|
33
|
+
libs: number;
|
|
34
|
+
total: number;
|
|
35
|
+
};
|
|
36
|
+
setSelectedIndex(index: number): void;
|
|
37
|
+
setFocusedPanel(panel: "detail" | "list"): void;
|
|
38
|
+
setFilterType(type: GraphFilterType): void;
|
|
39
|
+
setFilter(text: string): void;
|
|
40
|
+
setFilterActive(active: boolean): void;
|
|
41
|
+
}
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ScrollViewRef } from "@visulima/tui";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import type { GraphNode } from "./GraphStore.d.ts";
|
|
4
|
+
interface ProjectDetailPanelProps {
|
|
5
|
+
focused: boolean;
|
|
6
|
+
node: GraphNode | null;
|
|
7
|
+
scrollRef?: React.RefObject<ScrollViewRef>;
|
|
8
|
+
}
|
|
9
|
+
declare const ProjectDetailPanel: ({ focused, node, scrollRef }: ProjectDetailPanelProps) => React.JSX.Element;
|
|
10
|
+
export default ProjectDetailPanel;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { GraphFilterType, GraphNode } from "./GraphStore.d.ts";
|
|
3
|
+
interface ProjectListPanelProps {
|
|
4
|
+
filterActive: boolean;
|
|
5
|
+
filterText: string;
|
|
6
|
+
filterType: GraphFilterType;
|
|
7
|
+
focused: boolean;
|
|
8
|
+
nodes: GraphNode[];
|
|
9
|
+
scrollOffset: number;
|
|
10
|
+
selectedIndex: number;
|
|
11
|
+
stats: {
|
|
12
|
+
apps: number;
|
|
13
|
+
deps: number;
|
|
14
|
+
libs: number;
|
|
15
|
+
total: number;
|
|
16
|
+
};
|
|
17
|
+
viewportHeight: number;
|
|
18
|
+
}
|
|
19
|
+
declare const ProjectListPanel: ({ filterActive, filterText, filterType, focused, nodes, scrollOffset, selectedIndex, stats, viewportHeight, }: ProjectListPanelProps) => React.JSX.Element;
|
|
20
|
+
export default ProjectListPanel;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { GraphStore } from "./GraphStore.d.ts";
|
|
3
|
+
interface VisGraphAppProps {
|
|
4
|
+
autoExitSeconds?: number;
|
|
5
|
+
store: GraphStore;
|
|
6
|
+
}
|
|
7
|
+
declare const VisGraphApp: ({ autoExitSeconds, store }: VisGraphAppProps) => React.JSX.Element;
|
|
8
|
+
export default VisGraphApp;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ScrollViewRef } from "@visulima/tui";
|
|
2
|
+
import type { OptimizeEntry } from "./OptimizeStore.d.ts";
|
|
3
|
+
interface OptimizeDetailPanelProps {
|
|
4
|
+
entry: OptimizeEntry | null;
|
|
5
|
+
focused: boolean;
|
|
6
|
+
scrollRef?: React.RefObject<ScrollViewRef>;
|
|
7
|
+
}
|
|
8
|
+
declare const OptimizeDetailPanel: ({ entry, focused, scrollRef }: OptimizeDetailPanelProps) => React.JSX.Element;
|
|
9
|
+
export default OptimizeDetailPanel;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FilterType, OptimizeEntry } from "./OptimizeStore.d.ts";
|
|
2
|
+
interface OptimizeListPanelProps {
|
|
3
|
+
checkedEntries: Set<string>;
|
|
4
|
+
entries: OptimizeEntry[];
|
|
5
|
+
filterActive: boolean;
|
|
6
|
+
filterText: string;
|
|
7
|
+
filterType: FilterType;
|
|
8
|
+
focused: boolean;
|
|
9
|
+
isDryRun: boolean;
|
|
10
|
+
scrollOffset: number;
|
|
11
|
+
selectedIndex: number;
|
|
12
|
+
totalEntries: number;
|
|
13
|
+
viewportHeight: number;
|
|
14
|
+
}
|
|
15
|
+
declare const OptimizeListPanel: ({ checkedEntries, entries, filterActive, filterText, filterType, focused, isDryRun, scrollOffset, selectedIndex, totalEntries, viewportHeight, }: OptimizeListPanelProps) => React.JSX.Element;
|
|
16
|
+
export default OptimizeListPanel;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** An optimization entry that can be either an e18e module replacement or a Socket.dev override. */
|
|
2
|
+
interface OptimizeEntry {
|
|
3
|
+
/** Category for filtering and display. */
|
|
4
|
+
category: "micro-utility" | "native" | "preferred" | "socket";
|
|
5
|
+
/** Whether a codemod is available for this entry (e18e only). */
|
|
6
|
+
hasCodemod: boolean;
|
|
7
|
+
/** The override spec for socket entries (e.g., "npm:@socketregistry/is-regex@^1"). */
|
|
8
|
+
overrideSpec?: string;
|
|
9
|
+
/** The original package name. */
|
|
10
|
+
packageName: string;
|
|
11
|
+
/** Human-readable replacement target description. */
|
|
12
|
+
replacement: string;
|
|
13
|
+
}
|
|
14
|
+
type FilterType = "all" | "micro-utility" | "native" | "preferred" | "socket";
|
|
15
|
+
interface OptimizeState {
|
|
16
|
+
applyProgress: {
|
|
17
|
+
current: number;
|
|
18
|
+
total: number;
|
|
19
|
+
} | null;
|
|
20
|
+
checkedEntries: Set<string>;
|
|
21
|
+
entries: OptimizeEntry[];
|
|
22
|
+
error: string | null;
|
|
23
|
+
filterActive: boolean;
|
|
24
|
+
filterText: string;
|
|
25
|
+
filterType: FilterType;
|
|
26
|
+
focusedPanel: "detail" | "list";
|
|
27
|
+
phase: "applying" | "browsing" | "done" | "error";
|
|
28
|
+
selectedIndex: number;
|
|
29
|
+
}
|
|
30
|
+
type Listener = () => void;
|
|
31
|
+
declare class OptimizeStore {
|
|
32
|
+
#private;
|
|
33
|
+
constructor(entries: OptimizeEntry[]);
|
|
34
|
+
getSnapshot: () => OptimizeState;
|
|
35
|
+
subscribe: (listener: Listener) => () => void;
|
|
36
|
+
getFilteredEntries: () => OptimizeEntry[];
|
|
37
|
+
select(index: number): void;
|
|
38
|
+
toggleCheck(packageName: string): void;
|
|
39
|
+
toggleAll(): void;
|
|
40
|
+
setFilter(type: FilterType): void;
|
|
41
|
+
setFilterText(text: string): void;
|
|
42
|
+
setFilterActive(active: boolean): void;
|
|
43
|
+
setFocusedPanel(panel: "detail" | "list"): void;
|
|
44
|
+
setPhase(phase: OptimizeState["phase"]): void;
|
|
45
|
+
setProgress(current: number, total: number): void;
|
|
46
|
+
setError(error: string): void;
|
|
47
|
+
getCheckedEntries(): OptimizeEntry[];
|
|
48
|
+
}
|
|
49
|
+
export type { FilterType, OptimizeEntry, OptimizeState };
|
|
50
|
+
export { OptimizeStore };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { OptimizeStore } from "./OptimizeStore.d.ts";
|
|
3
|
+
interface VisOptimizeAppProps {
|
|
4
|
+
isDryRun: boolean;
|
|
5
|
+
store: OptimizeStore;
|
|
6
|
+
}
|
|
7
|
+
declare const VisOptimizeApp: ({ isDryRun, store }: VisOptimizeAppProps) => React.JSX.Element;
|
|
8
|
+
export default VisOptimizeApp;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Category colors for the optimize TUI — shared between list and detail panels. */
|
|
2
|
+
declare const CATEGORY_COLORS: Record<string, string>;
|
|
3
|
+
/** Short labels for category badges in the list panel. */
|
|
4
|
+
declare const CATEGORY_LABELS: Record<string, string>;
|
|
5
|
+
/** Human-readable descriptions for each optimization category. */
|
|
6
|
+
declare const CATEGORY_DESCRIPTIONS: Record<string, string>;
|
|
7
|
+
export { CATEGORY_COLORS, CATEGORY_DESCRIPTIONS, CATEGORY_LABELS };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ScrollViewRef } from "@visulima/tui";
|
|
2
|
+
import type { AiRecommendation } from "../../../ai-analysis.d.ts";
|
|
3
|
+
import type { OutdatedEntry } from "../../../catalog.d.ts";
|
|
4
|
+
interface PackageDetailPanelProps {
|
|
5
|
+
changelogUrl?: string;
|
|
6
|
+
entry: OutdatedEntry | null;
|
|
7
|
+
focused: boolean;
|
|
8
|
+
recommendation?: AiRecommendation;
|
|
9
|
+
scrollRef?: React.RefObject<ScrollViewRef>;
|
|
10
|
+
}
|
|
11
|
+
declare const PackageDetailPanel: ({ changelogUrl, entry, focused, recommendation, scrollRef }: PackageDetailPanelProps) => React.JSX.Element;
|
|
12
|
+
export default PackageDetailPanel;
|