machineconfig 1.96__py3-none-any.whl ā 2.0__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.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/cloud_manager.py +22 -26
- machineconfig/cluster/data_transfer.py +2 -2
- machineconfig/cluster/distribute.py +0 -2
- machineconfig/cluster/file_manager.py +4 -4
- machineconfig/cluster/job_params.py +1 -1
- machineconfig/cluster/loader_runner.py +8 -8
- machineconfig/cluster/remote_machine.py +4 -4
- machineconfig/cluster/script_execution.py +2 -2
- machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +1 -1
- machineconfig/cluster/sessions_managers/enhanced_command_runner.py +23 -23
- machineconfig/cluster/sessions_managers/wt_local.py +78 -76
- machineconfig/cluster/sessions_managers/wt_local_manager.py +91 -91
- machineconfig/cluster/sessions_managers/wt_remote.py +39 -39
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +94 -91
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +56 -54
- machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +49 -49
- machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +18 -18
- machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +42 -42
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +36 -36
- machineconfig/cluster/sessions_managers/zellij_local.py +43 -46
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +139 -120
- machineconfig/cluster/sessions_managers/zellij_remote.py +35 -35
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +33 -33
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +15 -15
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +25 -26
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +49 -49
- machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +5 -5
- machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +15 -15
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +11 -11
- machineconfig/cluster/templates/utils.py +3 -3
- machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
- machineconfig/jobs/python/check_installations.py +8 -9
- machineconfig/jobs/python/python_cargo_build_share.py +2 -2
- machineconfig/jobs/python/vscode/link_ve.py +7 -7
- machineconfig/jobs/python/vscode/select_interpreter.py +7 -7
- machineconfig/jobs/python/vscode/sync_code.py +5 -5
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +2 -2
- machineconfig/jobs/python_custom_installers/dev/aider.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/alacritty.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/brave.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +5 -5
- machineconfig/jobs/python_custom_installers/dev/code.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/cursor.py +9 -9
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/espanso.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/goes.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/lvim.py +4 -4
- machineconfig/jobs/python_custom_installers/dev/nerdfont.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/redis.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/wezterm.py +3 -3
- machineconfig/jobs/python_custom_installers/dev/winget.py +27 -27
- machineconfig/jobs/python_custom_installers/docker.py +3 -3
- machineconfig/jobs/python_custom_installers/gh.py +7 -7
- machineconfig/jobs/python_custom_installers/hx.py +1 -1
- machineconfig/jobs/python_custom_installers/warp-cli.py +3 -3
- machineconfig/jobs/python_generic_installers/config.json +412 -389
- machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
- machineconfig/logger.py +50 -0
- machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
- machineconfig/profile/create.py +23 -16
- machineconfig/profile/create_hardlinks.py +8 -8
- machineconfig/profile/shell.py +41 -37
- machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/linux/devops +2 -2
- machineconfig/scripts/linux/fire +1 -0
- machineconfig/scripts/linux/fire_agents +0 -1
- machineconfig/scripts/linux/mcinit +27 -0
- machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
- machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
- machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
- machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
- machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
- machineconfig/scripts/python/ai/mcinit.py +103 -0
- machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
- machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +47 -0
- machineconfig/scripts/python/archive/tmate_conn.py +5 -5
- machineconfig/scripts/python/archive/tmate_start.py +3 -3
- machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
- machineconfig/scripts/python/cloud_copy.py +19 -18
- machineconfig/scripts/python/cloud_mount.py +9 -7
- machineconfig/scripts/python/cloud_repo_sync.py +11 -11
- machineconfig/scripts/python/cloud_sync.py +1 -1
- machineconfig/scripts/python/croshell.py +14 -14
- machineconfig/scripts/python/devops.py +6 -6
- machineconfig/scripts/python/devops_add_identity.py +8 -6
- machineconfig/scripts/python/devops_add_ssh_key.py +18 -18
- machineconfig/scripts/python/devops_backup_retrieve.py +13 -13
- machineconfig/scripts/python/devops_devapps_install.py +3 -3
- machineconfig/scripts/python/devops_update_repos.py +1 -1
- machineconfig/scripts/python/dotfile.py +2 -2
- machineconfig/scripts/python/fire_agents.py +183 -41
- machineconfig/scripts/python/fire_jobs.py +17 -11
- machineconfig/scripts/python/ftpx.py +2 -2
- machineconfig/scripts/python/gh_models.py +94 -94
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
- machineconfig/scripts/python/helpers/helpers2.py +1 -1
- machineconfig/scripts/python/helpers/helpers4.py +8 -6
- machineconfig/scripts/python/helpers/helpers5.py +7 -7
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
- machineconfig/scripts/python/mount_nfs.py +3 -2
- machineconfig/scripts/python/mount_nw_drive.py +4 -4
- machineconfig/scripts/python/mount_ssh.py +3 -2
- machineconfig/scripts/python/repos.py +8 -8
- machineconfig/scripts/python/scheduler.py +1 -1
- machineconfig/scripts/python/start_slidev.py +8 -7
- machineconfig/scripts/python/start_terminals.py +1 -1
- machineconfig/scripts/python/viewer.py +40 -40
- machineconfig/scripts/python/wifi_conn.py +65 -66
- machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
- machineconfig/scripts/windows/mcinit.ps1 +4 -0
- machineconfig/settings/linters/.ruff.toml +2 -2
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
- machineconfig/settings/shells/wt/settings.json +8 -8
- machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +10 -7
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +9 -7
- machineconfig/utils/ai/browser_user_wrapper.py +5 -5
- machineconfig/utils/ai/generate_file_checklist.py +11 -12
- machineconfig/utils/ai/url2md.py +1 -1
- machineconfig/utils/cloud/onedrive/setup_oauth.py +4 -4
- machineconfig/utils/cloud/onedrive/transaction.py +129 -129
- machineconfig/utils/code.py +13 -6
- machineconfig/utils/installer.py +51 -53
- machineconfig/utils/installer_utils/installer_abc.py +21 -10
- machineconfig/utils/installer_utils/installer_class.py +42 -16
- machineconfig/utils/io_save.py +3 -15
- machineconfig/utils/options.py +10 -3
- machineconfig/utils/path.py +5 -0
- machineconfig/utils/path_reduced.py +201 -149
- machineconfig/utils/procs.py +23 -23
- machineconfig/utils/scheduling.py +11 -12
- machineconfig/utils/ssh.py +270 -0
- machineconfig/utils/terminal.py +180 -0
- machineconfig/utils/utils.py +1 -2
- machineconfig/utils/utils2.py +43 -0
- machineconfig/utils/utils5.py +163 -34
- machineconfig/utils/ve.py +2 -2
- {machineconfig-1.96.dist-info ā machineconfig-2.0.dist-info}/METADATA +13 -8
- {machineconfig-1.96.dist-info ā machineconfig-2.0.dist-info}/RECORD +163 -144
- machineconfig/cluster/self_ssh.py +0 -57
- {machineconfig-1.96.dist-info ā machineconfig-2.0.dist-info}/WHEEL +0 -0
- {machineconfig-1.96.dist-info ā machineconfig-2.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Autonomous, multi-step web research with numbered citations, cross-source verification, and a final Markdown report.'
|
|
3
|
+
tools: ['extensions', 'fetch', 'websearch', 'search', 'githubRepo', 'editFiles']
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deep Research mode
|
|
7
|
+
|
|
8
|
+
You are a rigorous research agent. Emulate the behavior of OpenAI āDeep Researchā and Perplexity āPro/Researchā modes:
|
|
9
|
+
- Plan first, then execute iterative searches and browsing.
|
|
10
|
+
- Read broadly, follow relevant links recursively, and take structured notes.
|
|
11
|
+
- Attribute every non-trivial claim with numbered citations and quotes.
|
|
12
|
+
- Cross-verify important facts across independent, high-quality sources.
|
|
13
|
+
- Produce a clean, self-contained Markdown report saved to ./.ai/deep_research_$suffix.md.
|
|
14
|
+
|
|
15
|
+
This mode is read-heavy. Do not modify project code. Only create or update files under ./.ai/.
|
|
16
|
+
|
|
17
|
+
## Inputs and outputs
|
|
18
|
+
- Input: a research question or task, optional `suffix` for report naming, optional provided URLs.
|
|
19
|
+
- Output: a Markdown report written to ./.ai/deep_research_$suffix.md and a concise chat summary with key findings and links.
|
|
20
|
+
|
|
21
|
+
## Tools you should use
|
|
22
|
+
- fetch: fetch page contents for provided or discovered URLs.
|
|
23
|
+
- websearch: perform web searches to discover authoritative sources. Iterate as needed.
|
|
24
|
+
- search: only for searching the local workspace when relevant (not the web).
|
|
25
|
+
- githubRepo: optionally pull examples or repos if directly relevant.
|
|
26
|
+
- editFiles: create/update the report file under ./.ai/.
|
|
27
|
+
|
|
28
|
+
## Execution protocol
|
|
29
|
+
Follow these phases every time. Provide compact progress updates between phases and after every ~3ā5 tool calls: what you did and whatās next.
|
|
30
|
+
|
|
31
|
+
1) Planning and scope
|
|
32
|
+
- Restate the question. Extract explicit and implicit sub-questions as a checklist.
|
|
33
|
+
- Define success criteria (decision to be made, comparison outcome, data needed, etc.).
|
|
34
|
+
- Draft a search plan: keywords, entities, time range/recency requirements, likely primary sources, and anticipated pitfalls.
|
|
35
|
+
|
|
36
|
+
2) Initial search and source triage
|
|
37
|
+
- Use websearch to find diverse, reputable sources (docs, standards, primary data, peer-reviewed or recognized outlets). Prefer primary sources where possible.
|
|
38
|
+
- For each candidate, use fetch to open it. Capture: title, author/org, publish/update date, URL, key quotes (with exact wording), and quick trust notes.
|
|
39
|
+
- Track sources in a table within your working notes (not necessarily in the final report) to avoid duplication.
|
|
40
|
+
|
|
41
|
+
3) Recursive exploration and verification
|
|
42
|
+
- Follow relevant links found in good sources (fetch them). Stop when additional sources stop changing conclusions materially.
|
|
43
|
+
- Cross-check critical numbers, timelines, and quotes against at least two independent sources when available.
|
|
44
|
+
- If sources conflict, explain the disagreement and weigh credibility (recency, expertise, methodology, bias, primary vs. secondary).
|
|
45
|
+
|
|
46
|
+
4) Synthesis and reporting
|
|
47
|
+
- Draft a clear, structured Markdown report with:
|
|
48
|
+
- Title and date
|
|
49
|
+
- Executive summary (bulleted, 5ā10 lines, with [n] citations inline)
|
|
50
|
+
- Key findings (short sections, each claim supported by [n] citations and brief quotes)
|
|
51
|
+
- Analysis (trade-offs, areas of uncertainty, limitations, and what to watch next)
|
|
52
|
+
- Recommendations or direct answers, if applicable (with citations)
|
|
53
|
+
- Appendix: Sources list with numbered entries [n], each including title, author/org, date (published/updated), URL, and quoted snippets used
|
|
54
|
+
- Ensure the report is readable and skimmable. Keep sentences concise.
|
|
55
|
+
|
|
56
|
+
5) Save the report
|
|
57
|
+
- Determine `$suffix` in this order: (a) user-provided; else (b) a short kebab-case slug from the question; append date (YYYYMMDD) if helpful.
|
|
58
|
+
- Ensure directory ./.ai exists; create it if missing.
|
|
59
|
+
- Write the report to ./.ai/deep_research_$suffix.md using editFiles.
|
|
60
|
+
|
|
61
|
+
6) Final checks
|
|
62
|
+
- Verify every non-obvious statement has a citation [n] pointing to a source in Appendix.
|
|
63
|
+
- Verify dates are present for sources when available; prefer the most recent reputable sources.
|
|
64
|
+
- Remove dead links if discovered; replace with archived or alternative sources when possible.
|
|
65
|
+
- Share a concise chat summary with 3ā6 bullets and the saved file path.
|
|
66
|
+
|
|
67
|
+
## Citation rules
|
|
68
|
+
- Use numeric references [1], [2], ... inline; match them in the Appendix.
|
|
69
|
+
- Quote short key phrases exactly (with quotation marks) and include context.
|
|
70
|
+
- Include publish/update date and access date (today) when available.
|
|
71
|
+
- Prefer primary documentation, official standards, authors/organizations with recognized expertise, and recent updates.
|
|
72
|
+
|
|
73
|
+
## Guardrails and quality
|
|
74
|
+
- Be explicit when uncertain; avoid speculation. If evidence is weak, state it.
|
|
75
|
+
- Distinguish proven facts vs. interpretations. Label opinions as such.
|
|
76
|
+
- Avoid paywalled content if it prevents verification; seek alternative open sources or include accessible abstracts.
|
|
77
|
+
- If new questions arise, loop back with targeted websearch/fetch until conclusions are well-supported.
|
|
78
|
+
|
|
79
|
+
## Usage
|
|
80
|
+
- In chat, switch to āDeep Researchā mode. Provide your query and optionally `suffix:` or `filename:` hint (e.g., suffix: chiplet-market-2025).
|
|
81
|
+
- This mode will produce the report and post the saved path, e.g., ./.ai/deep_research_chiplet-market-2025.md.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Appearance
|
|
3
|
+
"theme": "Default", // Could also be "GitHub", "Dracula", etc.
|
|
4
|
+
|
|
5
|
+
// Authentication
|
|
6
|
+
"selectedAuthType": "gemini-api-key", // Options: "gemini-api-key", "oauth-personal", "vertex-ai"
|
|
7
|
+
|
|
8
|
+
// Tool usage and safety
|
|
9
|
+
"sandbox": false, // Enable with true or specify backend ("docker", "podman")
|
|
10
|
+
"autoAccept": true, // Auto-approve safe tool calls
|
|
11
|
+
"usageStatisticsEnabled": false, // Collect anonymized usage stats
|
|
12
|
+
"telemetry": {
|
|
13
|
+
"enabled": false,
|
|
14
|
+
"target": "remote", // or "local"
|
|
15
|
+
"logPrompts": false
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
// Work environment configuration
|
|
19
|
+
"preferredEditor": "vim", // or "vscode", "nano", etc.
|
|
20
|
+
"fileFiltering": {
|
|
21
|
+
"respectGitIgnore": true,
|
|
22
|
+
"enableRecursiveFileSearch": true
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// Context and workspace behavior
|
|
26
|
+
"contextFileName": "GEMINI.md", // Can also be an array of filenames
|
|
27
|
+
"includeDirectories": [], // e.g., ["../shared", "~/common-utils"]
|
|
28
|
+
"chatCompression": {
|
|
29
|
+
"contextPercentageThreshold": 0.5 // Threshold for compressing history
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
// Bug reporting customization
|
|
33
|
+
"bugCommand": {
|
|
34
|
+
"urlTemplate": "https://github.com/google-gemini/gemini-cli/issues/new?template=bug_report.yml&title={title}&info={info}"
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// Extensions and integrations via MCP servers
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
// Example structure; override or extend as needed
|
|
40
|
+
// "myServer": {
|
|
41
|
+
// "command": "my_mcp_tool",
|
|
42
|
+
// "args": [],
|
|
43
|
+
// "httpUrl": "http://localhost:####/mcp",
|
|
44
|
+
// "headers": {},
|
|
45
|
+
// "timeout": 10000,
|
|
46
|
+
// "trust": false,
|
|
47
|
+
// "includeTools": [],
|
|
48
|
+
// "excludeTools": []
|
|
49
|
+
// }
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
// Control which tools are available
|
|
53
|
+
"coreTools": [
|
|
54
|
+
"EditTool",
|
|
55
|
+
"GlobTool",
|
|
56
|
+
"WebSearchTool",
|
|
57
|
+
"ReadFileTool",
|
|
58
|
+
"LSTool",
|
|
59
|
+
"ReadManyFilesTool",
|
|
60
|
+
"MemoryTool",
|
|
61
|
+
"GrepTool",
|
|
62
|
+
"ShellTool",
|
|
63
|
+
"WebFetchTool",
|
|
64
|
+
"WriteFileTool"
|
|
65
|
+
],
|
|
66
|
+
"excludeTools": [],
|
|
67
|
+
|
|
68
|
+
// Custom color themes (optional)
|
|
69
|
+
"customThemes": {
|
|
70
|
+
"MyCustomTheme": {
|
|
71
|
+
"name": "MyCustomTheme",
|
|
72
|
+
"type": "custom",
|
|
73
|
+
"Background": "#181818",
|
|
74
|
+
"Foreground": "#F8F8F2",
|
|
75
|
+
"AccentBlue": "#61AFEF",
|
|
76
|
+
"AccentPurple": "#C678DD",
|
|
77
|
+
"AccentGreen": "#98C379"
|
|
78
|
+
// Add more as desired
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
|
|
2
|
+
---
|
|
3
|
+
applyTo: "**/*.py"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Python Development Environment and tooling:
|
|
7
|
+
* If you find that uv is not available in terminal, look for how to install it in https://github.com/astral-sh/uv
|
|
8
|
+
* To initialize a new python project, use `cd $repo_root; uv init --python 3.13`
|
|
9
|
+
* To create virtual env, use `cd $repo_root; uv venv`.
|
|
10
|
+
* To install venv and dependency of an existing project, use `cd $repo_root; uv sync`.
|
|
11
|
+
* Please run any python file using `uv run $file.py`
|
|
12
|
+
* Same for tools, e.g. `un run python pytest $file_path`
|
|
13
|
+
* To add a package, use `cd $repo_root; uv add <package_name>`.
|
|
14
|
+
* Please never mention versions of package, so uv will bring the latest.
|
|
15
|
+
* On this note, I have to say that I am seriously concerned about AI using very outdated coding style.
|
|
16
|
+
* Use python 3.13 syntax features.
|
|
17
|
+
* Use modern standards, e.g. Path from pathlib.
|
|
18
|
+
* Never touch `pyproject.toml` manually, this file is strictly managed by `uv` tool on your behalf.
|
|
19
|
+
* If you are writing a test or any temporary script for discovering or undestanding something as an intermediate step, then,
|
|
20
|
+
please keep all your temp scripts and files under ./.ai/tmp_scripts directory, its included in .gitignore and won't litter the repo.
|
|
21
|
+
Its also nice if you create a subdirectory therein to contain relevant files for the task at hand, to avoid confusion with other files from other ai agents working simulataneously on other things.
|
|
22
|
+
* When you run a command in the terminal, please don't assume that it will run in the correct repo root directory. Always cd first to the repo root, or the desired directory, then run the command.
|
|
23
|
+
|
|
24
|
+
# Python Coding Rules
|
|
25
|
+
* Please type hint all the code. Use fully quilaified types, not just generics like dict, list, etc, rather dict[str, int], list[float], 'npt.NDarray[np.float32]', etc.
|
|
26
|
+
* Use `Any` type only if absoloutely necessary.
|
|
27
|
+
* Please use `# type: ignore blah blah`, to silence any warning from pyright or other linters and type checkers, but only when necessary. Otherwise, listen to them and adjust accordingly, or use cast from typing.
|
|
28
|
+
* Use typeddict, dataclasses and literals when necessary to avoid blackbox str or dict[str, str] etc.
|
|
29
|
+
* ALL functions / methods etc must clearly indicate the return type.
|
|
30
|
+
* Do not leave dangling imports or variables unused, prefix their name with underscore if necessary to undicate they are unused.
|
|
31
|
+
* Please prefer to use absolute imports, avoid relatives when possible.
|
|
32
|
+
* Use triple quotes and triple double quotes f-strings for string formatting and avoid when possible all goofy escaping when interpolation.
|
|
33
|
+
* If needed, opt for polars not pandas, whenever possible.
|
|
34
|
+
* when finished, run a linting static analysis check against files you touched, Any fix any mistakes.
|
|
35
|
+
* Please run `uv run -m pyright $file_touched` and address all issues. if `pyright is not there, first run `uv add pyright --dev`.
|
|
36
|
+
* For all type checkers and linters, like mypy, pyright, pyrefly and pylint, there are config files at different levels of the repo all the way up to home directory level. You don't need to worry about them, just be mindful that they exist. The tools themselves will respect the configs therein.
|
|
37
|
+
* If you want to run all linters and pycheckers agains the entire project to make sure everything is clean, I prepared a nice shell script, you can run it from the repo root as `./scripts/lint_and_typecheck.sh`. It will produce markdown files that are you are meant to look at @ ./.linters/*.md
|
|
38
|
+
|
|
39
|
+
# General Programming Ethos:
|
|
40
|
+
* Make sure all the code is rigorous, no lazy stuff.
|
|
41
|
+
* For example, always avoid default values in arguments of functions. Those are evil and cause confusion. Always be explicit in parameter passing.
|
|
42
|
+
* Unless asked explicitly, please never ever attempt to change code files by writing meta code to do string manipulation on files. Please do change the files one by one, no matter how many there is. Don't worry about time, its okay, take your time and do them one by one. You can stop in the middle and we will have another LLM to help with the rest.
|
|
43
|
+
* Please avoid writing README files and avoid docstring and comments in code unless absolutely necessary. Use clear naming conventions instead of documenting.
|
|
44
|
+
* Always prefer to functional style of programming over OOP.
|
|
45
|
+
* When passing arguments or constructing dicts or lists or tuples, avoid breaking lines too much, try to use ~ 150 characters per line before breaking to new one.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
installations = """
|
|
8
|
+
uv add --upgrade-package pylint pyright mypy pyrefly ty --dev # linters and type checkers
|
|
9
|
+
uv add --upgrade-package pytest --dev
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def get_repo_root(path: Path) -> Optional[Path]:
|
|
13
|
+
from git import Repo, InvalidGitRepositoryError
|
|
14
|
+
try:
|
|
15
|
+
repo = Repo(path, search_parent_directories=True)
|
|
16
|
+
root = repo.working_tree_dir
|
|
17
|
+
if root is not None:
|
|
18
|
+
return Path(root)
|
|
19
|
+
except InvalidGitRepositoryError:
|
|
20
|
+
pass
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
def add_ai_configs(repo_root: Path):
|
|
24
|
+
import machineconfig as mc
|
|
25
|
+
mc_root = Path(mc.__file__).parent
|
|
26
|
+
|
|
27
|
+
repo_root_resolved = get_repo_root(repo_root)
|
|
28
|
+
if repo_root_resolved is not None: repo_root = repo_root_resolved # this means you can run the command from any subdirectory of the repo.
|
|
29
|
+
|
|
30
|
+
if repo_root.joinpath("pyproject.toml").exists() is False:
|
|
31
|
+
uv_init = input(f"{repo_root} does not seem to be a python project (no pyproject.toml found), would you like to initialize one? (y/n) ")
|
|
32
|
+
if uv_init.strip().lower() == "y":
|
|
33
|
+
command_to_run = """
|
|
34
|
+
uv init --python 3.13
|
|
35
|
+
uv venv
|
|
36
|
+
"""
|
|
37
|
+
import subprocess
|
|
38
|
+
subprocess.run(command_to_run, shell=True, check=True)
|
|
39
|
+
else:
|
|
40
|
+
print("Terminating mcinit ...")
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
instructions_repository_dir = mc_root.joinpath("scripts/python/ai/instructions")
|
|
44
|
+
chatmodes_dir = mc_root.joinpath("scripts/python/ai/chatmodes")
|
|
45
|
+
prompts_dir = mc_root.joinpath("scripts/python/ai/prompts")
|
|
46
|
+
# python_rules_file = instructions_repository_dir.joinpath("python/dev.md")
|
|
47
|
+
|
|
48
|
+
# VSCODE:
|
|
49
|
+
# as per: https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions
|
|
50
|
+
# Copilot Chat on github website chat & basic guideline.
|
|
51
|
+
repo_root.joinpath(".github/chatmodes").mkdir(parents=True, exist_ok=True)
|
|
52
|
+
repo_root.joinpath(".github/prompts").mkdir(parents=True, exist_ok=True)
|
|
53
|
+
repo_root.joinpath(".github/instructions").mkdir(parents=True, exist_ok=True)
|
|
54
|
+
for a_chatmode in chatmodes_dir.iterdir():
|
|
55
|
+
repo_root.joinpath(".github/chatmodes", a_chatmode.name.split(".")[0] + ".chatmode.md").write_text(data=a_chatmode.read_text(encoding="utf-8"), encoding="utf-8")
|
|
56
|
+
for a_prompt in prompts_dir.iterdir():
|
|
57
|
+
repo_root.joinpath(".github/prompts", a_prompt.name.split(".")[0] + ".prompt.md").write_text(data=a_prompt.read_text(encoding="utf-8"), encoding="utf-8")
|
|
58
|
+
for an_instruction in instructions_repository_dir.rglob("*.md"):
|
|
59
|
+
repo_root.joinpath(".github/instructions", an_instruction.name.split(".")[0] + ".instruction.md").write_text(data=an_instruction.read_text(encoding="utf-8"), encoding="utf-8")
|
|
60
|
+
tmp = repo_root.joinpath(".github/copilot-instructions.md")
|
|
61
|
+
|
|
62
|
+
generic_instructions = instructions_repository_dir.joinpath("python/dev.instructions.md")
|
|
63
|
+
tmp.write_text(data=generic_instructions.read_text(encoding="utf-8"), encoding="utf-8")
|
|
64
|
+
|
|
65
|
+
# CURSOR, GEMINI, CLAUDE CODE, CRUSH, CLINE.
|
|
66
|
+
tmp = repo_root.joinpath(".cursor/rules/python_dev.mdc")
|
|
67
|
+
tmp.parent.mkdir(parents=True, exist_ok=True)
|
|
68
|
+
tmp.write_text(data=generic_instructions.read_text(encoding="utf-8"), encoding="utf-8")
|
|
69
|
+
tmp = repo_root.joinpath("CLAUDE.md")
|
|
70
|
+
tmp.write_text(data=generic_instructions.read_text(encoding="utf-8"), encoding="utf-8")
|
|
71
|
+
tmp = repo_root.joinpath("CRUSH.md")
|
|
72
|
+
tmp.write_text(data=generic_instructions.read_text(encoding="utf-8"), encoding="utf-8")
|
|
73
|
+
|
|
74
|
+
tmp = repo_root.joinpath("GEMINI.md")
|
|
75
|
+
tmp.write_text(data=generic_instructions.read_text(encoding="utf-8"), encoding="utf-8")
|
|
76
|
+
gemini_settings = mc_root.joinpath("scripts/python/ai/configs/.gemini/settings.json")
|
|
77
|
+
repo_root.joinpath(".gemini").mkdir(parents=True, exist_ok=True)
|
|
78
|
+
repo_root.joinpath(".gemini/settings.json").write_text(data=gemini_settings.read_text(encoding="utf-8"), encoding="utf-8")
|
|
79
|
+
|
|
80
|
+
# OTHERS
|
|
81
|
+
scripts_dir = mc_root.joinpath("scripts/python/ai/scripts")
|
|
82
|
+
repo_root.joinpath("scripts").mkdir(parents=True, exist_ok=True)
|
|
83
|
+
for a_script in scripts_dir.iterdir():
|
|
84
|
+
repo_root.joinpath("scripts", a_script.name).write_text(data=a_script.read_text(encoding="utf-8"), encoding="utf-8")
|
|
85
|
+
|
|
86
|
+
dot_ai_dir = repo_root.joinpath(".ai")
|
|
87
|
+
dot_ai_dir.mkdir(parents=True, exist_ok=True)
|
|
88
|
+
dot_git_ignore_path = repo_root.joinpath(".gitignore")
|
|
89
|
+
if dot_git_ignore_path.exists():
|
|
90
|
+
dot_git_ignore_content = dot_git_ignore_path.read_text(encoding="utf-8")
|
|
91
|
+
to_add: list[str] = []
|
|
92
|
+
to_check_for: list[str] = [".links", "notebooks", ".ai", "scripts",
|
|
93
|
+
"GEMINI.md", "CLAUDE.md", ".cursor", ".github"]
|
|
94
|
+
for item in to_check_for:
|
|
95
|
+
if item not in dot_git_ignore_content:
|
|
96
|
+
to_add.append(item)
|
|
97
|
+
# if "*.ipynb"
|
|
98
|
+
if len(to_add) > 0:
|
|
99
|
+
dot_git_ignore_path.write_text(data=dot_git_ignore_content + "\n" + "\n".join(to_add), encoding="utf-8")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
add_ai_configs(repo_root=Path.cwd())
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
```prompt
|
|
2
|
+
---
|
|
3
|
+
description: 'A minimal skeleton for deep research reports.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# <Title>
|
|
7
|
+
|
|
8
|
+
Date: <YYYY-MM-DD>
|
|
9
|
+
|
|
10
|
+
## Executive summary
|
|
11
|
+
- <key point 1> [n]
|
|
12
|
+
- <key point 2> [n]
|
|
13
|
+
- <key point 3> [n]
|
|
14
|
+
|
|
15
|
+
## Key findings
|
|
16
|
+
### <Finding A>
|
|
17
|
+
- Claim: <text> [n]
|
|
18
|
+
- Evidence: "<quote>" [n]
|
|
19
|
+
- Notes: <brief trust/limitations>
|
|
20
|
+
|
|
21
|
+
### <Finding B>
|
|
22
|
+
- Claim: <text> [n]
|
|
23
|
+
- Evidence: "<quote>" [n]
|
|
24
|
+
|
|
25
|
+
## Analysis
|
|
26
|
+
- Trade-offs
|
|
27
|
+
- Uncertainties
|
|
28
|
+
- What to watch next
|
|
29
|
+
|
|
30
|
+
## Recommendations / Direct answer
|
|
31
|
+
- <concise recommendation or answer> [n]
|
|
32
|
+
|
|
33
|
+
## Appendix: Sources
|
|
34
|
+
[1] <Title> ā <Author/Org>, <Date>. <URL>
|
|
35
|
+
[2] <Title> ā <Author/Org>, <Date>. <URL>
|
|
36
|
+
[3] <Title> ā <Author/Org>, <Date>. <URL>
|
|
37
|
+
|
|
38
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
# gotch1: make sure we are in the right directory: repo root. Solution: check if .pyproject.toml exists, otherwise stop.
|
|
3
|
+
if [ ! -f "./pyproject.toml" ]; then
|
|
4
|
+
echo "Error: pyproject.toml not found in the current directory. Please run this script from the root of a Python project."
|
|
5
|
+
exit 1
|
|
6
|
+
fi
|
|
7
|
+
|
|
8
|
+
echo "Running linting and type checking..."
|
|
9
|
+
|
|
10
|
+
echo "Setting up environment..."
|
|
11
|
+
uv add pylint pyright mypy pyrefly ruff ty --dev # linters and type checkers
|
|
12
|
+
uv add cleanpy --dev # codebase cleaner
|
|
13
|
+
|
|
14
|
+
uv add types-requests types-toml types-PyYAML types-pytz types-paramiko types-urllib3 --dev
|
|
15
|
+
uv add types-mysqlclient types-SQLAlchemy --dev
|
|
16
|
+
uv add types-pytest-lazy-fixtures --dev
|
|
17
|
+
|
|
18
|
+
uv run -m cleanpy .
|
|
19
|
+
uv run -m ruff clean
|
|
20
|
+
uv run -m ruff format .
|
|
21
|
+
uv run -m ruff check . --fix
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
mkdir .linters
|
|
25
|
+
|
|
26
|
+
echo "Running pyright..."
|
|
27
|
+
rm ./.linters/pyright_result.md || true
|
|
28
|
+
uv run pyright . > ./.linters/pyright_result.md
|
|
29
|
+
echo "Results of pyright are in ./.linters/pyright_result.md"
|
|
30
|
+
|
|
31
|
+
rm ./.linters/mypy_result.md || true
|
|
32
|
+
uv run mypy . > ./.linters/mypy_result.md
|
|
33
|
+
echo "Results of mypy are in ./.linters/mypy_result.md"
|
|
34
|
+
|
|
35
|
+
rm ./.linters/pylint_result.md || true
|
|
36
|
+
uv run pylint ./src/ > ./.linters/pylint_result.md
|
|
37
|
+
echo "Results of pylint are in ./.linters/pylint_result.md"
|
|
38
|
+
|
|
39
|
+
rm ./.linters/pylint_result.md || true
|
|
40
|
+
uv run pyrefly check . > ./.linters/pyrefly_result.md
|
|
41
|
+
echo "Results of pyrefly are in ./.linters/pyrefly_result.md"
|
|
42
|
+
|
|
43
|
+
rm ./.linters/ruff_result.md || true
|
|
44
|
+
uv run ruff check . > ./.linters/ruff_result.md
|
|
45
|
+
echo "Results of ruff are in ./.linters/ruff_result.md"
|
|
46
|
+
|
|
47
|
+
echo "All done! Please check the .linters directory for results."
|
|
@@ -21,19 +21,19 @@ def get_conn_string(sess_name: str) -> str:
|
|
|
21
21
|
|
|
22
22
|
def main():
|
|
23
23
|
console.print(Panel("š Tmate Connection Manager", title="[bold]Welcome[/bold]"))
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
parser = argparse.ArgumentParser(description='Tmate launcher')
|
|
26
26
|
parser.add_argument("sess_name", help="session name", default=random.choices(list(string.digits + string.ascii_letters), k=20))
|
|
27
27
|
args = parser.parse_args()
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
console.print(f"š Looking up session: {args.sess_name}")
|
|
30
30
|
conn_string = get_conn_string(args.sess_name)
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
console.print(Panel(f"SSH Connection String: ssh {conn_string}", title="[bold green]SSH Connection[/bold green]"))
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
console.print("š Connecting to tmate session...")
|
|
35
35
|
os.system(f"ssh {conn_string}")
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
console.print("ā
Connection closed")
|
|
38
38
|
|
|
39
39
|
|
|
@@ -30,13 +30,13 @@ def main():
|
|
|
30
30
|
console.print(f"š Looking up session configuration: {args.sess_name}")
|
|
31
31
|
sess_name = creds['sessions_names'][args.sess_name]
|
|
32
32
|
api_key = creds['keys']['api_key']
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
console.print(Panel(f"š Starting tmate session: {sess_name}", title="[bold green]Session Info[/bold green]"))
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
res = f"tmate -a ~/.ssh/authorized_keys -k {api_key} -n {sess_name} -F"
|
|
37
37
|
console.print("[bold cyan]Running:[/bold cyan] tmate with configured API key and session name")
|
|
38
38
|
os.system(res)
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
console.print("[green]Tmate session ended[/green]")
|
|
41
41
|
|
|
42
42
|
|
|
@@ -51,13 +51,13 @@ def main2():
|
|
|
51
51
|
|
|
52
52
|
def set_theme(theme: str):
|
|
53
53
|
print(f"š Setting WezTerm theme to: {theme}")
|
|
54
|
-
txt_lines = PathExtended("~/.config/wezterm/wezterm.lua").expanduser().read_text().splitlines()
|
|
54
|
+
txt_lines = PathExtended("~/.config/wezterm/wezterm.lua").expanduser().read_text(encoding="utf-8").splitlines()
|
|
55
55
|
res_lines = []
|
|
56
56
|
for line in txt_lines:
|
|
57
57
|
if 'config.color_scheme = ' in line:
|
|
58
58
|
res_lines.append(f"config.color_scheme = '{theme}'")
|
|
59
59
|
else: res_lines.append(line)
|
|
60
|
-
PathExtended("~/.config/wezterm/wezterm.lua").expanduser().write_text('\n'.join(res_lines))
|
|
60
|
+
PathExtended("~/.config/wezterm/wezterm.lua").expanduser().write_text('\n'.join(res_lines), encoding="utf-8")
|
|
61
61
|
time.sleep(0.1)
|
|
62
62
|
print("š¾ Configuration saved")
|
|
63
63
|
|
|
@@ -3,7 +3,7 @@ CC
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from machineconfig.utils.path_reduced import P as PathExtended
|
|
6
|
-
from
|
|
6
|
+
from tenacity import retry, stop_after_attempt, wait_chain, wait_fixed
|
|
7
7
|
import getpass
|
|
8
8
|
import argparse
|
|
9
9
|
import os
|
|
@@ -18,19 +18,19 @@ from machineconfig.utils.utils2 import pprint
|
|
|
18
18
|
|
|
19
19
|
console = Console()
|
|
20
20
|
|
|
21
|
-
@
|
|
21
|
+
@retry(stop=stop_after_attempt(3), wait=wait_chain(wait_fixed(1), wait_fixed(4), wait_fixed(9)))
|
|
22
22
|
def get_securely_shared_file(url: Optional[str] = None, folder: Optional[str] = None) -> None:
|
|
23
23
|
console.print(Panel("š Secure File Downloader", title="[bold blue]Downloader[/bold blue]", border_style="blue"))
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
folder_obj = PathExtended.cwd() if folder is None else PathExtended(folder)
|
|
26
26
|
print(f"š Target folder: {folder_obj}")
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
if os.environ.get("DECRYPTION_PASSWORD") is not None:
|
|
29
29
|
print("š Using password from environment variables")
|
|
30
30
|
pwd = str(os.environ.get("DECRYPTION_PASSWORD"))
|
|
31
31
|
else:
|
|
32
32
|
pwd = getpass.getpass(prompt="š Enter decryption password: ")
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
if url is None:
|
|
35
35
|
if os.environ.get("SHARE_URL") is not None:
|
|
36
36
|
url = os.environ.get("SHARE_URL")
|
|
@@ -38,21 +38,22 @@ def get_securely_shared_file(url: Optional[str] = None, folder: Optional[str] =
|
|
|
38
38
|
print("š Using URL from environment variables")
|
|
39
39
|
else:
|
|
40
40
|
url = input("š Enter share URL: ")
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
console.print(Panel("š” Downloading from URL...", title="[bold blue]Download[/bold blue]", border_style="blue"))
|
|
43
43
|
with Progress(transient=True) as progress:
|
|
44
44
|
_task = progress.add_task("Downloading... ", total=None)
|
|
45
45
|
url_obj = PathExtended(url).download(folder=folder_obj)
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
console.print(Panel(f"š„ Downloaded file: {url_obj}", title="[bold green]Success[/bold green]", border_style="green"))
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
console.print(Panel("š Decrypting and extracting...", title="[bold blue]Processing[/bold blue]", border_style="blue"))
|
|
50
50
|
with Progress(transient=True) as progress:
|
|
51
51
|
_task = progress.add_task("Decrypting... ", total=None)
|
|
52
52
|
tmp_folder = PathExtended.tmpdir(prefix="tmp_unzip")
|
|
53
53
|
try:
|
|
54
54
|
res = url_obj.decrypt(pwd=pwd, inplace=True).unzip(inplace=True, folder=tmp_folder)
|
|
55
|
-
res.search("*")
|
|
55
|
+
for x in res.search("*"):
|
|
56
|
+
x.move(folder=folder_obj, overwrite=True)
|
|
56
57
|
finally:
|
|
57
58
|
# Clean up temporary folder
|
|
58
59
|
if tmp_folder.exists():
|
|
@@ -61,7 +62,7 @@ def get_securely_shared_file(url: Optional[str] = None, folder: Optional[str] =
|
|
|
61
62
|
|
|
62
63
|
def arg_parser() -> None:
|
|
63
64
|
console.print(Panel("āļø Cloud Copy Utility", title="[bold blue]Cloud Copy[/bold blue]", border_style="blue", width=152))
|
|
64
|
-
|
|
65
|
+
|
|
65
66
|
parser = argparse.ArgumentParser(description='š Cloud CLI. It wraps rclone with sane defaults for optimum type time.')
|
|
66
67
|
|
|
67
68
|
# positional argument
|
|
@@ -105,40 +106,40 @@ def arg_parser() -> None:
|
|
|
105
106
|
|
|
106
107
|
console.print(Panel("š Parsing source and target paths...", title="[bold blue]Info[/bold blue]", border_style="blue"))
|
|
107
108
|
cloud, source, target = parse_cloud_source_target(args=args_obj, source=source, target=target)
|
|
108
|
-
|
|
109
|
+
|
|
109
110
|
console.print(Panel("āļø Configuration:", title="[bold blue]Config[/bold blue]", border_style="blue"))
|
|
110
111
|
pprint(args_obj.__dict__, "CLI config")
|
|
111
112
|
|
|
112
113
|
if args_obj.key is not None:
|
|
113
114
|
console.print(Panel("ā Key-based encryption is not supported yet", title="[bold red]Error[/bold red]", border_style="red"))
|
|
114
115
|
raise ValueError("Key-based encryption is not supported yet.")
|
|
115
|
-
|
|
116
|
+
|
|
116
117
|
if cloud in source:
|
|
117
118
|
console.print(Panel(f"š„ DOWNLOADING FROM CLOUD\nāļø Cloud: {cloud}\nš Source: {source.replace(cloud + ':', '')}\nšÆ Target: {target}", title="[bold blue]Download[/bold blue]", border_style="blue", width=152))
|
|
118
|
-
|
|
119
|
+
|
|
119
120
|
PathExtended(target).from_cloud(cloud=cloud, remotepath=source.replace(cloud + ":", ""),
|
|
120
121
|
unzip=args_obj.zip, decrypt=args_obj.encrypt, pwd=args_obj.pwd,
|
|
121
122
|
overwrite=args_obj.overwrite,
|
|
122
123
|
rel2home=args_obj.rel2home, os_specific=args_obj.os_specific, root=args_obj.root, strict=False,
|
|
123
124
|
)
|
|
124
125
|
console.print(Panel("ā
Download completed successfully", title="[bold green]Success[/bold green]", border_style="green", width=152))
|
|
125
|
-
|
|
126
|
+
|
|
126
127
|
elif cloud in target:
|
|
127
128
|
console.print(Panel(f"š¤ UPLOADING TO CLOUD\nāļø Cloud: {cloud}\nš Source: {source}\nšÆ Target: {target.replace(cloud + ':', '')}", title="[bold blue]Upload[/bold blue]", border_style="blue", width=152))
|
|
128
|
-
|
|
129
|
+
|
|
129
130
|
res = PathExtended(source).to_cloud(cloud=cloud, remotepath=target.replace(cloud + ":", ""),
|
|
130
131
|
zip=args_obj.zip, encrypt=args_obj.encrypt, pwd=args_obj.pwd,
|
|
131
132
|
rel2home=args_obj.rel2home, root=args_obj.root, os_specific=args_obj.os_specific, strict=False,
|
|
132
133
|
share=args_obj.share)
|
|
133
134
|
console.print(Panel("ā
Upload completed successfully", title="[bold green]Success[/bold green]", border_style="green", width=152))
|
|
134
|
-
|
|
135
|
+
|
|
135
136
|
if args_obj.share:
|
|
136
137
|
fname = f".share_url_{cloud}"
|
|
137
138
|
if PathExtended(source).is_dir(): share_url_path = PathExtended(source).joinpath(fname)
|
|
138
139
|
else: share_url_path = PathExtended(source).with_suffix(fname)
|
|
139
|
-
share_url_path.write_text(res.as_url_str())
|
|
140
|
+
share_url_path.write_text(res.as_url_str(), encoding="utf-8")
|
|
140
141
|
console.print(Panel(f"š SHARE URL GENERATED\nš URL file: {share_url_path}\nš {res.as_url_str()}", title="[bold blue]Share[/bold blue]", border_style="blue", width=152))
|
|
141
|
-
else:
|
|
142
|
+
else:
|
|
142
143
|
console.print(Panel(f"ā ERROR: Cloud '{cloud}' not found in source or target", title="[bold red]Error[/bold red]", border_style="red", width=152))
|
|
143
144
|
raise ValueError(f"Cloud `{cloud}` not found in source or target.")
|
|
144
145
|
|
|
@@ -28,13 +28,15 @@ def get_rclone_config():
|
|
|
28
28
|
def get_mprocs_mount_txt(cloud: str, rclone_cmd: str, cloud_brand: str): # cloud_brand = config[cloud]["type"]
|
|
29
29
|
header = f"{' ' + cloud + ' | ' + cloud_brand + ' '}".center(50, "=")
|
|
30
30
|
if platform.system() == "Windows":
|
|
31
|
-
sub_text_path = PathExtended.tmpfile(suffix=".ps1")
|
|
31
|
+
sub_text_path = PathExtended.tmpfile(suffix=".ps1")
|
|
32
|
+
sub_text_path.parent.mkdir(parents=True, exist_ok=True)
|
|
33
|
+
sub_text_path.write_text(f"""
|
|
32
34
|
echo "{header}"
|
|
33
35
|
iex 'rclone about {cloud}:'
|
|
34
36
|
echo 'See {DEFAULT_MOUNT}/{cloud} for the mounted cloud'
|
|
35
37
|
|
|
36
38
|
echo ''
|
|
37
|
-
""")
|
|
39
|
+
""", encoding="utf-8")
|
|
38
40
|
txt = f"""
|
|
39
41
|
cd ~
|
|
40
42
|
mprocs "powershell {sub_text_path}" "{rclone_cmd}" "btm" "timeout 2 & cd {DEFAULT_MOUNT} & lf" "timeout 2 & cd {DEFAULT_MOUNT} & pwsh" "pwsh" --names "info,service,monitor,explorer,main,terminal"
|
|
@@ -49,7 +51,7 @@ def mount(cloud: Optional[str], network: Optional[str], destination: Optional[st
|
|
|
49
51
|
# draw header box dynamically
|
|
50
52
|
title = "āļø Cloud Mount Utility"
|
|
51
53
|
console.print(Panel(title, title_align="left", border_style="blue"))
|
|
52
|
-
|
|
54
|
+
|
|
53
55
|
config = get_rclone_config()
|
|
54
56
|
if cloud is None:
|
|
55
57
|
res = choose_one_option(msg="which cloud", options=config.sections(), header="CLOUD MOUNT", default=None)
|
|
@@ -62,7 +64,7 @@ def mount(cloud: Optional[str], network: Optional[str], destination: Optional[st
|
|
|
62
64
|
mount_loc = PathExtended(DEFAULT_MOUNT).expanduser().joinpath(cloud)
|
|
63
65
|
else:
|
|
64
66
|
mount_loc = PathExtended(destination)
|
|
65
|
-
|
|
67
|
+
|
|
66
68
|
mount_info = f"š Mount location: {mount_loc}"
|
|
67
69
|
console.print(Panel(mount_info, border_style="blue"))
|
|
68
70
|
|
|
@@ -81,7 +83,7 @@ def mount(cloud: Optional[str], network: Optional[str], destination: Optional[st
|
|
|
81
83
|
pass
|
|
82
84
|
else: raise ValueError("unsupported platform")
|
|
83
85
|
|
|
84
|
-
elif network and platform.system() == "Windows":
|
|
86
|
+
elif network and platform.system() == "Windows":
|
|
85
87
|
mount_loc = "X: --network-mode"
|
|
86
88
|
print(f"š Setting up network mount at {mount_loc}")
|
|
87
89
|
else: raise ValueError("network mount only supported on windows")
|
|
@@ -130,7 +132,7 @@ zellij action move-focus up
|
|
|
130
132
|
"""
|
|
131
133
|
else: raise ValueError("unsupported platform")
|
|
132
134
|
# print(f"running command: \n{txt}")
|
|
133
|
-
PROGRAM_PATH.write_text(txt)
|
|
135
|
+
PROGRAM_PATH.write_text(txt, encoding="utf-8")
|
|
134
136
|
# draw success box dynamically
|
|
135
137
|
title1 = "ā
Cloud mount command prepared successfully"
|
|
136
138
|
title2 = "š Running mount process..."
|
|
@@ -141,7 +143,7 @@ def main():
|
|
|
141
143
|
# draw main title box dynamically
|
|
142
144
|
main_title = "āļø RCLONE CLOUD MOUNT"
|
|
143
145
|
console.print(Panel(main_title, title_align="left", border_style="blue"))
|
|
144
|
-
|
|
146
|
+
|
|
145
147
|
parser = argparse.ArgumentParser(description='mount cloud')
|
|
146
148
|
parser.add_argument('cloud', nargs='?', type=str, default=None, help='cloud to mount')
|
|
147
149
|
parser.add_argument('destination', nargs='?', type=str, default=None, help='destination to mount')
|