@cg3/equip 0.2.23 → 0.4.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.
Files changed (57) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +26 -10
  3. package/bin/equip.js +159 -68
  4. package/demo/README.md +1 -1
  5. package/dist/index.d.ts +76 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +177 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/lib/cli.d.ts +22 -0
  10. package/dist/lib/cli.d.ts.map +1 -0
  11. package/dist/lib/cli.js +148 -0
  12. package/dist/lib/cli.js.map +1 -0
  13. package/dist/lib/commands/doctor.d.ts +2 -0
  14. package/dist/lib/commands/doctor.d.ts.map +1 -0
  15. package/dist/lib/commands/doctor.js +162 -0
  16. package/dist/lib/commands/doctor.js.map +1 -0
  17. package/dist/lib/commands/status.d.ts +2 -0
  18. package/dist/lib/commands/status.d.ts.map +1 -0
  19. package/dist/lib/commands/status.js +134 -0
  20. package/dist/lib/commands/status.js.map +1 -0
  21. package/dist/lib/commands/update.d.ts +2 -0
  22. package/dist/lib/commands/update.d.ts.map +1 -0
  23. package/dist/lib/commands/update.js +93 -0
  24. package/dist/lib/commands/update.js.map +1 -0
  25. package/dist/lib/detect.d.ts +12 -0
  26. package/dist/lib/detect.d.ts.map +1 -0
  27. package/dist/lib/detect.js +109 -0
  28. package/dist/lib/detect.js.map +1 -0
  29. package/dist/lib/hooks.d.ts +40 -0
  30. package/dist/lib/hooks.d.ts.map +1 -0
  31. package/dist/lib/hooks.js +226 -0
  32. package/dist/lib/hooks.js.map +1 -0
  33. package/dist/lib/mcp.d.ts +73 -0
  34. package/dist/lib/mcp.d.ts.map +1 -0
  35. package/dist/lib/mcp.js +418 -0
  36. package/dist/lib/mcp.js.map +1 -0
  37. package/dist/lib/platforms.d.ts +67 -0
  38. package/dist/lib/platforms.d.ts.map +1 -0
  39. package/dist/lib/platforms.js +353 -0
  40. package/dist/lib/platforms.js.map +1 -0
  41. package/dist/lib/rules.d.ts +35 -0
  42. package/dist/lib/rules.d.ts.map +1 -0
  43. package/dist/lib/rules.js +161 -0
  44. package/dist/lib/rules.js.map +1 -0
  45. package/dist/lib/state.d.ts +33 -0
  46. package/dist/lib/state.d.ts.map +1 -0
  47. package/dist/lib/state.js +130 -0
  48. package/dist/lib/state.js.map +1 -0
  49. package/package.json +19 -13
  50. package/registry.json +9 -0
  51. package/index.js +0 -245
  52. package/lib/cli.js +0 -99
  53. package/lib/detect.js +0 -242
  54. package/lib/hooks.js +0 -238
  55. package/lib/mcp.js +0 -503
  56. package/lib/platforms.js +0 -210
  57. package/lib/rules.js +0 -170
package/lib/platforms.js DELETED
@@ -1,210 +0,0 @@
1
- // Platform path resolution and metadata.
2
- // Zero dependencies.
3
-
4
- "use strict";
5
-
6
- const path = require("path");
7
- const os = require("os");
8
-
9
- // ─── Path Helpers ────────────────────────────────────────────
10
-
11
- function getVsCodeUserDir() {
12
- const home = os.homedir();
13
- if (process.platform === "win32") return path.join(process.env.APPDATA || path.join(home, "AppData", "Roaming"), "Code", "User");
14
- if (process.platform === "darwin") return path.join(home, "Library", "Application Support", "Code", "User");
15
- return path.join(home, ".config", "Code", "User");
16
- }
17
-
18
- function getVsCodeMcpPath() {
19
- return path.join(getVsCodeUserDir(), "mcp.json");
20
- }
21
-
22
- function getClineConfigPath() {
23
- const base = getVsCodeUserDir();
24
- return path.join(base, "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
25
- }
26
-
27
- function getRooConfigPath() {
28
- const base = getVsCodeUserDir();
29
- return path.join(base, "globalStorage", "rooveterinaryinc.roo-cline", "settings", "cline_mcp_settings.json");
30
- }
31
-
32
- function getCodexConfigPath() {
33
- const home = os.homedir();
34
- return path.join(process.env.CODEX_HOME || path.join(home, ".codex"), "config.toml");
35
- }
36
-
37
- function getGeminiSettingsPath() {
38
- const home = os.homedir();
39
- return path.join(home, ".gemini", "settings.json");
40
- }
41
-
42
- function getJunieMcpPath() {
43
- const home = os.homedir();
44
- return path.join(home, ".junie", "mcp", "mcp.json");
45
- }
46
-
47
- function getCopilotJetBrainsMcpPath() {
48
- const home = os.homedir();
49
- if (process.platform === "win32") {
50
- return path.join(process.env.APPDATA || path.join(home, "AppData", "Roaming"), "github-copilot", "intellij", "mcp.json");
51
- }
52
- return path.join(home, ".config", "github-copilot", "intellij", "mcp.json");
53
- }
54
-
55
- function getCopilotCliMcpPath() {
56
- const home = os.homedir();
57
- return path.join(home, ".copilot", "mcp-config.json");
58
- }
59
-
60
- // ─── Platform Registry ──────────────────────────────────────
61
-
62
- /**
63
- * Returns platform definition for manual override.
64
- * @param {string} platformId
65
- * @returns {object} Platform object with configPath, rulesPath, rootKey, etc.
66
- */
67
- function createManualPlatform(platformId) {
68
- const home = os.homedir();
69
- const configs = {
70
- "claude-code": {
71
- configPath: path.join(home, ".claude.json"),
72
- rulesPath: path.join(home, ".claude", "CLAUDE.md"),
73
- rootKey: "mcpServers",
74
- configFormat: "json",
75
- },
76
- cursor: {
77
- configPath: path.join(home, ".cursor", "mcp.json"),
78
- rulesPath: null,
79
- rootKey: "mcpServers",
80
- configFormat: "json",
81
- },
82
- windsurf: {
83
- configPath: path.join(home, ".codeium", "windsurf", "mcp_config.json"),
84
- rulesPath: path.join(home, ".codeium", "windsurf", "memories", "global_rules.md"),
85
- rootKey: "mcpServers",
86
- configFormat: "json",
87
- },
88
- vscode: {
89
- configPath: getVsCodeMcpPath(),
90
- rulesPath: null,
91
- rootKey: "servers",
92
- configFormat: "json",
93
- },
94
- cline: {
95
- configPath: getClineConfigPath(),
96
- rulesPath: path.join(home, "Documents", "Cline", "Rules"),
97
- rootKey: "mcpServers",
98
- configFormat: "json",
99
- },
100
- "roo-code": {
101
- configPath: getRooConfigPath(),
102
- rulesPath: path.join(home, ".roo", "rules"),
103
- rootKey: "mcpServers",
104
- configFormat: "json",
105
- },
106
- codex: {
107
- configPath: getCodexConfigPath(),
108
- rulesPath: path.join(process.env.CODEX_HOME || path.join(home, ".codex"), "AGENTS.md"),
109
- rootKey: "mcp_servers",
110
- configFormat: "toml",
111
- },
112
- "gemini-cli": {
113
- configPath: getGeminiSettingsPath(),
114
- rulesPath: path.join(home, ".gemini", "GEMINI.md"),
115
- rootKey: "mcpServers",
116
- configFormat: "json",
117
- },
118
- junie: {
119
- configPath: getJunieMcpPath(),
120
- rulesPath: null,
121
- rootKey: "mcpServers",
122
- configFormat: "json",
123
- },
124
- "copilot-jetbrains": {
125
- configPath: getCopilotJetBrainsMcpPath(),
126
- rulesPath: null,
127
- rootKey: "mcpServers",
128
- configFormat: "json",
129
- },
130
- "copilot-cli": {
131
- configPath: getCopilotCliMcpPath(),
132
- rulesPath: null,
133
- rootKey: "mcpServers",
134
- configFormat: "json",
135
- },
136
- };
137
-
138
- const def = configs[platformId];
139
- if (!def) {
140
- throw new Error(`Unknown platform: ${platformId}. Supported: ${Object.keys(configs).join(", ")}`);
141
- }
142
-
143
- return { platform: platformId, version: "unknown", hasCli: false, existingMcp: null, ...def };
144
- }
145
-
146
- /**
147
- * Display name for a platform id.
148
- */
149
- function platformName(id) {
150
- const names = {
151
- "claude-code": "Claude Code",
152
- cursor: "Cursor",
153
- windsurf: "Windsurf",
154
- vscode: "VS Code",
155
- cline: "Cline",
156
- "roo-code": "Roo Code",
157
- codex: "Codex",
158
- "gemini-cli": "Gemini CLI",
159
- junie: "Junie",
160
- "copilot-jetbrains": "Copilot (JetBrains)",
161
- "copilot-cli": "Copilot CLI",
162
- };
163
- return names[id] || id;
164
- }
165
-
166
- /**
167
- * All known platform IDs.
168
- */
169
- const KNOWN_PLATFORMS = ["claude-code", "cursor", "windsurf", "vscode", "cline", "roo-code", "codex", "gemini-cli", "junie", "copilot-jetbrains", "copilot-cli"];
170
-
171
- /**
172
- * Resolve a friendly name or alias to a canonical platform ID.
173
- * Returns the ID if recognized, or the input unchanged if not.
174
- */
175
- function resolvePlatformId(input) {
176
- const s = input.trim().toLowerCase();
177
- // Exact match first
178
- if (KNOWN_PLATFORMS.includes(s)) return s;
179
- // Aliases
180
- const aliases = {
181
- claude: "claude-code",
182
- "claude-code": "claude-code",
183
- "claudecode": "claude-code",
184
- vscode: "vscode",
185
- "vs-code": "vscode",
186
- code: "vscode",
187
- roo: "roo-code",
188
- roocode: "roo-code",
189
- copilot: "copilot-cli",
190
- "copilot-jb": "copilot-jetbrains",
191
- gemini: "gemini-cli",
192
- };
193
- return aliases[s] || s;
194
- }
195
-
196
- module.exports = {
197
- getVsCodeUserDir,
198
- getVsCodeMcpPath,
199
- getClineConfigPath,
200
- getRooConfigPath,
201
- getCodexConfigPath,
202
- getGeminiSettingsPath,
203
- getJunieMcpPath,
204
- getCopilotJetBrainsMcpPath,
205
- getCopilotCliMcpPath,
206
- createManualPlatform,
207
- platformName,
208
- resolvePlatformId,
209
- KNOWN_PLATFORMS,
210
- };
package/lib/rules.js DELETED
@@ -1,170 +0,0 @@
1
- // Behavioral rules installation — marker-based versioned blocks.
2
- // Handles appending, updating, and removing rules from shared files.
3
- // Zero dependencies.
4
-
5
- "use strict";
6
-
7
- const fs = require("fs");
8
- const path = require("path");
9
-
10
- // ─── Constants ──────────────────────────────────────────────
11
-
12
- /**
13
- * Create regex patterns for a given marker name.
14
- * @param {string} marker - Marker name (e.g., "prior")
15
- * @returns {{ MARKER_RE: RegExp, BLOCK_RE: RegExp }}
16
- */
17
- function markerPatterns(marker) {
18
- return {
19
- MARKER_RE: new RegExp(`<!-- ${marker}:v[\\d.]+ -->`),
20
- BLOCK_RE: new RegExp(`<!-- ${marker}:v[\\d.]+ -->[\\s\\S]*?<!-- \\/${marker} -->\\n?`),
21
- };
22
- }
23
-
24
- /**
25
- * Parse version from marker in content.
26
- * @param {string} content
27
- * @param {string} marker
28
- * @returns {string|null}
29
- */
30
- function parseRulesVersion(content, marker) {
31
- const m = content.match(new RegExp(`<!-- ${marker}:v([\\d.]+) -->`));
32
- return m ? m[1] : null;
33
- }
34
-
35
- // ─── Install ─────────────────────────────────────────────────
36
-
37
- /**
38
- * Install behavioral rules to a platform's rules file.
39
- * Supports: file-based (append/update), standalone file, or clipboard.
40
- *
41
- * @param {object} platform - Platform object with rulesPath
42
- * @param {object} options
43
- * @param {string} options.content - Rules content (with markers)
44
- * @param {string} options.version - Current version string
45
- * @param {string} options.marker - Marker name for tracking
46
- * @param {string} [options.fileName] - For standalone file platforms (e.g., "prior.md")
47
- * @param {string[]} [options.clipboardPlatforms] - Platform ids that use clipboard
48
- * @param {boolean} [options.dryRun]
49
- * @param {Function} [options.copyToClipboard] - Clipboard function
50
- * @returns {{ action: string }} "created" | "updated" | "skipped" | "clipboard"
51
- */
52
- function installRules(platform, options) {
53
- const {
54
- content,
55
- version,
56
- marker,
57
- fileName,
58
- clipboardPlatforms = ["cursor", "vscode"],
59
- dryRun = false,
60
- copyToClipboard,
61
- } = options;
62
-
63
- // Clipboard-only platforms
64
- if (clipboardPlatforms.includes(platform.platform)) {
65
- if (!dryRun && copyToClipboard) {
66
- copyToClipboard(content);
67
- }
68
- return { action: "clipboard" };
69
- }
70
-
71
- if (!platform.rulesPath) return { action: "skipped" };
72
-
73
- // Determine actual file path — standalone file (directory-based) vs append (file-based)
74
- // Only use fileName if rulesPath is a directory (or doesn't exist yet as a file)
75
- let rulesPath;
76
- if (fileName) {
77
- try {
78
- const stat = fs.statSync(platform.rulesPath);
79
- rulesPath = stat.isDirectory() ? path.join(platform.rulesPath, fileName) : platform.rulesPath;
80
- } catch {
81
- // Path doesn't exist — check if it looks like a file (has extension) or directory
82
- rulesPath = path.extname(platform.rulesPath) ? platform.rulesPath : path.join(platform.rulesPath, fileName);
83
- }
84
- } else {
85
- rulesPath = platform.rulesPath;
86
- }
87
-
88
- const { MARKER_RE, BLOCK_RE } = markerPatterns(marker);
89
-
90
- let existing = "";
91
- try { existing = fs.readFileSync(rulesPath, "utf-8"); } catch {}
92
-
93
- const existingVersion = parseRulesVersion(existing, marker);
94
-
95
- if (existingVersion === version) {
96
- return { action: "skipped" };
97
- }
98
-
99
- if (!dryRun) {
100
- const dir = path.dirname(rulesPath);
101
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
102
-
103
- if (existingVersion) {
104
- // Replace existing block
105
- const updated = existing.replace(BLOCK_RE, content + "\n");
106
- fs.writeFileSync(rulesPath, updated);
107
- return { action: "updated" };
108
- }
109
-
110
- // Append
111
- const sep = existing && !existing.endsWith("\n\n") ? (existing.endsWith("\n") ? "\n" : "\n\n") : "";
112
- fs.writeFileSync(rulesPath, existing + sep + content + "\n");
113
- return { action: "created" };
114
- }
115
-
116
- return { action: existingVersion ? "updated" : "created" };
117
- }
118
-
119
- /**
120
- * Remove rules from a platform's rules file.
121
- * @param {object} platform - Platform object
122
- * @param {object} options
123
- * @param {string} options.marker - Marker name
124
- * @param {string} [options.fileName] - For standalone file platforms
125
- * @param {boolean} [options.dryRun]
126
- * @returns {boolean} Whether anything was removed
127
- */
128
- function uninstallRules(platform, options) {
129
- const { marker, fileName, dryRun = false } = options;
130
-
131
- if (!platform.rulesPath) return false;
132
-
133
- let rulesPath;
134
- if (fileName) {
135
- try {
136
- const stat = fs.statSync(platform.rulesPath);
137
- rulesPath = stat.isDirectory() ? path.join(platform.rulesPath, fileName) : platform.rulesPath;
138
- } catch {
139
- rulesPath = path.extname(platform.rulesPath) ? platform.rulesPath : path.join(platform.rulesPath, fileName);
140
- }
141
- } else {
142
- rulesPath = platform.rulesPath;
143
- }
144
-
145
- try {
146
- if (!fs.statSync(rulesPath).isFile()) return false;
147
- } catch { return false; }
148
-
149
- try {
150
- const content = fs.readFileSync(rulesPath, "utf-8");
151
- const { MARKER_RE, BLOCK_RE } = markerPatterns(marker);
152
- if (!MARKER_RE.test(content)) return false;
153
- if (!dryRun) {
154
- const cleaned = content.replace(BLOCK_RE, "").replace(/\n{3,}/g, "\n\n").trim();
155
- if (cleaned) {
156
- fs.writeFileSync(rulesPath, cleaned + "\n");
157
- } else {
158
- fs.unlinkSync(rulesPath);
159
- }
160
- }
161
- return true;
162
- } catch { return false; }
163
- }
164
-
165
- module.exports = {
166
- markerPatterns,
167
- parseRulesVersion,
168
- installRules,
169
- uninstallRules,
170
- };