@gogd-core/ggd 0.1.0 → 0.1.1
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/main.js +95 -2
- package/package.json +4 -1
- package/postinstall.js +201 -0
- package/src/commands/completion.d.ts +36 -0
- package/src/commands/index.d.ts +1 -0
- package/src/index.d.ts +1 -1
- package/src/postinstall.d.ts +33 -0
package/main.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// apps/ggd/src/main.ts
|
|
27
|
-
var
|
|
27
|
+
var import_commander4 = require("commander");
|
|
28
28
|
|
|
29
29
|
// apps/ggd/src/commands/env.ts
|
|
30
30
|
var import_commander = require("commander");
|
|
@@ -81,9 +81,102 @@ function createRunCommand() {
|
|
|
81
81
|
return run;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
// apps/ggd/src/commands/completion.ts
|
|
85
|
+
var import_commander3 = require("commander");
|
|
86
|
+
function detectShell() {
|
|
87
|
+
const shell = process.env["SHELL"] || "";
|
|
88
|
+
if (shell.includes("zsh"))
|
|
89
|
+
return "zsh";
|
|
90
|
+
if (shell.includes("bash"))
|
|
91
|
+
return "bash";
|
|
92
|
+
if (process.platform === "win32")
|
|
93
|
+
return "powershell";
|
|
94
|
+
return "bash";
|
|
95
|
+
}
|
|
96
|
+
function generateBashCompletion() {
|
|
97
|
+
return `###-begin-ggd-completions-###
|
|
98
|
+
_ggd_completions() {
|
|
99
|
+
local cur commands
|
|
100
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
101
|
+
commands="$(ggd --get-completions "\${COMP_WORDS[@]}")"
|
|
102
|
+
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
|
|
103
|
+
}
|
|
104
|
+
complete -F _ggd_completions ggd
|
|
105
|
+
###-end-ggd-completions-###`;
|
|
106
|
+
}
|
|
107
|
+
function generateZshCompletion() {
|
|
108
|
+
return `###-begin-ggd-completions-###
|
|
109
|
+
_ggd_completions() {
|
|
110
|
+
local commands
|
|
111
|
+
commands="$(ggd --get-completions "\${words[@]}")"
|
|
112
|
+
reply=(\${=commands})
|
|
113
|
+
}
|
|
114
|
+
compctl -K _ggd_completions ggd
|
|
115
|
+
###-end-ggd-completions-###`;
|
|
116
|
+
}
|
|
117
|
+
function generatePowershellCompletion() {
|
|
118
|
+
return `# begin-ggd-completions
|
|
119
|
+
Register-ArgumentCompleter -Native -CommandName ggd -ScriptBlock {
|
|
120
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
121
|
+
$words = $commandAst.ToString().Split(' ')
|
|
122
|
+
$completions = & ggd --get-completions @words 2>$null
|
|
123
|
+
$completions -split '\\s+' | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
124
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
# end-ggd-completions`;
|
|
128
|
+
}
|
|
129
|
+
function getCompletionScript(shell) {
|
|
130
|
+
switch (shell) {
|
|
131
|
+
case "bash":
|
|
132
|
+
return generateBashCompletion();
|
|
133
|
+
case "zsh":
|
|
134
|
+
return generateZshCompletion();
|
|
135
|
+
case "powershell":
|
|
136
|
+
return generatePowershellCompletion();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function getCompletions(program2, args) {
|
|
140
|
+
const commandNames = program2.commands.map((cmd) => cmd.name());
|
|
141
|
+
const current = args[args.length - 1] || "";
|
|
142
|
+
if (args.length <= 2) {
|
|
143
|
+
return commandNames.filter((name) => name.startsWith(current));
|
|
144
|
+
}
|
|
145
|
+
const subcommandName = args[1];
|
|
146
|
+
const subcommand = program2.commands.find((cmd) => cmd.name() === subcommandName);
|
|
147
|
+
if (subcommand && subcommand.commands.length > 0) {
|
|
148
|
+
const subNames = subcommand.commands.map((cmd) => cmd.name());
|
|
149
|
+
return subNames.filter((name) => name.startsWith(current));
|
|
150
|
+
}
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
var VALID_SHELLS = ["bash", "zsh", "powershell"];
|
|
154
|
+
function createCompletionCommand() {
|
|
155
|
+
const completion = new import_commander3.Command("completion").description("Output shell completion script").argument("[shell]", "Shell type: bash, zsh, powershell (auto-detected if omitted)").action((shell) => {
|
|
156
|
+
const resolved = shell ? validateShell(shell) : detectShell();
|
|
157
|
+
console.log(getCompletionScript(resolved));
|
|
158
|
+
});
|
|
159
|
+
return completion;
|
|
160
|
+
}
|
|
161
|
+
function validateShell(shell) {
|
|
162
|
+
if (!VALID_SHELLS.includes(shell)) {
|
|
163
|
+
console.error(`Unknown shell: ${shell}. Supported: ${VALID_SHELLS.join(", ")}`);
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
return "bash";
|
|
166
|
+
}
|
|
167
|
+
return shell;
|
|
168
|
+
}
|
|
169
|
+
|
|
84
170
|
// apps/ggd/src/main.ts
|
|
85
|
-
var program = new
|
|
171
|
+
var program = new import_commander4.Command();
|
|
86
172
|
program.name("ggd").description("GoGoodDev workspace CLI").version("0.1.0");
|
|
87
173
|
program.addCommand(createEnvCommand());
|
|
88
174
|
program.addCommand(createRunCommand());
|
|
175
|
+
program.addCommand(createCompletionCommand());
|
|
176
|
+
if (process.argv.includes("--get-completions")) {
|
|
177
|
+
const args = process.argv.slice(process.argv.indexOf("--get-completions") + 1);
|
|
178
|
+
const suggestions = getCompletions(program, args);
|
|
179
|
+
console.log(suggestions.join(" "));
|
|
180
|
+
process.exit(0);
|
|
181
|
+
}
|
|
89
182
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gogd-core/ggd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"commander": "12.1.0",
|
|
6
6
|
"execa": "5.1.1"
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
"bin": {
|
|
11
11
|
"ggd": "./main.js"
|
|
12
12
|
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"postinstall": "node ./postinstall.js"
|
|
15
|
+
},
|
|
13
16
|
"description": "GoGoodDev workspace CLI",
|
|
14
17
|
"repository": {
|
|
15
18
|
"type": "git",
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// apps/ggd/src/postinstall.ts
|
|
32
|
+
var postinstall_exports = {};
|
|
33
|
+
__export(postinstall_exports, {
|
|
34
|
+
detectShellForInstall: () => detectShellForInstall,
|
|
35
|
+
getCompletionScriptForShell: () => getCompletionScriptForShell,
|
|
36
|
+
getShellConfigPath: () => getShellConfigPath,
|
|
37
|
+
installCompletions: () => installCompletions,
|
|
38
|
+
removeExistingCompletions: () => removeExistingCompletions,
|
|
39
|
+
runPostinstall: () => runPostinstall
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(postinstall_exports);
|
|
42
|
+
var fs = __toESM(require("fs"));
|
|
43
|
+
var path = __toESM(require("path"));
|
|
44
|
+
var os = __toESM(require("os"));
|
|
45
|
+
|
|
46
|
+
// apps/ggd/src/commands/completion.ts
|
|
47
|
+
var import_commander = require("commander");
|
|
48
|
+
function generateBashCompletion() {
|
|
49
|
+
return `###-begin-ggd-completions-###
|
|
50
|
+
_ggd_completions() {
|
|
51
|
+
local cur commands
|
|
52
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
53
|
+
commands="$(ggd --get-completions "\${COMP_WORDS[@]}")"
|
|
54
|
+
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
|
|
55
|
+
}
|
|
56
|
+
complete -F _ggd_completions ggd
|
|
57
|
+
###-end-ggd-completions-###`;
|
|
58
|
+
}
|
|
59
|
+
function generateZshCompletion() {
|
|
60
|
+
return `###-begin-ggd-completions-###
|
|
61
|
+
_ggd_completions() {
|
|
62
|
+
local commands
|
|
63
|
+
commands="$(ggd --get-completions "\${words[@]}")"
|
|
64
|
+
reply=(\${=commands})
|
|
65
|
+
}
|
|
66
|
+
compctl -K _ggd_completions ggd
|
|
67
|
+
###-end-ggd-completions-###`;
|
|
68
|
+
}
|
|
69
|
+
function generatePowershellCompletion() {
|
|
70
|
+
return `# begin-ggd-completions
|
|
71
|
+
Register-ArgumentCompleter -Native -CommandName ggd -ScriptBlock {
|
|
72
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
73
|
+
$words = $commandAst.ToString().Split(' ')
|
|
74
|
+
$completions = & ggd --get-completions @words 2>$null
|
|
75
|
+
$completions -split '\\s+' | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
76
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
# end-ggd-completions`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// apps/ggd/src/postinstall.ts
|
|
83
|
+
var COMPLETION_MARKERS = ["###-begin-ggd-completions-###", "# begin-ggd-completions"];
|
|
84
|
+
var COMPLETION_END_MARKERS = ["###-end-ggd-completions-###", "# end-ggd-completions"];
|
|
85
|
+
function detectShellForInstall() {
|
|
86
|
+
const shellEnv = process.env["SHELL"] || "";
|
|
87
|
+
if (shellEnv.includes("zsh"))
|
|
88
|
+
return "zsh";
|
|
89
|
+
if (shellEnv.includes("bash"))
|
|
90
|
+
return "bash";
|
|
91
|
+
if (process.platform === "win32")
|
|
92
|
+
return "powershell";
|
|
93
|
+
if (shellEnv)
|
|
94
|
+
return "bash";
|
|
95
|
+
return "unknown";
|
|
96
|
+
}
|
|
97
|
+
function getShellConfigPath(shell) {
|
|
98
|
+
const home = os.homedir();
|
|
99
|
+
switch (shell) {
|
|
100
|
+
case "bash":
|
|
101
|
+
return path.join(home, ".bashrc");
|
|
102
|
+
case "zsh":
|
|
103
|
+
return path.join(home, ".zshrc");
|
|
104
|
+
case "powershell": {
|
|
105
|
+
const psProfile = process.env["USERPROFILE"] ? path.join(process.env["USERPROFILE"], "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1") : null;
|
|
106
|
+
return psProfile;
|
|
107
|
+
}
|
|
108
|
+
default:
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function getCompletionScriptForShell(shell) {
|
|
113
|
+
switch (shell) {
|
|
114
|
+
case "bash":
|
|
115
|
+
return generateBashCompletion();
|
|
116
|
+
case "zsh":
|
|
117
|
+
return generateZshCompletion();
|
|
118
|
+
case "powershell":
|
|
119
|
+
return generatePowershellCompletion();
|
|
120
|
+
default:
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function removeExistingCompletions(content) {
|
|
125
|
+
let startIdx = -1;
|
|
126
|
+
let startMarkerLen = 0;
|
|
127
|
+
for (const marker of COMPLETION_MARKERS) {
|
|
128
|
+
const idx = content.indexOf(marker);
|
|
129
|
+
if (idx !== -1) {
|
|
130
|
+
startIdx = idx;
|
|
131
|
+
startMarkerLen = marker.length;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (startIdx === -1)
|
|
136
|
+
return content;
|
|
137
|
+
let endIdx = -1;
|
|
138
|
+
let endMarkerLen = 0;
|
|
139
|
+
for (const marker of COMPLETION_END_MARKERS) {
|
|
140
|
+
const idx = content.indexOf(marker, startIdx + startMarkerLen);
|
|
141
|
+
if (idx !== -1) {
|
|
142
|
+
endIdx = idx;
|
|
143
|
+
endMarkerLen = marker.length;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (endIdx === -1)
|
|
148
|
+
return content;
|
|
149
|
+
const before = content.substring(0, startIdx).trimEnd();
|
|
150
|
+
const after = content.substring(endIdx + endMarkerLen).trimStart();
|
|
151
|
+
return before + (after ? "\n" + after : "") + "\n";
|
|
152
|
+
}
|
|
153
|
+
function installCompletions(shell) {
|
|
154
|
+
const configPath = getShellConfigPath(shell);
|
|
155
|
+
if (!configPath)
|
|
156
|
+
return false;
|
|
157
|
+
const script = getCompletionScriptForShell(shell);
|
|
158
|
+
if (!script)
|
|
159
|
+
return false;
|
|
160
|
+
try {
|
|
161
|
+
const dir = path.dirname(configPath);
|
|
162
|
+
if (!fs.existsSync(dir)) {
|
|
163
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
164
|
+
}
|
|
165
|
+
let existing = "";
|
|
166
|
+
if (fs.existsSync(configPath)) {
|
|
167
|
+
existing = fs.readFileSync(configPath, "utf8");
|
|
168
|
+
}
|
|
169
|
+
const cleaned = removeExistingCompletions(existing);
|
|
170
|
+
const updated = cleaned.trimEnd() + "\n\n" + script + "\n";
|
|
171
|
+
fs.writeFileSync(configPath, updated, "utf8");
|
|
172
|
+
return true;
|
|
173
|
+
} catch {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function runPostinstall() {
|
|
178
|
+
if (process.env["CI"] || process.env["CONTINUOUS_INTEGRATION"]) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const shell = detectShellForInstall();
|
|
182
|
+
if (shell === "unknown") {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const success = installCompletions(shell);
|
|
186
|
+
if (success) {
|
|
187
|
+
console.log(`ggd: shell completions installed for ${shell}. Restart your shell to activate.`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (require.main === module) {
|
|
191
|
+
runPostinstall();
|
|
192
|
+
}
|
|
193
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
194
|
+
0 && (module.exports = {
|
|
195
|
+
detectShellForInstall,
|
|
196
|
+
getCompletionScriptForShell,
|
|
197
|
+
getShellConfigPath,
|
|
198
|
+
installCompletions,
|
|
199
|
+
removeExistingCompletions,
|
|
200
|
+
runPostinstall
|
|
201
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ggd completion` command — outputs shell completion scripts.
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
type ShellType = 'bash' | 'zsh' | 'powershell';
|
|
6
|
+
/**
|
|
7
|
+
* Auto-detects the current shell from environment variables.
|
|
8
|
+
*/
|
|
9
|
+
export declare function detectShell(): ShellType;
|
|
10
|
+
/**
|
|
11
|
+
* Generates a Bash completion script for ggd.
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateBashCompletion(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generates a Zsh completion script for ggd.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateZshCompletion(): string;
|
|
18
|
+
/**
|
|
19
|
+
* Generates a PowerShell completion script for ggd.
|
|
20
|
+
*/
|
|
21
|
+
export declare function generatePowershellCompletion(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the completion script for the given shell type.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getCompletionScript(shell: ShellType): string;
|
|
26
|
+
/**
|
|
27
|
+
* Returns completion suggestions for the given CLI arguments.
|
|
28
|
+
* Used internally by `--get-completions`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getCompletions(program: Command, args: string[]): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Creates the `completion` command.
|
|
33
|
+
* Outputs a shell completion script to stdout.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createCompletionCommand(): Command;
|
|
36
|
+
export {};
|
package/src/commands/index.d.ts
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createEnvCommand, createRunCommand } from './commands';
|
|
1
|
+
export { createEnvCommand, createRunCommand, createCompletionCommand } from './commands';
|
|
2
2
|
export { exec, isWindows, defaultShell } from './core';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postinstall script for ggd CLI.
|
|
3
|
+
*
|
|
4
|
+
* Auto-installs shell completion on `npm install -g @gogd-core/ggd`.
|
|
5
|
+
* Gracefully skips if it cannot detect the shell or write to config files.
|
|
6
|
+
*/
|
|
7
|
+
type ShellType = 'bash' | 'zsh' | 'powershell' | 'unknown';
|
|
8
|
+
/**
|
|
9
|
+
* Detects the user's shell for postinstall context.
|
|
10
|
+
*/
|
|
11
|
+
export declare function detectShellForInstall(): ShellType;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the shell config file path for the given shell.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getShellConfigPath(shell: ShellType): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the completion script for the given shell.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getCompletionScriptForShell(shell: ShellType): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Removes any existing ggd completion block from content.
|
|
22
|
+
*/
|
|
23
|
+
export declare function removeExistingCompletions(content: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Installs shell completions by appending to the shell config file.
|
|
26
|
+
* Returns true on success, false on skip/failure.
|
|
27
|
+
*/
|
|
28
|
+
export declare function installCompletions(shell: ShellType): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Main postinstall entry point.
|
|
31
|
+
*/
|
|
32
|
+
export declare function runPostinstall(): void;
|
|
33
|
+
export {};
|