mkctx 1.0.2 → 2.0.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.
package/install.js DELETED
@@ -1,185 +0,0 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const { execSync } = require("child_process");
4
-
5
- function install() {
6
- const isWindows = process.platform === "win32";
7
- const binaryName = isWindows ? "mkctx.exe" : "mkctx";
8
- const sourceBinary = isWindows ? "mkctx.exe" : "mkctx";
9
- const sourcePath = path.join(__dirname, sourceBinary);
10
-
11
- // Rename the binary if necessary (from mkctx to mkctx.exe on Windows)
12
- if (isWindows && fs.existsSync("mkctx") && !fs.existsSync("mkctx.exe")) {
13
- fs.renameSync("mkctx", "mkctx.exe");
14
- console.log("✅ Binary renamed for Windows: mkctx -> mkctx.exe");
15
- }
16
-
17
- // Check if the binary exists
18
- if (!fs.existsSync(sourcePath)) {
19
- console.log("❌ Compiled binary not found at:", sourcePath);
20
- console.log("📋 Files in directory:");
21
- try {
22
- const files = fs.readdirSync(__dirname);
23
- files.forEach((file) => console.log(" -", file));
24
- } catch (e) {
25
- console.log(" Could not read directory");
26
- }
27
- return;
28
- }
29
-
30
- try {
31
- // Method 1: Use npm to get the global bin directory
32
- let npmGlobalBin;
33
- try {
34
- npmGlobalBin = execSync("npm bin -g").toString().trim();
35
- } catch (error) {
36
- // Alternative method to get global bin directory
37
- npmGlobalBin = execSync("npm root -g").toString().trim();
38
- npmGlobalBin = path.join(npmGlobalBin, ".bin");
39
- }
40
-
41
- const installPath = path.join(npmGlobalBin, binaryName);
42
-
43
- console.log(`📦 Installing mkctx at: ${installPath}`);
44
-
45
- // Ensure the directory exists
46
- if (!fs.existsSync(npmGlobalBin)) {
47
- fs.mkdirSync(npmGlobalBin, { recursive: true });
48
- }
49
-
50
- // Copy the binary
51
- fs.copyFileSync(sourcePath, installPath);
52
-
53
- // Set execution permissions (Unix only)
54
- if (!isWindows) {
55
- fs.chmodSync(installPath, 0o755);
56
- }
57
-
58
- console.log("✅ mkctx installed successfully via npm");
59
-
60
- // Create a .cmd wrapper for Windows
61
- if (isWindows) {
62
- createWindowsWrapper(npmGlobalBin);
63
- }
64
-
65
- return;
66
- } catch (error) {
67
- console.log(
68
- "⚠️ npm method failed, trying alternative method...",
69
- error.message
70
- );
71
- }
72
-
73
- // Alternative method: Search common PATH directories
74
- const alternativePaths = getAlternativePaths();
75
-
76
- for (const altPath of alternativePaths) {
77
- try {
78
- if (fs.existsSync(altPath)) {
79
- const altInstallPath = path.join(altPath, binaryName);
80
- console.log(`🔄 Trying to install at: ${altInstallPath}`);
81
-
82
- fs.copyFileSync(sourcePath, altInstallPath);
83
-
84
- // Set execution permissions (Unix only)
85
- if (!isWindows) {
86
- fs.chmodSync(altInstallPath, 0o755);
87
- }
88
-
89
- // Create Windows wrapper if needed
90
- if (isWindows) {
91
- createWindowsWrapper(altPath);
92
- }
93
-
94
- console.log(`✅ mkctx installed at: ${altInstallPath}`);
95
- return;
96
- }
97
- } catch (e) {
98
- console.log(` ❌ Installation failed at ${altPath}: ${e.message}`);
99
- }
100
- }
101
-
102
- // If we get here, all methods failed
103
- console.log("❌ Could not install automatically");
104
- console.log("📋 Manual installation required:");
105
- console.log(` 1. Copy the file '${sourcePath}' to a folder in your PATH`);
106
- console.log(` 2. Make sure the file has execution permissions`);
107
-
108
- // Show current PATH to help the user
109
- console.log("\n📁 Your PATH includes these folders:");
110
- const pathDirs = process.env.PATH
111
- ? process.env.PATH.split(path.delimiter)
112
- : [];
113
- pathDirs.forEach((dir) => console.log(" -", dir));
114
- }
115
-
116
- function createWindowsWrapper(installDir) {
117
- const wrapperPath = path.join(installDir, "mkctx.cmd");
118
- const wrapperContent = `@echo off
119
- "${path.join(installDir, "mkctx.exe")}" %*
120
- `;
121
- fs.writeFileSync(wrapperPath, wrapperContent);
122
- console.log(`✅ Created Windows wrapper: ${wrapperPath}`);
123
- }
124
-
125
- function getAlternativePaths() {
126
- const paths = [];
127
- const isWindows = process.platform === "win32";
128
-
129
- if (isWindows) {
130
- // Windows paths
131
- if (process.env.APPDATA) {
132
- paths.push(path.join(process.env.APPDATA, "npm"));
133
- }
134
- if (process.env.LOCALAPPDATA) {
135
- paths.push(
136
- path.join(process.env.LOCALAPPDATA, "Microsoft", "WindowsApps")
137
- );
138
- }
139
- if (process.env.ProgramFiles) {
140
- paths.push(path.join(process.env.ProgramFiles, "nodejs"));
141
- }
142
- // Common Node.js installation paths
143
- paths.push("C:\\Program Files\\nodejs");
144
- paths.push("C:\\Program Files (x86)\\nodejs");
145
-
146
- // User's local bin
147
- if (process.env.USERPROFILE) {
148
- paths.push(
149
- path.join(process.env.USERPROFILE, "AppData", "Roaming", "npm")
150
- );
151
- }
152
- } else {
153
- // Unix/Linux/macOS paths
154
- paths.push("/usr/local/bin");
155
- paths.push("/usr/bin");
156
- paths.push("/opt/local/bin");
157
-
158
- // User bin directory
159
- if (process.env.HOME) {
160
- paths.push(path.join(process.env.HOME, "bin"));
161
- paths.push(path.join(process.env.HOME, ".local", "bin"));
162
- }
163
-
164
- // Common directories on macOS
165
- if (process.platform === "darwin") {
166
- paths.push("/opt/homebrew/bin");
167
- paths.push("/usr/local/opt/bin");
168
- }
169
- }
170
-
171
- return paths.filter((p) => p !== null && p !== undefined);
172
- }
173
-
174
- // Handle uncaught errors
175
- process.on("uncaughtException", (error) => {
176
- console.log("❌ Installation failed:", error.message);
177
- process.exit(1);
178
- });
179
-
180
- process.on("unhandledRejection", (reason, promise) => {
181
- console.log("❌ Unhandled rejection at:", promise, "reason:", reason);
182
- process.exit(1);
183
- });
184
-
185
- install();
package/main.go DELETED
@@ -1,210 +0,0 @@
1
- package main
2
-
3
- import (
4
- "encoding/json"
5
- "fmt"
6
- "os"
7
- "path/filepath"
8
- "strings"
9
- )
10
-
11
- type Config struct {
12
- Src string `json:"src"`
13
- Ignore string `json:"ignore"`
14
- Output string `json:"output"`
15
- FirstComment string `json:"first_comment"`
16
- LastComment string `json:"last_comment"`
17
- }
18
-
19
- func main() {
20
- if len(os.Args) > 1 && os.Args[1] == "config" {
21
- createConfig()
22
- return
23
- }
24
- generateContext()
25
- }
26
-
27
- func createConfig() {
28
- config := Config{
29
- Src: "./src",
30
- Ignore: "*.log, temp/, node_modules/, .git/",
31
- Output: "./mkctx",
32
- FirstComment: "/* Project Context */",
33
- LastComment: "/* End of Context */",
34
- }
35
-
36
- configJSON, _ := json.MarshalIndent(config, "", " ")
37
-
38
- // Create mkctx directory if it doesn't exist
39
- _ = os.MkdirAll("mkctx", 0755)
40
-
41
- // Write configuration file
42
- _ = os.WriteFile("mkctx.config.json", configJSON, 0644)
43
-
44
- // Update .gitignore
45
- updateGitignore()
46
-
47
- fmt.Println("✅ Configuration created:")
48
- fmt.Println(" - mkctx.config.json")
49
- fmt.Println(" - mkctx/ folder")
50
- fmt.Println(" - Entry in .gitignore")
51
- }
52
-
53
- func updateGitignore() {
54
- gitignorePath := ".gitignore"
55
- content, err := os.ReadFile(gitignorePath)
56
- gitignoreExists := err == nil
57
-
58
- var newContent string
59
- if gitignoreExists {
60
- newContent = string(content)
61
- if !strings.Contains(newContent, "mkctx/") {
62
- newContent += "\n# mkctx - generated context\nmkctx/\n"
63
- }
64
- } else {
65
- newContent = "# mkctx - generated context\nmkctx/\n"
66
- }
67
-
68
- _ = os.WriteFile(gitignorePath, []byte(newContent), 0644)
69
- }
70
-
71
- func generateContext() {
72
- config := loadConfig()
73
- files := getFiles(config)
74
- content := buildContent(files, config)
75
-
76
- outputPath := config.Output
77
- if outputPath == "" {
78
- outputPath = "."
79
- }
80
-
81
- // Ensure output directory exists
82
- _ = os.MkdirAll(outputPath, 0755)
83
-
84
- outputFile := filepath.Join(outputPath, "context.md")
85
- err := os.WriteFile(outputFile, []byte(content), 0644)
86
- if err != nil {
87
- fmt.Printf("❌ Error creating file: %v\n", err)
88
- return
89
- }
90
- fmt.Printf("✅ Context generated at: %s\n", outputFile)
91
- }
92
-
93
- func loadConfig() Config {
94
- var config Config
95
- file, err := os.ReadFile("mkctx.config.json")
96
- if err != nil {
97
- return getDefaultConfig()
98
- }
99
- json.Unmarshal(file, &config)
100
-
101
- // Validate and complete configuration
102
- if config.Src == "" {
103
- config.Src = "."
104
- }
105
- if config.Output == "" {
106
- config.Output = "."
107
- }
108
-
109
- return config
110
- }
111
-
112
- func getDefaultConfig() Config {
113
- return Config{
114
- Src: ".",
115
- Output: ".",
116
- FirstComment: "/* Project Context */",
117
- LastComment: "/* End of Context */",
118
- }
119
- }
120
-
121
- func getFiles(config Config) []string {
122
- var files []string
123
-
124
- srcPath := config.Src
125
- if srcPath == "" {
126
- srcPath = "."
127
- }
128
-
129
- filepath.Walk(srcPath, func(path string, info os.FileInfo, err error) error {
130
- if err != nil || shouldIgnore(path, config) || info.IsDir() {
131
- return nil
132
- }
133
- files = append(files, path)
134
- return nil
135
- })
136
- return files
137
- }
138
-
139
- func shouldIgnore(path string, config Config) bool {
140
- // Ignore system files
141
- if strings.Contains(path, ".git") ||
142
- strings.Contains(path, ".DS_Store") ||
143
- strings.Contains(path, "Thumbs.db") {
144
- return true
145
- }
146
-
147
- // Ignore based on configuration
148
- if config.Ignore != "" {
149
- ignorePatterns := strings.Split(config.Ignore, ",")
150
- for _, pattern := range ignorePatterns {
151
- pattern = strings.TrimSpace(pattern)
152
- if pattern == "" {
153
- continue
154
- }
155
-
156
- // Simple pattern with wildcard
157
- if strings.Contains(pattern, "*") {
158
- if matched, _ := filepath.Match(pattern, filepath.Base(path)); matched {
159
- return true
160
- }
161
- }
162
-
163
- // Entire directory
164
- if strings.HasSuffix(pattern, "/") {
165
- dir := strings.TrimSuffix(pattern, "/")
166
- if strings.Contains(path, dir) {
167
- return true
168
- }
169
- }
170
-
171
- // Exact match
172
- if strings.Contains(path, pattern) {
173
- return true
174
- }
175
- }
176
- }
177
-
178
- return false
179
- }
180
-
181
- func buildContent(files []string, config Config) string {
182
- var content strings.Builder
183
-
184
- if config.FirstComment != "" {
185
- content.WriteString(config.FirstComment + "\n\n")
186
- }
187
-
188
- for _, file := range files {
189
- fileContent, err := os.ReadFile(file)
190
- if err != nil {
191
- continue
192
- }
193
-
194
- ext := filepath.Ext(file)
195
- lang := "text"
196
- if ext != "" {
197
- lang = ext[1:] // Remove the dot
198
- }
199
-
200
- content.WriteString("```" + lang + "\n")
201
- content.WriteString("// " + file + "\n")
202
- content.WriteString(string(fileContent))
203
- content.WriteString("\n```\n\n")
204
- }
205
-
206
- if config.LastComment != "" {
207
- content.WriteString(config.LastComment)
208
- }
209
- return content.String()
210
- }