portacode 0.3.19.dev1__tar.gz → 0.3.19.dev2__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.
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/PKG-INFO +1 -1
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/_version.py +2 -2
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/project_state_handlers.py +89 -39
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode.egg-info/PKG-INFO +1 -1
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/.claude/agents/communication-manager.md +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/.claude/settings.local.json +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/.gitignore +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/.gitmodules +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/LICENSE +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/MANIFEST.in +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/Makefile +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/README.md +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/backup.sh +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/docker-compose.yaml +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/README.md +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/__init__.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/__main__.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/cli.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/README.md +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/__init__.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/client.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/README.md +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/__init__.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/base.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/file_handlers.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/registry.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/session.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/system_handlers.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/tab_factory.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/terminal_handlers.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/multiplex.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/terminal.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/data.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/keypair.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/service.py +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode.egg-info/SOURCES.txt +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode.egg-info/dependency_links.txt +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode.egg-info/entry_points.txt +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode.egg-info/requires.txt +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode.egg-info/top_level.txt +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/pyproject.toml +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/restore.sh +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/setup.cfg +0 -0
- {portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/setup.py +0 -0
|
@@ -17,5 +17,5 @@ __version__: str
|
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
|
18
18
|
version_tuple: VERSION_TUPLE
|
|
19
19
|
|
|
20
|
-
__version__ = version = '0.3.19.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 3, 19, '
|
|
20
|
+
__version__ = version = '0.3.19.dev2'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 3, 19, 'dev2')
|
|
@@ -401,7 +401,7 @@ class GitManager:
|
|
|
401
401
|
return None
|
|
402
402
|
|
|
403
403
|
def _generate_html_diff(self, original_content: str, modified_content: str, file_path: str) -> Optional[str]:
|
|
404
|
-
"""Generate HTML diff with syntax highlighting using Pygments and diff-match-patch."""
|
|
404
|
+
"""Generate unified HTML diff with syntax highlighting using Pygments and diff-match-patch."""
|
|
405
405
|
if not DIFF_MATCH_PATCH_AVAILABLE or not PYGMENTS_AVAILABLE:
|
|
406
406
|
logger.debug("Required libraries not available for HTML diff generation")
|
|
407
407
|
return None
|
|
@@ -415,24 +415,12 @@ class GitManager:
|
|
|
415
415
|
# Get Pygments lexer for syntax highlighting
|
|
416
416
|
lexer = self._get_pygments_lexer(file_path)
|
|
417
417
|
|
|
418
|
-
#
|
|
419
|
-
|
|
420
|
-
style='monokai',
|
|
421
|
-
noclasses=False,
|
|
422
|
-
cssclass='highlight',
|
|
423
|
-
linenos=True,
|
|
424
|
-
lineanchors='line',
|
|
425
|
-
anchorlinenos=True,
|
|
426
|
-
hl_lines=[]
|
|
427
|
-
)
|
|
428
|
-
|
|
429
|
-
# Split content into lines for line-by-line processing
|
|
430
|
-
original_lines = original_content.splitlines(keepends=True)
|
|
431
|
-
modified_lines = modified_content.splitlines(keepends=True)
|
|
418
|
+
# Convert diffs to line-based unified diff
|
|
419
|
+
unified_diff_lines = self._create_unified_diff_lines(diffs, original_content, modified_content)
|
|
432
420
|
|
|
433
|
-
# Build HTML
|
|
421
|
+
# Build HTML
|
|
434
422
|
html_parts = []
|
|
435
|
-
html_parts.append('<div class="
|
|
423
|
+
html_parts.append('<div class="unified-diff-container">')
|
|
436
424
|
|
|
437
425
|
# Add stats header
|
|
438
426
|
char_additions = sum(len(text) for op, text in diffs if op == 1)
|
|
@@ -446,31 +434,45 @@ class GitManager:
|
|
|
446
434
|
</div>
|
|
447
435
|
''')
|
|
448
436
|
|
|
449
|
-
#
|
|
450
|
-
html_parts.append('<div class="diff-
|
|
437
|
+
# Generate unified diff view
|
|
438
|
+
html_parts.append('<div class="diff-content">')
|
|
439
|
+
html_parts.append('<table class="diff-table">')
|
|
451
440
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
441
|
+
for line_info in unified_diff_lines:
|
|
442
|
+
line_type = line_info['type'] # 'context', 'delete', 'add', 'header'
|
|
443
|
+
old_line_num = line_info.get('old_line_num', '')
|
|
444
|
+
new_line_num = line_info.get('new_line_num', '')
|
|
445
|
+
content = line_info['content']
|
|
446
|
+
|
|
447
|
+
# Apply syntax highlighting to the content
|
|
448
|
+
if lexer and content.strip() and line_type != 'header':
|
|
449
|
+
try:
|
|
450
|
+
# Remove the +/- prefix for highlighting, then add it back
|
|
451
|
+
clean_content = content[1:] if content and content[0] in '+-' else content
|
|
452
|
+
highlighted = highlight(clean_content, lexer, HtmlFormatter(nowrap=True, noclasses=False))
|
|
453
|
+
# Add the prefix back
|
|
454
|
+
if content and content[0] in '+-':
|
|
455
|
+
highlighted = content[0] + highlighted[len(clean_content):]
|
|
456
|
+
content = highlighted
|
|
457
|
+
except Exception:
|
|
458
|
+
content = self._escape_html(content)
|
|
459
|
+
else:
|
|
460
|
+
content = self._escape_html(content)
|
|
461
|
+
|
|
462
|
+
# CSS classes for different line types
|
|
463
|
+
row_class = f'diff-line diff-{line_type}'
|
|
464
|
+
|
|
465
|
+
html_parts.append(f'''
|
|
466
|
+
<tr class="{row_class}">
|
|
467
|
+
<td class="line-num old-line-num">{old_line_num}</td>
|
|
468
|
+
<td class="line-num new-line-num">{new_line_num}</td>
|
|
469
|
+
<td class="line-content">{content}</td>
|
|
470
|
+
</tr>
|
|
471
|
+
''')
|
|
461
472
|
|
|
462
|
-
|
|
463
|
-
html_parts.append('
|
|
464
|
-
html_parts.append('<h4>Modified</h4>')
|
|
465
|
-
if lexer and modified_content.strip():
|
|
466
|
-
highlighted = highlight(modified_content, lexer, formatter)
|
|
467
|
-
html_parts.append(highlighted)
|
|
468
|
-
else:
|
|
469
|
-
html_parts.append(f'<pre class="highlight"><code>{self._escape_html(modified_content)}</code></pre>')
|
|
473
|
+
html_parts.append('</table>')
|
|
474
|
+
html_parts.append('</div>')
|
|
470
475
|
html_parts.append('</div>')
|
|
471
|
-
|
|
472
|
-
html_parts.append('</div>') # Close diff-sides
|
|
473
|
-
html_parts.append('</div>') # Close container
|
|
474
476
|
|
|
475
477
|
return ''.join(html_parts)
|
|
476
478
|
|
|
@@ -478,6 +480,54 @@ class GitManager:
|
|
|
478
480
|
logger.error("Error generating HTML diff: %s", e)
|
|
479
481
|
return None
|
|
480
482
|
|
|
483
|
+
def _create_unified_diff_lines(self, diffs, original_content: str, modified_content: str):
|
|
484
|
+
"""Create unified diff lines from diff-match-patch output."""
|
|
485
|
+
lines = []
|
|
486
|
+
|
|
487
|
+
# Split content into lines
|
|
488
|
+
original_lines = original_content.splitlines()
|
|
489
|
+
modified_lines = modified_content.splitlines()
|
|
490
|
+
|
|
491
|
+
old_line_num = 1
|
|
492
|
+
new_line_num = 1
|
|
493
|
+
|
|
494
|
+
# Process each diff operation
|
|
495
|
+
for op, text in diffs:
|
|
496
|
+
text_lines = text.splitlines()
|
|
497
|
+
|
|
498
|
+
if op == 0: # EQUAL - context lines
|
|
499
|
+
for line in text_lines:
|
|
500
|
+
lines.append({
|
|
501
|
+
'type': 'context',
|
|
502
|
+
'old_line_num': old_line_num,
|
|
503
|
+
'new_line_num': new_line_num,
|
|
504
|
+
'content': ' ' + line
|
|
505
|
+
})
|
|
506
|
+
old_line_num += 1
|
|
507
|
+
new_line_num += 1
|
|
508
|
+
|
|
509
|
+
elif op == -1: # DELETE
|
|
510
|
+
for line in text_lines:
|
|
511
|
+
lines.append({
|
|
512
|
+
'type': 'delete',
|
|
513
|
+
'old_line_num': old_line_num,
|
|
514
|
+
'new_line_num': '',
|
|
515
|
+
'content': '-' + line
|
|
516
|
+
})
|
|
517
|
+
old_line_num += 1
|
|
518
|
+
|
|
519
|
+
elif op == 1: # INSERT
|
|
520
|
+
for line in text_lines:
|
|
521
|
+
lines.append({
|
|
522
|
+
'type': 'add',
|
|
523
|
+
'old_line_num': '',
|
|
524
|
+
'new_line_num': new_line_num,
|
|
525
|
+
'content': '+' + line
|
|
526
|
+
})
|
|
527
|
+
new_line_num += 1
|
|
528
|
+
|
|
529
|
+
return lines
|
|
530
|
+
|
|
481
531
|
def _escape_html(self, text: str) -> str:
|
|
482
532
|
"""Escape HTML special characters."""
|
|
483
533
|
return (text.replace('&', '&')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/file_handlers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/system_handlers.py
RENAMED
|
File without changes
|
{portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/tab_factory.py
RENAMED
|
File without changes
|
{portacode-0.3.19.dev1 → portacode-0.3.19.dev2}/portacode/connection/handlers/terminal_handlers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|