@liangmi/mo 0.0.5
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.
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/bin/mo-inner.mjs +3 -0
- package/bin/mo.mjs +3 -0
- package/config_schema.json +68 -0
- package/dist/mo-inner.mjs +86 -0
- package/dist/mo.mjs +5363 -0
- package/dist/runner-BDAeQY-R.mjs +1750 -0
- package/package.json +67 -0
- package/scripts/install.ts +63 -0
- package/scripts/uninstall.ts +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present, Liang Mi <https://github.com/liangmiQwQ> and contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# mo
|
|
2
|
+
|
|
3
|
+
**M**anage your **O**pensource projects!
|
|
4
|
+
|
|
5
|
+
It just keeps your repos organized like this:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
|
|
9
|
+
~/code
|
|
10
|
+
├── vitejs
|
|
11
|
+
│ ├── vite
|
|
12
|
+
│ └── devtools
|
|
13
|
+
└── vuejs
|
|
14
|
+
├── core
|
|
15
|
+
└── vue
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
|
|
23
|
+
vp install -g @liangmi/mo
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Requirements
|
|
28
|
+
|
|
29
|
+
- macOS or Linux (Windows is not supported)
|
|
30
|
+
- global install (local install is not supported for runtime usage)
|
|
31
|
+
- `git`
|
|
32
|
+
- GitHub CLI `gh` authenticated (`gh auth status`)
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
Run setup once:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
mo setup
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`mo setup` will:
|
|
43
|
+
|
|
44
|
+
1. check `git`
|
|
45
|
+
2. check `gh` authentication
|
|
46
|
+
3. ask for your projects root directory
|
|
47
|
+
4. ask which shell(s) you use (`zsh`, `bash`, `fish`)
|
|
48
|
+
5. optionally collect aliases for `mo clone`, `mo list`, and `mo cd`
|
|
49
|
+
6. write `~/.config/morc.json`
|
|
50
|
+
7. sync managed shellrc blocks
|
|
51
|
+
|
|
52
|
+
After setup:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
mo clone vitejs/vite
|
|
56
|
+
mo list
|
|
57
|
+
mo cd
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Commands
|
|
61
|
+
|
|
62
|
+
### `mo setup`
|
|
63
|
+
|
|
64
|
+
Initialize config and shell integration.
|
|
65
|
+
|
|
66
|
+
### `mo clone <owner>/<repo>`
|
|
67
|
+
|
|
68
|
+
Clone a GitHub repository into `<root>/<owner>/<repo>`.
|
|
69
|
+
|
|
70
|
+
Alias: `mo c <owner>/<repo>`
|
|
71
|
+
|
|
72
|
+
Example:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mo clone vuejs/core
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `mo list`
|
|
79
|
+
|
|
80
|
+
List repositories under your configured root.
|
|
81
|
+
|
|
82
|
+
Alias: `mo ls`
|
|
83
|
+
|
|
84
|
+
### `mo cd [target]`
|
|
85
|
+
|
|
86
|
+
Resolve and jump to a managed path in your shell integration function.
|
|
87
|
+
|
|
88
|
+
Without `target`, it opens an interactive selector for:
|
|
89
|
+
|
|
90
|
+
- root
|
|
91
|
+
- owner directory
|
|
92
|
+
- repository directory
|
|
93
|
+
|
|
94
|
+
With `target`, supported forms are:
|
|
95
|
+
|
|
96
|
+
- `root` or `.`
|
|
97
|
+
- `<owner>`
|
|
98
|
+
- `<owner>/<repo>`
|
|
99
|
+
|
|
100
|
+
Alias: `mo d`
|
|
101
|
+
|
|
102
|
+
## Config
|
|
103
|
+
|
|
104
|
+
Default config path:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
~/.config/morc.json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Example:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"$schema": "https://raw.githubusercontent.com/liangmiQwQ/mo/main/config_schema.json",
|
|
115
|
+
"root": "~/code",
|
|
116
|
+
"shells": ["zsh"],
|
|
117
|
+
"alias": {
|
|
118
|
+
"clone": ["k"],
|
|
119
|
+
"list": ["li"],
|
|
120
|
+
"cd": ["i"]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Fields
|
|
126
|
+
|
|
127
|
+
- `root` (required): absolute path or `~` path for your projects directory
|
|
128
|
+
- `shells` (required): one or more of `zsh`, `bash`, `fish`
|
|
129
|
+
- `alias` (optional): alias arrays for `clone`, `list`, `cd`
|
|
130
|
+
|
|
131
|
+
Alias names must match:
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
[A-Za-z_][A-Za-z0-9_-]*
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Shell Integration
|
|
138
|
+
|
|
139
|
+
`mo` manages shell integration blocks in your shellrc files:
|
|
140
|
+
|
|
141
|
+
- `~/.zshrc`
|
|
142
|
+
- `~/.bashrc`
|
|
143
|
+
- `~/.config/fish/config.fish`
|
|
144
|
+
|
|
145
|
+
## Notes
|
|
146
|
+
|
|
147
|
+
- If you run config-required commands without config, `mo` prompts you to run `mo setup`.
|
|
148
|
+
- `mo list` only shows repositories that are Git repos with a GitHub remote.
|
|
149
|
+
|
|
150
|
+
## Contribution
|
|
151
|
+
|
|
152
|
+
We're really excited to receive your contributions! Please see [ROADMAP.md](./ROADMAP.md) for details!
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
[MIT](./LICENSE) © Liang Mi
|
package/bin/mo-inner.mjs
ADDED
package/bin/mo.mjs
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Morc",
|
|
4
|
+
"description": "Configuration file for mo - Project manager for opensource developers on Github.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["root", "shells"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"root": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The root directory where all your GitHub repositories are stored. Relative to the config file location.",
|
|
11
|
+
"examples": ["~/code", "/Users/username/code", "C:\\Users\\username\\code"]
|
|
12
|
+
},
|
|
13
|
+
"editor": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "The default editor command to open repositories",
|
|
16
|
+
"examples": ["code", "cursor", "agy", "zed"]
|
|
17
|
+
},
|
|
18
|
+
"shells": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"description": "Shells whose shellrc files should be managed by mo. At least one shell is required.",
|
|
21
|
+
"items": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"enum": ["zsh", "bash", "fish"]
|
|
24
|
+
},
|
|
25
|
+
"minItems": 1,
|
|
26
|
+
"uniqueItems": true,
|
|
27
|
+
"examples": [["zsh"], ["zsh", "fish"]]
|
|
28
|
+
},
|
|
29
|
+
"alias": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"description": "Optional shell aliases for mo commands.",
|
|
32
|
+
"properties": {
|
|
33
|
+
"clone": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"items": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
|
|
38
|
+
},
|
|
39
|
+
"uniqueItems": true
|
|
40
|
+
},
|
|
41
|
+
"list": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
|
|
46
|
+
},
|
|
47
|
+
"uniqueItems": true
|
|
48
|
+
},
|
|
49
|
+
"cd": {
|
|
50
|
+
"type": "array",
|
|
51
|
+
"items": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
|
|
54
|
+
},
|
|
55
|
+
"uniqueItems": true
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"additionalProperties": false
|
|
59
|
+
},
|
|
60
|
+
"$schema": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"description": "The schema URL for this config file."
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"allowComments": true,
|
|
67
|
+
"allowTrailingCommas": true
|
|
68
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { S as cac, _ as buildAliasLines, c as supportedShells, l as error, o as getDefaultConfigPath, s as loadConfig, t as innerBinName } from "./runner-BDAeQY-R.mjs";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
//#region src/inner/shell.ts
|
|
4
|
+
function generateShellIntegration(shell) {
|
|
5
|
+
if (!isValidShell(shell)) error(`Invalid shell "${shell}". Supported: ${supportedShells.join(", ")}`);
|
|
6
|
+
const aliases = loadAliasConfig();
|
|
7
|
+
if (shell === "bash" || shell === "zsh") return generateBashZshIntegration(aliases);
|
|
8
|
+
else return generateFishIntegration(aliases);
|
|
9
|
+
}
|
|
10
|
+
function generateBashZshIntegration(aliases) {
|
|
11
|
+
return [
|
|
12
|
+
"# mo shell integration script",
|
|
13
|
+
"mo() {",
|
|
14
|
+
" if [ \"$1\" = \"cd\" ] || [ \"$1\" = \"d\" ]; then",
|
|
15
|
+
" shift",
|
|
16
|
+
" local mo_cd_target",
|
|
17
|
+
" mo_cd_target=\"$(command mo cd \"$@\")\" || return $?",
|
|
18
|
+
" export MO_CD_TARGET=\"$mo_cd_target\"",
|
|
19
|
+
" else",
|
|
20
|
+
" command mo \"$@\" || return $?",
|
|
21
|
+
" fi",
|
|
22
|
+
"",
|
|
23
|
+
" local mo_cd_result",
|
|
24
|
+
" mo_cd_result=\"$(mo-inner cd)\" || return $?",
|
|
25
|
+
" if [ -n \"$mo_cd_result\" ] && [ \"$mo_cd_result\" != \".\" ]; then",
|
|
26
|
+
" cd \"$mo_cd_result\" || return $?",
|
|
27
|
+
" fi",
|
|
28
|
+
"",
|
|
29
|
+
" unset MO_CD_TARGET",
|
|
30
|
+
"}",
|
|
31
|
+
...buildAliasLines(aliases, (name, target) => `alias ${name}='${target}'`),
|
|
32
|
+
""
|
|
33
|
+
].join("\n");
|
|
34
|
+
}
|
|
35
|
+
function generateFishIntegration(aliases) {
|
|
36
|
+
return [
|
|
37
|
+
"# mo shell integration script",
|
|
38
|
+
"function mo",
|
|
39
|
+
" if test (count $argv) -gt 0; and begin; test \"$argv[1]\" = \"cd\"; or test \"$argv[1]\" = \"d\"; end",
|
|
40
|
+
" set -l mo_cd_target (command mo cd $argv[2..-1])",
|
|
41
|
+
" or return $status",
|
|
42
|
+
" set -gx MO_CD_TARGET \"$mo_cd_target\"",
|
|
43
|
+
" else",
|
|
44
|
+
" command mo $argv",
|
|
45
|
+
" or return $status",
|
|
46
|
+
" end",
|
|
47
|
+
"",
|
|
48
|
+
" set -l mo_cd_result (mo-inner cd)",
|
|
49
|
+
" or return $status",
|
|
50
|
+
" if test -n \"$mo_cd_result\"; and test \"$mo_cd_result\" != \".\"",
|
|
51
|
+
" cd \"$mo_cd_result\"",
|
|
52
|
+
" or return $status",
|
|
53
|
+
" end",
|
|
54
|
+
"",
|
|
55
|
+
" set -e MO_CD_TARGET",
|
|
56
|
+
"end",
|
|
57
|
+
...buildAliasLines(aliases, (name, target) => `alias ${name} '${target}'`),
|
|
58
|
+
""
|
|
59
|
+
].join("\n");
|
|
60
|
+
}
|
|
61
|
+
function isValidShell(shell) {
|
|
62
|
+
return supportedShells.includes(shell);
|
|
63
|
+
}
|
|
64
|
+
function loadAliasConfig() {
|
|
65
|
+
if (!existsSync(getDefaultConfigPath())) return {};
|
|
66
|
+
try {
|
|
67
|
+
return loadConfig().alias ?? {};
|
|
68
|
+
} catch {
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/mo-inner.ts
|
|
74
|
+
const cli = cac(innerBinName);
|
|
75
|
+
cli.command("shell <shell>", "Generate shell integration code").action((shell) => console.log(generateShellIntegration(shell)));
|
|
76
|
+
cli.command("cd", "Print pending directory path from shell state").action(() => {
|
|
77
|
+
const pending = process.env.MO_CD_TARGET;
|
|
78
|
+
if (typeof pending !== "string" || !pending.trim()) {
|
|
79
|
+
console.log(".");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
console.log(pending);
|
|
83
|
+
});
|
|
84
|
+
cli.parse();
|
|
85
|
+
//#endregion
|
|
86
|
+
export {};
|