codegpt-ai 1.0.0 → 1.2.0

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/chat.py CHANGED
@@ -589,9 +589,29 @@ def audit_log(action, detail=""):
589
589
  def is_shell_safe(cmd_text):
590
590
  """Check if a shell command is safe to run."""
591
591
  cmd_lower = cmd_text.lower().strip()
592
+
593
+ # Blocklist check
592
594
  for blocked in SHELL_BLOCKLIST:
593
595
  if blocked in cmd_lower:
594
596
  return False, blocked
597
+
598
+ # Block shell injection patterns
599
+ injection_patterns = [
600
+ r'[;&|`]', # Command chaining/injection
601
+ r'\$\(', # Command substitution
602
+ r'>\s*/dev/', # Device writes
603
+ r'\\x[0-9a-f]', # Hex escapes
604
+ r'\\u[0-9a-f]', # Unicode escapes
605
+ r'\brm\b.*-[rR]', # rm with recursive flag (any form)
606
+ ]
607
+ for pattern in injection_patterns:
608
+ if re.search(pattern, cmd_text):
609
+ return False, f"blocked pattern: {pattern}"
610
+
611
+ # Max command length
612
+ if len(cmd_text) > 500:
613
+ return False, "command too long (500 char limit)"
614
+
595
615
  return True, ""
596
616
 
597
617
 
@@ -1978,10 +1998,11 @@ def run_shell(cmd_text):
1978
1998
  print_sys("Usage: /shell <command>\nExample: /shell dir")
1979
1999
  return
1980
2000
 
1981
- # Safety check — use the global blocklist
2001
+ # Safety check
1982
2002
  safe, blocked = is_shell_safe(cmd_text)
1983
2003
  if not safe:
1984
- print_err(f"Blocked: dangerous command detected ({blocked})")
2004
+ print_err(f"Blocked: {blocked}")
2005
+ audit_log("SHELL_BLOCKED", f"{blocked}: {cmd_text[:80]}")
1985
2006
  return
1986
2007
 
1987
2008
  console.print(Panel(
@@ -1991,10 +2012,19 @@ def run_shell(cmd_text):
1991
2012
  ))
1992
2013
 
1993
2014
  try:
1994
- result = subprocess.run(
1995
- cmd_text, shell=True, capture_output=True, text=True, timeout=30,
1996
- cwd=str(Path.home()),
1997
- )
2015
+ # Use shlex.split for safer argument parsing on non-Windows
2016
+ if os.name != "nt":
2017
+ import shlex
2018
+ args = shlex.split(cmd_text)
2019
+ result = subprocess.run(
2020
+ args, capture_output=True, text=True, timeout=30,
2021
+ cwd=str(Path.home()),
2022
+ )
2023
+ else:
2024
+ result = subprocess.run(
2025
+ cmd_text, shell=True, capture_output=True, text=True, timeout=30,
2026
+ cwd=str(Path.home()),
2027
+ )
1998
2028
  output = ""
1999
2029
  if result.stdout:
2000
2030
  output += result.stdout
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codegpt-ai",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Local AI Assistant Hub — 80+ commands, 29 tools, 8 agents, training, security",
5
5
  "author": "ArukuX",
6
6
  "license": "MIT",
@@ -29,7 +29,11 @@
29
29
  "engines": {
30
30
  "node": ">=16.0.0"
31
31
  },
32
- "dependencies": {
33
- "settings": "^0.1.1"
34
- }
32
+ "files": [
33
+ "bin/",
34
+ "chat.py",
35
+ "ai_cli/",
36
+ "CLAUDE.md",
37
+ "README.md"
38
+ ]
35
39
  }
@@ -1,7 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(wc:*)"
5
- ]
6
- }
7
- }
@@ -1,40 +0,0 @@
1
- name: Build & Release
2
-
3
- on:
4
- push:
5
- tags:
6
- - 'v*'
7
-
8
- permissions:
9
- contents: write
10
-
11
- jobs:
12
- build:
13
- runs-on: windows-latest
14
- steps:
15
- - uses: actions/checkout@v4
16
-
17
- - name: Set up Python
18
- uses: actions/setup-python@v5
19
- with:
20
- python-version: '3.12'
21
-
22
- - name: Install dependencies
23
- run: |
24
- pip install requests rich prompt-toolkit pyinstaller
25
-
26
- - name: Build exe
27
- run: |
28
- pyinstaller ai.spec
29
-
30
- - name: Verify exe
31
- run: |
32
- dist\ai.exe --version
33
-
34
- - name: Create Release
35
- uses: softprops/action-gh-release@v2
36
- with:
37
- files: dist/ai.exe
38
- generate_release_notes: true
39
- env:
40
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
package/ai.spec DELETED
@@ -1,81 +0,0 @@
1
- # -*- mode: python ; coding: utf-8 -*-
2
- # PyInstaller spec file for CodeGPT -> ai.exe
3
-
4
- import sys
5
- from pathlib import Path
6
-
7
- block_cipher = None
8
-
9
- a = Analysis(
10
- ['ai_cli/__main__.py'],
11
- pathex=['.'],
12
- binaries=[],
13
- datas=[
14
- ('chat.py', '.'),
15
- ('CLAUDE.md', '.'),
16
- ],
17
- hiddenimports=[
18
- 'requests',
19
- 'rich',
20
- 'rich.console',
21
- 'rich.markdown',
22
- 'rich.panel',
23
- 'rich.table',
24
- 'rich.text',
25
- 'rich.live',
26
- 'rich.rule',
27
- 'rich.align',
28
- 'prompt_toolkit',
29
- 'prompt_toolkit.history',
30
- 'prompt_toolkit.completion',
31
- 'prompt_toolkit.styles',
32
- 'ai_cli',
33
- 'ai_cli.__main__',
34
- 'ai_cli.updater',
35
- 'ai_cli.doctor',
36
- ],
37
- hookspath=[],
38
- hooksconfig={},
39
- runtime_hooks=[],
40
- excludes=[
41
- 'textual',
42
- 'telegram',
43
- 'flask',
44
- 'groq',
45
- 'flet',
46
- 'tkinter',
47
- 'unittest',
48
- 'xmlrpc',
49
- 'pydoc',
50
- 'doctest',
51
- ],
52
- win_no_prefer_redirects=False,
53
- win_private_assemblies=False,
54
- cipher=block_cipher,
55
- noarchive=False,
56
- )
57
-
58
- pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
59
-
60
- exe = EXE(
61
- pyz,
62
- a.scripts,
63
- a.binaries,
64
- a.zipfiles,
65
- a.datas,
66
- [],
67
- name='ai',
68
- debug=False,
69
- bootloader_ignore_signals=False,
70
- strip=False,
71
- upx=True,
72
- upx_exclude=[],
73
- runtime_tmpdir=None,
74
- console=True,
75
- disable_windowed_traceback=False,
76
- argv_emulation=False,
77
- target_arch=None,
78
- codesign_identity=None,
79
- entitlements_file=None,
80
- icon=None,
81
- )