make-laten 1.0.1 → 1.1.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.
@@ -915,260 +915,310 @@ async function fetchCommand(url, options) {
915
915
  }
916
916
  }
917
917
 
918
- // src/adapter/detector.ts
919
- import { exec as exec3 } from "child_process";
920
- import { promisify as promisify3 } from "util";
918
+ // src/adapter/installer.ts
921
919
  import fs2 from "fs/promises";
922
920
  import path from "path";
921
+ import { exec as exec3 } from "child_process";
922
+ import { promisify as promisify3 } from "util";
923
+ var execAsync3 = promisify3(exec3);
924
+ var RULES_CONTENT = `
925
+ # make-laten efficiency rules
923
926
 
924
- // src/adapter/types.ts
925
- var AGENT_CONFIGS = {
926
- "claude-code": { type: "hook" },
927
- "codex": { type: "hook" },
928
- "gemini-cli": { type: "hook" },
929
- "cursor": { type: "rules", rulesFile: ".cursorrules" },
930
- "windsurf": { type: "rules", rulesFile: ".windsurfrules" },
931
- "cline": { type: "rules", rulesFile: ".clinerules" },
932
- "copilot": { type: "rules", rulesFile: ".github/copilot-instructions.md" }
933
- };
927
+ ## Token Optimization
928
+ - When reading files, use \`make-laten read <file>\` for compressed output
929
+ - When searching code, use \`make-laten grep <pattern>\` for grouped results
930
+ - When checking git, use \`make-laten git diff\` for condensed output
931
+ - When fetching web, use \`make-laten fetch <url>\` for compressed content
934
932
 
935
- // src/adapter/detector.ts
936
- var execAsync3 = promisify3(exec3);
937
- var AgentDetector = class {
938
- async detectAgents() {
939
- const agents = [];
940
- for (const [name, config] of Object.entries(AGENT_CONFIGS)) {
941
- const detected = await this.detectAgent(name, config.type);
942
- if (detected) {
943
- agents.push(detected);
944
- }
945
- }
946
- return agents;
933
+ ## Quick Commands
934
+ - \`mread <file>\` \u2014 alias for make-laten read
935
+ - \`mgrep <pattern>\` \u2014 alias for make-laten grep
936
+ - \`mdiff\` \u2014 alias for make-laten git diff
937
+ - \`msearch <query>\` \u2014 alias for make-laten search
938
+ - \`mfetch <url>\` \u2014 alias for make-laten fetch
939
+ `;
940
+ function getHome() {
941
+ return process.env.HOME || process.env.USERPROFILE || "";
942
+ }
943
+ async function commandExists(cmd) {
944
+ try {
945
+ await execAsync3(`which ${cmd}`, { timeout: 3e3 });
946
+ return true;
947
+ } catch {
948
+ return false;
947
949
  }
948
- async detectAgent(name, type) {
949
- const commands = {
950
- "claude-code": "claude --version",
951
- "codex": "codex --version",
952
- "gemini-cli": "gemini --version"
953
- };
954
- if (commands[name]) {
950
+ }
951
+ var agents = [
952
+ {
953
+ name: "terminal (shell aliases)",
954
+ detected: async () => true,
955
+ install: async () => {
956
+ const shellInit = await execAsync3("echo $SHELL").then((r) => r.stdout.trim());
957
+ const rcFile = shellInit.includes("zsh") ? ".zshrc" : ".bashrc";
958
+ const rcPath = path.join(getHome(), rcFile);
959
+ const marker = "make-laten shell";
960
+ let existing = "";
955
961
  try {
956
- const { stdout } = await execAsync3(commands[name], { timeout: 5e3 });
957
- const version = stdout.trim().split("\n")[0];
958
- const agentPath = await this.getAgentPath(name);
959
- return { name, type, path: agentPath, version, detected: true };
962
+ existing = await fs2.readFile(rcPath, "utf-8");
960
963
  } catch {
961
- return null;
962
964
  }
963
- }
964
- if (type === "rules") {
965
- const rulesPath = AGENT_CONFIGS[name]?.rulesFile;
966
- if (rulesPath) {
967
- try {
968
- await fs2.access(path.join(process.cwd(), rulesPath));
969
- return { name, type, path: process.cwd(), version: null, detected: true };
970
- } catch {
971
- return null;
972
- }
965
+ if (!existing.includes(marker)) {
966
+ const npmRoot = await execAsync3("npm root -g").then((r) => r.stdout.trim());
967
+ const initScript = `
968
+ # make-laten shell integration
969
+ source ${npmRoot}/make-laten/shell/init.sh
970
+ `;
971
+ await fs2.appendFile(rcPath, initScript);
972
+ }
973
+ },
974
+ uninstall: async () => {
975
+ const shellInit = await execAsync3("echo $SHELL").then((r) => r.stdout.trim());
976
+ const rcFile = shellInit.includes("zsh") ? ".zshrc" : ".bashrc";
977
+ const rcPath = path.join(getHome(), rcFile);
978
+ try {
979
+ let content = await fs2.readFile(rcPath, "utf-8");
980
+ content = content.replace(/\n# make-laten shell integration\nsource .*\/make-laten\/shell\/init\.sh\n/g, "");
981
+ await fs2.writeFile(rcPath, content);
982
+ } catch {
973
983
  }
974
984
  }
975
- return null;
976
- }
977
- async getAgentPath(name) {
978
- const home = process.env.HOME || process.env.USERPROFILE || "";
979
- const paths = {
980
- "claude-code": path.join(home, ".claude"),
981
- "codex": path.join(home, ".codex"),
982
- "gemini-cli": path.join(home, ".gemini")
983
- };
984
- return paths[name] || path.join(home, `.${name}`);
985
- }
986
- async hasCommand(cmd) {
987
- try {
988
- await execAsync3(`which ${cmd}`, { timeout: 3e3 });
989
- return true;
990
- } catch {
991
- return false;
992
- }
993
- }
994
- };
995
-
996
- // src/adapter/hook.ts
997
- import fs3 from "fs/promises";
998
- import path2 from "path";
999
- var HookAdapter = class {
1000
- name;
1001
- version = "1.0.0";
1002
- type = "hook";
1003
- hooks = {};
1004
- constructor(name) {
1005
- this.name = name;
1006
- }
1007
- format(input) {
1008
- const { content, context } = input;
1009
- const parts = [];
1010
- if (context?.filePath) {
1011
- parts.push(`**File:** \`${context.filePath}\``);
1012
- }
1013
- parts.push(content);
1014
- return {
1015
- output: parts.join("\n\n"),
1016
- format: this.name,
1017
- metadata: { filePath: context?.filePath, timestamp: Date.now() }
1018
- };
1019
- }
1020
- parse(output) {
1021
- return { content: output, parsed: true };
1022
- }
1023
- setHooks(hooks) {
1024
- this.hooks = hooks;
1025
- }
1026
- async intercept(toolCall) {
1027
- if (this.hooks.preToolUse) {
1028
- return this.hooks.preToolUse(toolCall);
1029
- }
1030
- return toolCall;
1031
- }
1032
- async postProcess(result) {
1033
- if (this.hooks.postToolUse) {
1034
- return this.hooks.postToolUse(result);
1035
- }
1036
- return result;
1037
- }
1038
- async install(agentPath) {
1039
- const hooksDir = path2.join(agentPath, "hooks");
1040
- await fs3.mkdir(hooksDir, { recursive: true });
1041
- const preToolHook = `#!/usr/bin/env node
985
+ },
986
+ {
987
+ name: "claude-code",
988
+ detected: async () => commandExists("claude"),
989
+ install: async () => {
990
+ const hooksDir = path.join(getHome(), ".claude", "hooks");
991
+ await fs2.mkdir(hooksDir, { recursive: true });
992
+ const preHook = `#!/usr/bin/env node
1042
993
  const { readFileSync } = require('fs');
1043
994
  const input = JSON.parse(readFileSync('/dev/stdin', 'utf-8'));
1044
-
1045
995
  if (input.tool === 'Read' || input.tool === 'Bash') {
1046
996
  process.env.MAKE_LATEN_INTERCEPT = '1';
1047
997
  }
1048
-
1049
- process.stdout.write(JSON.stringify(input));
1050
- `;
1051
- const postToolHook = `#!/usr/bin/env node
998
+ process.stdout.write(JSON.stringify(input));`;
999
+ const postHook = `#!/usr/bin/env node
1052
1000
  const { readFileSync } = require('fs');
1053
1001
  const input = JSON.parse(readFileSync('/dev/stdin', 'utf-8'));
1054
-
1055
1002
  if (input.output && input.output.length > 10000) {
1056
1003
  input.output = input.output.slice(0, 10000) + '\\n... (truncated by make-laten)';
1057
1004
  }
1058
-
1059
- process.stdout.write(JSON.stringify(input));
1060
- `;
1061
- await fs3.writeFile(path2.join(hooksDir, "pre-tool-use.js"), preToolHook);
1062
- await fs3.writeFile(path2.join(hooksDir, "post-tool-use.js"), postToolHook);
1063
- }
1064
- async uninstall(agentPath) {
1065
- const hooksDir = path2.join(agentPath, "hooks");
1066
- try {
1067
- await fs3.rm(path2.join(hooksDir, "pre-tool-use.js"), { force: true });
1068
- await fs3.rm(path2.join(hooksDir, "post-tool-use.js"), { force: true });
1069
- } catch {
1005
+ process.stdout.write(JSON.stringify(input));`;
1006
+ await fs2.writeFile(path.join(hooksDir, "pre-tool-use.js"), preHook);
1007
+ await fs2.writeFile(path.join(hooksDir, "post-tool-use.js"), postHook);
1008
+ },
1009
+ uninstall: async () => {
1010
+ const hooksDir = path.join(getHome(), ".claude", "hooks");
1011
+ try {
1012
+ await fs2.rm(path.join(hooksDir, "pre-tool-use.js"), { force: true });
1013
+ } catch {
1014
+ }
1015
+ try {
1016
+ await fs2.rm(path.join(hooksDir, "post-tool-use.js"), { force: true });
1017
+ } catch {
1018
+ }
1070
1019
  }
1071
- }
1072
- async isInstalled(agentPath) {
1073
- try {
1074
- await fs3.access(path2.join(agentPath, "hooks", "pre-tool-use.js"));
1075
- return true;
1076
- } catch {
1077
- return false;
1020
+ },
1021
+ {
1022
+ name: "cursor",
1023
+ detected: async () => {
1024
+ try {
1025
+ await fs2.access(path.join(getHome(), ".cursor"));
1026
+ return true;
1027
+ } catch {
1028
+ return false;
1029
+ }
1030
+ },
1031
+ install: async () => {
1032
+ const rulesDir = path.join(getHome(), ".cursor", "rules");
1033
+ await fs2.mkdir(rulesDir, { recursive: true });
1034
+ const ruleFile = path.join(rulesDir, "make-laten.mdc");
1035
+ const content = `---
1036
+ description: make-laten efficiency rules
1037
+ globs:
1038
+ ---
1039
+ ${RULES_CONTENT}`;
1040
+ await fs2.writeFile(ruleFile, content);
1041
+ },
1042
+ uninstall: async () => {
1043
+ try {
1044
+ await fs2.rm(path.join(getHome(), ".cursor", "rules", "make-laten.mdc"), { force: true });
1045
+ } catch {
1046
+ }
1078
1047
  }
1079
- }
1080
- };
1081
-
1082
- // src/adapter/rules.ts
1083
- import fs4 from "fs/promises";
1084
- import path3 from "path";
1085
- var RULES_TEMPLATE = `
1086
- # make-laten efficiency rules
1087
-
1088
- ## Token Optimization
1089
- - When reading files, prefer using \`make-laten read <file>\` for compressed output
1090
- - When searching code, prefer using \`make-laten grep <pattern>\` for grouped results
1091
- - When checking git status, prefer using \`make-laten git diff\` for condensed output
1092
-
1093
- ## Caching
1094
- - make-laten automatically caches frequently accessed files
1095
- - Use \`make-laten cache stats\` to see cache performance
1096
- - Use \`make-laten cache clear\` to reset cache if needed
1097
-
1098
- ## Web Search
1099
- - Use \`make-laten search <query>\` for optimized web search
1100
- - Use \`make-laten fetch <url>\` for compressed web fetch
1101
- `;
1102
- var RulesAdapter = class {
1103
- name;
1104
- version = "1.0.0";
1105
- type = "rules";
1106
- constructor(agentName) {
1107
- this.name = agentName;
1108
- }
1109
- format(input) {
1110
- return {
1111
- output: input.content,
1112
- format: "markdown",
1113
- metadata: { agent: this.name, timestamp: Date.now() }
1114
- };
1115
- }
1116
- parse(output) {
1117
- return { content: output };
1118
- }
1119
- async install(agentPath) {
1120
- const config = AGENT_CONFIGS[this.name];
1121
- if (!config?.rulesFile) {
1122
- throw new Error(`No rules file configured for ${this.name}`);
1048
+ },
1049
+ {
1050
+ name: "codex",
1051
+ detected: async () => commandExists("codex"),
1052
+ install: async () => {
1053
+ const agentsMd = path.join(process.cwd(), "AGENTS.md");
1054
+ let existing = "";
1055
+ try {
1056
+ existing = await fs2.readFile(agentsMd, "utf-8");
1057
+ } catch {
1058
+ }
1059
+ if (!existing.includes("make-laten")) {
1060
+ const content = existing + "\n\n## make-laten Integration\n" + RULES_CONTENT;
1061
+ await fs2.writeFile(agentsMd, content);
1062
+ }
1063
+ },
1064
+ uninstall: async () => {
1065
+ try {
1066
+ let content = await fs2.readFile(path.join(process.cwd(), "AGENTS.md"), "utf-8");
1067
+ content = content.replace(/\n## make-laten Integration[\s\S]*$/, "");
1068
+ await fs2.writeFile(path.join(process.cwd(), "AGENTS.md"), content.trim() + "\n");
1069
+ } catch {
1070
+ }
1123
1071
  }
1124
- const rulesPath = path3.join(agentPath, config.rulesFile);
1125
- const existing = await fs4.readFile(rulesPath, "utf-8").catch(() => "");
1126
- if (existing.includes("make-laten")) {
1127
- return;
1072
+ },
1073
+ {
1074
+ name: "windsurf",
1075
+ detected: async () => {
1076
+ try {
1077
+ await fs2.access(path.join(process.cwd(), ".windsurf"));
1078
+ return true;
1079
+ } catch {
1080
+ try {
1081
+ await fs2.access(path.join(getHome(), ".windsurf"));
1082
+ return true;
1083
+ } catch {
1084
+ return false;
1085
+ }
1086
+ }
1087
+ },
1088
+ install: async () => {
1089
+ const rulesPath = path.join(process.cwd(), ".windsurfrules");
1090
+ let existing = "";
1091
+ try {
1092
+ existing = await fs2.readFile(rulesPath, "utf-8");
1093
+ } catch {
1094
+ }
1095
+ if (!existing.includes("make-laten")) {
1096
+ await fs2.writeFile(rulesPath, existing + "\n\n" + RULES_CONTENT);
1097
+ }
1098
+ },
1099
+ uninstall: async () => {
1100
+ try {
1101
+ let content = await fs2.readFile(path.join(process.cwd(), ".windsurfrules"), "utf-8");
1102
+ content = content.replace(/\n# make-laten efficiency rules[\s\S]*$/, "");
1103
+ await fs2.writeFile(path.join(process.cwd(), ".windsurfrules"), content.trim() + "\n");
1104
+ } catch {
1105
+ }
1128
1106
  }
1129
- await fs4.mkdir(path3.dirname(rulesPath), { recursive: true });
1130
- await fs4.writeFile(rulesPath, existing + "\n\n" + RULES_TEMPLATE);
1131
- }
1132
- async uninstall(agentPath) {
1133
- const config = AGENT_CONFIGS[this.name];
1134
- if (!config?.rulesFile) return;
1135
- const rulesPath = path3.join(agentPath, config.rulesFile);
1136
- try {
1137
- let content = await fs4.readFile(rulesPath, "utf-8");
1138
- const marker = "# make-laten efficiency rules";
1139
- const idx = content.indexOf(marker);
1140
- if (idx !== -1) {
1141
- const endIdx = content.indexOf("\n#", idx + marker.length);
1142
- content = content.slice(0, idx).trim() + "\n" + (endIdx !== -1 ? content.slice(endIdx) : "");
1143
- await fs4.writeFile(rulesPath, content.trim() + "\n");
1107
+ },
1108
+ {
1109
+ name: "cline",
1110
+ detected: async () => {
1111
+ try {
1112
+ await fs2.access(path.join(process.cwd(), ".clinerules"));
1113
+ return true;
1114
+ } catch {
1115
+ try {
1116
+ await fs2.access(path.join(getHome(), ".cline"));
1117
+ return true;
1118
+ } catch {
1119
+ return false;
1120
+ }
1121
+ }
1122
+ },
1123
+ install: async () => {
1124
+ const rulesPath = path.join(process.cwd(), ".clinerules");
1125
+ let existing = "";
1126
+ try {
1127
+ existing = await fs2.readFile(rulesPath, "utf-8");
1128
+ } catch {
1129
+ }
1130
+ if (!existing.includes("make-laten")) {
1131
+ await fs2.writeFile(rulesPath, existing + "\n\n" + RULES_CONTENT);
1132
+ }
1133
+ },
1134
+ uninstall: async () => {
1135
+ try {
1136
+ let content = await fs2.readFile(path.join(process.cwd(), ".clinerules"), "utf-8");
1137
+ content = content.replace(/\n# make-laten efficiency rules[\s\S]*$/, "");
1138
+ await fs2.writeFile(path.join(process.cwd(), ".clinerules"), content.trim() + "\n");
1139
+ } catch {
1144
1140
  }
1145
- } catch {
1146
1141
  }
1147
- }
1148
- async isInstalled(agentPath) {
1149
- const config = AGENT_CONFIGS[this.name];
1150
- if (!config?.rulesFile) return false;
1151
- try {
1152
- const content = await fs4.readFile(path3.join(agentPath, config.rulesFile), "utf-8");
1153
- return content.includes("make-laten");
1154
- } catch {
1155
- return false;
1142
+ },
1143
+ {
1144
+ name: "copilot",
1145
+ detected: async () => {
1146
+ try {
1147
+ await fs2.access(path.join(process.cwd(), ".github"));
1148
+ return true;
1149
+ } catch {
1150
+ return false;
1151
+ }
1152
+ },
1153
+ install: async () => {
1154
+ const dir = path.join(process.cwd(), ".github");
1155
+ await fs2.mkdir(dir, { recursive: true });
1156
+ const instructionsPath = path.join(dir, "copilot-instructions.md");
1157
+ let existing = "";
1158
+ try {
1159
+ existing = await fs2.readFile(instructionsPath, "utf-8");
1160
+ } catch {
1161
+ }
1162
+ if (!existing.includes("make-laten")) {
1163
+ await fs2.writeFile(instructionsPath, existing + "\n\n## make-laten Efficiency\n" + RULES_CONTENT);
1164
+ }
1165
+ },
1166
+ uninstall: async () => {
1167
+ try {
1168
+ let content = await fs2.readFile(path.join(process.cwd(), ".github", "copilot-instructions.md"), "utf-8");
1169
+ content = content.replace(/\n## make-laten Efficiency[\s\S]*$/, "");
1170
+ await fs2.writeFile(path.join(process.cwd(), ".github", "copilot-instructions.md"), content.trim() + "\n");
1171
+ } catch {
1172
+ }
1156
1173
  }
1157
- }
1158
- };
1174
+ },
1175
+ {
1176
+ name: "opencode",
1177
+ detected: async () => {
1178
+ try {
1179
+ await fs2.access(path.join(getHome(), ".config", "opencode"));
1180
+ return true;
1181
+ } catch {
1182
+ return false;
1183
+ }
1184
+ },
1185
+ install: async () => {
1186
+ const skillsDir = path.join(getHome(), ".config", "opencode", "skills", "make-laten");
1187
+ await fs2.mkdir(skillsDir, { recursive: true });
1188
+ const npmRoot = await execAsync3("npm root -g").then((r) => r.stdout.trim());
1189
+ const skillSrc = path.join(npmRoot, "make-laten", "skills", "SKILL.md");
1190
+ try {
1191
+ const skillContent = await fs2.readFile(skillSrc, "utf-8");
1192
+ await fs2.writeFile(path.join(skillsDir, "SKILL.md"), skillContent);
1193
+ } catch {
1194
+ await fs2.writeFile(path.join(skillsDir, "SKILL.md"), `---
1195
+ name: make-laten
1196
+ description: Token optimization toolkit
1197
+ ---
1159
1198
 
1160
- // src/adapter/installer.ts
1199
+ # make-laten Skill
1200
+
1201
+ Use make-laten CLI commands for all file/code/git operations.
1202
+ `);
1203
+ }
1204
+ },
1205
+ uninstall: async () => {
1206
+ try {
1207
+ await fs2.rm(path.join(getHome(), ".config", "opencode", "skills", "make-laten"), { recursive: true, force: true });
1208
+ } catch {
1209
+ }
1210
+ }
1211
+ }
1212
+ ];
1161
1213
  var Installer = class {
1162
- detector = new AgentDetector();
1163
1214
  async install() {
1164
- const agents = await this.detector.detectAgents();
1165
1215
  const installed = [];
1166
1216
  const skipped = [];
1167
1217
  for (const agent of agents) {
1168
1218
  try {
1169
- const adapter = this.createAdapter(agent);
1170
- if (adapter.install) {
1171
- await adapter.install(agent.path);
1219
+ const detected = await agent.detected();
1220
+ if (detected) {
1221
+ await agent.install();
1172
1222
  installed.push(agent.name);
1173
1223
  } else {
1174
1224
  skipped.push(agent.name);
@@ -1180,36 +1230,27 @@ var Installer = class {
1180
1230
  return { installed, skipped };
1181
1231
  }
1182
1232
  async uninstall() {
1183
- const agents = await this.detector.detectAgents();
1184
1233
  const removed = [];
1185
1234
  for (const agent of agents) {
1186
1235
  try {
1187
- const adapter = this.createAdapter(agent);
1188
- if (adapter.uninstall) {
1189
- await adapter.uninstall(agent.path);
1190
- removed.push(agent.name);
1191
- }
1236
+ await agent.uninstall();
1237
+ removed.push(agent.name);
1192
1238
  } catch {
1193
1239
  }
1194
1240
  }
1195
1241
  return { removed };
1196
1242
  }
1197
1243
  async status() {
1198
- const agents = await this.detector.detectAgents();
1244
+ const result = [];
1199
1245
  for (const agent of agents) {
1200
- const adapter = this.createAdapter(agent);
1201
- if (adapter.isInstalled) {
1202
- agent.detected = await adapter.isInstalled(agent.path);
1246
+ try {
1247
+ const detected = await agent.detected();
1248
+ result.push({ name: agent.name, detected, installed: false });
1249
+ } catch {
1250
+ result.push({ name: agent.name, detected: false, installed: false });
1203
1251
  }
1204
1252
  }
1205
- return agents;
1206
- }
1207
- createAdapter(agent) {
1208
- const config = AGENT_CONFIGS[agent.name];
1209
- if (config?.type === "rules") {
1210
- return new RulesAdapter(agent.name);
1211
- }
1212
- return new HookAdapter(agent.name);
1253
+ return result;
1213
1254
  }
1214
1255
  };
1215
1256
 
@@ -1217,20 +1258,17 @@ var Installer = class {
1217
1258
  async function installCommand(options) {
1218
1259
  const installer = new Installer();
1219
1260
  if (options.status) {
1220
- console.log("Detecting installed agents...\n");
1221
- const agents = await installer.status();
1222
- if (agents.length === 0) {
1223
- console.log("No supported agents detected.");
1224
- return;
1225
- }
1226
- for (const agent of agents) {
1227
- const status = agent.detected ? "\u2713 installed" : "\u25CB detected";
1228
- console.log(` ${status} ${agent.name} (${agent.type})${agent.version ? ` v${agent.version}` : ""}`);
1261
+ console.log("Detecting platforms...\n");
1262
+ const status = await installer.status();
1263
+ for (const s of status) {
1264
+ const icon = s.detected ? "\u2713" : "\u25CB";
1265
+ const label = s.detected ? "detected" : "not found";
1266
+ console.log(` ${icon} ${s.name} (${label})`);
1229
1267
  }
1230
1268
  return;
1231
1269
  }
1232
1270
  if (options.uninstall) {
1233
- console.log("Uninstalling make-laten adapters...\n");
1271
+ console.log("Uninstalling make-laten from all platforms...\n");
1234
1272
  const { removed } = await installer.uninstall();
1235
1273
  if (removed.length === 0) {
1236
1274
  console.log("Nothing to uninstall.");
@@ -1239,31 +1277,262 @@ async function installCommand(options) {
1239
1277
  for (const name of removed) {
1240
1278
  console.log(` \u2713 removed from ${name}`);
1241
1279
  }
1280
+ console.log(`
1281
+ Done! Removed from ${removed.length} platform(s).`);
1242
1282
  return;
1243
1283
  }
1244
- console.log("Installing make-laten adapters...\n");
1284
+ console.log("Installing make-laten across all platforms...\n");
1245
1285
  const { installed, skipped } = await installer.install();
1246
- if (installed.length === 0 && skipped.length === 0) {
1247
- console.log("No supported agents detected.");
1248
- console.log("make-laten CLI works standalone \u2014 use commands directly:");
1249
- console.log(" make-laten read <file>");
1250
- console.log(" make-laten grep <pattern>");
1251
- console.log(" make-laten git diff");
1252
- return;
1253
- }
1254
1286
  for (const name of installed) {
1255
- console.log(` \u2713 ${name} configured`);
1287
+ console.log(` \u2713 ${name}`);
1256
1288
  }
1257
1289
  for (const name of skipped) {
1258
- console.log(` \u25CB ${name} skipped (already configured or unavailable)`);
1290
+ console.log(` \u25CB ${name} (not detected)`);
1259
1291
  }
1260
1292
  console.log(`
1261
- Done! Configured for ${installed.length} agent(s).`);
1293
+ Done! Configured for ${installed.length} platform(s).`);
1294
+ console.log("\nAvailable commands (terminal):");
1295
+ console.log(" mread <file> compressed file read");
1296
+ console.log(" mgrep <pattern> grouped grep results");
1297
+ console.log(" mdiff compressed git diff");
1298
+ console.log(" mstatus git status summary");
1299
+ console.log(" msearch <query> web search");
1300
+ console.log(" mfetch <url> web fetch + compress");
1301
+ }
1302
+
1303
+ // src/cli/commands/init.ts
1304
+ import { exec as exec4 } from "child_process";
1305
+ import { promisify as promisify4 } from "util";
1306
+ import fs3 from "fs/promises";
1307
+ import path2 from "path";
1308
+ import readline from "readline";
1309
+ var execAsync4 = promisify4(exec4);
1310
+ function getHome2() {
1311
+ return process.env.HOME || process.env.USERPROFILE || "";
1312
+ }
1313
+ async function commandExists2(cmd) {
1314
+ try {
1315
+ await execAsync4(`which ${cmd}`, { timeout: 3e3 });
1316
+ return true;
1317
+ } catch {
1318
+ return false;
1319
+ }
1320
+ }
1321
+ async function directoryExists(dirPath) {
1322
+ try {
1323
+ await fs3.access(dirPath);
1324
+ return true;
1325
+ } catch {
1326
+ return false;
1327
+ }
1328
+ }
1329
+ async function detectAllAgents() {
1330
+ const home = getHome2();
1331
+ const agents2 = [];
1332
+ const claudeConfig = path2.join(home, ".claude", "mcp.json");
1333
+ const claudeDir = path2.join(home, ".claude");
1334
+ agents2.push({
1335
+ name: "Claude Code",
1336
+ detected: await commandExists2("claude") || await directoryExists(claudeDir),
1337
+ configPath: claudeConfig,
1338
+ mcpConfig: {
1339
+ mcpServers: {
1340
+ "make-laten": { command: "npx", args: ["-y", "make-laten-mcp", "server"] }
1341
+ }
1342
+ },
1343
+ version: await commandExists2("claude") ? await execAsync4("claude --version", { timeout: 3e3 }).then((r) => r.stdout.trim().split("\n")[0]).catch(() => "unknown") : void 0
1344
+ });
1345
+ const cursorMcp = path2.join(home, ".cursor", "mcp.json");
1346
+ const cursorDir = path2.join(home, ".cursor");
1347
+ agents2.push({
1348
+ name: "Cursor",
1349
+ detected: await directoryExists(cursorDir),
1350
+ configPath: cursorMcp,
1351
+ mcpConfig: {
1352
+ mcpServers: {
1353
+ "make-laten": { command: "npx", args: ["-y", "make-laten-mcp", "server"] }
1354
+ }
1355
+ }
1356
+ });
1357
+ const codexMcp = path2.join(home, ".codex", "config.json");
1358
+ const codexDir = path2.join(home, ".codex");
1359
+ agents2.push({
1360
+ name: "Codex",
1361
+ detected: await commandExists2("codex") || await directoryExists(codexDir),
1362
+ configPath: codexMcp,
1363
+ mcpConfig: {
1364
+ mcpServers: {
1365
+ "make-laten": { command: "npx", args: ["-y", "make-laten-mcp", "server"] }
1366
+ }
1367
+ }
1368
+ });
1369
+ const windsurfMcp = path2.join(home, ".codeium", "windsurf", "mcp_config.json");
1370
+ const windsurfDir = path2.join(home, ".codeium", "windsurf");
1371
+ agents2.push({
1372
+ name: "Windsurf",
1373
+ detected: await directoryExists(windsurfDir),
1374
+ configPath: windsurfMcp,
1375
+ mcpConfig: {
1376
+ mcpServers: {
1377
+ "make-laten": { command: "npx", args: ["-y", "make-laten-mcp", "server"] }
1378
+ }
1379
+ }
1380
+ });
1381
+ const openCodeConfig = path2.join(home, ".config", "opencode", "opencode.json");
1382
+ const openCodeDir = path2.join(home, ".config", "opencode");
1383
+ agents2.push({
1384
+ name: "OpenCode",
1385
+ detected: await directoryExists(openCodeDir),
1386
+ configPath: openCodeConfig,
1387
+ mcpConfig: {
1388
+ mcpServers: {
1389
+ "make-laten": { command: "npx", args: ["-y", "make-laten-mcp", "server"] }
1390
+ }
1391
+ }
1392
+ });
1393
+ const clineDir = path2.join(home, ".cline");
1394
+ const clineMcp = path2.join(home, ".cline", "mcp_settings.json");
1395
+ agents2.push({
1396
+ name: "Cline",
1397
+ detected: await directoryExists(clineDir),
1398
+ configPath: clineMcp,
1399
+ mcpConfig: {
1400
+ mcpServers: {
1401
+ "make-laten": { command: "npx", args: ["-y", "make-laten-mcp", "server"] }
1402
+ }
1403
+ }
1404
+ });
1405
+ const vscodeDir = path2.join(home, "Library", "Application Support", "Code", "User", "globalStorage");
1406
+ agents2.push({
1407
+ name: "GitHub Copilot (VS Code)",
1408
+ detected: await directoryExists(vscodeDir),
1409
+ configPath: "",
1410
+ mcpConfig: {}
1411
+ });
1412
+ const geminiDir = path2.join(home, ".gemini");
1413
+ agents2.push({
1414
+ name: "Gemini CLI",
1415
+ detected: await commandExists2("gemini") || await directoryExists(geminiDir),
1416
+ configPath: path2.join(home, ".gemini", "settings.json"),
1417
+ mcpConfig: {
1418
+ mcpServers: {
1419
+ "make-laten": { command: "npx", args: ["-y", "make-laten-mcp", "server"] }
1420
+ }
1421
+ }
1422
+ });
1423
+ return agents2;
1424
+ }
1425
+ async function writeMCPConfig(agent) {
1426
+ try {
1427
+ const dir = path2.dirname(agent.configPath);
1428
+ await fs3.mkdir(dir, { recursive: true });
1429
+ let existing = {};
1430
+ try {
1431
+ const raw = await fs3.readFile(agent.configPath, "utf-8");
1432
+ existing = JSON.parse(raw);
1433
+ } catch {
1434
+ }
1435
+ const merged = {
1436
+ ...existing,
1437
+ mcpServers: {
1438
+ ...existing.mcpServers || {},
1439
+ ...agent.mcpConfig.mcpServers
1440
+ }
1441
+ };
1442
+ await fs3.writeFile(agent.configPath, JSON.stringify(merged, null, 2));
1443
+ return true;
1444
+ } catch {
1445
+ return false;
1446
+ }
1447
+ }
1448
+ function askQuestion(rl, question) {
1449
+ return new Promise((resolve) => rl.question(question, resolve));
1450
+ }
1451
+ async function initCommand(options) {
1452
+ console.log("");
1453
+ console.log(" make-laten setup wizard");
1454
+ console.log(" ======================");
1455
+ console.log("");
1456
+ const agents2 = await detectAllAgents();
1457
+ const detected = agents2.filter((a) => a.detected);
1458
+ const notDetected = agents2.filter((a) => !a.detected);
1459
+ console.log(" Detected agents:");
1460
+ for (const agent of detected) {
1461
+ const ver = agent.version ? ` v${agent.version}` : "";
1462
+ console.log(` \u2713 ${agent.name}${ver}`);
1463
+ }
1464
+ if (notDetected.length > 0) {
1465
+ console.log("");
1466
+ console.log(" Not detected (skipped):");
1467
+ for (const agent of notDetected) {
1468
+ console.log(` \u25CB ${agent.name}`);
1469
+ }
1470
+ }
1471
+ console.log("");
1472
+ if (options.all) {
1473
+ for (const agent of detected) {
1474
+ const success = await writeMCPConfig(agent);
1475
+ if (success) {
1476
+ console.log(` \u2713 ${agent.name} \u2192 MCP configured`);
1477
+ } else {
1478
+ console.log(` \u2717 ${agent.name} \u2192 failed`);
1479
+ }
1480
+ }
1481
+ } else if (options.project) {
1482
+ const cwd = process.cwd();
1483
+ const mcpConfig = {
1484
+ mcpServers: {
1485
+ "make-laten": { command: "npx", args: ["-y", "make-laten-mcp", "server"] }
1486
+ }
1487
+ };
1488
+ const configPath = path2.join(cwd, ".mcp.json");
1489
+ let existing = {};
1490
+ try {
1491
+ const raw = await fs3.readFile(configPath, "utf-8");
1492
+ existing = JSON.parse(raw);
1493
+ } catch {
1494
+ }
1495
+ const merged = {
1496
+ ...existing,
1497
+ mcpServers: {
1498
+ ...existing.mcpServers || {},
1499
+ ...mcpConfig.mcpServers
1500
+ }
1501
+ };
1502
+ await fs3.writeFile(configPath, JSON.stringify(merged, null, 2));
1503
+ console.log(` \u2713 .mcp.json created in ${cwd}`);
1504
+ } else {
1505
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1506
+ for (const agent of detected) {
1507
+ const answer = await askQuestion(rl, ` Configure ${agent.name}? (Y/n) `);
1508
+ if (answer.toLowerCase() !== "n") {
1509
+ const success = await writeMCPConfig(agent);
1510
+ if (success) {
1511
+ console.log(` \u2713 ${agent.name} \u2192 MCP configured`);
1512
+ } else {
1513
+ console.log(` \u2717 ${agent.name} \u2192 failed`);
1514
+ }
1515
+ } else {
1516
+ console.log(` \u25CB ${agent.name} \u2192 skipped`);
1517
+ }
1518
+ }
1519
+ rl.close();
1520
+ }
1521
+ console.log("");
1522
+ console.log(" Setup complete!");
1523
+ console.log("");
1524
+ console.log(" make-laten provides:");
1525
+ console.log(" \u2022 MCP server \u2192 auto-compress for all AI agents");
1526
+ console.log(" \u2022 CLI commands \u2192 mread, mgrep, mdiff, msearch, mfetch");
1527
+ console.log(" \u2022 Shell aliases \u2192 auto-load in new terminals");
1528
+ console.log("");
1529
+ console.log(" Restart your agent to activate MCP tools.");
1530
+ console.log("");
1262
1531
  }
1263
1532
 
1264
1533
  // src/cli/index.ts
1265
1534
  var program = new Command();
1266
- program.name("make-laten").description("Universal efficiency skill for AI coding agents").version("0.1.0");
1535
+ program.name("make-laten").description("Universal efficiency toolkit for AI coding agents").version("1.0.3");
1267
1536
  program.command("read").description("Compressed file read").argument("<file>", "File path").action(readCommand);
1268
1537
  program.command("grep").description("Compressed grep with file grouping").argument("<pattern>", "Search pattern").argument("[directory]", "Directory to search", ".").option("-i, --ignore <ext>", "File extension to ignore").action(grepCommand);
1269
1538
  var gitCmd = program.command("git").description("Git operations");
@@ -1274,6 +1543,7 @@ cacheCmd.command("stats").description("Show cache statistics").action(cacheStats
1274
1543
  cacheCmd.command("clear").description("Clear cache").action(cacheClearCommand);
1275
1544
  program.command("search").description("Search the web").argument("<query>", "Search query").option("-b, --backend <backend>", "Search backend").option("-m, --max <n>", "Max results", "5").action(searchCommand);
1276
1545
  program.command("fetch").description("Fetch and compress web content").argument("<url>", "URL to fetch").option("--no-compress", "Disable compression").option("--no-extract", "Disable semantic extraction").action(fetchCommand);
1277
- program.command("install").description("Install make-laten adapters for detected agents").option("-u, --uninstall", "Remove adapters").option("-s, --status", "Show installation status").action(installCommand);
1546
+ program.command("install").description("Install make-laten across all detected platforms").option("-u, --uninstall", "Remove adapters").option("-s, --status", "Show installation status").action(installCommand);
1547
+ program.command("init").description("Interactive setup wizard \u2014 detect agents & configure MCP").option("-a, --all", "Configure all detected agents (no prompts)").option("-p, --project", "Create .mcp.json in current directory only").action(initCommand);
1278
1548
  program.parse();
1279
1549
  //# sourceMappingURL=index.mjs.map