ferp 0.7.1__py3-none-any.whl

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.
Files changed (87) hide show
  1. ferp/__init__.py +3 -0
  2. ferp/__main__.py +4 -0
  3. ferp/__version__.py +1 -0
  4. ferp/app.py +9 -0
  5. ferp/cli.py +160 -0
  6. ferp/core/__init__.py +0 -0
  7. ferp/core/app.py +1312 -0
  8. ferp/core/bundle_installer.py +245 -0
  9. ferp/core/command_provider.py +77 -0
  10. ferp/core/dependency_manager.py +59 -0
  11. ferp/core/fs_controller.py +70 -0
  12. ferp/core/fs_watcher.py +144 -0
  13. ferp/core/messages.py +49 -0
  14. ferp/core/path_actions.py +124 -0
  15. ferp/core/paths.py +3 -0
  16. ferp/core/protocols.py +8 -0
  17. ferp/core/script_controller.py +515 -0
  18. ferp/core/script_protocol.py +35 -0
  19. ferp/core/script_runner.py +421 -0
  20. ferp/core/settings.py +16 -0
  21. ferp/core/settings_store.py +69 -0
  22. ferp/core/state.py +156 -0
  23. ferp/core/task_store.py +164 -0
  24. ferp/core/transcript_logger.py +95 -0
  25. ferp/domain/__init__.py +0 -0
  26. ferp/domain/scripts.py +29 -0
  27. ferp/fscp/host/__init__.py +11 -0
  28. ferp/fscp/host/host.py +439 -0
  29. ferp/fscp/host/managed_process.py +113 -0
  30. ferp/fscp/host/process_registry.py +124 -0
  31. ferp/fscp/protocol/__init__.py +13 -0
  32. ferp/fscp/protocol/errors.py +2 -0
  33. ferp/fscp/protocol/messages.py +55 -0
  34. ferp/fscp/protocol/schemas/__init__.py +0 -0
  35. ferp/fscp/protocol/schemas/fscp/1.0/cancel.json +16 -0
  36. ferp/fscp/protocol/schemas/fscp/1.0/definitions.json +29 -0
  37. ferp/fscp/protocol/schemas/fscp/1.0/discriminator.json +14 -0
  38. ferp/fscp/protocol/schemas/fscp/1.0/envelope.json +13 -0
  39. ferp/fscp/protocol/schemas/fscp/1.0/exit.json +20 -0
  40. ferp/fscp/protocol/schemas/fscp/1.0/init.json +36 -0
  41. ferp/fscp/protocol/schemas/fscp/1.0/input_response.json +21 -0
  42. ferp/fscp/protocol/schemas/fscp/1.0/log.json +21 -0
  43. ferp/fscp/protocol/schemas/fscp/1.0/message.json +23 -0
  44. ferp/fscp/protocol/schemas/fscp/1.0/progress.json +23 -0
  45. ferp/fscp/protocol/schemas/fscp/1.0/request_input.json +47 -0
  46. ferp/fscp/protocol/schemas/fscp/1.0/result.json +16 -0
  47. ferp/fscp/protocol/schemas/fscp/__init__.py +0 -0
  48. ferp/fscp/protocol/state.py +16 -0
  49. ferp/fscp/protocol/validator.py +123 -0
  50. ferp/fscp/scripts/__init__.py +0 -0
  51. ferp/fscp/scripts/runtime/__init__.py +4 -0
  52. ferp/fscp/scripts/runtime/__main__.py +40 -0
  53. ferp/fscp/scripts/runtime/errors.py +14 -0
  54. ferp/fscp/scripts/runtime/io.py +64 -0
  55. ferp/fscp/scripts/runtime/script.py +149 -0
  56. ferp/fscp/scripts/runtime/state.py +17 -0
  57. ferp/fscp/scripts/runtime/worker.py +13 -0
  58. ferp/fscp/scripts/sdk.py +548 -0
  59. ferp/fscp/transcript/__init__.py +3 -0
  60. ferp/fscp/transcript/events.py +14 -0
  61. ferp/resources/__init__.py +0 -0
  62. ferp/services/__init__.py +3 -0
  63. ferp/services/file_listing.py +120 -0
  64. ferp/services/monday_sync.py +155 -0
  65. ferp/services/releases.py +214 -0
  66. ferp/services/scripts.py +90 -0
  67. ferp/services/update_check.py +130 -0
  68. ferp/styles/index.tcss +638 -0
  69. ferp/themes/themes.py +238 -0
  70. ferp/widgets/__init__.py +17 -0
  71. ferp/widgets/dialogs.py +167 -0
  72. ferp/widgets/file_tree.py +991 -0
  73. ferp/widgets/forms.py +146 -0
  74. ferp/widgets/output_panel.py +244 -0
  75. ferp/widgets/panels.py +13 -0
  76. ferp/widgets/process_list.py +158 -0
  77. ferp/widgets/readme_modal.py +59 -0
  78. ferp/widgets/scripts.py +192 -0
  79. ferp/widgets/task_capture.py +74 -0
  80. ferp/widgets/task_list.py +493 -0
  81. ferp/widgets/top_bar.py +110 -0
  82. ferp-0.7.1.dist-info/METADATA +128 -0
  83. ferp-0.7.1.dist-info/RECORD +87 -0
  84. ferp-0.7.1.dist-info/WHEEL +5 -0
  85. ferp-0.7.1.dist-info/entry_points.txt +2 -0
  86. ferp-0.7.1.dist-info/licenses/LICENSE +21 -0
  87. ferp-0.7.1.dist-info/top_level.txt +1 -0
ferp/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .__version__ import __version__
2
+
3
+ __all__ = ["__version__"]
ferp/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ from ferp.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
ferp/__version__.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = "0.7.1"
ferp/app.py ADDED
@@ -0,0 +1,9 @@
1
+ from ferp.core.app import Ferp
2
+
3
+
4
+ def main() -> None:
5
+ Ferp().run()
6
+
7
+
8
+ if __name__ == "__main__":
9
+ main()
ferp/cli.py ADDED
@@ -0,0 +1,160 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import json
5
+ import zipfile
6
+ from pathlib import Path
7
+ from typing import Sequence
8
+
9
+ from ferp import __version__
10
+ from ferp.app import main as run_app
11
+
12
+
13
+ def build_parser() -> argparse.ArgumentParser:
14
+ parser = argparse.ArgumentParser(
15
+ prog="ferp",
16
+ description="FERP — For Executing Repetitive Processes",
17
+ )
18
+
19
+ parser.add_argument(
20
+ "--version",
21
+ action="version",
22
+ version=f"%(prog)s {__version__}",
23
+ help="Print version and exit.",
24
+ )
25
+
26
+ parser.add_argument(
27
+ "--no-ui",
28
+ action="store_true",
29
+ help="Parse CLI arguments without launching the UI.",
30
+ )
31
+
32
+ subparsers = parser.add_subparsers(dest="command")
33
+
34
+ bundle_parser = subparsers.add_parser(
35
+ "bundle",
36
+ help="Package a Python FSCP script (and optional README) into a .ferp bundle.",
37
+ )
38
+ bundle_parser.add_argument(
39
+ "script",
40
+ help="Path to the Python script to bundle.",
41
+ )
42
+ bundle_parser.add_argument(
43
+ "readme",
44
+ nargs="?",
45
+ help="Optional README/guide to include.",
46
+ )
47
+ bundle_parser.add_argument(
48
+ "--id",
49
+ dest="script_id",
50
+ help="Unique script identifier. Defaults to the script's filename stem.",
51
+ )
52
+ bundle_parser.add_argument(
53
+ "--name",
54
+ dest="script_name",
55
+ help="Human-friendly script name. Defaults to the script's filename.",
56
+ )
57
+ bundle_parser.add_argument(
58
+ "--version",
59
+ dest="script_version",
60
+ default="1.0.0",
61
+ help="Script version recorded in the manifest (default: 1.0.0).",
62
+ )
63
+ bundle_parser.add_argument(
64
+ "--target",
65
+ choices=["current_directory", "highlighted_file", "highlighted_directory"],
66
+ default="current_directory",
67
+ help="Which path FER​P should send to the script (default: current_directory).",
68
+ )
69
+ bundle_parser.add_argument(
70
+ "--dependency",
71
+ dest="dependencies",
72
+ action="append",
73
+ default=[],
74
+ help="Add a pip requirement specifier (repeat for multiple).",
75
+ )
76
+ bundle_parser.add_argument(
77
+ "-o",
78
+ "--output",
79
+ help="Output file (.ferp). Defaults to <script_id>.ferp in the current directory.",
80
+ )
81
+ bundle_parser.set_defaults(handler=handle_bundle)
82
+
83
+ return parser
84
+
85
+
86
+ def handle_bundle(args: argparse.Namespace) -> None:
87
+ script_path = Path(args.script).expanduser()
88
+ if not script_path.exists() or not script_path.is_file():
89
+ raise SystemExit(f"Script not found: {script_path}")
90
+ if script_path.suffix.lower() != ".py":
91
+ raise SystemExit("Bundles currently support Python (.py) scripts only.")
92
+
93
+ readme_path: Path | None = None
94
+ if args.readme:
95
+ readme_path = Path(args.readme).expanduser()
96
+ if not readme_path.exists() or not readme_path.is_file():
97
+ raise SystemExit(f"README not found: {readme_path}")
98
+
99
+ script_id = args.script_id or _slugify(script_path.stem)
100
+ if not script_id:
101
+ raise SystemExit("Unable to derive script id. Use --id to specify one.")
102
+
103
+ script_name = args.script_name or script_path.stem.replace("_", " ").title()
104
+
105
+ bundle_path = (
106
+ Path(args.output).expanduser()
107
+ if args.output
108
+ else Path.cwd() / f"{script_id}.ferp"
109
+ )
110
+ if bundle_path.suffix.lower() != ".ferp":
111
+ bundle_path = bundle_path.with_suffix(".ferp")
112
+
113
+ manifest: dict[str, object] = {
114
+ "id": script_id,
115
+ "name": script_name,
116
+ "version": args.script_version,
117
+ "entrypoint": script_path.name,
118
+ "target": args.target,
119
+ }
120
+
121
+ if readme_path:
122
+ manifest["readme"] = readme_path.name
123
+ dependencies = [dep.strip() for dep in args.dependencies if dep and dep.strip()]
124
+ if dependencies:
125
+ manifest["dependencies"] = dependencies
126
+
127
+ bundle_path.parent.mkdir(parents=True, exist_ok=True)
128
+ with zipfile.ZipFile(bundle_path, "w", compression=zipfile.ZIP_DEFLATED) as archive:
129
+ archive.writestr("manifest.json", json.dumps(manifest, indent=2))
130
+ archive.write(script_path, arcname=script_path.name)
131
+ if readme_path:
132
+ archive.write(readme_path, arcname=readme_path.name)
133
+
134
+ print(f"Bundle created: {bundle_path}")
135
+
136
+
137
+ def _slugify(value: str) -> str:
138
+ cleaned = "".join(ch if ch.isalnum() else "-" for ch in value.lower())
139
+ while "--" in cleaned:
140
+ cleaned = cleaned.replace("--", "-")
141
+ return cleaned.strip("-")
142
+
143
+
144
+ def main(argv: Sequence[str] | None = None) -> None:
145
+ parser = build_parser()
146
+ args = parser.parse_args(argv)
147
+
148
+ if args.command == "bundle":
149
+ args.handler(args)
150
+ print(args)
151
+ return
152
+
153
+ if args.no_ui:
154
+ return
155
+
156
+ run_app()
157
+
158
+
159
+ if __name__ == "__main__":
160
+ main()
ferp/core/__init__.py ADDED
File without changes