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,21 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
cd "$(dirname "$0")/../.."
|
|
5
|
+
|
|
6
|
+
echo "Linking local chrome-proc to global npm..."
|
|
7
|
+
npm link
|
|
8
|
+
|
|
9
|
+
echo ""
|
|
10
|
+
echo "Verifying installation..."
|
|
11
|
+
GLOBAL_BIN="$(npm prefix -g)/bin/chrome-proc"
|
|
12
|
+
if [ -L "$GLOBAL_BIN" ]; then
|
|
13
|
+
TARGET="$(readlink "$GLOBAL_BIN")"
|
|
14
|
+
echo "Global binary linked: $GLOBAL_BIN -> $TARGET"
|
|
15
|
+
else
|
|
16
|
+
echo "Warning: $GLOBAL_BIN is not a symlink"
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
echo ""
|
|
20
|
+
echo "Running chrome-proc --version (or help)..."
|
|
21
|
+
chrome-proc --help | head -3
|
|
@@ -5,28 +5,47 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
5
5
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
6
6
|
cd "$PROJECT_DIR"
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
BUMP="${1:-patch}"
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
echo ""
|
|
12
|
-
|
|
13
|
-
if ! npm whoami > /dev/null 2>&1; then
|
|
14
|
-
echo "ERROR: You are not logged into npm."
|
|
15
|
-
echo "Please run: npm login"
|
|
16
|
-
echo "Then re-run this script."
|
|
17
|
-
exit 1
|
|
10
|
+
if [[ "$BUMP" != "patch" && "$BUMP" != "minor" && "$BUMP" != "major" ]]; then
|
|
11
|
+
echo "Usage: $0 [patch|minor|major] (default: patch)"
|
|
12
|
+
exit 1
|
|
18
13
|
fi
|
|
19
|
-
USERNAME=$(npm whoami)
|
|
20
|
-
echo "Authenticated as: $USERNAME"
|
|
21
14
|
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
echo "
|
|
15
|
+
# ── Guard checks ────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
echo "==> Checking working tree is clean..."
|
|
18
|
+
if ! git diff --exit-code --quiet || ! git diff --cached --exit-code --quiet; then
|
|
19
|
+
echo "ERROR: Working tree has uncommitted changes. Commit or stash them first."
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
echo "==> Checking current branch is main..."
|
|
24
|
+
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
|
25
|
+
if [[ "$BRANCH" != "main" ]]; then
|
|
26
|
+
echo "ERROR: Must be on 'main' to publish (currently on '$BRANCH')."
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
echo "==> Checking npm authentication..."
|
|
31
|
+
if ! npm whoami &>/dev/null; then
|
|
32
|
+
echo "ERROR: Not logged in to npm. Run 'npm login' first."
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# ── Bump version ────────────────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
echo "==> Bumping $BUMP version..."
|
|
39
|
+
npm version "$BUMP" --no-git-tag-version
|
|
40
|
+
NEW_VERSION="$(node -p "require('./package.json').version")"
|
|
41
|
+
echo " New version: $NEW_VERSION"
|
|
42
|
+
|
|
43
|
+
# ── Build ───────────────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
echo "==> Building..."
|
|
25
46
|
npm run build
|
|
26
47
|
|
|
27
|
-
|
|
28
|
-
echo ""
|
|
29
|
-
echo "[3/5] Verifying build artifacts..."
|
|
48
|
+
echo "==> Verifying build artifacts..."
|
|
30
49
|
if [ ! -f "dist/index.js" ]; then
|
|
31
50
|
echo "ERROR: dist/index.js not found. Build may have failed."
|
|
32
51
|
exit 1
|
|
@@ -37,35 +56,40 @@ if [ ! -f "bin/chrome-proc" ]; then
|
|
|
37
56
|
fi
|
|
38
57
|
echo "Artifacts verified."
|
|
39
58
|
|
|
40
|
-
#
|
|
41
|
-
echo ""
|
|
42
|
-
echo "[4/5] Checking if version already exists on npm..."
|
|
43
|
-
VERSION=$(node -p "require('./package.json').version")
|
|
44
|
-
if npm view "chrome-proc@$VERSION" version > /dev/null 2>&1; then
|
|
45
|
-
echo "ERROR: chrome-proc@$VERSION already exists on npm."
|
|
46
|
-
echo "Please bump the version in package.json before publishing."
|
|
47
|
-
exit 1
|
|
48
|
-
fi
|
|
49
|
-
echo "Version $VERSION is available for publish."
|
|
59
|
+
# ── Publish ─────────────────────────────────────────────────────────────────
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
echo ""
|
|
53
|
-
echo "[5/5] Publishing chrome-proc@$VERSION to npm..."
|
|
61
|
+
echo "==> Publishing chrome-proc@$NEW_VERSION to npm..."
|
|
54
62
|
npm publish --access public
|
|
55
63
|
|
|
56
|
-
#
|
|
57
|
-
|
|
58
|
-
echo "
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
# ── Commit + tag + push (after successful publish) ──────────────────────────
|
|
65
|
+
|
|
66
|
+
echo "==> Committing version bump..."
|
|
67
|
+
git add package.json package-lock.json
|
|
68
|
+
git commit -m "$NEW_VERSION"
|
|
69
|
+
|
|
70
|
+
echo "==> Generating tag description..."
|
|
71
|
+
LAST_TAG="$(git describe --tags --abbrev=0 2>/dev/null || echo "")"
|
|
72
|
+
if [[ -n "$LAST_TAG" ]]; then
|
|
73
|
+
COMMITS="$(git log "$LAST_TAG"..HEAD --oneline)"
|
|
74
|
+
PROMPT="Here are the commits since $LAST_TAG:
|
|
75
|
+
$COMMITS
|
|
76
|
+
|
|
77
|
+
Write a concise release note summary for version $NEW_VERSION suitable for an annotated git tag. Use a short paragraph or bullet points."
|
|
66
78
|
else
|
|
67
|
-
|
|
68
|
-
echo "Published version: $PUBLISHED_VERSION"
|
|
69
|
-
echo "Expected version: $VERSION"
|
|
70
|
-
echo "Check https://www.npmjs.com/package/chrome-proc for status."
|
|
79
|
+
PROMPT="Write a concise release note summary for version $NEW_VERSION suitable for an annotated git tag. This is the first release."
|
|
71
80
|
fi
|
|
81
|
+
|
|
82
|
+
TAG_MSG="$(cc-hub run -p "$PROMPT")"
|
|
83
|
+
|
|
84
|
+
echo "==> Creating annotated tag v$NEW_VERSION..."
|
|
85
|
+
TMPFILE="$(mktemp)"
|
|
86
|
+
printf '%s\n' "$TAG_MSG" > "$TMPFILE"
|
|
87
|
+
git tag -a "v$NEW_VERSION" -F "$TMPFILE"
|
|
88
|
+
rm -f "$TMPFILE"
|
|
89
|
+
|
|
90
|
+
echo "==> Pushing commit and tag to origin/main..."
|
|
91
|
+
git push origin main
|
|
92
|
+
git push origin "v$NEW_VERSION"
|
|
93
|
+
|
|
94
|
+
echo ""
|
|
95
|
+
echo "✓ Released chrome-proc@$NEW_VERSION"
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# chrome-proc
|
|
2
|
+
|
|
3
|
+
## Work Log
|
|
4
|
+
|
|
5
|
+
### 2026-05-10 17:49:52 — Session: 77ad126d-67e8-4819-9ca5-21747d7fc43b
|
|
6
|
+
- Designed and implemented cross-platform support for `chrome-proc` via a unified facade (`src/platform/*`) covering macOS, Linux, and Windows.
|
|
7
|
+
- Key abstraction: `IPlatformProvider` / `IProcessManager` interfaces with per-platform implementations for Chrome path resolution, default data directories, process listing, and signal-based killing.
|
|
8
|
+
- Refactored `process.ts` into a thin delegation layer so commands remain platform-agnostic; `launch.ts`, `localState.ts`, and `completion.ts` updated to consume the facade.
|
|
9
|
+
- Added PowerShell completion generation for Windows alongside existing bash/zsh completions.
|
|
10
|
+
- Built and verified on macOS; deployed locally via `npm link` so the global CLI runs the updated code.
|
package/README.md
CHANGED
|
@@ -1 +1,50 @@
|
|
|
1
|
+
# chrome-proc
|
|
1
2
|
|
|
3
|
+
Manage Chrome browser processes, profiles, and CDP endpoints.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g chrome-proc
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
chrome-proc <command> [options]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Commands
|
|
18
|
+
|
|
19
|
+
- `list` — List Chrome processes
|
|
20
|
+
- `-v, --verbose` — Show full command line
|
|
21
|
+
- `-j, --json` — Output as JSON lines
|
|
22
|
+
- `kill` — Kill Chrome processes
|
|
23
|
+
- `-f, --force` — Use SIGKILL instead of SIGTERM
|
|
24
|
+
- `-a, --all` — Kill helper processes too
|
|
25
|
+
- `launch` — Launch Chrome browser
|
|
26
|
+
- `--dir <dir>` — Chrome user data directory
|
|
27
|
+
- `--profile <profile>` — Chrome profile name
|
|
28
|
+
- `-d, --debug` — Enable remote debugging mode
|
|
29
|
+
- `-p, --debugging-port <port>` — Remote debugging port
|
|
30
|
+
- `profile` — Manage Chrome profiles
|
|
31
|
+
- `profile list [-j, --json]`
|
|
32
|
+
- `profile name <profile_dir> <new_name>`
|
|
33
|
+
- `profile delete <profile_dir>`
|
|
34
|
+
- `cdp` — List CDP WebSocket URLs
|
|
35
|
+
- `-j, --json` — Output as JSON lines
|
|
36
|
+
- `completion <shell>` — Generate shell completion script
|
|
37
|
+
|
|
38
|
+
## Shell Completions
|
|
39
|
+
|
|
40
|
+
Add to your shell config:
|
|
41
|
+
|
|
42
|
+
**Bash** (`~/.bashrc`):
|
|
43
|
+
```bash
|
|
44
|
+
eval "$(chrome-proc completion bash)"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Zsh** (`~/.zshrc`):
|
|
48
|
+
```zsh
|
|
49
|
+
eval "$(chrome-proc completion zsh)"
|
|
50
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.completionCommand = completionCommand;
|
|
4
|
+
const platform_1 = require("../platform");
|
|
5
|
+
const localState_1 = require("../utils/localState");
|
|
6
|
+
function completionCommand(shell) {
|
|
7
|
+
const platform = (0, platform_1.getPlatform)();
|
|
8
|
+
const shells = platform.supportedShells();
|
|
9
|
+
if (!shells.includes(shell)) {
|
|
10
|
+
console.error(`Error: unsupported shell '${shell}'. Supported: ${shells.join(", ")}`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
console.log(platform.generateCompletion(shell, getProfileDirs()));
|
|
14
|
+
}
|
|
15
|
+
function getProfileDirs() {
|
|
16
|
+
try {
|
|
17
|
+
const state = (0, localState_1.readLocalState)();
|
|
18
|
+
return Object.keys(state.profile?.info_cache ?? {});
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
}
|
package/dist/commands/launch.js
CHANGED
|
@@ -3,9 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.launchCommand = launchCommand;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
|
+
const platform_1 = require("../platform");
|
|
6
7
|
const process_1 = require("../utils/process");
|
|
7
8
|
function launchCommand(options) {
|
|
8
|
-
const chromeBin =
|
|
9
|
+
const chromeBin = (0, platform_1.getPlatform)().getChromeExecutablePath();
|
|
9
10
|
const profile = options.profile ?? process.env.CHROME_PROFILE ?? "";
|
|
10
11
|
const dataDir = options.dir ?? process.env.CHROME_DATA_DIR ?? "";
|
|
11
12
|
if (!(0, fs_1.existsSync)(chromeBin)) {
|
|
@@ -29,10 +30,9 @@ function launchCommand(options) {
|
|
|
29
30
|
console.error("Warning: --debugging-port is ignored without --debug");
|
|
30
31
|
}
|
|
31
32
|
if ((0, process_1.isChromeRunning)()) {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
console.error(`Warning: Chrome is already running (PIDs: ${existing})`);
|
|
33
|
+
const existing = (0, process_1.getChromePids)(true);
|
|
34
|
+
if (existing.length > 0) {
|
|
35
|
+
console.error(`Warning: Chrome is already running (PIDs: ${existing.join(" ")})`);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
console.log("Launching Chrome...");
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const kill_1 = require("./commands/kill");
|
|
|
7
7
|
const launch_1 = require("./commands/launch");
|
|
8
8
|
const profile_1 = require("./commands/profile");
|
|
9
9
|
const cdp_1 = require("./commands/cdp");
|
|
10
|
+
const completion_1 = require("./commands/completion");
|
|
10
11
|
const program = new commander_1.Command();
|
|
11
12
|
program
|
|
12
13
|
.name("chrome-proc")
|
|
@@ -66,4 +67,10 @@ program
|
|
|
66
67
|
.action(async (options) => {
|
|
67
68
|
await (0, cdp_1.cdpCommand)(options);
|
|
68
69
|
});
|
|
70
|
+
program
|
|
71
|
+
.command("completion <shell>")
|
|
72
|
+
.description("Generate shell completion script (bash or zsh)")
|
|
73
|
+
.action((shell) => {
|
|
74
|
+
(0, completion_1.completionCommand)(shell);
|
|
75
|
+
});
|
|
69
76
|
program.parse();
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateBashCompletion = generateBashCompletion;
|
|
4
|
+
exports.generateZshCompletion = generateZshCompletion;
|
|
5
|
+
exports.generatePowerShellCompletion = generatePowerShellCompletion;
|
|
6
|
+
function generateBashCompletion(profileDirs) {
|
|
7
|
+
const profileDirsNewline = profileDirs.join("\n");
|
|
8
|
+
return `#!/usr/bin/env bash
|
|
9
|
+
_chrome_proc() {
|
|
10
|
+
local cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
11
|
+
local prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
12
|
+
|
|
13
|
+
local commands="list kill launch profile cdp completion"
|
|
14
|
+
local profile_subcommands="list name delete"
|
|
15
|
+
|
|
16
|
+
local list_opts="--verbose --json"
|
|
17
|
+
local kill_opts="--force --all"
|
|
18
|
+
local launch_opts="--dir --profile --debug --debugging-port"
|
|
19
|
+
local profile_list_opts="--json"
|
|
20
|
+
local cdp_opts="--json"
|
|
21
|
+
local completion_shells="bash zsh powershell"
|
|
22
|
+
|
|
23
|
+
local profile_dirs='
|
|
24
|
+
${profileDirsNewline}
|
|
25
|
+
'
|
|
26
|
+
|
|
27
|
+
local cmd=""
|
|
28
|
+
local subcmd=""
|
|
29
|
+
local i=1
|
|
30
|
+
|
|
31
|
+
while [[ $i -lt $COMP_CWORD ]]; do
|
|
32
|
+
local word="\${COMP_WORDS[$i]}"
|
|
33
|
+
if [[ "$word" != -* ]]; then
|
|
34
|
+
if [[ -z "$cmd" ]]; then
|
|
35
|
+
cmd="$word"
|
|
36
|
+
elif [[ "$cmd" == "profile" && -z "$subcmd" ]]; then
|
|
37
|
+
subcmd="$word"
|
|
38
|
+
break
|
|
39
|
+
else
|
|
40
|
+
break
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
((i++))
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
if [[ -z "$cmd" ]]; then
|
|
47
|
+
if [[ "$cur" == -* ]]; then
|
|
48
|
+
COMPREPLY=()
|
|
49
|
+
else
|
|
50
|
+
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
|
51
|
+
fi
|
|
52
|
+
return
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
case "$cmd" in
|
|
56
|
+
list)
|
|
57
|
+
COMPREPLY=( $(compgen -W "$list_opts" -- "$cur") )
|
|
58
|
+
;;
|
|
59
|
+
kill)
|
|
60
|
+
COMPREPLY=( $(compgen -W "$kill_opts" -- "$cur") )
|
|
61
|
+
;;
|
|
62
|
+
launch)
|
|
63
|
+
COMPREPLY=( $(compgen -W "$launch_opts" -- "$cur") )
|
|
64
|
+
;;
|
|
65
|
+
cdp)
|
|
66
|
+
COMPREPLY=( $(compgen -W "$cdp_opts" -- "$cur") )
|
|
67
|
+
;;
|
|
68
|
+
completion)
|
|
69
|
+
COMPREPLY=( $(compgen -W "$completion_shells" -- "$cur") )
|
|
70
|
+
;;
|
|
71
|
+
profile)
|
|
72
|
+
if [[ -z "$subcmd" ]]; then
|
|
73
|
+
if [[ "$cur" == -* ]]; then
|
|
74
|
+
COMPREPLY=()
|
|
75
|
+
else
|
|
76
|
+
COMPREPLY=( $(compgen -W "$profile_subcommands" -- "$cur") )
|
|
77
|
+
fi
|
|
78
|
+
else
|
|
79
|
+
case "$subcmd" in
|
|
80
|
+
list)
|
|
81
|
+
COMPREPLY=( $(compgen -W "$profile_list_opts" -- "$cur") )
|
|
82
|
+
;;
|
|
83
|
+
name|delete)
|
|
84
|
+
if [[ -n "$profile_dirs" && ( -z "$prev" || "$prev" == "name" || "$prev" == "delete" ) ]]; then
|
|
85
|
+
local OLD_IFS="$IFS"
|
|
86
|
+
IFS=$'\n'
|
|
87
|
+
COMPREPLY=( $(compgen -W "$profile_dirs" -- "$cur") )
|
|
88
|
+
IFS="$OLD_IFS"
|
|
89
|
+
else
|
|
90
|
+
COMPREPLY=()
|
|
91
|
+
fi
|
|
92
|
+
;;
|
|
93
|
+
*)
|
|
94
|
+
COMPREPLY=()
|
|
95
|
+
;;
|
|
96
|
+
esac
|
|
97
|
+
fi
|
|
98
|
+
;;
|
|
99
|
+
*)
|
|
100
|
+
COMPREPLY=()
|
|
101
|
+
;;
|
|
102
|
+
esac
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
complete -F _chrome_proc chrome-proc
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
function generateZshCompletion(profileDirs) {
|
|
109
|
+
const profileDirsNewline = profileDirs.join("\n");
|
|
110
|
+
return `#!/usr/bin/env zsh
|
|
111
|
+
#compdef chrome-proc
|
|
112
|
+
|
|
113
|
+
_chrome_proc() {
|
|
114
|
+
local curcontext="$curcontext" state line
|
|
115
|
+
typeset -A opt_args
|
|
116
|
+
|
|
117
|
+
local profile_dirs='
|
|
118
|
+
${profileDirsNewline}
|
|
119
|
+
'
|
|
120
|
+
|
|
121
|
+
_arguments -C \\
|
|
122
|
+
'1: :->command' \\
|
|
123
|
+
'2: :->subcommand' \\
|
|
124
|
+
'*: :->args'
|
|
125
|
+
|
|
126
|
+
case "$state" in
|
|
127
|
+
command)
|
|
128
|
+
local commands=(list kill launch profile cdp completion)
|
|
129
|
+
_describe -t commands 'chrome-proc command' commands
|
|
130
|
+
;;
|
|
131
|
+
subcommand)
|
|
132
|
+
case "$line[1]" in
|
|
133
|
+
list)
|
|
134
|
+
local opts=('--verbose:Show full command line' '--json:Output as JSON lines')
|
|
135
|
+
_describe -t options 'list options' opts
|
|
136
|
+
;;
|
|
137
|
+
kill)
|
|
138
|
+
local opts=('--force:Use SIGKILL instead of SIGTERM' '--all:Kill helper processes too')
|
|
139
|
+
_describe -t options 'kill options' opts
|
|
140
|
+
;;
|
|
141
|
+
launch)
|
|
142
|
+
local opts=('--dir:Chrome user data directory' '--profile:Chrome profile name' '--debug:Enable remote debugging mode' '--debugging-port:Remote debugging port')
|
|
143
|
+
_describe -t options 'launch options' opts
|
|
144
|
+
;;
|
|
145
|
+
cdp)
|
|
146
|
+
local opts=('--json:Output as JSON lines')
|
|
147
|
+
_describe -t options 'cdp options' opts
|
|
148
|
+
;;
|
|
149
|
+
completion)
|
|
150
|
+
local shells=(bash zsh powershell)
|
|
151
|
+
_describe -t shells 'shell' shells
|
|
152
|
+
;;
|
|
153
|
+
profile)
|
|
154
|
+
local subcmds=(list name delete)
|
|
155
|
+
_describe -t subcommands 'profile subcommand' subcmds
|
|
156
|
+
;;
|
|
157
|
+
esac
|
|
158
|
+
;;
|
|
159
|
+
args)
|
|
160
|
+
case "$line[1]" in
|
|
161
|
+
list)
|
|
162
|
+
local opts=('--verbose:Show full command line' '--json:Output as JSON lines')
|
|
163
|
+
_describe -t options 'list options' opts
|
|
164
|
+
;;
|
|
165
|
+
kill)
|
|
166
|
+
local opts=('--force:Use SIGKILL instead of SIGTERM' '--all:Kill helper processes too')
|
|
167
|
+
_describe -t options 'kill options' opts
|
|
168
|
+
;;
|
|
169
|
+
launch)
|
|
170
|
+
local opts=('--dir:Chrome user data directory' '--profile:Chrome profile name' '--debug:Enable remote debugging mode' '--debugging-port:Remote debugging port')
|
|
171
|
+
_describe -t options 'launch options' opts
|
|
172
|
+
;;
|
|
173
|
+
cdp)
|
|
174
|
+
local opts=('--json:Output as JSON lines')
|
|
175
|
+
_describe -t options 'cdp options' opts
|
|
176
|
+
;;
|
|
177
|
+
profile)
|
|
178
|
+
case "$line[2]" in
|
|
179
|
+
list)
|
|
180
|
+
local opts=('--json:Output as JSON lines')
|
|
181
|
+
_describe -t options 'profile list options' opts
|
|
182
|
+
;;
|
|
183
|
+
name|delete)
|
|
184
|
+
if [[ -n "$profile_dirs" ]]; then
|
|
185
|
+
local dirs=(\${(f)profile_dirs})
|
|
186
|
+
_describe -t directories 'profile directory' dirs
|
|
187
|
+
fi
|
|
188
|
+
;;
|
|
189
|
+
esac
|
|
190
|
+
;;
|
|
191
|
+
esac
|
|
192
|
+
;;
|
|
193
|
+
esac
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
_chrome_proc "$@"
|
|
197
|
+
`;
|
|
198
|
+
}
|
|
199
|
+
function generatePowerShellCompletion(profileDirs) {
|
|
200
|
+
const profileDirsQuoted = profileDirs.map((d) => `'${d.replace(/'/g, "''")}'`).join(", ");
|
|
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
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.darwinProvider = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const os_1 = require("os");
|
|
6
|
+
const completion_helpers_1 = require("./completion-helpers");
|
|
7
|
+
const CHROME_BIN = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
|
|
8
|
+
function getChromePids(exact = false) {
|
|
9
|
+
try {
|
|
10
|
+
const flag = exact ? "-x" : "-f";
|
|
11
|
+
const output = (0, child_process_1.execSync)(`pgrep ${flag} "Google Chrome"`, { encoding: "utf-8" });
|
|
12
|
+
return output
|
|
13
|
+
.trim()
|
|
14
|
+
.split("\n")
|
|
15
|
+
.filter((line) => line.trim() !== "")
|
|
16
|
+
.map((line) => parseInt(line.trim(), 10))
|
|
17
|
+
.filter((pid) => !isNaN(pid));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function getProcessArgs(pid) {
|
|
24
|
+
try {
|
|
25
|
+
return (0, child_process_1.execSync)(`ps -p "${pid}" -o args=`, { encoding: "utf-8" }).trim();
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return "?";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function getProcessName(pid) {
|
|
32
|
+
try {
|
|
33
|
+
return (0, child_process_1.execSync)(`ps -p "${pid}" -o comm=`, { encoding: "utf-8" }).trim();
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return "?";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function killPid(pid, signal) {
|
|
40
|
+
try {
|
|
41
|
+
(0, child_process_1.execSync)(`/bin/kill -${signal} "${pid}"`, { stdio: "pipe" });
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function isChromeRunning() {
|
|
49
|
+
return getChromePids(true).length > 0;
|
|
50
|
+
}
|
|
51
|
+
const processManager = {
|
|
52
|
+
getChromePids,
|
|
53
|
+
getProcessArgs,
|
|
54
|
+
getProcessName,
|
|
55
|
+
killPid,
|
|
56
|
+
isChromeRunning,
|
|
57
|
+
};
|
|
58
|
+
exports.darwinProvider = {
|
|
59
|
+
name: "darwin",
|
|
60
|
+
getChromeExecutablePath() {
|
|
61
|
+
return CHROME_BIN;
|
|
62
|
+
},
|
|
63
|
+
getDefaultChromeDataDir() {
|
|
64
|
+
return `${(0, os_1.homedir)()}/Library/Application Support/Google/Chrome`;
|
|
65
|
+
},
|
|
66
|
+
getProcessManager() {
|
|
67
|
+
return processManager;
|
|
68
|
+
},
|
|
69
|
+
supportedShells() {
|
|
70
|
+
return ["bash", "zsh"];
|
|
71
|
+
},
|
|
72
|
+
generateCompletion(shell, profileDirs) {
|
|
73
|
+
switch (shell) {
|
|
74
|
+
case "bash":
|
|
75
|
+
return (0, completion_helpers_1.generateBashCompletion)(profileDirs);
|
|
76
|
+
case "zsh":
|
|
77
|
+
return (0, completion_helpers_1.generateZshCompletion)(profileDirs);
|
|
78
|
+
default:
|
|
79
|
+
throw new Error(`Unsupported shell: ${shell}`);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPlatform = getPlatform;
|
|
4
|
+
const darwin_1 = require("./darwin");
|
|
5
|
+
const linux_1 = require("./linux");
|
|
6
|
+
const win32_1 = require("./win32");
|
|
7
|
+
const providers = {
|
|
8
|
+
darwin: darwin_1.darwinProvider,
|
|
9
|
+
linux: linux_1.linuxProvider,
|
|
10
|
+
win32: win32_1.win32Provider,
|
|
11
|
+
};
|
|
12
|
+
function getPlatform() {
|
|
13
|
+
const p = providers[process.platform];
|
|
14
|
+
if (!p) {
|
|
15
|
+
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
16
|
+
}
|
|
17
|
+
return p;
|
|
18
|
+
}
|