@gobi-ai/cli 0.7.3 → 0.9.0

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.
@@ -1,199 +0,0 @@
1
- import { execSync } from "node:child_process";
2
- import {
3
- readFileSync,
4
- writeFileSync,
5
- mkdirSync,
6
- existsSync,
7
- readdirSync,
8
- unlinkSync,
9
- } from "node:fs";
10
- import { join, dirname } from "node:path";
11
- import { fileURLToPath } from "node:url";
12
- import { createRequire } from "node:module";
13
-
14
- const __filename = fileURLToPath(import.meta.url);
15
- const __dirname = dirname(__filename);
16
- const SKILL_DIR = join(__dirname, "..");
17
- const REFERENCES_DIR = join(SKILL_DIR, "references");
18
- const TEMPLATE_PATH = join(SKILL_DIR, "SKILL.template.md");
19
- const OUTPUT_PATH = join(SKILL_DIR, "SKILL.md");
20
- const PROJECT_ROOT = join(SKILL_DIR, "..", "..");
21
- // Read version from package.json
22
- const require = createRequire(import.meta.url);
23
- const { version } = require(join(PROJECT_ROOT, "package.json")) as {
24
- version: string;
25
- };
26
-
27
- // Use the built dist/index.js so this works in CI without global install
28
- const GOBI_BIN = join(PROJECT_ROOT, "dist", "index.js");
29
-
30
- if (!existsSync(GOBI_BIN)) {
31
- console.error(
32
- "Error: dist/index.js not found. Run 'npm run build' first."
33
- );
34
- process.exit(1);
35
- }
36
-
37
- // ---------------------------------------------------------------------------
38
- // Helpers
39
- // ---------------------------------------------------------------------------
40
-
41
- function runHelp(args: string[]): string {
42
- const cmd = `node ${GOBI_BIN} ${args.join(" ")} --help`;
43
- return execSync(cmd, {
44
- encoding: "utf-8",
45
- env: { ...process.env, NO_COLOR: "1" },
46
- timeout: 10_000,
47
- }).trim();
48
- }
49
-
50
- interface CommandInfo {
51
- name: string;
52
- description: string;
53
- }
54
-
55
- /**
56
- * Parse Commander.js help output to extract the Commands section.
57
- * Commander format:
58
- * Commands:
59
- * name [options] description
60
- * help [command] display help for command
61
- */
62
- function parseCommands(helpText: string): CommandInfo[] {
63
- const commands: CommandInfo[] = [];
64
- const lines = helpText.split("\n");
65
- let inCommands = false;
66
-
67
- for (const line of lines) {
68
- if (line.trim() === "Commands:") {
69
- inCommands = true;
70
- continue;
71
- }
72
- if (inCommands) {
73
- // Match: leading whitespace, command name, possible args, 2+ spaces, description
74
- const match = line.match(/^\s{2,}(\S+)\s+.*?\s{2,}(.+)$/);
75
- if (match) {
76
- const [, name, desc] = match;
77
- if (name !== "help") {
78
- commands.push({ name, description: desc.trim() });
79
- }
80
- } else if (line.trim() === "") {
81
- break;
82
- } else if (commands.length > 0 && line.match(/^\s{10,}\S/)) {
83
- // Continuation line of the previous command's wrapped description
84
- commands[commands.length - 1].description += " " + line.trim();
85
- }
86
- }
87
- }
88
-
89
- return commands;
90
- }
91
-
92
- // ---------------------------------------------------------------------------
93
- // Generate reference docs
94
- // ---------------------------------------------------------------------------
95
-
96
- function generateReferenceDoc(
97
- commandPath: string[],
98
- helpText: string,
99
- subcommands: { name: string; helpText: string }[]
100
- ): string {
101
- const lines: string[] = [];
102
- const fullCommand = ["gobi", ...commandPath].join(" ");
103
-
104
- lines.push(`# ${fullCommand}`);
105
- lines.push("");
106
- lines.push("```");
107
- lines.push(helpText);
108
- lines.push("```");
109
-
110
- for (const sub of subcommands) {
111
- lines.push("");
112
- lines.push(`## ${sub.name}`);
113
- lines.push("");
114
- lines.push("```");
115
- lines.push(sub.helpText);
116
- lines.push("```");
117
- }
118
-
119
- return lines.join("\n") + "\n";
120
- }
121
-
122
- // ---------------------------------------------------------------------------
123
- // Main
124
- // ---------------------------------------------------------------------------
125
-
126
- // Ensure references directory exists
127
- if (!existsSync(REFERENCES_DIR)) {
128
- mkdirSync(REFERENCES_DIR, { recursive: true });
129
- }
130
-
131
- // Clean existing generated reference files
132
- for (const file of readdirSync(REFERENCES_DIR)) {
133
- if (file.endsWith(".md")) {
134
- unlinkSync(join(REFERENCES_DIR, file));
135
- }
136
- }
137
-
138
- // 1. Get top-level commands
139
- const topHelp = runHelp([]);
140
- const topCommands = parseCommands(topHelp);
141
-
142
- // 2. Generate reference files for each command group
143
- const referenceFiles: { name: string; path: string; title: string }[] = [];
144
- const commandLines: string[] = [];
145
-
146
- for (const cmd of topCommands) {
147
- let cmdHelp: string;
148
- try {
149
- cmdHelp = runHelp([cmd.name]);
150
- } catch {
151
- // Leaf command with no subcommands — use top-level help
152
- cmdHelp = `${cmd.description}`;
153
- }
154
-
155
- const subCommands = parseCommands(cmdHelp);
156
-
157
- // Build command listing
158
- commandLines.push(`- \`gobi ${cmd.name}\` — ${cmd.description}`);
159
-
160
- const subHelpTexts: { name: string; helpText: string }[] = [];
161
- for (const sub of subCommands) {
162
- try {
163
- const subHelp = runHelp([cmd.name, sub.name]);
164
- subHelpTexts.push({ name: sub.name, helpText: subHelp });
165
- commandLines.push(
166
- ` - \`gobi ${cmd.name} ${sub.name}\` — ${sub.description}`
167
- );
168
- } catch {
169
- // Skip commands that fail (e.g. interactive-only)
170
- }
171
- }
172
-
173
- const refContent = generateReferenceDoc([cmd.name], cmdHelp, subHelpTexts);
174
- const refFile = `${cmd.name}.md`;
175
- writeFileSync(join(REFERENCES_DIR, refFile), refContent);
176
- referenceFiles.push({
177
- name: refFile,
178
- path: `references/${refFile}`,
179
- title: `gobi ${cmd.name}`,
180
- });
181
- }
182
-
183
- // 3. Build placeholders
184
- const COMMANDS = commandLines.join("\n");
185
- const REFERENCE_TOC = referenceFiles
186
- .map((ref) => `- [${ref.title}](${ref.path})`)
187
- .join("\n");
188
-
189
- // 4. Read template and fill placeholders
190
- let template = readFileSync(TEMPLATE_PATH, "utf-8");
191
- template = template.replace(/\{\{VERSION\}\}/g, version);
192
- template = template.replace("{{COMMANDS}}", COMMANDS);
193
- template = template.replace("{{REFERENCE_TOC}}", REFERENCE_TOC);
194
-
195
- // 5. Write generated SKILL.md
196
- writeFileSync(OUTPUT_PATH, template);
197
-
198
- console.log(`Generated SKILL.md (v${version})`);
199
- console.log(`Generated ${referenceFiles.length} reference files`);
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes