chrome-proc 1.0.0 → 1.0.1
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/.claude/scripts/deploy-local.sh +21 -0
- package/.claude/scripts/publish-npm.sh +68 -44
- package/CLAUDE.md +10 -0
- package/README.md +49 -0
- package/dist/commands/completion.js +23 -0
- package/dist/commands/launch.js +5 -5
- package/dist/index.js +7 -0
- package/dist/platform/completion-helpers.js +253 -0
- package/dist/platform/darwin.js +82 -0
- package/dist/platform/index.js +18 -0
- package/dist/platform/linux.js +102 -0
- package/dist/platform/types.js +2 -0
- package/dist/platform/win32.js +108 -0
- package/dist/utils/localState.js +4 -3
- package/dist/utils/process.js +6 -34
- package/package.json +6 -2
- package/src/commands/completion.ts +21 -0
- package/src/commands/launch.ts +6 -6
- package/src/index.ts +8 -0
- package/src/platform/completion-helpers.ts +253 -0
- package/src/platform/darwin.ts +89 -0
- package/src/platform/index.ts +18 -0
- package/src/platform/linux.ts +110 -0
- package/src/platform/types.ts +16 -0
- package/src/platform/win32.ts +122 -0
- package/src/utils/localState.ts +4 -3
- package/src/utils/process.ts +6 -30
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.linuxProvider = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const os_1 = require("os");
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const completion_helpers_1 = require("./completion-helpers");
|
|
8
|
+
const CHROME_CANDIDATES = [
|
|
9
|
+
"/usr/bin/google-chrome",
|
|
10
|
+
"/usr/bin/google-chrome-stable",
|
|
11
|
+
"/usr/bin/chromium",
|
|
12
|
+
"/usr/bin/chromium-browser",
|
|
13
|
+
];
|
|
14
|
+
function getChromePids(exact = false) {
|
|
15
|
+
const names = ["chrome", "google-chrome", "google-chrome-stable", "chromium", "chromium-browser"];
|
|
16
|
+
const pids = [];
|
|
17
|
+
for (const name of names) {
|
|
18
|
+
try {
|
|
19
|
+
const flag = exact ? "-x" : "-f";
|
|
20
|
+
const output = (0, child_process_1.execSync)(`pgrep ${flag} "${name}"`, { encoding: "utf-8" });
|
|
21
|
+
output
|
|
22
|
+
.trim()
|
|
23
|
+
.split("\n")
|
|
24
|
+
.filter((line) => line.trim() !== "")
|
|
25
|
+
.map((line) => parseInt(line.trim(), 10))
|
|
26
|
+
.filter((pid) => !isNaN(pid) && !pids.includes(pid))
|
|
27
|
+
.forEach((pid) => pids.push(pid));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// pgrep exits with code 1 when no matches found
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return pids;
|
|
34
|
+
}
|
|
35
|
+
function getProcessArgs(pid) {
|
|
36
|
+
try {
|
|
37
|
+
return (0, child_process_1.execSync)(`ps -p "${pid}" -o args=`, { encoding: "utf-8" }).trim();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return "?";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function getProcessName(pid) {
|
|
44
|
+
try {
|
|
45
|
+
return (0, child_process_1.execSync)(`ps -p "${pid}" -o comm=`, { encoding: "utf-8" }).trim();
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return "?";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function killPid(pid, signal) {
|
|
52
|
+
try {
|
|
53
|
+
(0, child_process_1.execSync)(`kill -${signal} "${pid}"`, { stdio: "pipe" });
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function isChromeRunning() {
|
|
61
|
+
return getChromePids(true).length > 0;
|
|
62
|
+
}
|
|
63
|
+
const processManager = {
|
|
64
|
+
getChromePids,
|
|
65
|
+
getProcessArgs,
|
|
66
|
+
getProcessName,
|
|
67
|
+
killPid,
|
|
68
|
+
isChromeRunning,
|
|
69
|
+
};
|
|
70
|
+
function findChrome() {
|
|
71
|
+
for (const candidate of CHROME_CANDIDATES) {
|
|
72
|
+
if ((0, fs_1.existsSync)(candidate)) {
|
|
73
|
+
return candidate;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return CHROME_CANDIDATES[0];
|
|
77
|
+
}
|
|
78
|
+
exports.linuxProvider = {
|
|
79
|
+
name: "linux",
|
|
80
|
+
getChromeExecutablePath() {
|
|
81
|
+
return findChrome();
|
|
82
|
+
},
|
|
83
|
+
getDefaultChromeDataDir() {
|
|
84
|
+
return `${(0, os_1.homedir)()}/.config/google-chrome`;
|
|
85
|
+
},
|
|
86
|
+
getProcessManager() {
|
|
87
|
+
return processManager;
|
|
88
|
+
},
|
|
89
|
+
supportedShells() {
|
|
90
|
+
return ["bash", "zsh"];
|
|
91
|
+
},
|
|
92
|
+
generateCompletion(shell, profileDirs) {
|
|
93
|
+
switch (shell) {
|
|
94
|
+
case "bash":
|
|
95
|
+
return (0, completion_helpers_1.generateBashCompletion)(profileDirs);
|
|
96
|
+
case "zsh":
|
|
97
|
+
return (0, completion_helpers_1.generateZshCompletion)(profileDirs);
|
|
98
|
+
default:
|
|
99
|
+
throw new Error(`Unsupported shell: ${shell}`);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.win32Provider = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const completion_helpers_1 = require("./completion-helpers");
|
|
7
|
+
function getChromePids(_exact = false) {
|
|
8
|
+
try {
|
|
9
|
+
const output = (0, child_process_1.execSync)(`tasklist /FI "IMAGENAME eq chrome.exe" /FO CSV /NH`, { encoding: "utf-8" }).trim();
|
|
10
|
+
if (!output || output.startsWith("INFO:"))
|
|
11
|
+
return [];
|
|
12
|
+
return output
|
|
13
|
+
.split("\n")
|
|
14
|
+
.map((line) => {
|
|
15
|
+
const match = line.match(/^"[^"]+","(\d+)"/);
|
|
16
|
+
return match ? parseInt(match[1], 10) : NaN;
|
|
17
|
+
})
|
|
18
|
+
.filter((pid) => !isNaN(pid));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function getProcessArgs(pid) {
|
|
25
|
+
try {
|
|
26
|
+
const output = (0, child_process_1.execSync)(`powershell.exe -NoProfile -Command "(Get-CimInstance Win32_Process -Filter \\"ProcessId=${pid}\\").CommandLine"`, { encoding: "utf-8" }).trim();
|
|
27
|
+
return output || "?";
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return "?";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function getProcessName(pid) {
|
|
34
|
+
try {
|
|
35
|
+
const output = (0, child_process_1.execSync)(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`, { encoding: "utf-8" }).trim();
|
|
36
|
+
if (!output || output.startsWith("INFO:"))
|
|
37
|
+
return "?";
|
|
38
|
+
const match = output.match(/^"([^"]+)"/);
|
|
39
|
+
return match ? match[1] : "?";
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return "?";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function killPid(pid, signal) {
|
|
46
|
+
try {
|
|
47
|
+
const forceFlag = signal === "KILL" ? "/F" : "";
|
|
48
|
+
(0, child_process_1.execSync)(`taskkill /PID ${pid} /T ${forceFlag}`, { stdio: "pipe" });
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function isChromeRunning() {
|
|
56
|
+
return getChromePids().length > 0;
|
|
57
|
+
}
|
|
58
|
+
const processManager = {
|
|
59
|
+
getChromePids,
|
|
60
|
+
getProcessArgs,
|
|
61
|
+
getProcessName,
|
|
62
|
+
killPid,
|
|
63
|
+
isChromeRunning,
|
|
64
|
+
};
|
|
65
|
+
function findChrome() {
|
|
66
|
+
const candidates = [];
|
|
67
|
+
if (process.env.LOCALAPPDATA) {
|
|
68
|
+
candidates.push(`${process.env.LOCALAPPDATA}\\Google\\Chrome\\Application\\chrome.exe`);
|
|
69
|
+
}
|
|
70
|
+
if (process.env.PROGRAMFILES) {
|
|
71
|
+
candidates.push(`${process.env.PROGRAMFILES}\\Google\\Chrome\\Application\\chrome.exe`);
|
|
72
|
+
}
|
|
73
|
+
if (process.env["PROGRAMFILES(X86)"]) {
|
|
74
|
+
candidates.push(`${process.env["PROGRAMFILES(X86)"]}\\Google\\Chrome\\Application\\chrome.exe`);
|
|
75
|
+
}
|
|
76
|
+
for (const candidate of candidates) {
|
|
77
|
+
if ((0, fs_1.existsSync)(candidate)) {
|
|
78
|
+
return candidate;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return candidates[0] || "chrome.exe";
|
|
82
|
+
}
|
|
83
|
+
exports.win32Provider = {
|
|
84
|
+
name: "win32",
|
|
85
|
+
getChromeExecutablePath() {
|
|
86
|
+
return findChrome();
|
|
87
|
+
},
|
|
88
|
+
getDefaultChromeDataDir() {
|
|
89
|
+
if (process.env.LOCALAPPDATA) {
|
|
90
|
+
return `${process.env.LOCALAPPDATA}\\Google\\Chrome\\User Data`;
|
|
91
|
+
}
|
|
92
|
+
return `${process.env.USERPROFILE || ""}\\AppData\\Local\\Google\\Chrome\\User Data`;
|
|
93
|
+
},
|
|
94
|
+
getProcessManager() {
|
|
95
|
+
return processManager;
|
|
96
|
+
},
|
|
97
|
+
supportedShells() {
|
|
98
|
+
return ["powershell"];
|
|
99
|
+
},
|
|
100
|
+
generateCompletion(shell, profileDirs) {
|
|
101
|
+
switch (shell) {
|
|
102
|
+
case "powershell":
|
|
103
|
+
return (0, completion_helpers_1.generatePowerShellCompletion)(profileDirs);
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(`Unsupported shell: ${shell}`);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
};
|
package/dist/utils/localState.js
CHANGED
|
@@ -8,12 +8,13 @@ exports.profileExists = profileExists;
|
|
|
8
8
|
exports.validateProfileDir = validateProfileDir;
|
|
9
9
|
const fs_1 = require("fs");
|
|
10
10
|
const path_1 = require("path");
|
|
11
|
+
const platform_1 = require("../platform");
|
|
11
12
|
function getChromeDataDir() {
|
|
12
13
|
const dir = process.env.CHROME_DATA_DIR;
|
|
13
|
-
if (
|
|
14
|
-
|
|
14
|
+
if (dir) {
|
|
15
|
+
return dir;
|
|
15
16
|
}
|
|
16
|
-
return
|
|
17
|
+
return (0, platform_1.getPlatform)().getDefaultChromeDataDir();
|
|
17
18
|
}
|
|
18
19
|
function getLocalStatePath() {
|
|
19
20
|
return (0, path_1.join)(getChromeDataDir(), "Local State");
|
package/dist/utils/process.js
CHANGED
|
@@ -6,51 +6,23 @@ exports.getProcessName = getProcessName;
|
|
|
6
6
|
exports.extractDebugPort = extractDebugPort;
|
|
7
7
|
exports.killPid = killPid;
|
|
8
8
|
exports.isChromeRunning = isChromeRunning;
|
|
9
|
-
const
|
|
9
|
+
const platform_1 = require("../platform");
|
|
10
10
|
function getChromePids(exact = false) {
|
|
11
|
-
|
|
12
|
-
const flag = exact ? "-x" : "-f";
|
|
13
|
-
const output = (0, child_process_1.execSync)(`pgrep ${flag} "Google Chrome"`, { encoding: "utf-8" });
|
|
14
|
-
return output
|
|
15
|
-
.trim()
|
|
16
|
-
.split("\n")
|
|
17
|
-
.filter((line) => line.trim() !== "")
|
|
18
|
-
.map((line) => parseInt(line.trim(), 10))
|
|
19
|
-
.filter((pid) => !isNaN(pid));
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
11
|
+
return (0, platform_1.getPlatform)().getProcessManager().getChromePids(exact);
|
|
24
12
|
}
|
|
25
13
|
function getProcessArgs(pid) {
|
|
26
|
-
|
|
27
|
-
return (0, child_process_1.execSync)(`ps -p "${pid}" -o args=`, { encoding: "utf-8" }).trim();
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return "?";
|
|
31
|
-
}
|
|
14
|
+
return (0, platform_1.getPlatform)().getProcessManager().getProcessArgs(pid);
|
|
32
15
|
}
|
|
33
16
|
function getProcessName(pid) {
|
|
34
|
-
|
|
35
|
-
return (0, child_process_1.execSync)(`ps -p "${pid}" -o comm=`, { encoding: "utf-8" }).trim();
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return "?";
|
|
39
|
-
}
|
|
17
|
+
return (0, platform_1.getPlatform)().getProcessManager().getProcessName(pid);
|
|
40
18
|
}
|
|
41
19
|
function extractDebugPort(args) {
|
|
42
20
|
const match = args.match(/--remote-debugging-port=(\d+)/);
|
|
43
21
|
return match ? parseInt(match[1], 10) : null;
|
|
44
22
|
}
|
|
45
23
|
function killPid(pid, signal) {
|
|
46
|
-
|
|
47
|
-
(0, child_process_1.execSync)(`/bin/kill -${signal} "${pid}"`, { stdio: "pipe" });
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
24
|
+
return (0, platform_1.getPlatform)().getProcessManager().killPid(pid, signal);
|
|
53
25
|
}
|
|
54
26
|
function isChromeRunning() {
|
|
55
|
-
return
|
|
27
|
+
return (0, platform_1.getPlatform)().getProcessManager().isChromeRunning();
|
|
56
28
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-proc",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Manage Chrome browser processes, profiles, and CDP endpoints",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
"build": "tsc",
|
|
11
11
|
"dev": "tsc --watch"
|
|
12
12
|
},
|
|
13
|
-
"keywords": [
|
|
13
|
+
"keywords": [
|
|
14
|
+
"chrome",
|
|
15
|
+
"cdp",
|
|
16
|
+
"devtools"
|
|
17
|
+
],
|
|
14
18
|
"license": "MIT",
|
|
15
19
|
"dependencies": {
|
|
16
20
|
"commander": "^12.0.0"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getPlatform } from "../platform";
|
|
2
|
+
import { readLocalState } from "../utils/localState";
|
|
3
|
+
|
|
4
|
+
export function completionCommand(shell: string): void {
|
|
5
|
+
const platform = getPlatform();
|
|
6
|
+
const shells = platform.supportedShells();
|
|
7
|
+
if (!shells.includes(shell)) {
|
|
8
|
+
console.error(`Error: unsupported shell '${shell}'. Supported: ${shells.join(", ")}`);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
console.log(platform.generateCompletion(shell, getProfileDirs()));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getProfileDirs(): string[] {
|
|
15
|
+
try {
|
|
16
|
+
const state = readLocalState();
|
|
17
|
+
return Object.keys(state.profile?.info_cache ?? {});
|
|
18
|
+
} catch {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/commands/launch.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import { existsSync } from "fs";
|
|
3
|
-
import {
|
|
3
|
+
import { getPlatform } from "../platform";
|
|
4
|
+
import { isChromeRunning, getChromePids } from "../utils/process";
|
|
4
5
|
|
|
5
6
|
interface LaunchOptions {
|
|
6
7
|
dir?: string;
|
|
@@ -10,7 +11,7 @@ interface LaunchOptions {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export function launchCommand(options: LaunchOptions): void {
|
|
13
|
-
const chromeBin =
|
|
14
|
+
const chromeBin = getPlatform().getChromeExecutablePath();
|
|
14
15
|
const profile = options.profile ?? process.env.CHROME_PROFILE ?? "";
|
|
15
16
|
const dataDir = options.dir ?? process.env.CHROME_DATA_DIR ?? "";
|
|
16
17
|
|
|
@@ -38,10 +39,9 @@ export function launchCommand(options: LaunchOptions): void {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
if (isChromeRunning()) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
console.error(`Warning: Chrome is already running (PIDs: ${existing})`);
|
|
42
|
+
const existing = getChromePids(true);
|
|
43
|
+
if (existing.length > 0) {
|
|
44
|
+
console.error(`Warning: Chrome is already running (PIDs: ${existing.join(" ")})`);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { killCommand } from "./commands/kill";
|
|
|
5
5
|
import { launchCommand } from "./commands/launch";
|
|
6
6
|
import { profileList, profileName, profileDelete } from "./commands/profile";
|
|
7
7
|
import { cdpCommand } from "./commands/cdp";
|
|
8
|
+
import { completionCommand } from "./commands/completion";
|
|
8
9
|
|
|
9
10
|
const program = new Command();
|
|
10
11
|
|
|
@@ -75,4 +76,11 @@ program
|
|
|
75
76
|
await cdpCommand(options);
|
|
76
77
|
});
|
|
77
78
|
|
|
79
|
+
program
|
|
80
|
+
.command("completion <shell>")
|
|
81
|
+
.description("Generate shell completion script (bash or zsh)")
|
|
82
|
+
.action((shell: string) => {
|
|
83
|
+
completionCommand(shell);
|
|
84
|
+
});
|
|
85
|
+
|
|
78
86
|
program.parse();
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
export function generateBashCompletion(profileDirs: string[]): string {
|
|
2
|
+
const profileDirsNewline = profileDirs.join("\n");
|
|
3
|
+
|
|
4
|
+
return `#!/usr/bin/env bash
|
|
5
|
+
_chrome_proc() {
|
|
6
|
+
local cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
7
|
+
local prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
8
|
+
|
|
9
|
+
local commands="list kill launch profile cdp completion"
|
|
10
|
+
local profile_subcommands="list name delete"
|
|
11
|
+
|
|
12
|
+
local list_opts="--verbose --json"
|
|
13
|
+
local kill_opts="--force --all"
|
|
14
|
+
local launch_opts="--dir --profile --debug --debugging-port"
|
|
15
|
+
local profile_list_opts="--json"
|
|
16
|
+
local cdp_opts="--json"
|
|
17
|
+
local completion_shells="bash zsh powershell"
|
|
18
|
+
|
|
19
|
+
local profile_dirs='
|
|
20
|
+
${profileDirsNewline}
|
|
21
|
+
'
|
|
22
|
+
|
|
23
|
+
local cmd=""
|
|
24
|
+
local subcmd=""
|
|
25
|
+
local i=1
|
|
26
|
+
|
|
27
|
+
while [[ $i -lt $COMP_CWORD ]]; do
|
|
28
|
+
local word="\${COMP_WORDS[$i]}"
|
|
29
|
+
if [[ "$word" != -* ]]; then
|
|
30
|
+
if [[ -z "$cmd" ]]; then
|
|
31
|
+
cmd="$word"
|
|
32
|
+
elif [[ "$cmd" == "profile" && -z "$subcmd" ]]; then
|
|
33
|
+
subcmd="$word"
|
|
34
|
+
break
|
|
35
|
+
else
|
|
36
|
+
break
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
((i++))
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
if [[ -z "$cmd" ]]; then
|
|
43
|
+
if [[ "$cur" == -* ]]; then
|
|
44
|
+
COMPREPLY=()
|
|
45
|
+
else
|
|
46
|
+
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
|
47
|
+
fi
|
|
48
|
+
return
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
case "$cmd" in
|
|
52
|
+
list)
|
|
53
|
+
COMPREPLY=( $(compgen -W "$list_opts" -- "$cur") )
|
|
54
|
+
;;
|
|
55
|
+
kill)
|
|
56
|
+
COMPREPLY=( $(compgen -W "$kill_opts" -- "$cur") )
|
|
57
|
+
;;
|
|
58
|
+
launch)
|
|
59
|
+
COMPREPLY=( $(compgen -W "$launch_opts" -- "$cur") )
|
|
60
|
+
;;
|
|
61
|
+
cdp)
|
|
62
|
+
COMPREPLY=( $(compgen -W "$cdp_opts" -- "$cur") )
|
|
63
|
+
;;
|
|
64
|
+
completion)
|
|
65
|
+
COMPREPLY=( $(compgen -W "$completion_shells" -- "$cur") )
|
|
66
|
+
;;
|
|
67
|
+
profile)
|
|
68
|
+
if [[ -z "$subcmd" ]]; then
|
|
69
|
+
if [[ "$cur" == -* ]]; then
|
|
70
|
+
COMPREPLY=()
|
|
71
|
+
else
|
|
72
|
+
COMPREPLY=( $(compgen -W "$profile_subcommands" -- "$cur") )
|
|
73
|
+
fi
|
|
74
|
+
else
|
|
75
|
+
case "$subcmd" in
|
|
76
|
+
list)
|
|
77
|
+
COMPREPLY=( $(compgen -W "$profile_list_opts" -- "$cur") )
|
|
78
|
+
;;
|
|
79
|
+
name|delete)
|
|
80
|
+
if [[ -n "$profile_dirs" && ( -z "$prev" || "$prev" == "name" || "$prev" == "delete" ) ]]; then
|
|
81
|
+
local OLD_IFS="$IFS"
|
|
82
|
+
IFS=$'\n'
|
|
83
|
+
COMPREPLY=( $(compgen -W "$profile_dirs" -- "$cur") )
|
|
84
|
+
IFS="$OLD_IFS"
|
|
85
|
+
else
|
|
86
|
+
COMPREPLY=()
|
|
87
|
+
fi
|
|
88
|
+
;;
|
|
89
|
+
*)
|
|
90
|
+
COMPREPLY=()
|
|
91
|
+
;;
|
|
92
|
+
esac
|
|
93
|
+
fi
|
|
94
|
+
;;
|
|
95
|
+
*)
|
|
96
|
+
COMPREPLY=()
|
|
97
|
+
;;
|
|
98
|
+
esac
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
complete -F _chrome_proc chrome-proc
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function generateZshCompletion(profileDirs: string[]): string {
|
|
106
|
+
const profileDirsNewline = profileDirs.join("\n");
|
|
107
|
+
|
|
108
|
+
return `#!/usr/bin/env zsh
|
|
109
|
+
#compdef chrome-proc
|
|
110
|
+
|
|
111
|
+
_chrome_proc() {
|
|
112
|
+
local curcontext="$curcontext" state line
|
|
113
|
+
typeset -A opt_args
|
|
114
|
+
|
|
115
|
+
local profile_dirs='
|
|
116
|
+
${profileDirsNewline}
|
|
117
|
+
'
|
|
118
|
+
|
|
119
|
+
_arguments -C \\
|
|
120
|
+
'1: :->command' \\
|
|
121
|
+
'2: :->subcommand' \\
|
|
122
|
+
'*: :->args'
|
|
123
|
+
|
|
124
|
+
case "$state" in
|
|
125
|
+
command)
|
|
126
|
+
local commands=(list kill launch profile cdp completion)
|
|
127
|
+
_describe -t commands 'chrome-proc command' commands
|
|
128
|
+
;;
|
|
129
|
+
subcommand)
|
|
130
|
+
case "$line[1]" in
|
|
131
|
+
list)
|
|
132
|
+
local opts=('--verbose:Show full command line' '--json:Output as JSON lines')
|
|
133
|
+
_describe -t options 'list options' opts
|
|
134
|
+
;;
|
|
135
|
+
kill)
|
|
136
|
+
local opts=('--force:Use SIGKILL instead of SIGTERM' '--all:Kill helper processes too')
|
|
137
|
+
_describe -t options 'kill options' opts
|
|
138
|
+
;;
|
|
139
|
+
launch)
|
|
140
|
+
local opts=('--dir:Chrome user data directory' '--profile:Chrome profile name' '--debug:Enable remote debugging mode' '--debugging-port:Remote debugging port')
|
|
141
|
+
_describe -t options 'launch options' opts
|
|
142
|
+
;;
|
|
143
|
+
cdp)
|
|
144
|
+
local opts=('--json:Output as JSON lines')
|
|
145
|
+
_describe -t options 'cdp options' opts
|
|
146
|
+
;;
|
|
147
|
+
completion)
|
|
148
|
+
local shells=(bash zsh powershell)
|
|
149
|
+
_describe -t shells 'shell' shells
|
|
150
|
+
;;
|
|
151
|
+
profile)
|
|
152
|
+
local subcmds=(list name delete)
|
|
153
|
+
_describe -t subcommands 'profile subcommand' subcmds
|
|
154
|
+
;;
|
|
155
|
+
esac
|
|
156
|
+
;;
|
|
157
|
+
args)
|
|
158
|
+
case "$line[1]" in
|
|
159
|
+
list)
|
|
160
|
+
local opts=('--verbose:Show full command line' '--json:Output as JSON lines')
|
|
161
|
+
_describe -t options 'list options' opts
|
|
162
|
+
;;
|
|
163
|
+
kill)
|
|
164
|
+
local opts=('--force:Use SIGKILL instead of SIGTERM' '--all:Kill helper processes too')
|
|
165
|
+
_describe -t options 'kill options' opts
|
|
166
|
+
;;
|
|
167
|
+
launch)
|
|
168
|
+
local opts=('--dir:Chrome user data directory' '--profile:Chrome profile name' '--debug:Enable remote debugging mode' '--debugging-port:Remote debugging port')
|
|
169
|
+
_describe -t options 'launch options' opts
|
|
170
|
+
;;
|
|
171
|
+
cdp)
|
|
172
|
+
local opts=('--json:Output as JSON lines')
|
|
173
|
+
_describe -t options 'cdp options' opts
|
|
174
|
+
;;
|
|
175
|
+
profile)
|
|
176
|
+
case "$line[2]" in
|
|
177
|
+
list)
|
|
178
|
+
local opts=('--json:Output as JSON lines')
|
|
179
|
+
_describe -t options 'profile list options' opts
|
|
180
|
+
;;
|
|
181
|
+
name|delete)
|
|
182
|
+
if [[ -n "$profile_dirs" ]]; then
|
|
183
|
+
local dirs=(\${(f)profile_dirs})
|
|
184
|
+
_describe -t directories 'profile directory' dirs
|
|
185
|
+
fi
|
|
186
|
+
;;
|
|
187
|
+
esac
|
|
188
|
+
;;
|
|
189
|
+
esac
|
|
190
|
+
;;
|
|
191
|
+
esac
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
_chrome_proc "$@"
|
|
195
|
+
`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function generatePowerShellCompletion(profileDirs: string[]): string {
|
|
199
|
+
const profileDirsQuoted = profileDirs.map((d) => `'${d.replace(/'/g, "''")}'`).join(", ");
|
|
200
|
+
|
|
201
|
+
return `Register-ArgumentCompleter -Native -CommandName chrome-proc -ScriptBlock {
|
|
202
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
203
|
+
|
|
204
|
+
$commands = @('list', 'kill', 'launch', 'profile', 'cdp', 'completion')
|
|
205
|
+
$profileSubcommands = @('list', 'name', 'delete')
|
|
206
|
+
$tokens = $commandAst.CommandElements | ForEach-Object { $_.Value }
|
|
207
|
+
$cmd = $tokens[1]
|
|
208
|
+
$subcmd = $tokens[2]
|
|
209
|
+
|
|
210
|
+
if (-not $cmd) {
|
|
211
|
+
$commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
switch ($cmd) {
|
|
216
|
+
'list' {
|
|
217
|
+
@('--verbose', '--json') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
218
|
+
}
|
|
219
|
+
'kill' {
|
|
220
|
+
@('--force', '--all') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
221
|
+
}
|
|
222
|
+
'launch' {
|
|
223
|
+
@('--dir', '--profile', '--debug', '--debugging-port') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
224
|
+
}
|
|
225
|
+
'cdp' {
|
|
226
|
+
@('--json') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
227
|
+
}
|
|
228
|
+
'completion' {
|
|
229
|
+
@('bash', 'zsh', 'powershell') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
230
|
+
}
|
|
231
|
+
'profile' {
|
|
232
|
+
if (-not $subcmd) {
|
|
233
|
+
$profileSubcommands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
234
|
+
} else {
|
|
235
|
+
switch ($subcmd) {
|
|
236
|
+
'list' {
|
|
237
|
+
@('--json') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
238
|
+
}
|
|
239
|
+
'name' {
|
|
240
|
+
$profileDirs = @(${profileDirsQuoted})
|
|
241
|
+
$profileDirs | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
242
|
+
}
|
|
243
|
+
'delete' {
|
|
244
|
+
$profileDirs = @(${profileDirsQuoted})
|
|
245
|
+
$profileDirs | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { $_ }
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
`;
|
|
253
|
+
}
|