make-laten 1.0.1 → 1.0.3

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,26 +1277,27 @@ 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");
1262
1301
  }
1263
1302
 
1264
1303
  // src/cli/index.ts