vibe-coding-master 0.7.17 → 0.7.19

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.
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>VibeCodingMaster</title>
7
- <script type="module" crossorigin src="/assets/index-CStWyouh.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-CDkDHrWQ.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-Ci7z8tW3.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-coding-master",
3
- "version": "0.7.17",
3
+ "version": "0.7.19",
4
4
  "description": "Local GUI session cockpit for Claude Code role sessions.",
5
5
  "type": "module",
6
6
  "files": [
@@ -4,6 +4,9 @@
4
4
  Usage:
5
5
  .ai/tools/run-long-check [--timeout <duration>] -- <command> [args...]
6
6
 
7
+ Pass the validation executable and its arguments directly. Shell command-string
8
+ wrappers are rejected because they can hide the validation command's exit code.
9
+
7
10
  The command runs in a detached worker process group. The worker itself
8
11
  enforces the job ceiling (--timeout, max 60m) and a supervision lease: when
9
12
  no foreground watcher renews .ai/vcm/jobs/<job-id>/lease, the worker kills
@@ -28,6 +31,7 @@ QUEUED_STALE_SECONDS = 60
28
31
  ACTIVE_STATUSES = {"queued", "starting", "running"}
29
32
  DEFAULT_LEASE_START_GRACE_SECONDS = 300
30
33
  DEFAULT_LEASE_RENEW_GRACE_SECONDS = 120
34
+ SHELL_EXECUTABLES = {"sh", "bash", "zsh", "dash", "ksh", "fish", "csh", "tcsh"}
31
35
 
32
36
 
33
37
  def root_dir() -> Path:
@@ -83,6 +87,25 @@ def job_id() -> str:
83
87
  return f"{timestamp}-{uuid.uuid4().hex[:8]}"
84
88
 
85
89
 
90
+ def shell_command_wrapper(command: list[str]) -> str | None:
91
+ if not command:
92
+ return None
93
+
94
+ candidates = range(len(command)) if Path(command[0]).name == "env" else range(1)
95
+ for index in candidates:
96
+ executable = Path(command[index]).name
97
+ if executable not in SHELL_EXECUTABLES:
98
+ continue
99
+ if any(
100
+ option.startswith("-")
101
+ and not option.startswith("--")
102
+ and "c" in option[1:]
103
+ for option in command[index + 1:]
104
+ ):
105
+ return executable
106
+ return None
107
+
108
+
86
109
  def process_exists(pid: int) -> bool:
87
110
  try:
88
111
  os.kill(pid, 0)
@@ -394,7 +417,23 @@ def main() -> int:
394
417
  )
395
418
  return 2
396
419
 
397
- return start_job(argv[index + 1:], timeout_seconds)
420
+ command = argv[index + 1:]
421
+ shell_wrapper = shell_command_wrapper(command)
422
+ if shell_wrapper:
423
+ print(
424
+ f"error: {shell_wrapper} command-string wrappers are not allowed; "
425
+ "pass the validation executable and its arguments directly so its "
426
+ "exit code remains authoritative",
427
+ file=sys.stderr,
428
+ )
429
+ print(
430
+ "run-long-check already captures stdout/stderr; do not add pipelines "
431
+ "or trailing commands to trim output",
432
+ file=sys.stderr,
433
+ )
434
+ return 2
435
+
436
+ return start_job(command, timeout_seconds)
398
437
 
399
438
 
400
439
  if __name__ == "__main__":