@massa-ai/opencode-plugin 1.41.0 → 1.43.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 +140 -21
- package/dist/index.js +12 -6
- package/package.json +3 -3
package/dist/config-cli.js
CHANGED
|
@@ -552,6 +552,7 @@ var init_massa_ai_config = __esm(() => {
|
|
|
552
552
|
// ../../packages/shared/dist/config/config-loader.js
|
|
553
553
|
var exports_config_loader = {};
|
|
554
554
|
__export(exports_config_loader, {
|
|
555
|
+
writeFileAtomically: () => writeFileAtomically,
|
|
555
556
|
saveConfig: () => saveConfig,
|
|
556
557
|
migrateDataDirOnce: () => migrateDataDirOnce,
|
|
557
558
|
loadConfigSafe: () => loadConfigSafe,
|
|
@@ -636,15 +637,17 @@ function migrateDataDirOnce() {
|
|
|
636
637
|
function __resetMigrationForTests() {
|
|
637
638
|
migrationAttempted = false;
|
|
638
639
|
}
|
|
639
|
-
function
|
|
640
|
-
|
|
641
|
-
|
|
640
|
+
function writeFileAtomically(targetPath, content) {
|
|
641
|
+
const dir = path3.dirname(targetPath);
|
|
642
|
+
if (!fs.existsSync(dir)) {
|
|
643
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
642
644
|
}
|
|
643
645
|
const unique = `${process.pid}.${++tempFileCounter}.${crypto.randomBytes(6).toString("hex")}`;
|
|
644
|
-
const tempFile = path3.join(
|
|
646
|
+
const tempFile = path3.join(dir, `.${path3.basename(targetPath)}.${unique}.tmp`);
|
|
645
647
|
try {
|
|
646
|
-
fs.writeFileSync(tempFile,
|
|
647
|
-
fs.
|
|
648
|
+
fs.writeFileSync(tempFile, content, { mode: 384 });
|
|
649
|
+
fs.chmodSync(tempFile, 384);
|
|
650
|
+
fs.renameSync(tempFile, targetPath);
|
|
648
651
|
} catch (error) {
|
|
649
652
|
try {
|
|
650
653
|
fs.unlinkSync(tempFile);
|
|
@@ -652,6 +655,9 @@ function saveConfig(config) {
|
|
|
652
655
|
throw error;
|
|
653
656
|
}
|
|
654
657
|
}
|
|
658
|
+
function saveConfig(config) {
|
|
659
|
+
writeFileAtomically(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
660
|
+
}
|
|
655
661
|
function initConfig() {
|
|
656
662
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
657
663
|
saveConfig(defaultMassaAiConfig);
|
|
@@ -1785,7 +1791,7 @@ function listProfiles(opts = {}) {
|
|
|
1785
1791
|
installed,
|
|
1786
1792
|
skipped: false,
|
|
1787
1793
|
skipReason: null,
|
|
1788
|
-
activeProfile: platform?.modelProfile?.profile ?? "balanced",
|
|
1794
|
+
activeProfile: platform?.modelProfile?.profile ?? opts.hostDefaults?.[host] ?? "balanced",
|
|
1789
1795
|
bundleVersion: platform?.plugin?.version ?? null,
|
|
1790
1796
|
availableProfiles
|
|
1791
1797
|
};
|
|
@@ -1941,12 +1947,123 @@ function orderRows(universe, rows) {
|
|
|
1941
1947
|
function reportSucceeded(report) {
|
|
1942
1948
|
return report.hosts.every((h) => h.status === "switched" || h.status === "skipped");
|
|
1943
1949
|
}
|
|
1944
|
-
//
|
|
1945
|
-
import
|
|
1950
|
+
// ../../packages/shared/dist/profile-switch/variant-sync.js
|
|
1951
|
+
import fs6 from "fs";
|
|
1946
1952
|
import path9 from "path";
|
|
1953
|
+
import crypto4 from "crypto";
|
|
1954
|
+
var tempFileCounter2 = 0;
|
|
1955
|
+
function writeFileIntoDirAtomically(destDir, destName, content) {
|
|
1956
|
+
const unique = `${process.pid}.${++tempFileCounter2}.${crypto4.randomBytes(6).toString("hex")}`;
|
|
1957
|
+
const tempFile = path9.join(destDir, `.${destName}.${unique}.tmp`);
|
|
1958
|
+
try {
|
|
1959
|
+
fs6.writeFileSync(tempFile, content);
|
|
1960
|
+
fs6.renameSync(tempFile, path9.join(destDir, destName));
|
|
1961
|
+
} catch (error) {
|
|
1962
|
+
try {
|
|
1963
|
+
fs6.unlinkSync(tempFile);
|
|
1964
|
+
} catch {}
|
|
1965
|
+
throw error;
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
function isSafeDirName(name) {
|
|
1969
|
+
if (name === "." || name === "..")
|
|
1970
|
+
return false;
|
|
1971
|
+
if (name.includes("/") || name.includes("\\") || name.includes(path9.sep))
|
|
1972
|
+
return false;
|
|
1973
|
+
return path9.basename(name) === name;
|
|
1974
|
+
}
|
|
1975
|
+
function syncHost(host, sourceRoot, targetHome) {
|
|
1976
|
+
const layout = resolveHostLayout(host, { targetHome });
|
|
1977
|
+
if (layout.route === "skip") {
|
|
1978
|
+
return { host, status: "skipped", profiles: [], retained: [], files: 0, reason: layout.reason };
|
|
1979
|
+
}
|
|
1980
|
+
const srcDir = path9.join(sourceRoot, "apps", `${host}-plugin`, "agent-profiles");
|
|
1981
|
+
if (!fs6.existsSync(srcDir) || !fs6.statSync(srcDir).isDirectory()) {
|
|
1982
|
+
return { host, status: "skipped", profiles: [], retained: [], files: 0, reason: "no generated variants for this host" };
|
|
1983
|
+
}
|
|
1984
|
+
if (!fs6.existsSync(layout.variantsRoot)) {
|
|
1985
|
+
return {
|
|
1986
|
+
host,
|
|
1987
|
+
status: "skipped",
|
|
1988
|
+
profiles: [],
|
|
1989
|
+
retained: [],
|
|
1990
|
+
files: 0,
|
|
1991
|
+
reason: `variant tree not present at ${layout.variantsRoot} \u2014 run the plugin installer ` + "or an initial profile switch"
|
|
1992
|
+
};
|
|
1993
|
+
}
|
|
1994
|
+
const profiles = [];
|
|
1995
|
+
let files = 0;
|
|
1996
|
+
for (const entry of fs6.readdirSync(srcDir, { withFileTypes: true })) {
|
|
1997
|
+
if (!entry.isDirectory())
|
|
1998
|
+
continue;
|
|
1999
|
+
if (!isSafeDirName(entry.name))
|
|
2000
|
+
continue;
|
|
2001
|
+
const srcProfileDir = path9.join(srcDir, entry.name);
|
|
2002
|
+
const destProfileDir = path9.join(layout.variantsRoot, entry.name);
|
|
2003
|
+
fs6.mkdirSync(destProfileDir, { recursive: true });
|
|
2004
|
+
for (const fileEntry of fs6.readdirSync(srcProfileDir, { withFileTypes: true })) {
|
|
2005
|
+
if (!fileEntry.isFile())
|
|
2006
|
+
continue;
|
|
2007
|
+
const content = fs6.readFileSync(path9.join(srcProfileDir, fileEntry.name));
|
|
2008
|
+
writeFileIntoDirAtomically(destProfileDir, fileEntry.name, content);
|
|
2009
|
+
files++;
|
|
2010
|
+
}
|
|
2011
|
+
profiles.push(entry.name);
|
|
2012
|
+
}
|
|
2013
|
+
const retained = fs6.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && !profiles.includes(e.name)).map((e) => e.name).sort();
|
|
2014
|
+
return { host, status: "synced", profiles: profiles.sort(), retained, files };
|
|
2015
|
+
}
|
|
2016
|
+
function syncGeneratedVariants(opts) {
|
|
2017
|
+
const hosts = opts.hosts ?? HOSTS;
|
|
2018
|
+
if (!opts.sourceRoot) {
|
|
2019
|
+
return hosts.map((host) => ({
|
|
2020
|
+
host,
|
|
2021
|
+
status: "skipped",
|
|
2022
|
+
profiles: [],
|
|
2023
|
+
retained: [],
|
|
2024
|
+
files: 0,
|
|
2025
|
+
reason: "no source checkout \u2014 nothing to sync"
|
|
2026
|
+
}));
|
|
2027
|
+
}
|
|
2028
|
+
const sourceRoot = opts.sourceRoot;
|
|
2029
|
+
return hosts.map((host) => {
|
|
2030
|
+
try {
|
|
2031
|
+
return syncHost(host, sourceRoot, opts.targetHome);
|
|
2032
|
+
} catch (err) {
|
|
2033
|
+
return { host, status: "failed", profiles: [], retained: [], files: 0, error: err.message };
|
|
2034
|
+
}
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
// ../../packages/shared/dist/profile-switch/repo-root.js
|
|
2038
|
+
import fs7 from "fs";
|
|
2039
|
+
import path10 from "path";
|
|
2040
|
+
function findRepoRootWithMarker(startDir, marker, maxLevels) {
|
|
2041
|
+
let dir = startDir;
|
|
2042
|
+
for (let i = 0;i <= maxLevels; i++) {
|
|
2043
|
+
if (fs7.existsSync(path10.join(dir, marker)))
|
|
2044
|
+
return dir;
|
|
2045
|
+
const parent = path10.dirname(dir);
|
|
2046
|
+
if (parent === dir)
|
|
2047
|
+
break;
|
|
2048
|
+
dir = parent;
|
|
2049
|
+
}
|
|
2050
|
+
return null;
|
|
2051
|
+
}
|
|
2052
|
+
// src/config-cli.ts
|
|
2053
|
+
import { promises as fs8 } from "fs";
|
|
2054
|
+
import path11 from "path";
|
|
1947
2055
|
import os6 from "os";
|
|
1948
2056
|
import { fileURLToPath } from "url";
|
|
1949
|
-
var __dirname2 =
|
|
2057
|
+
var __dirname2 = path11.dirname(fileURLToPath(import.meta.url));
|
|
2058
|
+
var GENERATOR_MARKER = "scripts/generate-subagent-artifacts.ts";
|
|
2059
|
+
var GENERATOR_MARKER_MAX_LEVELS = 6;
|
|
2060
|
+
function formatVariantSync(results) {
|
|
2061
|
+
for (const r of results) {
|
|
2062
|
+
if (r.status === "synced") {
|
|
2063
|
+
console.log(` synced ${r.host}: ${r.files} file(s) across ${r.profiles.length} profile(s)`);
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
1950
2067
|
function help() {
|
|
1951
2068
|
console.log(`
|
|
1952
2069
|
massa-ai-config - Configuration manager for massa-ai
|
|
@@ -2148,18 +2265,18 @@ Using defaults:`);
|
|
|
2148
2265
|
return 1;
|
|
2149
2266
|
}
|
|
2150
2267
|
const scope = typeof options.project === "boolean" ? "project" : "user";
|
|
2151
|
-
const agentsDir = scope === "project" ?
|
|
2152
|
-
const sourceAgentsDir =
|
|
2268
|
+
const agentsDir = scope === "project" ? path11.join(process.cwd(), ".opencode/agents") : path11.join(process.env.XDG_CONFIG_HOME && process.env.XDG_CONFIG_HOME.trim() || path11.join(os6.homedir(), ".config"), "opencode", "agents");
|
|
2269
|
+
const sourceAgentsDir = path11.resolve(__dirname2, "..", "agents");
|
|
2153
2270
|
if (subcommand === "install") {
|
|
2154
|
-
await
|
|
2271
|
+
await fs8.mkdir(agentsDir, { recursive: true });
|
|
2155
2272
|
let count = 0;
|
|
2156
|
-
const entries = await
|
|
2273
|
+
const entries = await fs8.readdir(sourceAgentsDir);
|
|
2157
2274
|
for (const entry of entries) {
|
|
2158
2275
|
if (!entry.startsWith("massa-ai-") || !entry.endsWith(".md"))
|
|
2159
2276
|
continue;
|
|
2160
|
-
const src =
|
|
2161
|
-
const dest =
|
|
2162
|
-
await
|
|
2277
|
+
const src = path11.join(sourceAgentsDir, entry);
|
|
2278
|
+
const dest = path11.join(agentsDir, entry);
|
|
2279
|
+
await fs8.copyFile(src, dest);
|
|
2163
2280
|
count++;
|
|
2164
2281
|
}
|
|
2165
2282
|
console.log(`+ ${count} subagent specialists (generated from skills/agents/*/SKILL.md)`);
|
|
@@ -2167,14 +2284,14 @@ Using defaults:`);
|
|
|
2167
2284
|
} else {
|
|
2168
2285
|
let removed = 0;
|
|
2169
2286
|
try {
|
|
2170
|
-
const entries = await
|
|
2287
|
+
const entries = await fs8.readdir(agentsDir);
|
|
2171
2288
|
for (const entry of entries) {
|
|
2172
2289
|
if (!entry.startsWith("massa-ai-") || !entry.endsWith(".md"))
|
|
2173
2290
|
continue;
|
|
2174
|
-
const filePath =
|
|
2175
|
-
const content = await
|
|
2291
|
+
const filePath = path11.join(agentsDir, entry);
|
|
2292
|
+
const content = await fs8.readFile(filePath, "utf8");
|
|
2176
2293
|
if (content.includes("massa-ai-owned: true")) {
|
|
2177
|
-
await
|
|
2294
|
+
await fs8.unlink(filePath);
|
|
2178
2295
|
removed++;
|
|
2179
2296
|
}
|
|
2180
2297
|
}
|
|
@@ -2210,6 +2327,8 @@ Using defaults:`);
|
|
|
2210
2327
|
return 1;
|
|
2211
2328
|
}
|
|
2212
2329
|
try {
|
|
2330
|
+
const sourceRoot = findRepoRootWithMarker(__dirname2, GENERATOR_MARKER, GENERATOR_MARKER_MAX_LEVELS);
|
|
2331
|
+
formatVariantSync(syncGeneratedVariants({ sourceRoot }));
|
|
2213
2332
|
const report = switchProfile({
|
|
2214
2333
|
profile: name,
|
|
2215
2334
|
host: hostOpt,
|
package/dist/index.js
CHANGED
|
@@ -551,6 +551,7 @@ var init_massa_ai_config = __esm(() => {
|
|
|
551
551
|
// ../../packages/shared/dist/config/config-loader.js
|
|
552
552
|
var exports_config_loader = {};
|
|
553
553
|
__export(exports_config_loader, {
|
|
554
|
+
writeFileAtomically: () => writeFileAtomically,
|
|
554
555
|
saveConfig: () => saveConfig,
|
|
555
556
|
migrateDataDirOnce: () => migrateDataDirOnce,
|
|
556
557
|
loadConfigSafe: () => loadConfigSafe,
|
|
@@ -635,15 +636,17 @@ function migrateDataDirOnce() {
|
|
|
635
636
|
function __resetMigrationForTests() {
|
|
636
637
|
migrationAttempted = false;
|
|
637
638
|
}
|
|
638
|
-
function
|
|
639
|
-
|
|
640
|
-
|
|
639
|
+
function writeFileAtomically(targetPath, content) {
|
|
640
|
+
const dir = path3.dirname(targetPath);
|
|
641
|
+
if (!fs.existsSync(dir)) {
|
|
642
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
641
643
|
}
|
|
642
644
|
const unique = `${process.pid}.${++tempFileCounter}.${crypto.randomBytes(6).toString("hex")}`;
|
|
643
|
-
const tempFile = path3.join(
|
|
645
|
+
const tempFile = path3.join(dir, `.${path3.basename(targetPath)}.${unique}.tmp`);
|
|
644
646
|
try {
|
|
645
|
-
fs.writeFileSync(tempFile,
|
|
646
|
-
fs.
|
|
647
|
+
fs.writeFileSync(tempFile, content, { mode: 384 });
|
|
648
|
+
fs.chmodSync(tempFile, 384);
|
|
649
|
+
fs.renameSync(tempFile, targetPath);
|
|
647
650
|
} catch (error) {
|
|
648
651
|
try {
|
|
649
652
|
fs.unlinkSync(tempFile);
|
|
@@ -651,6 +654,9 @@ function saveConfig(config) {
|
|
|
651
654
|
throw error;
|
|
652
655
|
}
|
|
653
656
|
}
|
|
657
|
+
function saveConfig(config) {
|
|
658
|
+
writeFileAtomically(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
659
|
+
}
|
|
654
660
|
function initConfig() {
|
|
655
661
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
656
662
|
saveConfig(defaultMassaAiConfig);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massa-ai/opencode-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.43.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",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@opencode-ai/plugin": "^1.2.15",
|
|
26
26
|
"@opencode-ai/sdk": "^1.2.15",
|
|
27
|
-
"@massa-ai/core": "^1.
|
|
28
|
-
"@massa-ai/shared": "^1.
|
|
27
|
+
"@massa-ai/core": "^1.43.0",
|
|
28
|
+
"@massa-ai/shared": "^1.43.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.10.5",
|