codedthemes-cli 0.1.15__tar.gz → 0.1.16__tar.gz
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.
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/PKG-INFO +1 -1
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes/cli.py +63 -33
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes_cli.egg-info/PKG-INFO +1 -1
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/pyproject.toml +1 -1
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/README.md +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes/__init__.py +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes/config.py +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes/mcp_client.py +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes/patch_utils.py +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes/repo_utils.py +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes/sync_manager.py +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes_cli.egg-info/SOURCES.txt +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes_cli.egg-info/dependency_links.txt +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes_cli.egg-info/entry_points.txt +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes_cli.egg-info/requires.txt +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes_cli.egg-info/top_level.txt +0 -0
- {codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/setup.cfg +0 -0
|
@@ -240,10 +240,29 @@ def handle_init():
|
|
|
240
240
|
sys.exit(1)
|
|
241
241
|
|
|
242
242
|
|
|
243
|
+
def clean_remote_path(p: str) -> str:
|
|
244
|
+
"""
|
|
245
|
+
Strips the deeply nested remote container path if present.
|
|
246
|
+
e.g., 'home/runner/work/<owner>/<repo>/src/...' -> 'src/...'
|
|
247
|
+
"""
|
|
248
|
+
if not p: return p
|
|
249
|
+
p = p.replace('\\', '/')
|
|
250
|
+
if p.startswith('/'): p = p[1:]
|
|
251
|
+
if p.startswith('home/runner/work/'):
|
|
252
|
+
parts = p.split('/')
|
|
253
|
+
if len(parts) > 4: # e.g. ['home', 'runner', 'work', 'owner', 'repo', 'src', ...]
|
|
254
|
+
return '/'.join(parts[5:])
|
|
255
|
+
return p
|
|
256
|
+
|
|
243
257
|
def handle_apply(query: str):
|
|
244
258
|
"""
|
|
245
259
|
Plans and executes changes based on a natural language query.
|
|
246
260
|
"""
|
|
261
|
+
if not query or not query.strip():
|
|
262
|
+
print("✖ Error: Query cannot be empty.")
|
|
263
|
+
print("💡 Example: codedthemes apply \"Update the primary color to deep purple\"")
|
|
264
|
+
return
|
|
265
|
+
|
|
247
266
|
try:
|
|
248
267
|
repo_root = detect_repo_root()
|
|
249
268
|
repo_abs_path = os.path.abspath(repo_root)
|
|
@@ -335,10 +354,10 @@ def handle_apply(query: str):
|
|
|
335
354
|
print(f"✖ Planning failed: {plan.get('message', 'Unknown error')}")
|
|
336
355
|
return
|
|
337
356
|
|
|
338
|
-
target_files = plan.get("files_to_modify", [])
|
|
357
|
+
target_files = [clean_remote_path(f) for f in plan.get("files_to_modify", [])]
|
|
339
358
|
instructions = plan.get("plan_instructions", [])
|
|
340
|
-
files_to_create = plan.get("files_to_create", [])
|
|
341
|
-
files_to_delete = plan.get("files_to_delete", [])
|
|
359
|
+
files_to_create = [clean_remote_path(f) for f in plan.get("files_to_create", [])]
|
|
360
|
+
files_to_delete = [clean_remote_path(f) for f in plan.get("files_to_delete", [])]
|
|
342
361
|
|
|
343
362
|
if not any([target_files, files_to_create, files_to_delete, instructions]):
|
|
344
363
|
print("Information: No changes planned.")
|
|
@@ -396,41 +415,52 @@ def handle_apply(query: str):
|
|
|
396
415
|
updates = res_data.get("updates_for_local", [])
|
|
397
416
|
deletes = res_data.get("deleted_files", [])
|
|
398
417
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
418
|
+
# 1. Apply local updates
|
|
419
|
+
for item in updates:
|
|
420
|
+
rel_path = clean_remote_path(item.get("path"))
|
|
421
|
+
code = item.get("code")
|
|
422
|
+
if not rel_path or code is None: continue
|
|
423
|
+
abs_path = os.path.abspath(os.path.join(repo_abs_path, rel_path.replace('/', os.sep)))
|
|
424
|
+
|
|
425
|
+
try:
|
|
426
|
+
os.makedirs(os.path.dirname(abs_path), exist_ok=True)
|
|
427
|
+
with open(abs_path, 'w', encoding='utf-8') as f:
|
|
428
|
+
f.write(code)
|
|
429
|
+
print(f"✔ Updated: {rel_path}")
|
|
430
|
+
except Exception as e:
|
|
431
|
+
print(f"✖ Error writing {rel_path}: {e}")
|
|
404
432
|
|
|
433
|
+
# 2. Apply local deletions
|
|
434
|
+
for rel_path_raw in (deletes or []):
|
|
435
|
+
rel_path = clean_remote_path(rel_path_raw)
|
|
436
|
+
abs_path = os.path.normpath(os.path.join(repo_abs_path, rel_path.replace('/', os.sep)))
|
|
437
|
+
if os.path.exists(abs_path) and abs_path.startswith(os.path.abspath(repo_abs_path)):
|
|
405
438
|
try:
|
|
406
|
-
os.
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
for rel_path in (deletes or []):
|
|
414
|
-
abs_path = os.path.normpath(os.path.join(repo_abs_path, rel_path.replace('/', os.sep)))
|
|
415
|
-
if os.path.exists(abs_path) and abs_path.startswith(os.path.abspath(repo_abs_path)):
|
|
416
|
-
try:
|
|
417
|
-
if os.path.isfile(abs_path): os.remove(abs_path)
|
|
418
|
-
elif os.path.isdir(abs_path): shutil.rmtree(abs_path)
|
|
419
|
-
print(f"✔ Deleted: {rel_path}")
|
|
420
|
-
except: pass
|
|
421
|
-
|
|
439
|
+
if os.path.isfile(abs_path): os.remove(abs_path)
|
|
440
|
+
elif os.path.isdir(abs_path): shutil.rmtree(abs_path)
|
|
441
|
+
print(f"✔ Deleted: {rel_path}")
|
|
442
|
+
except: pass
|
|
443
|
+
|
|
444
|
+
# 3. Synchronize state
|
|
445
|
+
if updates or deletes:
|
|
422
446
|
sync_manager.update_sync_state(repo_abs_path, workspace_id, user_email)
|
|
423
447
|
print("✔ Local sync state updated.")
|
|
424
448
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
449
|
+
# 4. Show Integration Report (Always show errors or details)
|
|
450
|
+
_details_raw = res_data.get("details", [])
|
|
451
|
+
details_list = _details_raw.get("report", []) if isinstance(_details_raw, dict) else (_details_raw if isinstance(_details_raw, list) else [])
|
|
452
|
+
if details_list:
|
|
453
|
+
print("\n📊 Integration Report:")
|
|
454
|
+
for item in details_list:
|
|
455
|
+
status_icon = "✔" if item.get("success") else "✖"
|
|
456
|
+
print(f" [{status_icon}] {item.get('file_path')}: {item.get('message', '')}")
|
|
457
|
+
|
|
458
|
+
# 5. Output Final Message if no updates were applied
|
|
459
|
+
if not updates and not deletes:
|
|
460
|
+
msg = res_data.get('message', 'Changes applied successfully.')
|
|
461
|
+
if isinstance(msg, str) and "AI MUST now sync" in msg:
|
|
462
|
+
msg = msg.split("AI MUST now sync")[0].strip()
|
|
463
|
+
print(f"✔ {msg}")
|
|
434
464
|
|
|
435
465
|
except Exception as e:
|
|
436
466
|
print(f"✖ Error: {e}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codedthemes_cli-0.1.15 → codedthemes_cli-0.1.16}/codedthemes_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|