@massa-ai/opencode-plugin 1.2.1 → 1.4.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/config-cli.js +170 -156
- package/dist/index.js +7 -3
- package/package.json +3 -3
package/dist/config-cli.js
CHANGED
|
@@ -557,7 +557,8 @@ __export(exports_config_loader, {
|
|
|
557
557
|
getConfigPath: () => getConfigPath,
|
|
558
558
|
getConfigForEnv: () => getConfigForEnv,
|
|
559
559
|
getConfigDir: () => getConfigDir,
|
|
560
|
-
configExists: () => configExists
|
|
560
|
+
configExists: () => configExists,
|
|
561
|
+
__resetMigrationForTests: () => __resetMigrationForTests
|
|
561
562
|
});
|
|
562
563
|
import fs from "fs";
|
|
563
564
|
import path3 from "path";
|
|
@@ -627,6 +628,9 @@ function migrateDataDirOnce() {
|
|
|
627
628
|
console.error(`[massa-ai] Data directory migration skipped:`, err);
|
|
628
629
|
}
|
|
629
630
|
}
|
|
631
|
+
function __resetMigrationForTests() {
|
|
632
|
+
migrationAttempted = false;
|
|
633
|
+
}
|
|
630
634
|
function saveConfig(config) {
|
|
631
635
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
632
636
|
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
@@ -636,7 +640,7 @@ function saveConfig(config) {
|
|
|
636
640
|
function initConfig() {
|
|
637
641
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
638
642
|
saveConfig(defaultMassaAiConfig);
|
|
639
|
-
console.
|
|
643
|
+
console.error(`Created default config at ${CONFIG_FILE}`);
|
|
640
644
|
}
|
|
641
645
|
}
|
|
642
646
|
function getConfigForEnv() {
|
|
@@ -686,7 +690,7 @@ function findEnvFile() {
|
|
|
686
690
|
return;
|
|
687
691
|
}
|
|
688
692
|
var envPath = findEnvFile();
|
|
689
|
-
import_dotenv.config({ path: envPath });
|
|
693
|
+
import_dotenv.config({ path: envPath, quiet: true });
|
|
690
694
|
try {
|
|
691
695
|
const { loadConfigSafe: loadConfigSafe2, migrateDataDirOnce: migrateDataDirOnce2 } = (init_config_loader(), __toCommonJS(exports_config_loader));
|
|
692
696
|
migrateDataDirOnce2();
|
|
@@ -1136,8 +1140,6 @@ import { promises as fs2 } from "fs";
|
|
|
1136
1140
|
import path5 from "path";
|
|
1137
1141
|
import os3 from "os";
|
|
1138
1142
|
import { fileURLToPath } from "url";
|
|
1139
|
-
var args = process.argv.slice(2);
|
|
1140
|
-
var command = args[0];
|
|
1141
1143
|
var __dirname2 = path5.dirname(fileURLToPath(import.meta.url));
|
|
1142
1144
|
function help() {
|
|
1143
1145
|
console.log(`
|
|
@@ -1160,7 +1162,7 @@ Commands:
|
|
|
1160
1162
|
--model <name> Model name
|
|
1161
1163
|
--base-url <url> Base URL (for ollama)
|
|
1162
1164
|
|
|
1163
|
-
agents Manage the
|
|
1165
|
+
agents Manage the 15 subagent specialist definitions
|
|
1164
1166
|
agents install [--user|--project] Write 12 agent .md files
|
|
1165
1167
|
agents uninstall [--user|--project] Remove only massa-ai-owned agents
|
|
1166
1168
|
|
|
@@ -1173,13 +1175,13 @@ Examples:
|
|
|
1173
1175
|
massa-ai-config agents install --user
|
|
1174
1176
|
`);
|
|
1175
1177
|
}
|
|
1176
|
-
function parseOptions(
|
|
1178
|
+
function parseOptions(args) {
|
|
1177
1179
|
const options = {};
|
|
1178
|
-
for (let i = 0;i <
|
|
1179
|
-
if (
|
|
1180
|
-
const key =
|
|
1181
|
-
if (i + 1 <
|
|
1182
|
-
options[key] =
|
|
1180
|
+
for (let i = 0;i < args.length; i++) {
|
|
1181
|
+
if (args[i].startsWith("--")) {
|
|
1182
|
+
const key = args[i].slice(2);
|
|
1183
|
+
if (i + 1 < args.length && !args[i + 1].startsWith("--")) {
|
|
1184
|
+
options[key] = args[i + 1];
|
|
1183
1185
|
i++;
|
|
1184
1186
|
} else {
|
|
1185
1187
|
options[key] = true;
|
|
@@ -1188,166 +1190,178 @@ function parseOptions(args2) {
|
|
|
1188
1190
|
}
|
|
1189
1191
|
return options;
|
|
1190
1192
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
case "init": {
|
|
1198
|
-
initConfig();
|
|
1199
|
-
if (options.mistral && typeof options.mistral === "string") {
|
|
1200
|
-
const config2 = loadConfig();
|
|
1201
|
-
config2.embedding = {
|
|
1202
|
-
provider: "mistral",
|
|
1203
|
-
model: "mistral-embed",
|
|
1204
|
-
apiKey: options.mistral,
|
|
1205
|
-
dimensions: 1024
|
|
1206
|
-
};
|
|
1207
|
-
saveConfig(config2);
|
|
1208
|
-
console.log("\u2713 Configured for Mistral embeddings");
|
|
1209
|
-
} else if (options.openai && typeof options.openai === "string") {
|
|
1210
|
-
const config2 = loadConfig();
|
|
1211
|
-
config2.embedding = {
|
|
1212
|
-
provider: "openai",
|
|
1213
|
-
model: "text-embedding-3-small",
|
|
1214
|
-
apiKey: options.openai,
|
|
1215
|
-
dimensions: 1536
|
|
1216
|
-
};
|
|
1217
|
-
saveConfig(config2);
|
|
1218
|
-
console.log("\u2713 Configured for OpenAI embeddings");
|
|
1219
|
-
} else {
|
|
1220
|
-
console.log("\u2713 Configured for Ollama (local) embeddings");
|
|
1221
|
-
}
|
|
1222
|
-
console.log(`
|
|
1223
|
-
Config file: ${getConfigPath()}`);
|
|
1224
|
-
break;
|
|
1225
|
-
}
|
|
1226
|
-
case "path": {
|
|
1227
|
-
console.log(getConfigPath());
|
|
1228
|
-
break;
|
|
1193
|
+
async function runCli(argv) {
|
|
1194
|
+
const args = argv;
|
|
1195
|
+
const command = args[0];
|
|
1196
|
+
if (!command || command === "--help" || command === "-h") {
|
|
1197
|
+
help();
|
|
1198
|
+
return 0;
|
|
1229
1199
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1200
|
+
const options = parseOptions(args.slice(1));
|
|
1201
|
+
switch (command) {
|
|
1202
|
+
case "init": {
|
|
1203
|
+
initConfig();
|
|
1204
|
+
if (options.mistral && typeof options.mistral === "string") {
|
|
1205
|
+
const config2 = loadConfig();
|
|
1206
|
+
config2.embedding = {
|
|
1207
|
+
provider: "mistral",
|
|
1208
|
+
model: "mistral-embed",
|
|
1209
|
+
apiKey: options.mistral,
|
|
1210
|
+
dimensions: 1024
|
|
1211
|
+
};
|
|
1212
|
+
saveConfig(config2);
|
|
1213
|
+
console.log("\u2713 Configured for Mistral embeddings");
|
|
1214
|
+
} else if (options.openai && typeof options.openai === "string") {
|
|
1215
|
+
const config2 = loadConfig();
|
|
1216
|
+
config2.embedding = {
|
|
1217
|
+
provider: "openai",
|
|
1218
|
+
model: "text-embedding-3-small",
|
|
1219
|
+
apiKey: options.openai,
|
|
1220
|
+
dimensions: 1536
|
|
1221
|
+
};
|
|
1222
|
+
saveConfig(config2);
|
|
1223
|
+
console.log("\u2713 Configured for OpenAI embeddings");
|
|
1224
|
+
} else {
|
|
1225
|
+
console.log("\u2713 Configured for Ollama (local) embeddings");
|
|
1226
|
+
}
|
|
1233
1227
|
console.log(`
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
process.exit(0);
|
|
1237
|
-
}
|
|
1238
|
-
const config2 = loadConfig();
|
|
1239
|
-
console.log(JSON.stringify(config2, null, 2));
|
|
1240
|
-
break;
|
|
1241
|
-
}
|
|
1242
|
-
case "set": {
|
|
1243
|
-
const key = args[1];
|
|
1244
|
-
const value = args[2];
|
|
1245
|
-
if (!key || !value) {
|
|
1246
|
-
console.error("Usage: massa-ai-config set <key> <value>");
|
|
1247
|
-
process.exit(1);
|
|
1228
|
+
Config file: ${getConfigPath()}`);
|
|
1229
|
+
break;
|
|
1248
1230
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
for (let i = 0;i < keys.length - 1; i++) {
|
|
1253
|
-
obj = obj[keys[i]];
|
|
1231
|
+
case "path": {
|
|
1232
|
+
console.log(getConfigPath());
|
|
1233
|
+
break;
|
|
1254
1234
|
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
console.
|
|
1265
|
-
|
|
1235
|
+
case "show": {
|
|
1236
|
+
if (!configExists()) {
|
|
1237
|
+
console.log("No config file found. Run `massa-ai-config init` to create one.");
|
|
1238
|
+
console.log(`
|
|
1239
|
+
Using defaults:`);
|
|
1240
|
+
console.log(JSON.stringify(defaultMassaAiConfig, null, 2));
|
|
1241
|
+
return 0;
|
|
1242
|
+
}
|
|
1243
|
+
const config2 = loadConfig();
|
|
1244
|
+
console.log(JSON.stringify(config2, null, 2));
|
|
1245
|
+
break;
|
|
1266
1246
|
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
dimensions: 768
|
|
1274
|
-
};
|
|
1275
|
-
} else if (provider === "mistral") {
|
|
1276
|
-
if (!options["api-key"]) {
|
|
1277
|
-
console.error("Error: --api-key required for Mistral");
|
|
1278
|
-
process.exit(1);
|
|
1247
|
+
case "set": {
|
|
1248
|
+
const key = args[1];
|
|
1249
|
+
const value = args[2];
|
|
1250
|
+
if (!key || !value) {
|
|
1251
|
+
console.error("Usage: massa-ai-config set <key> <value>");
|
|
1252
|
+
return 1;
|
|
1279
1253
|
}
|
|
1280
|
-
config2
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
};
|
|
1286
|
-
} else if (provider === "openai") {
|
|
1287
|
-
if (!options["api-key"]) {
|
|
1288
|
-
console.error("Error: --api-key required for OpenAI");
|
|
1289
|
-
process.exit(1);
|
|
1254
|
+
const config2 = loadConfig();
|
|
1255
|
+
const keys = key.split(".");
|
|
1256
|
+
let obj = config2;
|
|
1257
|
+
for (let i = 0;i < keys.length - 1; i++) {
|
|
1258
|
+
obj = obj[keys[i]];
|
|
1290
1259
|
}
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
};
|
|
1260
|
+
const parsedValue = isNaN(Number(value)) ? value : Number(value);
|
|
1261
|
+
obj[keys[keys.length - 1]] = parsedValue;
|
|
1262
|
+
saveConfig(config2);
|
|
1263
|
+
console.log(`\u2713 Set ${key} = ${value}`);
|
|
1264
|
+
break;
|
|
1297
1265
|
}
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1266
|
+
case "use": {
|
|
1267
|
+
const provider = args[1];
|
|
1268
|
+
if (!provider || !["ollama", "mistral", "openai"].includes(provider)) {
|
|
1269
|
+
console.error("Provider must be: ollama, mistral, or openai");
|
|
1270
|
+
return 1;
|
|
1271
|
+
}
|
|
1272
|
+
const config2 = loadConfig();
|
|
1273
|
+
if (provider === "ollama") {
|
|
1274
|
+
config2.embedding = {
|
|
1275
|
+
provider: "ollama",
|
|
1276
|
+
model: options.model || "nomic-embed-text:latest",
|
|
1277
|
+
baseURL: options["base-url"] || "http://localhost:11434",
|
|
1278
|
+
dimensions: 768
|
|
1279
|
+
};
|
|
1280
|
+
} else if (provider === "mistral") {
|
|
1281
|
+
if (!options["api-key"]) {
|
|
1282
|
+
console.error("Error: --api-key required for Mistral");
|
|
1283
|
+
return 1;
|
|
1284
|
+
}
|
|
1285
|
+
config2.embedding = {
|
|
1286
|
+
provider: "mistral",
|
|
1287
|
+
model: options.model || "mistral-embed",
|
|
1288
|
+
apiKey: options["api-key"],
|
|
1289
|
+
dimensions: 1024
|
|
1290
|
+
};
|
|
1291
|
+
} else if (provider === "openai") {
|
|
1292
|
+
if (!options["api-key"]) {
|
|
1293
|
+
console.error("Error: --api-key required for OpenAI");
|
|
1294
|
+
return 1;
|
|
1295
|
+
}
|
|
1296
|
+
config2.embedding = {
|
|
1297
|
+
provider: "openai",
|
|
1298
|
+
model: options.model || "text-embedding-3-small",
|
|
1299
|
+
apiKey: options["api-key"],
|
|
1300
|
+
dimensions: 1536
|
|
1301
|
+
};
|
|
1302
|
+
}
|
|
1303
|
+
saveConfig(config2);
|
|
1304
|
+
console.log(`\u2713 Switched to ${provider} embeddings`);
|
|
1305
|
+
console.log(` Model: ${config2.embedding.model}`);
|
|
1306
|
+
break;
|
|
1308
1307
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
let count = 0;
|
|
1315
|
-
const entries = await fs2.readdir(sourceAgentsDir);
|
|
1316
|
-
for (const entry of entries) {
|
|
1317
|
-
if (!entry.startsWith("massa-ai-") || !entry.endsWith(".md"))
|
|
1318
|
-
continue;
|
|
1319
|
-
const src = path5.join(sourceAgentsDir, entry);
|
|
1320
|
-
const dest = path5.join(agentsDir, entry);
|
|
1321
|
-
await fs2.copyFile(src, dest);
|
|
1322
|
-
count++;
|
|
1308
|
+
case "agents": {
|
|
1309
|
+
const subcommand = args[1];
|
|
1310
|
+
if (subcommand !== "install" && subcommand !== "uninstall") {
|
|
1311
|
+
console.error("Usage: massa-ai-config agents <install|uninstall> [--user|--project]");
|
|
1312
|
+
return 1;
|
|
1323
1313
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1314
|
+
const scope = typeof options.project === "boolean" ? "project" : "user";
|
|
1315
|
+
const agentsDir = scope === "project" ? path5.join(process.cwd(), ".opencode/agents") : path5.join(process.env.XDG_CONFIG_HOME && process.env.XDG_CONFIG_HOME.trim() || path5.join(os3.homedir(), ".config"), "opencode", "agents");
|
|
1316
|
+
const sourceAgentsDir = path5.resolve(__dirname2, "..", "agents");
|
|
1317
|
+
if (subcommand === "install") {
|
|
1318
|
+
await fs2.mkdir(agentsDir, { recursive: true });
|
|
1319
|
+
let count = 0;
|
|
1320
|
+
const entries = await fs2.readdir(sourceAgentsDir);
|
|
1330
1321
|
for (const entry of entries) {
|
|
1331
1322
|
if (!entry.startsWith("massa-ai-") || !entry.endsWith(".md"))
|
|
1332
1323
|
continue;
|
|
1333
|
-
const
|
|
1334
|
-
const
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1324
|
+
const src = path5.join(sourceAgentsDir, entry);
|
|
1325
|
+
const dest = path5.join(agentsDir, entry);
|
|
1326
|
+
await fs2.copyFile(src, dest);
|
|
1327
|
+
count++;
|
|
1328
|
+
}
|
|
1329
|
+
console.log(`+ ${count} subagent specialists (generated from skills/agents/*/SKILL.md)`);
|
|
1330
|
+
console.log(` written to: ${agentsDir}`);
|
|
1331
|
+
} else {
|
|
1332
|
+
let removed = 0;
|
|
1333
|
+
try {
|
|
1334
|
+
const entries = await fs2.readdir(agentsDir);
|
|
1335
|
+
for (const entry of entries) {
|
|
1336
|
+
if (!entry.startsWith("massa-ai-") || !entry.endsWith(".md"))
|
|
1337
|
+
continue;
|
|
1338
|
+
const filePath = path5.join(agentsDir, entry);
|
|
1339
|
+
const content = await fs2.readFile(filePath, "utf8");
|
|
1340
|
+
if (content.includes("massa-ai-owned: true")) {
|
|
1341
|
+
await fs2.unlink(filePath);
|
|
1342
|
+
removed++;
|
|
1343
|
+
}
|
|
1338
1344
|
}
|
|
1345
|
+
} catch (e) {
|
|
1346
|
+
if (e.code !== "ENOENT")
|
|
1347
|
+
throw e;
|
|
1339
1348
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
throw e;
|
|
1349
|
+
console.log(`- removed ${removed} massa-ai-owned agent files from ${agentsDir}`);
|
|
1350
|
+
console.log(" User agents preserved.");
|
|
1343
1351
|
}
|
|
1344
|
-
|
|
1345
|
-
console.log(" User agents preserved.");
|
|
1352
|
+
break;
|
|
1346
1353
|
}
|
|
1347
|
-
|
|
1354
|
+
default:
|
|
1355
|
+
console.error(`Unknown command: ${command}`);
|
|
1356
|
+
help();
|
|
1357
|
+
return 1;
|
|
1348
1358
|
}
|
|
1349
|
-
|
|
1350
|
-
console.error(`Unknown command: ${command}`);
|
|
1351
|
-
help();
|
|
1352
|
-
process.exit(1);
|
|
1359
|
+
return 0;
|
|
1353
1360
|
}
|
|
1361
|
+
if (import.meta.main) {
|
|
1362
|
+
runCli(process.argv.slice(2)).then((code) => process.exit(code));
|
|
1363
|
+
}
|
|
1364
|
+
export {
|
|
1365
|
+
runCli,
|
|
1366
|
+
parseOptions
|
|
1367
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -556,7 +556,8 @@ __export(exports_config_loader, {
|
|
|
556
556
|
getConfigPath: () => getConfigPath,
|
|
557
557
|
getConfigForEnv: () => getConfigForEnv,
|
|
558
558
|
getConfigDir: () => getConfigDir,
|
|
559
|
-
configExists: () => configExists
|
|
559
|
+
configExists: () => configExists,
|
|
560
|
+
__resetMigrationForTests: () => __resetMigrationForTests
|
|
560
561
|
});
|
|
561
562
|
import fs from "fs";
|
|
562
563
|
import path3 from "path";
|
|
@@ -626,6 +627,9 @@ function migrateDataDirOnce() {
|
|
|
626
627
|
console.error(`[massa-ai] Data directory migration skipped:`, err);
|
|
627
628
|
}
|
|
628
629
|
}
|
|
630
|
+
function __resetMigrationForTests() {
|
|
631
|
+
migrationAttempted = false;
|
|
632
|
+
}
|
|
629
633
|
function saveConfig(config2) {
|
|
630
634
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
631
635
|
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
@@ -635,7 +639,7 @@ function saveConfig(config2) {
|
|
|
635
639
|
function initConfig() {
|
|
636
640
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
637
641
|
saveConfig(defaultMassaAiConfig);
|
|
638
|
-
console.
|
|
642
|
+
console.error(`Created default config at ${CONFIG_FILE}`);
|
|
639
643
|
}
|
|
640
644
|
}
|
|
641
645
|
function getConfigForEnv() {
|
|
@@ -13005,7 +13009,7 @@ function findEnvFile() {
|
|
|
13005
13009
|
return;
|
|
13006
13010
|
}
|
|
13007
13011
|
var envPath = findEnvFile();
|
|
13008
|
-
import_dotenv.config({ path: envPath });
|
|
13012
|
+
import_dotenv.config({ path: envPath, quiet: true });
|
|
13009
13013
|
try {
|
|
13010
13014
|
const { loadConfigSafe: loadConfigSafe2, migrateDataDirOnce: migrateDataDirOnce2 } = (init_config_loader(), __toCommonJS(exports_config_loader));
|
|
13011
13015
|
migrateDataDirOnce2();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massa-ai/opencode-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "massa-ai plugin for OpenCode - Semantic code search, memory, and context compression",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@opencode-ai/plugin": "^1.2.15",
|
|
23
23
|
"@opencode-ai/sdk": "^1.2.15",
|
|
24
|
-
"@massa-ai/core": "^1.
|
|
25
|
-
"@massa-ai/shared": "^1.
|
|
24
|
+
"@massa-ai/core": "^1.4.0",
|
|
25
|
+
"@massa-ai/shared": "^1.4.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.10.5",
|