portacode 1.3.34__tar.gz → 1.3.36__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.

Potentially problematic release.


This version of portacode might be problematic. Click here for more details.

Files changed (101) hide show
  1. {portacode-1.3.34 → portacode-1.3.36}/PKG-INFO +1 -1
  2. {portacode-1.3.34 → portacode-1.3.36}/portacode/_version.py +2 -2
  3. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +77 -4
  4. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/__init__.py +3 -1
  5. portacode-1.3.36/portacode/connection/handlers/file_handlers.py +1094 -0
  6. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state/git_manager.py +63 -1
  7. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/terminal.py +3 -1
  8. {portacode-1.3.34 → portacode-1.3.36}/portacode.egg-info/PKG-INFO +1 -1
  9. {portacode-1.3.34 → portacode-1.3.36}/portacode.egg-info/SOURCES.txt +3 -0
  10. portacode-1.3.36/todo/UI_UX/opening_a_file_on_desktop_results_in_nothing.md +1 -0
  11. portacode-1.3.36/todo/issues/portacode_service_silently_down.md +69 -0
  12. portacode-1.3.36/todo/issues/project_cpu_hotspots.md +33 -0
  13. portacode-1.3.34/portacode/connection/handlers/file_handlers.py +0 -437
  14. {portacode-1.3.34 → portacode-1.3.36}/.claude/agents/communication-manager.md +0 -0
  15. {portacode-1.3.34 → portacode-1.3.36}/.claude/settings.local.json +0 -0
  16. {portacode-1.3.34 → portacode-1.3.36}/.gitignore +0 -0
  17. {portacode-1.3.34 → portacode-1.3.36}/.gitmodules +0 -0
  18. {portacode-1.3.34 → portacode-1.3.36}/LICENSE +0 -0
  19. {portacode-1.3.34 → portacode-1.3.36}/MANIFEST.in +0 -0
  20. {portacode-1.3.34 → portacode-1.3.36}/Makefile +0 -0
  21. {portacode-1.3.34 → portacode-1.3.36}/README.md +0 -0
  22. {portacode-1.3.34 → portacode-1.3.36}/backup.sh +0 -0
  23. {portacode-1.3.34 → portacode-1.3.36}/connect.py +0 -0
  24. {portacode-1.3.34 → portacode-1.3.36}/connect.sh +0 -0
  25. {portacode-1.3.34 → portacode-1.3.36}/docker-compose.yaml +0 -0
  26. {portacode-1.3.34 → portacode-1.3.36}/portacode/README.md +0 -0
  27. {portacode-1.3.34 → portacode-1.3.36}/portacode/__init__.py +0 -0
  28. {portacode-1.3.34 → portacode-1.3.36}/portacode/__main__.py +0 -0
  29. {portacode-1.3.34 → portacode-1.3.36}/portacode/cli.py +0 -0
  30. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/README.md +0 -0
  31. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/__init__.py +0 -0
  32. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/client.py +0 -0
  33. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/README.md +0 -0
  34. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/base.py +0 -0
  35. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/chunked_content.py +0 -0
  36. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_aware_file_handlers.py +0 -0
  37. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state/README.md +0 -0
  38. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state/__init__.py +0 -0
  39. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state/file_system_watcher.py +0 -0
  40. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state/handlers.py +0 -0
  41. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state/manager.py +0 -0
  42. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state/models.py +0 -0
  43. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state/utils.py +0 -0
  44. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/project_state_handlers.py +0 -0
  45. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/registry.py +0 -0
  46. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/session.py +0 -0
  47. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/system_handlers.py +0 -0
  48. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/tab_factory.py +0 -0
  49. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/handlers/terminal_handlers.py +0 -0
  50. {portacode-1.3.34 → portacode-1.3.36}/portacode/connection/multiplex.py +0 -0
  51. {portacode-1.3.34 → portacode-1.3.36}/portacode/data.py +0 -0
  52. {portacode-1.3.34 → portacode-1.3.36}/portacode/keypair.py +0 -0
  53. {portacode-1.3.34 → portacode-1.3.36}/portacode/logging_categories.py +0 -0
  54. {portacode-1.3.34 → portacode-1.3.36}/portacode/service.py +0 -0
  55. {portacode-1.3.34 → portacode-1.3.36}/portacode/static/js/test-ntp-clock.html +0 -0
  56. {portacode-1.3.34 → portacode-1.3.36}/portacode/static/js/utils/ntp-clock.js +0 -0
  57. {portacode-1.3.34 → portacode-1.3.36}/portacode/utils/NTP_ARCHITECTURE.md +0 -0
  58. {portacode-1.3.34 → portacode-1.3.36}/portacode/utils/__init__.py +0 -0
  59. {portacode-1.3.34 → portacode-1.3.36}/portacode/utils/ntp_clock.py +0 -0
  60. {portacode-1.3.34 → portacode-1.3.36}/portacode.egg-info/dependency_links.txt +0 -0
  61. {portacode-1.3.34 → portacode-1.3.36}/portacode.egg-info/entry_points.txt +0 -0
  62. {portacode-1.3.34 → portacode-1.3.36}/portacode.egg-info/requires.txt +0 -0
  63. {portacode-1.3.34 → portacode-1.3.36}/portacode.egg-info/top_level.txt +0 -0
  64. {portacode-1.3.34 → portacode-1.3.36}/pyproject.toml +0 -0
  65. {portacode-1.3.34 → portacode-1.3.36}/restore.sh +0 -0
  66. {portacode-1.3.34 → portacode-1.3.36}/run_tests.py +0 -0
  67. {portacode-1.3.34 → portacode-1.3.36}/setup.cfg +0 -0
  68. {portacode-1.3.34 → portacode-1.3.36}/setup.py +0 -0
  69. {portacode-1.3.34 → portacode-1.3.36}/test.sh +0 -0
  70. {portacode-1.3.34 → portacode-1.3.36}/test_modules/README.md +0 -0
  71. {portacode-1.3.34 → portacode-1.3.36}/test_modules/__init__.py +0 -0
  72. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_device_online.py +0 -0
  73. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_file_operations.py +0 -0
  74. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_git_status_ui.py +0 -0
  75. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_login_flow.py +0 -0
  76. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_navigate_testing_folder.py +0 -0
  77. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_terminal_buffer_performance.py +0 -0
  78. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_terminal_interaction.py +0 -0
  79. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_terminal_loading_race_condition.py +0 -0
  80. {portacode-1.3.34 → portacode-1.3.36}/test_modules/test_terminal_start.py +0 -0
  81. {portacode-1.3.34 → portacode-1.3.36}/test_request_id.py +0 -0
  82. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/.env.example +0 -0
  83. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/README.md +0 -0
  84. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/__init__.py +0 -0
  85. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/cli.py +0 -0
  86. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/core/__init__.py +0 -0
  87. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/core/base_test.py +0 -0
  88. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/core/cli_manager.py +0 -0
  89. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/core/hierarchical_runner.py +0 -0
  90. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/core/playwright_manager.py +0 -0
  91. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/core/runner.py +0 -0
  92. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/core/shared_cli_manager.py +0 -0
  93. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/core/test_discovery.py +0 -0
  94. {portacode-1.3.34 → portacode-1.3.36}/testing_framework/requirements.txt +0 -0
  95. {portacode-1.3.34 → portacode-1.3.36}/todo/agent_context_management.md +0 -0
  96. {portacode-1.3.34 → portacode-1.3.36}/todo/issues/device_performance_degradation.md +0 -0
  97. {portacode-1.3.34 → portacode-1.3.36}/todo/issues/git_data_not_captured_in_proxmox.md +0 -0
  98. {portacode-1.3.34 → portacode-1.3.36}/todo/issues/indefinite_resource_loading.md +0 -0
  99. {portacode-1.3.34 → portacode-1.3.36}/todo/issues/premature_terminal_exit.md +0 -0
  100. {portacode-1.3.34 → portacode-1.3.36}/todo/issues/terminals_exit_upon_starting.md +0 -0
  101. {portacode-1.3.34 → portacode-1.3.36}/tools/test_python_ntp_clock.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: portacode
3
- Version: 1.3.34
3
+ Version: 1.3.36
4
4
  Summary: Portacode CLI client and SDK
5
5
  Home-page: https://github.com/portacode/portacode
6
6
  Author: Meena Erian
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.3.34'
32
- __version_tuple__ = version_tuple = (1, 3, 34)
31
+ __version__ = version = '1.3.36'
32
+ __version_tuple__ = version_tuple = (1, 3, 36)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -43,6 +43,7 @@ This document describes the complete protocol for communicating with devices thr
43
43
  - [`system_info`](#system_info)
44
44
  - [File Actions](#file-actions)
45
45
  - [`file_read`](#file_read)
46
+ - [`file_search`](#file_search)
46
47
  - [`file_write`](#file_write)
47
48
  - [`directory_list`](#directory_list)
48
49
  - [`file_info`](#file_info)
@@ -80,6 +81,7 @@ This document describes the complete protocol for communicating with devices thr
80
81
  - [`system_info`](#system_info-event)
81
82
  - [File Events](#file-events)
82
83
  - [`file_read_response`](#file_read_response)
84
+ - [`file_search_response`](#file_search_response)
83
85
  - [`file_write_response`](#file_write_response)
84
86
  - [`directory_list_response`](#directory_list_response)
85
87
  - [`file_info_response`](#file_info_response)
@@ -317,12 +319,46 @@ Reads the content of a file. Handled by [`file_read`](./file_handlers.py).
317
319
  **Payload Fields:**
318
320
 
319
321
  * `path` (string, mandatory): The absolute path to the file to read.
322
+ * `start_line` (integer, optional): 1-based line number to start reading from. Defaults to `1`.
323
+ * `end_line` (integer, optional): 1-based line number to stop reading at (inclusive). When provided, limits the response to the range between `start_line` and `end_line`.
324
+ * `max_lines` (integer, optional): Maximum number of lines to return (capped at 2000). Useful for pagination when `end_line` is not specified.
325
+ * `encoding` (string, optional): Text encoding to use when reading the file. Defaults to `utf-8` with replacement for invalid bytes.
320
326
 
321
327
  **Responses:**
322
328
 
323
329
  * On success, the device will respond with a [`file_read_response`](#file_read_response) event.
324
330
  * On error, a generic [`error`](#error) event is sent.
325
331
 
332
+ ### `file_search`
333
+
334
+ Searches for text matches within files beneath a given root directory. Handled by [`file_search`](./file_handlers.py).
335
+
336
+ **Payload Fields:**
337
+
338
+ * `root_path` (string, mandatory): The absolute path that acts as the search root (typically a project folder).
339
+ * `query` (string, mandatory): The search query. Treated as plain text unless `regex=true`.
340
+ * `match_case` (boolean, optional): When `true`, performs a case-sensitive search. Defaults to `false`.
341
+ * `regex` (boolean, optional): When `true`, interprets `query` as a regular expression. Defaults to `false`.
342
+ * `whole_word` (boolean, optional): When `true`, matches only whole words. Works with both plain text and regex queries.
343
+ * `include_patterns` (array[string], optional): Glob patterns that files must match to be included (e.g., `["src/**/*.py"]`).
344
+ * `exclude_patterns` (array[string], optional): Glob patterns for files/directories to skip (e.g., `["**/tests/**"]`).
345
+ * `include_hidden` (boolean, optional): When `true`, includes hidden files and folders. Defaults to `false`.
346
+ * `max_results` (integer, optional): Maximum number of match entries to return (capped at 500). Defaults to `40`.
347
+ * `max_matches_per_file` (integer, optional): Maximum number of matches to return per file (capped at 50). Defaults to `5`.
348
+ * `max_file_size` (integer, optional): Maximum file size in bytes to scan (defaults to 1 MiB).
349
+ * `max_line_length` (integer, optional): Maximum number of characters to return per matching line (defaults to `200`).
350
+
351
+ **Default Behaviour:**
352
+
353
+ * Binary files and large vendor/static directories (e.g., `node_modules`, `dist`, `static`) are skipped automatically unless custom `exclude_patterns` are provided.
354
+ * Only common source/text extensions are scanned by default (override with `include_patterns` to widen the scope).
355
+ * Searches stop after 10 seconds, respecting both per-file and global match limits to avoid oversized responses.
356
+
357
+ **Responses:**
358
+
359
+ * On success, the device will respond with a [`file_search_response`](#file_search_response) event containing the matches.
360
+ * On error, a generic [`error`](#error) event is sent.
361
+
326
362
  ### `file_write`
327
363
 
328
364
  Writes content to a file. Handled by [`file_write`](./file_handlers.py).
@@ -345,6 +381,8 @@ Lists the contents of a directory. Handled by [`directory_list`](./file_handlers
345
381
 
346
382
  * `path` (string, optional): The path to the directory to list. Defaults to the current directory.
347
383
  * `show_hidden` (boolean, optional): Whether to include hidden files in the listing. Defaults to `false`.
384
+ * `limit` (integer, optional): Maximum number of entries to return (defaults to “all”). Values above 1000 are clamped to 1000.
385
+ * `offset` (integer, optional): Number of entries to skip before collecting results (defaults to `0`).
348
386
 
349
387
  **Responses:**
350
388
 
@@ -814,8 +852,39 @@ Returns the content of a file in response to a `file_read` action. Handled by [`
814
852
  **Event Fields:**
815
853
 
816
854
  * `path` (string, mandatory): The path of the file that was read.
817
- * `content` (string, mandatory): The content of the file.
818
- * `size` (integer, mandatory): The size of the file in bytes.
855
+ * `content` (string, mandatory): The file content returned (may be a slice when pagination parameters are used).
856
+ * `size` (integer, mandatory): The total size of the file in bytes.
857
+ * `total_lines` (integer, optional): Total number of lines detected in the file.
858
+ * `returned_lines` (integer, optional): Number of lines included in `content`.
859
+ * `start_line` (integer, optional): The first line number included in the response (if any lines were returned).
860
+ * `requested_start_line` (integer, optional): The requested starting line supplied in the command.
861
+ * `end_line` (integer, optional): The last line number included in the response.
862
+ * `has_more_before` (boolean, optional): Whether there is additional content before the returned range.
863
+ * `has_more_after` (boolean, optional): Whether there is additional content after the returned range.
864
+ * `encoding` (string, optional): Encoding that was used while reading the file.
865
+
866
+ ### <a name="file_search_response"></a>`file_search_response`
867
+
868
+ Returns aggregated search results in response to a `file_search` action. Handled by [`file_search`](./file_handlers.py).
869
+
870
+ **Event Fields:**
871
+
872
+ * `root_path` (string, mandatory): The root directory that was searched.
873
+ * `query` (string, mandatory): The query string that was used.
874
+ * `match_case` (boolean, mandatory): Indicates if the search was case sensitive.
875
+ * `regex` (boolean, mandatory): Indicates if the query was interpreted as a regular expression.
876
+ * `whole_word` (boolean, mandatory): Indicates if the search matched whole words only.
877
+ * `include_patterns` (array[string], mandatory): Effective include glob patterns.
878
+ * `exclude_patterns` (array[string], mandatory): Effective exclude glob patterns.
879
+ * `matches` (array, mandatory): List of match objects containing `relative_path`, `path`, `line_number`, `line`, `match_spans` `[start, end]`, `match_count`, and `line_truncated` (boolean).
880
+ * `matches_returned` (integer, mandatory): Number of match entries returned (length of `matches`).
881
+ * `total_matches` (integer, mandatory): Total number of matches found while scanning.
882
+ * `files_scanned` (integer, mandatory): Count of files inspected.
883
+ * `truncated` (boolean, mandatory): Indicates if additional matches exist beyond those returned.
884
+ * `truncated_count` (integer, optional): Number of matches that were omitted due to truncation limits.
885
+ * `max_results` (integer, mandatory): Maximum number of matches requested.
886
+ * `max_matches_per_file` (integer, mandatory): Maximum matches requested per file.
887
+ * `errors` (array[string], optional): Non-fatal errors encountered during scanning (e.g., unreadable files).
819
888
 
820
889
  ### <a name="file_write_response"></a>`file_write_response`
821
890
 
@@ -835,7 +904,11 @@ Returns the contents of a directory in response to a `directory_list` action. Ha
835
904
 
836
905
  * `path` (string, mandatory): The path of the directory that was listed.
837
906
  * `items` (array, mandatory): A list of objects, each representing a file or directory in the listed directory.
838
- * `count` (integer, mandatory): The number of items in the `items` list.
907
+ * `count` (integer, mandatory): The number of items returned in this response (honours `limit`/`offset`).
908
+ * `total_count` (integer, mandatory): Total number of entries in the directory before pagination.
909
+ * `offset` (integer, optional): Offset that was applied.
910
+ * `limit` (integer, optional): Limit that was applied (or `null` if none).
911
+ * `has_more` (boolean, optional): Indicates whether additional items remain beyond the returned slice.
839
912
 
840
913
  ### <a name="file_info_response"></a>`file_info_response`
841
914
 
@@ -1277,4 +1350,4 @@ Sent by the server to clients to provide initial device list snapshot.
1277
1350
 
1278
1351
  **Event Fields:**
1279
1352
 
1280
- * `devices` (array, mandatory): Array of device objects with status information
1353
+ * `devices` (array, mandatory): Array of device objects with status information
@@ -23,6 +23,7 @@ from .file_handlers import (
23
23
  FileCreateHandler,
24
24
  FolderCreateHandler,
25
25
  FileRenameHandler,
26
+ FileSearchHandler,
26
27
  ContentRequestHandler,
27
28
  )
28
29
  from .project_state_handlers import (
@@ -58,6 +59,7 @@ __all__ = [
58
59
  "FileCreateHandler",
59
60
  "FolderCreateHandler",
60
61
  "FileRenameHandler",
62
+ "FileSearchHandler",
61
63
  "ContentRequestHandler",
62
64
  # Project state handlers
63
65
  "ProjectStateFolderExpandHandler",
@@ -71,4 +73,4 @@ __all__ = [
71
73
  "ProjectStateGitUnstageHandler",
72
74
  "ProjectStateGitRevertHandler",
73
75
  "ProjectStateGitCommitHandler",
74
- ]
76
+ ]