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