@doriandev/devcc 0.1.2
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/LICENSE +15 -0
- package/README.md +659 -0
- package/bin/devcc.mjs +66 -0
- package/dist/devcc/app/App.d.ts +178 -0
- package/dist/devcc/app/App.d.ts.map +1 -0
- package/dist/devcc/app/App.js +1255 -0
- package/dist/devcc/app/App.js.map +1 -0
- package/dist/devcc/app/builtinCommands.d.ts +17 -0
- package/dist/devcc/app/builtinCommands.d.ts.map +1 -0
- package/dist/devcc/app/builtinCommands.js +389 -0
- package/dist/devcc/app/builtinCommands.js.map +1 -0
- package/dist/devcc/app/keymap.d.ts +21 -0
- package/dist/devcc/app/keymap.d.ts.map +1 -0
- package/dist/devcc/app/keymap.js +162 -0
- package/dist/devcc/app/keymap.js.map +1 -0
- package/dist/devcc/app/theme.d.ts +49 -0
- package/dist/devcc/app/theme.d.ts.map +1 -0
- package/dist/devcc/app/theme.js +68 -0
- package/dist/devcc/app/theme.js.map +1 -0
- package/dist/devcc/cli.d.ts +3 -0
- package/dist/devcc/cli.d.ts.map +1 -0
- package/dist/devcc/cli.js +113 -0
- package/dist/devcc/cli.js.map +1 -0
- package/dist/devcc/components/CommandPalette.d.ts +26 -0
- package/dist/devcc/components/CommandPalette.d.ts.map +1 -0
- package/dist/devcc/components/CommandPalette.js +113 -0
- package/dist/devcc/components/CommandPalette.js.map +1 -0
- package/dist/devcc/components/ConfirmDialog.d.ts +31 -0
- package/dist/devcc/components/ConfirmDialog.d.ts.map +1 -0
- package/dist/devcc/components/ConfirmDialog.js +147 -0
- package/dist/devcc/components/ConfirmDialog.js.map +1 -0
- package/dist/devcc/components/Footer.d.ts +22 -0
- package/dist/devcc/components/Footer.d.ts.map +1 -0
- package/dist/devcc/components/Footer.js +72 -0
- package/dist/devcc/components/Footer.js.map +1 -0
- package/dist/devcc/components/Header.d.ts +12 -0
- package/dist/devcc/components/Header.d.ts.map +1 -0
- package/dist/devcc/components/Header.js +84 -0
- package/dist/devcc/components/Header.js.map +1 -0
- package/dist/devcc/components/HelpOverlay.d.ts +18 -0
- package/dist/devcc/components/HelpOverlay.d.ts.map +1 -0
- package/dist/devcc/components/HelpOverlay.js +48 -0
- package/dist/devcc/components/HelpOverlay.js.map +1 -0
- package/dist/devcc/components/Overlay.d.ts +31 -0
- package/dist/devcc/components/Overlay.d.ts.map +1 -0
- package/dist/devcc/components/Overlay.js +60 -0
- package/dist/devcc/components/Overlay.js.map +1 -0
- package/dist/devcc/components/ProjectPicker.d.ts +26 -0
- package/dist/devcc/components/ProjectPicker.d.ts.map +1 -0
- package/dist/devcc/components/ProjectPicker.js +114 -0
- package/dist/devcc/components/ProjectPicker.js.map +1 -0
- package/dist/devcc/components/Sidebar.d.ts +42 -0
- package/dist/devcc/components/Sidebar.d.ts.map +1 -0
- package/dist/devcc/components/Sidebar.js +127 -0
- package/dist/devcc/components/Sidebar.js.map +1 -0
- package/dist/devcc/components/StatusBadge.d.ts +16 -0
- package/dist/devcc/components/StatusBadge.d.ts.map +1 -0
- package/dist/devcc/components/StatusBadge.js +30 -0
- package/dist/devcc/components/StatusBadge.js.map +1 -0
- package/dist/devcc/components/primitives.d.ts +62 -0
- package/dist/devcc/components/primitives.d.ts.map +1 -0
- package/dist/devcc/components/primitives.js +169 -0
- package/dist/devcc/components/primitives.js.map +1 -0
- package/dist/devcc/components/styled.d.ts +16 -0
- package/dist/devcc/components/styled.d.ts.map +1 -0
- package/dist/devcc/components/styled.js +35 -0
- package/dist/devcc/components/styled.js.map +1 -0
- package/dist/devcc/core/commands.d.ts +89 -0
- package/dist/devcc/core/commands.d.ts.map +1 -0
- package/dist/devcc/core/commands.js +68 -0
- package/dist/devcc/core/commands.js.map +1 -0
- package/dist/devcc/core/config.d.ts +81 -0
- package/dist/devcc/core/config.d.ts.map +1 -0
- package/dist/devcc/core/config.js +313 -0
- package/dist/devcc/core/config.js.map +1 -0
- package/dist/devcc/core/events.d.ts +21 -0
- package/dist/devcc/core/events.d.ts.map +1 -0
- package/dist/devcc/core/events.js +27 -0
- package/dist/devcc/core/events.js.map +1 -0
- package/dist/devcc/core/state.d.ts +104 -0
- package/dist/devcc/core/state.d.ts.map +1 -0
- package/dist/devcc/core/state.js +139 -0
- package/dist/devcc/core/state.js.map +1 -0
- package/dist/devcc/deps/DependencyService.d.ts +50 -0
- package/dist/devcc/deps/DependencyService.d.ts.map +1 -0
- package/dist/devcc/deps/DependencyService.js +109 -0
- package/dist/devcc/deps/DependencyService.js.map +1 -0
- package/dist/devcc/deps/parse.d.ts +49 -0
- package/dist/devcc/deps/parse.d.ts.map +1 -0
- package/dist/devcc/deps/parse.js +158 -0
- package/dist/devcc/deps/parse.js.map +1 -0
- package/dist/devcc/git/GitService.d.ts +60 -0
- package/dist/devcc/git/GitService.d.ts.map +1 -0
- package/dist/devcc/git/GitService.js +160 -0
- package/dist/devcc/git/GitService.js.map +1 -0
- package/dist/devcc/git/parse.d.ts +57 -0
- package/dist/devcc/git/parse.d.ts.map +1 -0
- package/dist/devcc/git/parse.js +174 -0
- package/dist/devcc/git/parse.js.map +1 -0
- package/dist/devcc/index.d.ts +37 -0
- package/dist/devcc/index.d.ts.map +1 -0
- package/dist/devcc/index.js +36 -0
- package/dist/devcc/index.js.map +1 -0
- package/dist/devcc/logs/LogBuffer.d.ts +86 -0
- package/dist/devcc/logs/LogBuffer.d.ts.map +1 -0
- package/dist/devcc/logs/LogBuffer.js +200 -0
- package/dist/devcc/logs/LogBuffer.js.map +1 -0
- package/dist/devcc/logs/merge.d.ts +36 -0
- package/dist/devcc/logs/merge.d.ts.map +1 -0
- package/dist/devcc/logs/merge.js +71 -0
- package/dist/devcc/logs/merge.js.map +1 -0
- package/dist/devcc/processes/ManagedProcess.d.ts +129 -0
- package/dist/devcc/processes/ManagedProcess.d.ts.map +1 -0
- package/dist/devcc/processes/ManagedProcess.js +80 -0
- package/dist/devcc/processes/ManagedProcess.js.map +1 -0
- package/dist/devcc/processes/ProcessManager.d.ts +112 -0
- package/dist/devcc/processes/ProcessManager.d.ts.map +1 -0
- package/dist/devcc/processes/ProcessManager.js +525 -0
- package/dist/devcc/processes/ProcessManager.js.map +1 -0
- package/dist/devcc/processes/graph.d.ts +35 -0
- package/dist/devcc/processes/graph.d.ts.map +1 -0
- package/dist/devcc/processes/graph.js +68 -0
- package/dist/devcc/processes/graph.js.map +1 -0
- package/dist/devcc/projects/ProjectRegistry.d.ts +52 -0
- package/dist/devcc/projects/ProjectRegistry.d.ts.map +1 -0
- package/dist/devcc/projects/ProjectRegistry.js +177 -0
- package/dist/devcc/projects/ProjectRegistry.js.map +1 -0
- package/dist/devcc/services/ServiceManager.d.ts +48 -0
- package/dist/devcc/services/ServiceManager.d.ts.map +1 -0
- package/dist/devcc/services/ServiceManager.js +146 -0
- package/dist/devcc/services/ServiceManager.js.map +1 -0
- package/dist/devcc/services/docker.d.ts +37 -0
- package/dist/devcc/services/docker.d.ts.map +1 -0
- package/dist/devcc/services/docker.js +179 -0
- package/dist/devcc/services/docker.js.map +1 -0
- package/dist/devcc/services/node.d.ts +40 -0
- package/dist/devcc/services/node.d.ts.map +1 -0
- package/dist/devcc/services/node.js +107 -0
- package/dist/devcc/services/node.js.map +1 -0
- package/dist/devcc/services/ollama.d.ts +27 -0
- package/dist/devcc/services/ollama.d.ts.map +1 -0
- package/dist/devcc/services/ollama.js +66 -0
- package/dist/devcc/services/ollama.js.map +1 -0
- package/dist/devcc/services/postgres.d.ts +30 -0
- package/dist/devcc/services/postgres.d.ts.map +1 -0
- package/dist/devcc/services/postgres.js +47 -0
- package/dist/devcc/services/postgres.js.map +1 -0
- package/dist/devcc/services/redis.d.ts +20 -0
- package/dist/devcc/services/redis.d.ts.map +1 -0
- package/dist/devcc/services/redis.js +39 -0
- package/dist/devcc/services/redis.js.map +1 -0
- package/dist/devcc/services/types.d.ts +51 -0
- package/dist/devcc/services/types.d.ts.map +1 -0
- package/dist/devcc/services/types.js +10 -0
- package/dist/devcc/services/types.js.map +1 -0
- package/dist/devcc/system/SystemMonitor.d.ts +87 -0
- package/dist/devcc/system/SystemMonitor.d.ts.map +1 -0
- package/dist/devcc/system/SystemMonitor.js +142 -0
- package/dist/devcc/system/SystemMonitor.js.map +1 -0
- package/dist/devcc/utils/errors.d.ts +31 -0
- package/dist/devcc/utils/errors.d.ts.map +1 -0
- package/dist/devcc/utils/errors.js +52 -0
- package/dist/devcc/utils/errors.js.map +1 -0
- package/dist/devcc/utils/exec.d.ts +41 -0
- package/dist/devcc/utils/exec.d.ts.map +1 -0
- package/dist/devcc/utils/exec.js +112 -0
- package/dist/devcc/utils/exec.js.map +1 -0
- package/dist/devcc/utils/format.d.ts +18 -0
- package/dist/devcc/utils/format.d.ts.map +1 -0
- package/dist/devcc/utils/format.js +85 -0
- package/dist/devcc/utils/format.js.map +1 -0
- package/dist/devcc/utils/fuzzy.d.ts +12 -0
- package/dist/devcc/utils/fuzzy.d.ts.map +1 -0
- package/dist/devcc/utils/fuzzy.js +20 -0
- package/dist/devcc/utils/fuzzy.js.map +1 -0
- package/dist/devcc/utils/logger.d.ts +41 -0
- package/dist/devcc/utils/logger.d.ts.map +1 -0
- package/dist/devcc/utils/logger.js +117 -0
- package/dist/devcc/utils/logger.js.map +1 -0
- package/dist/devcc/utils/packageManager.d.ts +39 -0
- package/dist/devcc/utils/packageManager.d.ts.map +1 -0
- package/dist/devcc/utils/packageManager.js +85 -0
- package/dist/devcc/utils/packageManager.js.map +1 -0
- package/dist/devcc/utils/paths.d.ts +12 -0
- package/dist/devcc/utils/paths.d.ts.map +1 -0
- package/dist/devcc/utils/paths.js +39 -0
- package/dist/devcc/utils/paths.js.map +1 -0
- package/dist/devcc/views/DependenciesView.d.ts +34 -0
- package/dist/devcc/views/DependenciesView.d.ts.map +1 -0
- package/dist/devcc/views/DependenciesView.js +170 -0
- package/dist/devcc/views/DependenciesView.js.map +1 -0
- package/dist/devcc/views/GitView.d.ts +29 -0
- package/dist/devcc/views/GitView.d.ts.map +1 -0
- package/dist/devcc/views/GitView.js +226 -0
- package/dist/devcc/views/GitView.js.map +1 -0
- package/dist/devcc/views/LogsView.d.ts +39 -0
- package/dist/devcc/views/LogsView.d.ts.map +1 -0
- package/dist/devcc/views/LogsView.js +249 -0
- package/dist/devcc/views/LogsView.js.map +1 -0
- package/dist/devcc/views/OverviewView.d.ts +16 -0
- package/dist/devcc/views/OverviewView.d.ts.map +1 -0
- package/dist/devcc/views/OverviewView.js +135 -0
- package/dist/devcc/views/OverviewView.js.map +1 -0
- package/dist/devcc/views/ProcessesView.d.ts +26 -0
- package/dist/devcc/views/ProcessesView.d.ts.map +1 -0
- package/dist/devcc/views/ProcessesView.js +161 -0
- package/dist/devcc/views/ProcessesView.js.map +1 -0
- package/dist/devcc/views/ScriptsView.d.ts +30 -0
- package/dist/devcc/views/ScriptsView.d.ts.map +1 -0
- package/dist/devcc/views/ScriptsView.js +168 -0
- package/dist/devcc/views/ScriptsView.js.map +1 -0
- package/dist/devcc/views/ServicesView.d.ts +28 -0
- package/dist/devcc/views/ServicesView.d.ts.map +1 -0
- package/dist/devcc/views/ServicesView.js +153 -0
- package/dist/devcc/views/ServicesView.js.map +1 -0
- package/dist/devcc/views/SettingsView.d.ts +20 -0
- package/dist/devcc/views/SettingsView.d.ts.map +1 -0
- package/dist/devcc/views/SettingsView.js +114 -0
- package/dist/devcc/views/SettingsView.js.map +1 -0
- package/dist/devcc/views/SystemView.d.ts +13 -0
- package/dist/devcc/views/SystemView.d.ts.map +1 -0
- package/dist/devcc/views/SystemView.js +82 -0
- package/dist/devcc/views/SystemView.js.map +1 -0
- package/dist/devcc/views/View.d.ts +35 -0
- package/dist/devcc/views/View.d.ts.map +1 -0
- package/dist/devcc/views/View.js +42 -0
- package/dist/devcc/views/View.js.map +1 -0
- package/package.json +79 -0
- package/src/devcc/app/App.ts +1463 -0
- package/src/devcc/app/builtinCommands.ts +429 -0
- package/src/devcc/app/keymap.ts +167 -0
- package/src/devcc/app/theme.ts +83 -0
- package/src/devcc/cli.ts +122 -0
- package/src/devcc/components/CommandPalette.ts +136 -0
- package/src/devcc/components/ConfirmDialog.ts +174 -0
- package/src/devcc/components/Footer.ts +85 -0
- package/src/devcc/components/Header.ts +93 -0
- package/src/devcc/components/HelpOverlay.ts +62 -0
- package/src/devcc/components/Overlay.ts +91 -0
- package/src/devcc/components/ProjectPicker.ts +138 -0
- package/src/devcc/components/Sidebar.ts +163 -0
- package/src/devcc/components/StatusBadge.ts +36 -0
- package/src/devcc/components/primitives.ts +213 -0
- package/src/devcc/components/styled.ts +44 -0
- package/src/devcc/core/commands.ts +140 -0
- package/src/devcc/core/config.ts +405 -0
- package/src/devcc/core/events.ts +41 -0
- package/src/devcc/core/state.ts +236 -0
- package/src/devcc/deps/DependencyService.ts +152 -0
- package/src/devcc/deps/parse.ts +210 -0
- package/src/devcc/git/GitService.ts +205 -0
- package/src/devcc/git/parse.ts +203 -0
- package/src/devcc/index.ts +115 -0
- package/src/devcc/logs/LogBuffer.ts +237 -0
- package/src/devcc/logs/merge.ts +87 -0
- package/src/devcc/processes/ManagedProcess.ts +195 -0
- package/src/devcc/processes/ProcessManager.ts +625 -0
- package/src/devcc/processes/graph.ts +98 -0
- package/src/devcc/projects/ProjectRegistry.ts +219 -0
- package/src/devcc/services/ServiceManager.ts +180 -0
- package/src/devcc/services/docker.ts +220 -0
- package/src/devcc/services/node.ts +137 -0
- package/src/devcc/services/ollama.ts +80 -0
- package/src/devcc/services/postgres.ts +57 -0
- package/src/devcc/services/redis.ts +47 -0
- package/src/devcc/services/types.ts +59 -0
- package/src/devcc/system/SystemMonitor.ts +207 -0
- package/src/devcc/utils/errors.ts +64 -0
- package/src/devcc/utils/exec.ts +165 -0
- package/src/devcc/utils/format.ts +83 -0
- package/src/devcc/utils/fuzzy.ts +44 -0
- package/src/devcc/utils/logger.ts +140 -0
- package/src/devcc/utils/packageManager.ts +112 -0
- package/src/devcc/utils/paths.ts +39 -0
- package/src/devcc/views/DependenciesView.ts +206 -0
- package/src/devcc/views/GitView.ts +259 -0
- package/src/devcc/views/LogsView.ts +300 -0
- package/src/devcc/views/OverviewView.ts +187 -0
- package/src/devcc/views/ProcessesView.ts +177 -0
- package/src/devcc/views/ScriptsView.ts +187 -0
- package/src/devcc/views/ServicesView.ts +188 -0
- package/src/devcc/views/SettingsView.ts +146 -0
- package/src/devcc/views/SystemView.ts +110 -0
- package/src/devcc/views/View.ts +63 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service adapters describe things the project depends on but that devcc does
|
|
3
|
+
* not necessarily own: Docker, a database, a local model server, a dev server
|
|
4
|
+
* someone started in another terminal.
|
|
5
|
+
*
|
|
6
|
+
* Adapters are detected at runtime. Nothing here assumes a given project has
|
|
7
|
+
* any particular service.
|
|
8
|
+
*/
|
|
9
|
+
export type ServiceState = "running" | "stopped" | "degraded" | "unknown" | "unavailable";
|
|
10
|
+
export interface ServiceStatusItem {
|
|
11
|
+
name: string;
|
|
12
|
+
state: ServiceState;
|
|
13
|
+
detail?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ServiceStatus {
|
|
16
|
+
state: ServiceState;
|
|
17
|
+
/** One-line summary shown next to the service name. */
|
|
18
|
+
detail?: string;
|
|
19
|
+
/** Where to reach it, e.g. `localhost:5432`. */
|
|
20
|
+
endpoint?: string;
|
|
21
|
+
/** Sub-entries, e.g. individual compose containers. */
|
|
22
|
+
items?: ServiceStatusItem[];
|
|
23
|
+
checkedAt: Date;
|
|
24
|
+
}
|
|
25
|
+
export interface ServiceActionContext {
|
|
26
|
+
/** Ask the user before doing something destructive. Resolves to the answer. */
|
|
27
|
+
confirm: (title: string, message: string) => Promise<boolean>;
|
|
28
|
+
}
|
|
29
|
+
export interface ServiceAdapter {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
/** Grouping label shown in the Services view. */
|
|
33
|
+
category: "container" | "database" | "runtime" | "ai" | "web";
|
|
34
|
+
/** Cheap check: is this service relevant to this project/host at all? */
|
|
35
|
+
detect: () => Promise<boolean>;
|
|
36
|
+
getStatus: () => Promise<ServiceStatus>;
|
|
37
|
+
start?: (context: ServiceActionContext) => Promise<void>;
|
|
38
|
+
stop?: (context: ServiceActionContext) => Promise<void>;
|
|
39
|
+
restart?: (context: ServiceActionContext) => Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
export interface ServiceSnapshot {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
category: ServiceAdapter["category"];
|
|
45
|
+
status: ServiceStatus;
|
|
46
|
+
canStart: boolean;
|
|
47
|
+
canStop: boolean;
|
|
48
|
+
canRestart: boolean;
|
|
49
|
+
}
|
|
50
|
+
export declare const UNKNOWN_STATUS: ServiceStatus;
|
|
51
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/devcc/services/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,CAAA;AAEzF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAA;IACnB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC3B,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,+EAA+E;IAC/E,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9D;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,QAAQ,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,IAAI,GAAG,KAAK,CAAA;IAE7D,yEAAyE;IACzE,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9B,SAAS,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IAEvC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3D;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IACpC,MAAM,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,eAAO,MAAM,cAAc,EAAE,aAA4D,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service adapters describe things the project depends on but that devcc does
|
|
3
|
+
* not necessarily own: Docker, a database, a local model server, a dev server
|
|
4
|
+
* someone started in another terminal.
|
|
5
|
+
*
|
|
6
|
+
* Adapters are detected at runtime. Nothing here assumes a given project has
|
|
7
|
+
* any particular service.
|
|
8
|
+
*/
|
|
9
|
+
export const UNKNOWN_STATUS = { state: "unknown", checkedAt: new Date(0) };
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/devcc/services/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmDH,MAAM,CAAC,MAAM,cAAc,GAAkB,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { cpus } from "node:os";
|
|
2
|
+
import { TypedEmitter } from "../core/events.js";
|
|
3
|
+
export interface CpuSample {
|
|
4
|
+
idle: number;
|
|
5
|
+
total: number;
|
|
6
|
+
}
|
|
7
|
+
export interface DiskUsage {
|
|
8
|
+
total: number;
|
|
9
|
+
free: number;
|
|
10
|
+
used: number;
|
|
11
|
+
ratio: number;
|
|
12
|
+
}
|
|
13
|
+
export interface SystemMetrics {
|
|
14
|
+
/** 0..1, averaged across cores since the previous sample. */
|
|
15
|
+
cpu: number;
|
|
16
|
+
memoryTotal: number;
|
|
17
|
+
memoryFree: number;
|
|
18
|
+
memoryUsed: number;
|
|
19
|
+
memoryRatio: number;
|
|
20
|
+
loadAverage: [number, number, number];
|
|
21
|
+
/** Host uptime in milliseconds. */
|
|
22
|
+
uptimeMs: number;
|
|
23
|
+
/** devcc's own uptime in milliseconds. */
|
|
24
|
+
processUptimeMs: number;
|
|
25
|
+
disk: DiskUsage | null;
|
|
26
|
+
sampledAt: Date;
|
|
27
|
+
}
|
|
28
|
+
export interface HostInfo {
|
|
29
|
+
hostname: string;
|
|
30
|
+
platform: string;
|
|
31
|
+
release: string;
|
|
32
|
+
arch: string;
|
|
33
|
+
cpuModel: string;
|
|
34
|
+
cpuCount: number;
|
|
35
|
+
totalMemory: number;
|
|
36
|
+
home: string;
|
|
37
|
+
runtime: string;
|
|
38
|
+
nodeVersion: string;
|
|
39
|
+
}
|
|
40
|
+
/** Versions of external tools; populated lazily so startup is never blocked. */
|
|
41
|
+
export interface ToolVersions {
|
|
42
|
+
git: string | null;
|
|
43
|
+
docker: string | null;
|
|
44
|
+
packageManager: string | null;
|
|
45
|
+
}
|
|
46
|
+
export type SystemMonitorEvents = {
|
|
47
|
+
"system:metrics": [SystemMetrics];
|
|
48
|
+
"system:tools": [ToolVersions];
|
|
49
|
+
};
|
|
50
|
+
/** Aggregate `os.cpus()` times into idle/total counters. */
|
|
51
|
+
export declare function sampleCpu(cpuInfos?: ReturnType<typeof cpus>): CpuSample;
|
|
52
|
+
/**
|
|
53
|
+
* CPU utilisation between two samples, as a 0..1 ratio.
|
|
54
|
+
* Returns 0 when the samples are identical (no elapsed time).
|
|
55
|
+
*/
|
|
56
|
+
export declare function cpuUsageBetween(previous: CpuSample, current: CpuSample): number;
|
|
57
|
+
export declare function detectRuntime(): string;
|
|
58
|
+
export interface SystemMonitorOptions {
|
|
59
|
+
rootDir: string;
|
|
60
|
+
intervalMs?: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Samples host metrics on a timer using Node APIs only.
|
|
64
|
+
*
|
|
65
|
+
* The one exception is tool versions (`git`, `docker`), which have no API; those
|
|
66
|
+
* are read once, lazily, off the startup path.
|
|
67
|
+
*/
|
|
68
|
+
export declare class SystemMonitor extends TypedEmitter<SystemMonitorEvents> {
|
|
69
|
+
private readonly options;
|
|
70
|
+
private timer;
|
|
71
|
+
private previousSample;
|
|
72
|
+
private metrics;
|
|
73
|
+
private tools;
|
|
74
|
+
private readonly intervalMs;
|
|
75
|
+
private readonly startedAt;
|
|
76
|
+
constructor(options: SystemMonitorOptions);
|
|
77
|
+
getMetrics(): SystemMetrics | null;
|
|
78
|
+
getTools(): ToolVersions;
|
|
79
|
+
getHostInfo(): HostInfo;
|
|
80
|
+
start(): void;
|
|
81
|
+
stop(): void;
|
|
82
|
+
sample(): Promise<SystemMetrics>;
|
|
83
|
+
/** Read tool versions once. Safe to call repeatedly; results are cached. */
|
|
84
|
+
refreshTools(packageManager: string): Promise<ToolVersions>;
|
|
85
|
+
private readDisk;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=SystemMonitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SystemMonitor.d.ts","sourceRoot":"","sources":["../../../src/devcc/system/SystemMonitor.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,IAAI,EAA4E,MAAM,SAAS,CAAA;AAC9G,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,gBAAgB,EAAE,CAAC,aAAa,CAAC,CAAA;IACjC,cAAc,EAAE,CAAC,YAAY,CAAC,CAAA;CAC/B,CAAA;AAED,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,QAAQ,GAAE,UAAU,CAAC,OAAO,IAAI,CAAU,GAAG,SAAS,CAQ/E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,GAAG,MAAM,CAM/E;AAED,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,YAAY,CAAC,mBAAmB,CAAC;IAQtD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAPpC,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,KAAK,CAAkE;IAC/E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAa;gBAEV,OAAO,EAAE,oBAAoB;IAK1D,UAAU,IAAI,aAAa,GAAG,IAAI;IAIlC,QAAQ,IAAI,YAAY;IAIxB,WAAW,IAAI,QAAQ;IAgBvB,KAAK,IAAI,IAAI;IAOb,IAAI,IAAI,IAAI;IAMN,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;IA2BtC,4EAA4E;IACtE,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;YAWnD,QAAQ;CAYvB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { statfs } from "node:fs/promises";
|
|
2
|
+
import { arch, cpus, freemem, homedir, hostname, loadavg, platform, release, totalmem, uptime } from "node:os";
|
|
3
|
+
import { TypedEmitter } from "../core/events.js";
|
|
4
|
+
import { exec } from "../utils/exec.js";
|
|
5
|
+
/** Aggregate `os.cpus()` times into idle/total counters. */
|
|
6
|
+
export function sampleCpu(cpuInfos = cpus()) {
|
|
7
|
+
let idle = 0;
|
|
8
|
+
let total = 0;
|
|
9
|
+
for (const cpu of cpuInfos) {
|
|
10
|
+
idle += cpu.times.idle;
|
|
11
|
+
total += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.idle + cpu.times.irq;
|
|
12
|
+
}
|
|
13
|
+
return { idle, total };
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* CPU utilisation between two samples, as a 0..1 ratio.
|
|
17
|
+
* Returns 0 when the samples are identical (no elapsed time).
|
|
18
|
+
*/
|
|
19
|
+
export function cpuUsageBetween(previous, current) {
|
|
20
|
+
const idleDelta = current.idle - previous.idle;
|
|
21
|
+
const totalDelta = current.total - previous.total;
|
|
22
|
+
if (totalDelta <= 0)
|
|
23
|
+
return 0;
|
|
24
|
+
const usage = 1 - idleDelta / totalDelta;
|
|
25
|
+
return Math.max(0, Math.min(1, usage));
|
|
26
|
+
}
|
|
27
|
+
export function detectRuntime() {
|
|
28
|
+
const bunVersion = globalThis.Bun?.version;
|
|
29
|
+
if (bunVersion)
|
|
30
|
+
return `bun ${bunVersion}`;
|
|
31
|
+
return `node ${process.versions.node}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Samples host metrics on a timer using Node APIs only.
|
|
35
|
+
*
|
|
36
|
+
* The one exception is tool versions (`git`, `docker`), which have no API; those
|
|
37
|
+
* are read once, lazily, off the startup path.
|
|
38
|
+
*/
|
|
39
|
+
export class SystemMonitor extends TypedEmitter {
|
|
40
|
+
options;
|
|
41
|
+
timer = null;
|
|
42
|
+
previousSample = sampleCpu();
|
|
43
|
+
metrics = null;
|
|
44
|
+
tools = { git: null, docker: null, packageManager: null };
|
|
45
|
+
intervalMs;
|
|
46
|
+
startedAt = Date.now();
|
|
47
|
+
constructor(options) {
|
|
48
|
+
super();
|
|
49
|
+
this.options = options;
|
|
50
|
+
this.intervalMs = options.intervalMs ?? 1_500;
|
|
51
|
+
}
|
|
52
|
+
getMetrics() {
|
|
53
|
+
return this.metrics;
|
|
54
|
+
}
|
|
55
|
+
getTools() {
|
|
56
|
+
return this.tools;
|
|
57
|
+
}
|
|
58
|
+
getHostInfo() {
|
|
59
|
+
const cpuList = cpus();
|
|
60
|
+
return {
|
|
61
|
+
hostname: hostname(),
|
|
62
|
+
platform: platform(),
|
|
63
|
+
release: release(),
|
|
64
|
+
arch: arch(),
|
|
65
|
+
cpuModel: cpuList[0]?.model.trim() ?? "unknown",
|
|
66
|
+
cpuCount: cpuList.length,
|
|
67
|
+
totalMemory: totalmem(),
|
|
68
|
+
home: homedir(),
|
|
69
|
+
runtime: detectRuntime(),
|
|
70
|
+
nodeVersion: process.versions.node,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
start() {
|
|
74
|
+
if (this.timer)
|
|
75
|
+
return;
|
|
76
|
+
void this.sample();
|
|
77
|
+
this.timer = setInterval(() => void this.sample(), this.intervalMs);
|
|
78
|
+
this.timer.unref?.();
|
|
79
|
+
}
|
|
80
|
+
stop() {
|
|
81
|
+
if (!this.timer)
|
|
82
|
+
return;
|
|
83
|
+
clearInterval(this.timer);
|
|
84
|
+
this.timer = null;
|
|
85
|
+
}
|
|
86
|
+
async sample() {
|
|
87
|
+
const current = sampleCpu();
|
|
88
|
+
const cpu = cpuUsageBetween(this.previousSample, current);
|
|
89
|
+
this.previousSample = current;
|
|
90
|
+
const total = totalmem();
|
|
91
|
+
const free = freemem();
|
|
92
|
+
const [one = 0, five = 0, fifteen = 0] = loadavg();
|
|
93
|
+
const metrics = {
|
|
94
|
+
cpu,
|
|
95
|
+
memoryTotal: total,
|
|
96
|
+
memoryFree: free,
|
|
97
|
+
memoryUsed: total - free,
|
|
98
|
+
memoryRatio: total > 0 ? (total - free) / total : 0,
|
|
99
|
+
loadAverage: [one, five, fifteen],
|
|
100
|
+
uptimeMs: uptime() * 1000,
|
|
101
|
+
processUptimeMs: Date.now() - this.startedAt,
|
|
102
|
+
disk: await this.readDisk(),
|
|
103
|
+
sampledAt: new Date(),
|
|
104
|
+
};
|
|
105
|
+
this.metrics = metrics;
|
|
106
|
+
this.emit("system:metrics", metrics);
|
|
107
|
+
return metrics;
|
|
108
|
+
}
|
|
109
|
+
/** Read tool versions once. Safe to call repeatedly; results are cached. */
|
|
110
|
+
async refreshTools(packageManager) {
|
|
111
|
+
const [git, docker, pm] = await Promise.all([
|
|
112
|
+
versionOf("git", ["--version"], /git version (\S+)/u),
|
|
113
|
+
versionOf("docker", ["--version"], /Docker version ([^,\s]+)/u),
|
|
114
|
+
versionOf(packageManager, ["--version"], /(\S+)/u),
|
|
115
|
+
]);
|
|
116
|
+
this.tools = { git, docker, packageManager: pm };
|
|
117
|
+
this.emit("system:tools", this.tools);
|
|
118
|
+
return this.tools;
|
|
119
|
+
}
|
|
120
|
+
async readDisk() {
|
|
121
|
+
try {
|
|
122
|
+
const stats = await statfs(this.options.rootDir);
|
|
123
|
+
const total = Number(stats.blocks) * Number(stats.bsize);
|
|
124
|
+
const free = Number(stats.bavail) * Number(stats.bsize);
|
|
125
|
+
if (!Number.isFinite(total) || total <= 0)
|
|
126
|
+
return null;
|
|
127
|
+
const used = total - free;
|
|
128
|
+
return { total, free, used, ratio: used / total };
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function versionOf(command, args, pattern) {
|
|
136
|
+
const result = await exec(command, args, { timeoutMs: 3_000 });
|
|
137
|
+
if (!result.ok)
|
|
138
|
+
return null;
|
|
139
|
+
const text = result.stdout.trim().split("\n")[0] ?? "";
|
|
140
|
+
return pattern.exec(text)?.[1] ?? (text === "" ? null : text);
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=SystemMonitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SystemMonitor.js","sourceRoot":"","sources":["../../../src/devcc/system/SystemMonitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single, consistent error model for everything Dev Command Center does.
|
|
3
|
+
*
|
|
4
|
+
* Every failure that reaches the UI is normalised into a `DevccError` so the
|
|
5
|
+
* notification centre, the log file and the diagnostics panel can all render it
|
|
6
|
+
* the same way.
|
|
7
|
+
*/
|
|
8
|
+
export type DevccErrorScope = "config" | "process" | "script" | "git" | "docker" | "service" | "system" | "command" | "internal";
|
|
9
|
+
export interface DevccErrorOptions {
|
|
10
|
+
scope: DevccErrorScope;
|
|
11
|
+
/** Short, user facing summary. Shown in the notification area. */
|
|
12
|
+
message: string;
|
|
13
|
+
/** Longer text (command output, stack, ...) shown when the error is inspected. */
|
|
14
|
+
detail?: string;
|
|
15
|
+
cause?: unknown;
|
|
16
|
+
/** Whether the application can keep running normally. Defaults to `true`. */
|
|
17
|
+
recoverable?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare class DevccError extends Error {
|
|
20
|
+
readonly scope: DevccErrorScope;
|
|
21
|
+
readonly detail?: string;
|
|
22
|
+
readonly recoverable: boolean;
|
|
23
|
+
constructor(options: DevccErrorOptions);
|
|
24
|
+
}
|
|
25
|
+
/** Best-effort message extraction from an unknown thrown value. */
|
|
26
|
+
export declare function errorMessage(error: unknown): string;
|
|
27
|
+
/** Stack (or message) of an unknown thrown value, for the log file. */
|
|
28
|
+
export declare function errorDetail(error: unknown): string | undefined;
|
|
29
|
+
/** Normalise anything thrown into a `DevccError` without losing information. */
|
|
30
|
+
export declare function toDevccError(error: unknown, scope: DevccErrorScope, fallbackMessage?: string): DevccError;
|
|
31
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/devcc/utils/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,eAAe,GACzB,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAEpG,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,CAAA;IACtB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAA;IACf,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;gBAEjB,OAAO,EAAE,iBAAiB;CAOvC;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQnD;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI9D;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,UAAU,CAQzG"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single, consistent error model for everything Dev Command Center does.
|
|
3
|
+
*
|
|
4
|
+
* Every failure that reaches the UI is normalised into a `DevccError` so the
|
|
5
|
+
* notification centre, the log file and the diagnostics panel can all render it
|
|
6
|
+
* the same way.
|
|
7
|
+
*/
|
|
8
|
+
export class DevccError extends Error {
|
|
9
|
+
scope;
|
|
10
|
+
detail;
|
|
11
|
+
recoverable;
|
|
12
|
+
constructor(options) {
|
|
13
|
+
super(options.message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
14
|
+
this.name = "DevccError";
|
|
15
|
+
this.scope = options.scope;
|
|
16
|
+
this.detail = options.detail;
|
|
17
|
+
this.recoverable = options.recoverable ?? true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Best-effort message extraction from an unknown thrown value. */
|
|
21
|
+
export function errorMessage(error) {
|
|
22
|
+
if (error instanceof Error)
|
|
23
|
+
return error.message;
|
|
24
|
+
if (typeof error === "string")
|
|
25
|
+
return error;
|
|
26
|
+
try {
|
|
27
|
+
return JSON.stringify(error);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return String(error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Stack (or message) of an unknown thrown value, for the log file. */
|
|
34
|
+
export function errorDetail(error) {
|
|
35
|
+
if (error instanceof DevccError)
|
|
36
|
+
return error.detail ?? error.stack;
|
|
37
|
+
if (error instanceof Error)
|
|
38
|
+
return error.stack;
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
/** Normalise anything thrown into a `DevccError` without losing information. */
|
|
42
|
+
export function toDevccError(error, scope, fallbackMessage) {
|
|
43
|
+
if (error instanceof DevccError)
|
|
44
|
+
return error;
|
|
45
|
+
return new DevccError({
|
|
46
|
+
scope,
|
|
47
|
+
message: fallbackMessage ? `${fallbackMessage}: ${errorMessage(error)}` : errorMessage(error),
|
|
48
|
+
detail: errorDetail(error),
|
|
49
|
+
cause: error,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/devcc/utils/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,KAAK,CAAiB;IACtB,MAAM,CAAS;IACf,WAAW,CAAS;IAE7B,YAAY,OAA0B;QACpC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;QAC1F,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;QACxB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,CAAA;IAChD,CAAC;CACF;AAED,mEAAmE;AACnE,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,KAAK,CAAC,OAAO,CAAA;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,UAAU;QAAE,OAAO,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAA;IACnE,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,KAAK,CAAC,KAAK,CAAA;IAC9C,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,KAAsB,EAAE,eAAwB;IAC3F,IAAI,KAAK,YAAY,UAAU;QAAE,OAAO,KAAK,CAAA;IAC7C,OAAO,IAAI,UAAU,CAAC;QACpB,KAAK;QACL,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,KAAK,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC;QAC7F,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC;QAC1B,KAAK,EAAE,KAAK;KACb,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small, safe process helpers.
|
|
3
|
+
*
|
|
4
|
+
* Everything goes through `spawn(executable, args[])` - never a shell string -
|
|
5
|
+
* so no caller can accidentally build an injectable command line.
|
|
6
|
+
*/
|
|
7
|
+
export interface ExecOptions {
|
|
8
|
+
cwd?: string;
|
|
9
|
+
env?: NodeJS.ProcessEnv;
|
|
10
|
+
/** Hard timeout in milliseconds. Defaults to 5s: nothing in the UI may hang. */
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
/** Bytes of stdout/stderr to retain. Defaults to 1 MiB. */
|
|
13
|
+
maxBuffer?: number;
|
|
14
|
+
input?: string;
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
}
|
|
17
|
+
export interface ExecResult {
|
|
18
|
+
ok: boolean;
|
|
19
|
+
code: number | null;
|
|
20
|
+
signal: NodeJS.Signals | null;
|
|
21
|
+
stdout: string;
|
|
22
|
+
stderr: string;
|
|
23
|
+
timedOut: boolean;
|
|
24
|
+
durationMs: number;
|
|
25
|
+
/** Set when the executable could not be spawned at all (e.g. ENOENT). */
|
|
26
|
+
spawnError?: Error;
|
|
27
|
+
}
|
|
28
|
+
export declare const DEFAULT_EXEC_TIMEOUT_MS = 5000;
|
|
29
|
+
/**
|
|
30
|
+
* Run a command and collect its output. Never rejects - inspect `ok`/`spawnError`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function exec(command: string, args?: readonly string[], options?: ExecOptions): Promise<ExecResult>;
|
|
33
|
+
/** Convenience wrapper that returns trimmed stdout, or `null` when the command failed. */
|
|
34
|
+
export declare function execOutput(command: string, args?: readonly string[], options?: ExecOptions): Promise<string | null>;
|
|
35
|
+
/** True when `command --version` (or the given probe args) succeeds. */
|
|
36
|
+
export declare function commandExists(command: string, probeArgs?: readonly string[]): Promise<boolean>;
|
|
37
|
+
/** Open a TCP connection to check whether something is listening. */
|
|
38
|
+
export declare function probeTcpPort(port: number, host?: string, timeoutMs?: number): Promise<boolean>;
|
|
39
|
+
/** Resolve a promise to a fallback value when it takes too long. */
|
|
40
|
+
export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, fallback: T): Promise<T>;
|
|
41
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../../src/devcc/utils/exec.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,UAAU,CAAC,EAAE,KAAK,CAAA;CACnB;AAED,eAAO,MAAM,uBAAuB,OAAQ,CAAA;AAE5C;;GAEG;AACH,wBAAgB,IAAI,CAClB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,SAAS,MAAM,EAAO,EAC5B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAkErB;AAED,0FAA0F;AAC1F,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,SAAS,MAAM,EAAO,EAC5B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAED,wEAAwE;AACxE,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,SAAS,MAAM,EAAkB,GAC3C,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAc,EAAE,SAAS,SAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBhG;AAED,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAc9F"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { connect } from "node:net";
|
|
3
|
+
export const DEFAULT_EXEC_TIMEOUT_MS = 5_000;
|
|
4
|
+
/**
|
|
5
|
+
* Run a command and collect its output. Never rejects - inspect `ok`/`spawnError`.
|
|
6
|
+
*/
|
|
7
|
+
export function exec(command, args = [], options = {}) {
|
|
8
|
+
const { cwd, env, timeoutMs = DEFAULT_EXEC_TIMEOUT_MS, maxBuffer = 1024 * 1024, input, signal } = options;
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
const startedAt = Date.now();
|
|
11
|
+
const spawnOptions = {
|
|
12
|
+
cwd,
|
|
13
|
+
env: env ?? process.env,
|
|
14
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
15
|
+
windowsHide: true,
|
|
16
|
+
};
|
|
17
|
+
let settled = false;
|
|
18
|
+
let timedOut = false;
|
|
19
|
+
let stdout = "";
|
|
20
|
+
let stderr = "";
|
|
21
|
+
const child = spawn(command, [...args], spawnOptions);
|
|
22
|
+
const finish = (result) => {
|
|
23
|
+
if (settled)
|
|
24
|
+
return;
|
|
25
|
+
settled = true;
|
|
26
|
+
clearTimeout(timer);
|
|
27
|
+
signal?.removeEventListener("abort", onAbort);
|
|
28
|
+
resolve({ ...result, durationMs: Date.now() - startedAt });
|
|
29
|
+
};
|
|
30
|
+
const timer = setTimeout(() => {
|
|
31
|
+
timedOut = true;
|
|
32
|
+
child.kill("SIGKILL");
|
|
33
|
+
}, timeoutMs);
|
|
34
|
+
timer.unref?.();
|
|
35
|
+
const onAbort = () => child.kill("SIGKILL");
|
|
36
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
37
|
+
child.stdout?.setEncoding("utf8");
|
|
38
|
+
child.stdout?.on("data", (chunk) => {
|
|
39
|
+
if (stdout.length < maxBuffer)
|
|
40
|
+
stdout += chunk;
|
|
41
|
+
});
|
|
42
|
+
child.stderr?.setEncoding("utf8");
|
|
43
|
+
child.stderr?.on("data", (chunk) => {
|
|
44
|
+
if (stderr.length < maxBuffer)
|
|
45
|
+
stderr += chunk;
|
|
46
|
+
});
|
|
47
|
+
child.on("error", (error) => {
|
|
48
|
+
finish({ ok: false, code: null, signal: null, stdout, stderr, timedOut, spawnError: error });
|
|
49
|
+
});
|
|
50
|
+
child.on("close", (code, closeSignal) => {
|
|
51
|
+
finish({
|
|
52
|
+
ok: !timedOut && code === 0,
|
|
53
|
+
code,
|
|
54
|
+
signal: closeSignal,
|
|
55
|
+
stdout,
|
|
56
|
+
stderr,
|
|
57
|
+
timedOut,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
if (input !== undefined) {
|
|
61
|
+
child.stdin?.end(input);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
child.stdin?.end();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Convenience wrapper that returns trimmed stdout, or `null` when the command failed. */
|
|
69
|
+
export async function execOutput(command, args = [], options = {}) {
|
|
70
|
+
const result = await exec(command, args, options);
|
|
71
|
+
return result.ok ? result.stdout.trim() : null;
|
|
72
|
+
}
|
|
73
|
+
/** True when `command --version` (or the given probe args) succeeds. */
|
|
74
|
+
export async function commandExists(command, probeArgs = ["--version"]) {
|
|
75
|
+
const result = await exec(command, probeArgs, { timeoutMs: 3_000 });
|
|
76
|
+
return result.ok;
|
|
77
|
+
}
|
|
78
|
+
/** Open a TCP connection to check whether something is listening. */
|
|
79
|
+
export function probeTcpPort(port, host = "127.0.0.1", timeoutMs = 700) {
|
|
80
|
+
return new Promise((resolve) => {
|
|
81
|
+
const socket = connect({ port, host });
|
|
82
|
+
let settled = false;
|
|
83
|
+
const done = (value) => {
|
|
84
|
+
if (settled)
|
|
85
|
+
return;
|
|
86
|
+
settled = true;
|
|
87
|
+
socket.destroy();
|
|
88
|
+
resolve(value);
|
|
89
|
+
};
|
|
90
|
+
socket.setTimeout(timeoutMs);
|
|
91
|
+
socket.once("connect", () => done(true));
|
|
92
|
+
socket.once("timeout", () => done(false));
|
|
93
|
+
socket.once("error", () => done(false));
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/** Resolve a promise to a fallback value when it takes too long. */
|
|
97
|
+
export function withTimeout(promise, timeoutMs, fallback) {
|
|
98
|
+
return new Promise((resolve) => {
|
|
99
|
+
const timer = setTimeout(() => resolve(fallback), timeoutMs);
|
|
100
|
+
timer.unref?.();
|
|
101
|
+
promise
|
|
102
|
+
.then((value) => {
|
|
103
|
+
clearTimeout(timer);
|
|
104
|
+
resolve(value);
|
|
105
|
+
})
|
|
106
|
+
.catch(() => {
|
|
107
|
+
clearTimeout(timer);
|
|
108
|
+
resolve(fallback);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../../src/devcc/utils/exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Formatting helpers shared by the views. Pure functions, easy to test. */
|
|
2
|
+
export declare function formatBytes(bytes: number, fractionDigits?: number): string;
|
|
3
|
+
/** Bytes rendered in GB without a unit suffix, for `7.2 / 36 GB` style pairs. */
|
|
4
|
+
export declare function toGigabytes(bytes: number, fractionDigits?: number): string;
|
|
5
|
+
export declare function formatPercent(ratio: number, fractionDigits?: number): string;
|
|
6
|
+
/** Compact duration: `4s`, `2m 10s`, `1h 04m`, `3d 02h`. */
|
|
7
|
+
export declare function formatDuration(ms: number): string;
|
|
8
|
+
export declare function formatClock(date: Date): string;
|
|
9
|
+
export declare function formatTimestamp(date: Date): string;
|
|
10
|
+
/** Pad or truncate to an exact display width. */
|
|
11
|
+
export declare function fit(text: string, width: number): string;
|
|
12
|
+
export declare function truncate(text: string, maxLength: number): string;
|
|
13
|
+
/** Single-line preview of a possibly multi-line string. */
|
|
14
|
+
export declare function singleLine(text: string, maxLength?: number): string;
|
|
15
|
+
/** A small horizontal meter, e.g. `████░░░░░░`. */
|
|
16
|
+
export declare function meter(ratio: number, width?: number, filledChar?: string, emptyChar?: string): string;
|
|
17
|
+
export declare function pluralise(count: number, singular: string, plural?: string): string;
|
|
18
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/devcc/utils/format.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,MAAM,CAWrE;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,MAAM,CAErE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,MAAM,CAGvE;AAED,4DAA4D;AAC5D,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUjD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE9C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAOlD;AAED,iDAAiD;AACjD,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAEhE;AAED,mDAAmD;AACnD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,UAAU,SAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAK1F;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAiB,GAAG,MAAM,CAE1F"}
|