shellscripts 0.23.1__py3-none-any.whl
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.
- shell_scripts/__init__.py +5 -0
- shell_scripts/__main__.py +5 -0
- shell_scripts/commands/__init__.py +81 -0
- shell_scripts/commands/_dc_common.py +138 -0
- shell_scripts/commands/ai_install.py +453 -0
- shell_scripts/commands/bin_links.py +78 -0
- shell_scripts/commands/claude.py +56 -0
- shell_scripts/commands/clean.py +98 -0
- shell_scripts/commands/codex.py +107 -0
- shell_scripts/commands/copilot.py +54 -0
- shell_scripts/commands/dicom2jpg.py +98 -0
- shell_scripts/commands/dicomviewer.py +83 -0
- shell_scripts/commands/diff_cmd.py +50 -0
- shell_scripts/commands/doxygen_cmd.py +159 -0
- shell_scripts/commands/edit_cmd.py +50 -0
- shell_scripts/commands/gemini.py +54 -0
- shell_scripts/commands/kiro.py +54 -0
- shell_scripts/commands/opencode.py +54 -0
- shell_scripts/commands/pdf_crop.py +520 -0
- shell_scripts/commands/pdf_merge.py +180 -0
- shell_scripts/commands/pdf_split_by_format.py +243 -0
- shell_scripts/commands/pdf_split_by_toc.py +197 -0
- shell_scripts/commands/pdf_tiler_090.py +61 -0
- shell_scripts/commands/pdf_tiler_100.py +61 -0
- shell_scripts/commands/pdf_toc_clean.py +175 -0
- shell_scripts/commands/pi.py +61 -0
- shell_scripts/commands/req_cmd.py +362 -0
- shell_scripts/commands/tests_cmd.py +87 -0
- shell_scripts/commands/ubuntu_dark_theme.py +64 -0
- shell_scripts/commands/venv_cmd.py +82 -0
- shell_scripts/commands/video2h264.py +89 -0
- shell_scripts/commands/video2h265.py +87 -0
- shell_scripts/commands/view_cmd.py +50 -0
- shell_scripts/commands/vscode_cmd.py +42 -0
- shell_scripts/commands/vsinsider_cmd.py +42 -0
- shell_scripts/config.py +328 -0
- shell_scripts/core.py +324 -0
- shell_scripts/utils.py +455 -0
- shell_scripts/version_check.py +323 -0
- shellscripts-0.23.1.dist-info/METADATA +310 -0
- shellscripts-0.23.1.dist-info/RECORD +45 -0
- shellscripts-0.23.1.dist-info/WHEEL +5 -0
- shellscripts-0.23.1.dist-info/entry_points.txt +3 -0
- shellscripts-0.23.1.dist-info/licenses/LICENSE +674 -0
- shellscripts-0.23.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""@brief GNOME/Qt dark-theme configurator.
|
|
3
|
+
|
|
4
|
+
@details Conditionally executes available theme helper executables and validates
|
|
5
|
+
each executable immediately before invocation.
|
|
6
|
+
@satisfies REQ-022, REQ-055, REQ-056
|
|
7
|
+
"""
|
|
8
|
+
import subprocess
|
|
9
|
+
|
|
10
|
+
from shell_scripts.utils import print_info, command_exists, print_error, require_commands
|
|
11
|
+
|
|
12
|
+
PROGRAM = "shellscripts"
|
|
13
|
+
DESCRIPTION = "Apply GNOME and Qt dark theme settings."
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def print_help(version):
|
|
17
|
+
print(f"Usage: {PROGRAM} ubuntu-dark-theme ({version})")
|
|
18
|
+
print()
|
|
19
|
+
print("ubuntu-dark-theme options:")
|
|
20
|
+
print(" --help - Show this help message.")
|
|
21
|
+
print()
|
|
22
|
+
print("Applies Adwaita-dark GTK theme via gsettings, then launches")
|
|
23
|
+
print("gtk-chtheme, qt5ct, and qt6ct for further customization.")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def run(args):
|
|
27
|
+
"""@brief Apply dark-theme settings with conditional executable checks.
|
|
28
|
+
|
|
29
|
+
@details For each available theme tool (`gsettings`, `gtk-chtheme`, `qt5ct`,
|
|
30
|
+
`qt6ct`), validates command executability before subprocess invocation.
|
|
31
|
+
@param args {list[str]} Unused command arguments.
|
|
32
|
+
@return {int} `0` on completion.
|
|
33
|
+
@satisfies REQ-022, REQ-055, REQ-056
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
print_info("Configure Adwaita-dark")
|
|
37
|
+
|
|
38
|
+
if command_exists("gsettings"):
|
|
39
|
+
require_commands("gsettings")
|
|
40
|
+
subprocess.run([
|
|
41
|
+
"gsettings", "set", "org.gnome.desktop.interface",
|
|
42
|
+
"gtk-theme", "Adwaita-dark",
|
|
43
|
+
])
|
|
44
|
+
else:
|
|
45
|
+
print_error("gsettings not found.")
|
|
46
|
+
|
|
47
|
+
if command_exists("gtk-chtheme"):
|
|
48
|
+
require_commands("gtk-chtheme")
|
|
49
|
+
subprocess.run(["gtk-chtheme"])
|
|
50
|
+
|
|
51
|
+
import os
|
|
52
|
+
env5 = os.environ.copy()
|
|
53
|
+
env5["QT_QPA_PLATFORMTHEME"] = "qt5ct"
|
|
54
|
+
if command_exists("qt5ct"):
|
|
55
|
+
require_commands("qt5ct")
|
|
56
|
+
subprocess.run(["qt5ct"], env=env5)
|
|
57
|
+
|
|
58
|
+
env6 = os.environ.copy()
|
|
59
|
+
env6["QT_QPA_PLATFORMTHEME"] = "qt6ct"
|
|
60
|
+
if command_exists("qt6ct"):
|
|
61
|
+
require_commands("qt6ct")
|
|
62
|
+
subprocess.run(["qt6ct"], env=env6)
|
|
63
|
+
|
|
64
|
+
return 0
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""@brief Virtual-environment recreation workflow with optional dependency install.
|
|
3
|
+
|
|
4
|
+
@details Ensures required Python executables are available for the active flow
|
|
5
|
+
before creating `.venv` and optionally running `pip install -r requirements.txt`.
|
|
6
|
+
@satisfies REQ-038, REQ-055, REQ-056
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
import shutil
|
|
12
|
+
import subprocess
|
|
13
|
+
|
|
14
|
+
from shell_scripts.utils import (
|
|
15
|
+
require_project_root,
|
|
16
|
+
print_info,
|
|
17
|
+
print_success,
|
|
18
|
+
require_commands,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
PROGRAM = "shellscripts"
|
|
22
|
+
DESCRIPTION = "Create or recreate Python virtual environment with requirements."
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def print_help(version):
|
|
26
|
+
print(f"Usage: {PROGRAM} venv [options] ({version})")
|
|
27
|
+
print()
|
|
28
|
+
print("venv options:")
|
|
29
|
+
print(" --force - Force recreation even if .venv exists.")
|
|
30
|
+
print(" --help - Show this help message.")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def run(args):
|
|
34
|
+
"""@brief Recreate virtual environment with executable pre-checks.
|
|
35
|
+
|
|
36
|
+
@details Validates `sys.executable` and flow-conditional `pip` executable
|
|
37
|
+
before corresponding subprocess invocations.
|
|
38
|
+
@param args {list[str]} Command arguments (`--force` accepted).
|
|
39
|
+
@return {int} `0` on successful execution.
|
|
40
|
+
@satisfies REQ-038, REQ-055, REQ-056
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
force = "--force" in args
|
|
44
|
+
require_commands(sys.executable)
|
|
45
|
+
project_root = require_project_root()
|
|
46
|
+
os.chdir(project_root)
|
|
47
|
+
|
|
48
|
+
print(f"Run on path: {project_root}")
|
|
49
|
+
|
|
50
|
+
venv_dir = project_root / ".venv"
|
|
51
|
+
|
|
52
|
+
if venv_dir.is_dir():
|
|
53
|
+
if force:
|
|
54
|
+
print_info("Removing old virtual environment...")
|
|
55
|
+
shutil.rmtree(venv_dir)
|
|
56
|
+
else:
|
|
57
|
+
print_info("Removing old virtual environment...")
|
|
58
|
+
shutil.rmtree(venv_dir)
|
|
59
|
+
|
|
60
|
+
print_info("Creating virtual environment...")
|
|
61
|
+
subprocess.run(
|
|
62
|
+
[sys.executable, "-m", "venv", str(venv_dir)],
|
|
63
|
+
check=True,
|
|
64
|
+
)
|
|
65
|
+
print_success("Virtual environment created.")
|
|
66
|
+
|
|
67
|
+
pip = str(venv_dir / "bin" / "pip")
|
|
68
|
+
req_file = project_root / "requirements.txt"
|
|
69
|
+
|
|
70
|
+
if req_file.exists():
|
|
71
|
+
require_commands(pip)
|
|
72
|
+
print_info("Installing python requirements...")
|
|
73
|
+
subprocess.run(
|
|
74
|
+
[pip, "install", "-r", str(req_file)],
|
|
75
|
+
stdout=subprocess.DEVNULL,
|
|
76
|
+
check=True,
|
|
77
|
+
)
|
|
78
|
+
print_success("Requirements installed.")
|
|
79
|
+
else:
|
|
80
|
+
print_info("No requirements.txt found, skipping pip install.")
|
|
81
|
+
|
|
82
|
+
return 0
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""@brief FFmpeg-based H.264 MP4 transcoder command.
|
|
3
|
+
|
|
4
|
+
@details Converts one input video to H.264/AAC MP4 using fixed FFmpeg
|
|
5
|
+
arguments required by CLI contract. Output path is generated by appending
|
|
6
|
+
`.mp4` to the input filename and preserving the input directory.
|
|
7
|
+
@satisfies REQ-057, REQ-055, REQ-056, REQ-064
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import subprocess
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from shell_scripts.utils import print_error, require_commands
|
|
14
|
+
|
|
15
|
+
## @var PROGRAM
|
|
16
|
+
# @brief CLI program identifier used in usage text.
|
|
17
|
+
# @satisfies DES-008
|
|
18
|
+
PROGRAM = "shellscripts"
|
|
19
|
+
## @var DESCRIPTION
|
|
20
|
+
# @brief Command description exposed in global help index.
|
|
21
|
+
# @satisfies PRJ-002, DES-008, REQ-057
|
|
22
|
+
DESCRIPTION = "Convert one video to H.264 MP4 via ffmpeg."
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def print_help(version):
|
|
26
|
+
"""@brief Print command usage for `video2h264`.
|
|
27
|
+
|
|
28
|
+
@details Emits deterministic help text describing required positional input
|
|
29
|
+
and output naming semantics.
|
|
30
|
+
@param version {str} CLI version string for usage suffix.
|
|
31
|
+
@return {None} Writes help text to stdout.
|
|
32
|
+
@satisfies DES-008, REQ-057
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
print(f"Usage: {PROGRAM} video2h264 <input-video> ({version})")
|
|
36
|
+
print()
|
|
37
|
+
print("video2h264 options:")
|
|
38
|
+
print(" <input-video> - Input video file path (required).")
|
|
39
|
+
print(" --help - Show this help message.")
|
|
40
|
+
print()
|
|
41
|
+
print("Output path is generated as <input-video>.mp4 in the input directory.")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def run(args):
|
|
45
|
+
"""@brief Execute H.264 transcode command with fixed FFmpeg parameters.
|
|
46
|
+
|
|
47
|
+
@details Validates input argument presence and file existence, then executes
|
|
48
|
+
`ffmpeg` using required libx264 profile, level, CRF, pixel format, and AAC
|
|
49
|
+
audio bitrate options through blocking subprocess invocation.
|
|
50
|
+
@param args {list[str]} Expected single positional input-video path.
|
|
51
|
+
@return {int} `1` on argument/validation failure; child return code otherwise.
|
|
52
|
+
@satisfies REQ-057, REQ-055, REQ-056, REQ-064
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
if len(args) != 1 or args[0].startswith("-"):
|
|
56
|
+
print_error("Input video file required.")
|
|
57
|
+
print_help("")
|
|
58
|
+
return 1
|
|
59
|
+
|
|
60
|
+
input_file = Path(args[0])
|
|
61
|
+
if not input_file.is_file():
|
|
62
|
+
print_error(f"File not found: {input_file}")
|
|
63
|
+
return 1
|
|
64
|
+
|
|
65
|
+
output_file = input_file.parent / f"{input_file.name}.mp4"
|
|
66
|
+
cmd = [
|
|
67
|
+
"ffmpeg",
|
|
68
|
+
"-i",
|
|
69
|
+
str(input_file),
|
|
70
|
+
"-c:v",
|
|
71
|
+
"libx264",
|
|
72
|
+
"-profile:v",
|
|
73
|
+
"high",
|
|
74
|
+
"-level",
|
|
75
|
+
"4.1",
|
|
76
|
+
"-crf",
|
|
77
|
+
"20",
|
|
78
|
+
"-pix_fmt",
|
|
79
|
+
"yuv420p",
|
|
80
|
+
"-c:a",
|
|
81
|
+
"aac",
|
|
82
|
+
"-b:a",
|
|
83
|
+
"192k",
|
|
84
|
+
str(output_file),
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
require_commands(cmd[0])
|
|
88
|
+
result = subprocess.run(cmd)
|
|
89
|
+
return result.returncode
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""@brief FFmpeg-based H.265 MP4 transcoder command.
|
|
3
|
+
|
|
4
|
+
@details Converts one input video to H.265/AAC MP4 using fixed FFmpeg
|
|
5
|
+
arguments required by CLI contract. Output path is generated by appending
|
|
6
|
+
`.mp4` to the input filename and preserving the input directory.
|
|
7
|
+
@satisfies REQ-058, REQ-055, REQ-056, REQ-064
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import subprocess
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from shell_scripts.utils import print_error, require_commands
|
|
14
|
+
|
|
15
|
+
## @var PROGRAM
|
|
16
|
+
# @brief CLI program identifier used in usage text.
|
|
17
|
+
# @satisfies DES-008
|
|
18
|
+
PROGRAM = "shellscripts"
|
|
19
|
+
## @var DESCRIPTION
|
|
20
|
+
# @brief Command description exposed in global help index.
|
|
21
|
+
# @satisfies PRJ-002, DES-008, REQ-058
|
|
22
|
+
DESCRIPTION = "Convert one video to H.265 MP4 via ffmpeg."
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def print_help(version):
|
|
26
|
+
"""@brief Print command usage for `video2h265`.
|
|
27
|
+
|
|
28
|
+
@details Emits deterministic help text describing required positional input
|
|
29
|
+
and output naming semantics.
|
|
30
|
+
@param version {str} CLI version string for usage suffix.
|
|
31
|
+
@return {None} Writes help text to stdout.
|
|
32
|
+
@satisfies DES-008, REQ-058
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
print(f"Usage: {PROGRAM} video2h265 <input-video> ({version})")
|
|
36
|
+
print()
|
|
37
|
+
print("video2h265 options:")
|
|
38
|
+
print(" <input-video> - Input video file path (required).")
|
|
39
|
+
print(" --help - Show this help message.")
|
|
40
|
+
print()
|
|
41
|
+
print("Output path is generated as <input-video>.mp4 in the input directory.")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def run(args):
|
|
45
|
+
"""@brief Execute H.265 transcode command with fixed FFmpeg parameters.
|
|
46
|
+
|
|
47
|
+
@details Validates input argument presence and file existence, then executes
|
|
48
|
+
`ffmpeg` using required libx265 CRF, codec tag, pixel format, and AAC audio
|
|
49
|
+
bitrate options through blocking subprocess invocation.
|
|
50
|
+
@param args {list[str]} Expected single positional input-video path.
|
|
51
|
+
@return {int} `1` on argument/validation failure; child return code otherwise.
|
|
52
|
+
@satisfies REQ-058, REQ-055, REQ-056, REQ-064
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
if len(args) != 1 or args[0].startswith("-"):
|
|
56
|
+
print_error("Input video file required.")
|
|
57
|
+
print_help("")
|
|
58
|
+
return 1
|
|
59
|
+
|
|
60
|
+
input_file = Path(args[0])
|
|
61
|
+
if not input_file.is_file():
|
|
62
|
+
print_error(f"File not found: {input_file}")
|
|
63
|
+
return 1
|
|
64
|
+
|
|
65
|
+
output_file = input_file.parent / f"{input_file.name}.mp4"
|
|
66
|
+
cmd = [
|
|
67
|
+
"ffmpeg",
|
|
68
|
+
"-i",
|
|
69
|
+
str(input_file),
|
|
70
|
+
"-c:v",
|
|
71
|
+
"libx265",
|
|
72
|
+
"-crf",
|
|
73
|
+
"23",
|
|
74
|
+
"-tag:v",
|
|
75
|
+
"hvc1",
|
|
76
|
+
"-pix_fmt",
|
|
77
|
+
"yuv420p",
|
|
78
|
+
"-c:a",
|
|
79
|
+
"aac",
|
|
80
|
+
"-b:a",
|
|
81
|
+
"192k",
|
|
82
|
+
str(output_file),
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
require_commands(cmd[0])
|
|
86
|
+
result = subprocess.run(cmd)
|
|
87
|
+
return result.returncode
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""@brief MIME-based view command wrapper.
|
|
3
|
+
|
|
4
|
+
@details Exposes the `view` CLI command and delegates category-based executable
|
|
5
|
+
selection to shared `_dc_common.dispatch` logic.
|
|
6
|
+
@satisfies PRJ-003, DES-007, REQ-023, REQ-024
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
from shell_scripts.config import get_dispatch_profile
|
|
12
|
+
from shell_scripts.commands._dc_common import dispatch
|
|
13
|
+
|
|
14
|
+
PROGRAM = "shellscripts"
|
|
15
|
+
DESCRIPTION = "File viewer dispatcher by MIME type."
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def print_help(version):
|
|
19
|
+
"""@brief Render command help for `view`.
|
|
20
|
+
|
|
21
|
+
@details Prints usage, required file argument semantics, and argument
|
|
22
|
+
forwarding contract for the selected external viewer executable.
|
|
23
|
+
@param version {str} Version string appended in usage output.
|
|
24
|
+
@return {None} Writes help text to stdout.
|
|
25
|
+
@satisfies DES-008
|
|
26
|
+
"""
|
|
27
|
+
print(f"Usage: {PROGRAM} view <file> [args...] ({version})")
|
|
28
|
+
print()
|
|
29
|
+
print("view options:")
|
|
30
|
+
print(" <file> - File to view (required).")
|
|
31
|
+
print(" Additional arguments are passed to the selected viewer.")
|
|
32
|
+
print(" --help - Show this help message.")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def run(args):
|
|
36
|
+
"""@brief Execute MIME-routed view dispatch.
|
|
37
|
+
|
|
38
|
+
@details Validates that a file argument exists; on missing argument prints
|
|
39
|
+
error plus help and returns status code `2`; otherwise resolves runtime
|
|
40
|
+
dispatch profile and delegates by file category through shared `_dc_common`.
|
|
41
|
+
@param args {list[str]} CLI args where `args[0]` is file path.
|
|
42
|
+
@return {int} Return code `2` on missing file; otherwise delegated dispatch result.
|
|
43
|
+
@satisfies REQ-023, REQ-024
|
|
44
|
+
"""
|
|
45
|
+
if not args:
|
|
46
|
+
print("Error: file argument required.", file=sys.stderr)
|
|
47
|
+
print_help("")
|
|
48
|
+
return 2
|
|
49
|
+
category_cmds, fallback = get_dispatch_profile("view")
|
|
50
|
+
return dispatch(category_cmds, fallback, args[0], args[1:])
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""@brief VS Code launcher in project context with Codex integration.
|
|
3
|
+
|
|
4
|
+
@details Resolves project root, configures `CODEX_HOME`, validates VS Code
|
|
5
|
+
executable availability, and performs blocking subprocess invocation.
|
|
6
|
+
@satisfies REQ-020, REQ-021, REQ-055, REQ-056, REQ-064
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import subprocess
|
|
11
|
+
|
|
12
|
+
from shell_scripts.utils import require_project_root, require_commands
|
|
13
|
+
|
|
14
|
+
PROGRAM = "shellscripts"
|
|
15
|
+
DESCRIPTION = "Open VS Code in the project root with Codex integration."
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def print_help(version):
|
|
19
|
+
print(f"Usage: {PROGRAM} vscode [args...] ({version})")
|
|
20
|
+
print()
|
|
21
|
+
print("vscode options:")
|
|
22
|
+
print(" [args...] - Arguments passed through to VS Code.")
|
|
23
|
+
print(" --help - Show this help message.")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def run(args):
|
|
27
|
+
"""@brief Launch VS Code after executable validation.
|
|
28
|
+
|
|
29
|
+
@details Sets `CODEX_HOME`, validates executable availability for VS Code
|
|
30
|
+
binary, and executes the command with project-root working directory.
|
|
31
|
+
@param args {list[str]} Additional CLI args forwarded to VS Code.
|
|
32
|
+
@return {int} Child process return code.
|
|
33
|
+
@satisfies REQ-020, REQ-021, REQ-055, REQ-056, REQ-064
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
project_root = require_project_root()
|
|
37
|
+
codex_home = str(project_root / ".codex")
|
|
38
|
+
os.environ["CODEX_HOME"] = codex_home
|
|
39
|
+
cmd = ["/usr/share/code/bin/code"] + args + [str(project_root)]
|
|
40
|
+
require_commands(cmd[0])
|
|
41
|
+
result = subprocess.run(cmd, cwd=project_root)
|
|
42
|
+
return result.returncode
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""@brief VS Code Insiders launcher in project context with Codex integration.
|
|
3
|
+
|
|
4
|
+
@details Resolves project root, configures `CODEX_HOME`, validates VS Code
|
|
5
|
+
Insiders executable availability, and performs blocking subprocess invocation.
|
|
6
|
+
@satisfies REQ-020, REQ-021, REQ-055, REQ-056, REQ-064
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import subprocess
|
|
11
|
+
|
|
12
|
+
from shell_scripts.utils import require_project_root, require_commands
|
|
13
|
+
|
|
14
|
+
PROGRAM = "shellscripts"
|
|
15
|
+
DESCRIPTION = "Open VS Code Insiders in the project root with Codex integration."
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def print_help(version):
|
|
19
|
+
print(f"Usage: {PROGRAM} vsinsider [args...] ({version})")
|
|
20
|
+
print()
|
|
21
|
+
print("vsinsider options:")
|
|
22
|
+
print(" [args...] - Arguments passed through to VS Code Insiders.")
|
|
23
|
+
print(" --help - Show this help message.")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def run(args):
|
|
27
|
+
"""@brief Launch VS Code Insiders after executable validation.
|
|
28
|
+
|
|
29
|
+
@details Sets `CODEX_HOME`, validates executable availability for VS Code
|
|
30
|
+
Insiders binary, and executes the command with project-root working directory.
|
|
31
|
+
@param args {list[str]} Additional CLI args forwarded to VS Code Insiders.
|
|
32
|
+
@return {int} Child process return code.
|
|
33
|
+
@satisfies REQ-020, REQ-021, REQ-055, REQ-056, REQ-064
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
project_root = require_project_root()
|
|
37
|
+
codex_home = str(project_root / ".codex")
|
|
38
|
+
os.environ["CODEX_HOME"] = codex_home
|
|
39
|
+
cmd = ["/usr/share/code-insiders/bin/code-insiders"] + args + [str(project_root)]
|
|
40
|
+
require_commands(cmd[0])
|
|
41
|
+
result = subprocess.run(cmd, cwd=project_root)
|
|
42
|
+
return result.returncode
|