@massa-ai/opencode-plugin 1.59.0 → 1.60.1

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.
@@ -493,13 +493,33 @@ var init_inference_providers = __esm(() => {
493
493
  },
494
494
  knownDimensions: {
495
495
  "text-embedding-nomic-embed-text-v1.5": 768,
496
- "text-embedding-qwen3-embedding-0.6b": 1024
496
+ "text-embedding-qwen3-embedding-0.6b": 1024,
497
+ "qwen3-embedding-0.6b-dwq": 1024
497
498
  },
498
499
  defaultModels: {
499
500
  embedding: "text-embedding-qwen3-embedding-0.6b",
500
501
  instruct: "qwen3-vl-8b-instruct",
501
502
  coding: "qwen2.5-coder-7b-instruct"
502
503
  },
504
+ mlxModels: {
505
+ embedding: {
506
+ repo: "mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ",
507
+ model: "qwen3-embedding-0.6b-dwq"
508
+ },
509
+ instruct: {
510
+ repo: "mlx-community/Qwen3-VL-8B-Instruct-4bit",
511
+ model: "qwen3-vl-8b-instruct"
512
+ },
513
+ coding: {
514
+ repo: "mlx-community/Qwen2.5-Coder-7B-Instruct-4bit",
515
+ model: "qwen2.5-coder-7b-instruct"
516
+ }
517
+ },
518
+ ggufRepos: {
519
+ embedding: "Qwen/Qwen3-Embedding-0.6B-GGUF",
520
+ instruct: "lmstudio-community/Qwen3-VL-8B-Instruct-GGUF",
521
+ coding: "lmstudio-community/Qwen2.5-Coder-7B-Instruct-GGUF"
522
+ },
503
523
  appliesContextPerRequest: false,
504
524
  embedBatchSize: 64,
505
525
  supportsOllamaVersionProbe: false,
@@ -2323,9 +2343,9 @@ function acquireLock(stateFilePath, options = {}) {
2323
2343
  }
2324
2344
  }
2325
2345
  // ../../packages/shared/dist/profile-switch/engine.js
2326
- import fs6 from "fs";
2327
- import path10 from "path";
2328
- import os6 from "os";
2346
+ import fs7 from "fs";
2347
+ import path11 from "path";
2348
+ import os7 from "os";
2329
2349
  import crypto3 from "crypto";
2330
2350
  import { execFileSync as execFileSync2 } from "child_process";
2331
2351
 
@@ -2405,12 +2425,13 @@ function selectRecord(records) {
2405
2425
  }
2406
2426
  return best ?? pool[pool.length - 1];
2407
2427
  }
2408
- function resolveClaudeMarketplaceRoot(opts = {}) {
2428
+ function resolveClaudeMarketplaceInstall(opts = {}) {
2409
2429
  const targetHome = opts.targetHome ?? os5.homedir();
2410
2430
  const pluginKey = opts.pluginKey ?? DEFAULT_PLUGIN_KEY;
2411
2431
  const directoryResult = resolveDirectorySourceRoot(targetHome, pluginKey);
2412
- if (directoryResult !== undefined)
2413
- return directoryResult;
2432
+ if (directoryResult !== undefined) {
2433
+ return directoryResult === null ? null : { root: directoryResult, route: "directory-source" };
2434
+ }
2414
2435
  const registryPath = path9.join(targetHome, ".claude", "plugins", "installed_plugins.json");
2415
2436
  let records;
2416
2437
  try {
@@ -2432,7 +2453,186 @@ function resolveClaudeMarketplaceRoot(opts = {}) {
2432
2453
  } catch {
2433
2454
  return null;
2434
2455
  }
2435
- return installPath;
2456
+ return { root: installPath, route: "registry-cache" };
2457
+ }
2458
+ function resolveClaudeMarketplaceRoot(opts = {}) {
2459
+ return resolveClaudeMarketplaceInstall(opts)?.root ?? null;
2460
+ }
2461
+ function readInstalledPluginVersion(opts = {}) {
2462
+ const targetHome = opts.targetHome ?? os5.homedir();
2463
+ const pluginKey = opts.pluginKey ?? DEFAULT_PLUGIN_KEY;
2464
+ const registryPath = path9.join(targetHome, ".claude", "plugins", "installed_plugins.json");
2465
+ let records;
2466
+ try {
2467
+ const parsed = JSON.parse(fs5.readFileSync(registryPath, "utf8"));
2468
+ records = parsed?.plugins?.[pluginKey];
2469
+ } catch {
2470
+ return null;
2471
+ }
2472
+ if (!Array.isArray(records) || records.length === 0)
2473
+ return null;
2474
+ return selectRecord(records)?.version ?? null;
2475
+ }
2476
+
2477
+ // ../../packages/shared/dist/profile-switch/doctor.js
2478
+ import fs6 from "fs";
2479
+ import os6 from "os";
2480
+ import path10 from "path";
2481
+
2482
+ // ../../packages/shared/dist/profile-switch/frontmatter.js
2483
+ function parseFrontmatter(raw) {
2484
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/.exec(raw);
2485
+ if (!match) {
2486
+ throw new Error("charter missing YAML frontmatter (--- ... ---) block");
2487
+ }
2488
+ const yamlText = match[1] ?? "";
2489
+ const body = (match[2] ?? "").replace(/^\r?\n/, "");
2490
+ const frontmatter = parseSimpleYaml(yamlText);
2491
+ return { frontmatter, body };
2492
+ }
2493
+ function parseSimpleYaml(text) {
2494
+ const result = {};
2495
+ const lines = text.split(/\r?\n/);
2496
+ let i = 0;
2497
+ while (i < lines.length) {
2498
+ const line = lines[i] ?? "";
2499
+ if (line.trim() === "" || line.trim().startsWith("#")) {
2500
+ i++;
2501
+ continue;
2502
+ }
2503
+ const m = /^([A-Za-z_][A-Za-z0-9_]*):\s*(.*)$/.exec(line);
2504
+ if (!m) {
2505
+ i++;
2506
+ continue;
2507
+ }
2508
+ const key = m[1];
2509
+ const rest = (m[2] ?? "").trim();
2510
+ if (rest !== "") {
2511
+ result[key] = unquoteScalar(rest);
2512
+ i++;
2513
+ continue;
2514
+ }
2515
+ const nested = {};
2516
+ i++;
2517
+ while (i < lines.length) {
2518
+ const nestedLine = lines[i] ?? "";
2519
+ if (/^\s{2,}\S/.test(nestedLine) === false)
2520
+ break;
2521
+ const nm = /^\s{2,}([A-Za-z_][A-Za-z0-9_]*):\s*(.*)$/.exec(nestedLine);
2522
+ if (!nm)
2523
+ break;
2524
+ nested[nm[1]] = unquoteScalar((nm[2] ?? "").trim());
2525
+ i++;
2526
+ }
2527
+ result[key] = nested;
2528
+ }
2529
+ return result;
2530
+ }
2531
+ function unquoteScalar(s) {
2532
+ if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) {
2533
+ return s.slice(1, -1);
2534
+ }
2535
+ return s;
2536
+ }
2537
+
2538
+ // ../../packages/shared/dist/profile-switch/doctor.js
2539
+ var ENV_OVERRIDE_VARS = ["CLAUDE_CODE_SUBAGENT_MODEL"];
2540
+ function readTextFile(filePath) {
2541
+ try {
2542
+ return fs6.readFileSync(filePath, "utf8");
2543
+ } catch {
2544
+ return null;
2545
+ }
2546
+ }
2547
+ function readJsonFile(filePath) {
2548
+ const raw = readTextFile(filePath);
2549
+ if (raw === null)
2550
+ return null;
2551
+ try {
2552
+ return JSON.parse(raw);
2553
+ } catch {
2554
+ return null;
2555
+ }
2556
+ }
2557
+ function readPluginVersion(pluginRoot) {
2558
+ const manifest = readJsonFile(path10.join(pluginRoot, ".claude-plugin", "plugin.json"));
2559
+ return typeof manifest?.version === "string" ? manifest.version : null;
2560
+ }
2561
+ function detectEnvOverride(env) {
2562
+ for (const name of ENV_OVERRIDE_VARS) {
2563
+ const value = env[name];
2564
+ if (typeof value === "string" && value.trim()) {
2565
+ return { name, value: value.trim() };
2566
+ }
2567
+ }
2568
+ return null;
2569
+ }
2570
+ function readRoles(liveRoot, activeProfile) {
2571
+ const agentsDir = path10.join(liveRoot, "agents");
2572
+ let entries;
2573
+ try {
2574
+ entries = fs6.readdirSync(agentsDir, { withFileTypes: true });
2575
+ } catch {
2576
+ return [];
2577
+ }
2578
+ const roles = [];
2579
+ for (const entry of entries) {
2580
+ if (!entry.isFile() || !entry.name.startsWith("massa-ai-") || !entry.name.endsWith(".md")) {
2581
+ continue;
2582
+ }
2583
+ const activeRaw = readTextFile(path10.join(agentsDir, entry.name));
2584
+ let model = null;
2585
+ let effort = null;
2586
+ if (activeRaw !== null) {
2587
+ try {
2588
+ const { frontmatter } = parseFrontmatter(activeRaw);
2589
+ model = typeof frontmatter.model === "string" ? frontmatter.model : null;
2590
+ effort = typeof frontmatter.effort === "string" ? frontmatter.effort : null;
2591
+ } catch {}
2592
+ }
2593
+ let staleVariant = false;
2594
+ if (activeProfile && activeRaw !== null) {
2595
+ const variantRaw = readTextFile(path10.join(liveRoot, "agent-profiles", activeProfile, entry.name));
2596
+ if (variantRaw !== null) {
2597
+ staleVariant = variantRaw !== activeRaw;
2598
+ }
2599
+ }
2600
+ roles.push({ name: entry.name, model, effort, staleVariant });
2601
+ }
2602
+ return roles.sort((a, b) => a.name.localeCompare(b.name));
2603
+ }
2604
+ function runtimeDriftReport(opts = {}) {
2605
+ const targetHome = opts.targetHome ?? os6.homedir();
2606
+ const stateFilePath = opts.stateFilePath ?? path10.join(targetHome, ".config", "massa-ai", "install-state.json");
2607
+ let state = opts.state ?? null;
2608
+ if (state === null) {
2609
+ try {
2610
+ state = readInstallState(stateFilePath);
2611
+ } catch {
2612
+ state = null;
2613
+ }
2614
+ }
2615
+ const platform = state?.platforms?.claude;
2616
+ const stateVersion = typeof platform?.plugin?.version === "string" ? platform.plugin.version : null;
2617
+ const activeProfile = platform?.modelProfile?.profile ?? null;
2618
+ const install = resolveClaudeMarketplaceInstall({ targetHome, pluginKey: opts.pluginKey });
2619
+ const liveRoot = install?.root ?? null;
2620
+ const sourceVersion = liveRoot === null ? null : readPluginVersion(liveRoot);
2621
+ const pinnedVersion = readInstalledPluginVersion({ targetHome, pluginKey: opts.pluginKey });
2622
+ const roles = liveRoot === null ? [] : readRoles(liveRoot, activeProfile);
2623
+ return {
2624
+ host: "claude",
2625
+ route: install?.route ?? "unresolved",
2626
+ liveRoot,
2627
+ sourceVersion,
2628
+ stateVersion,
2629
+ pinnedVersion,
2630
+ activeProfile,
2631
+ roles,
2632
+ envOverride: detectEnvOverride(opts.env ?? process.env),
2633
+ versionDrift: sourceVersion !== null && stateVersion !== null && sourceVersion !== stateVersion,
2634
+ profileMaterialized: roles.some((role) => role.staleVariant)
2635
+ };
2436
2636
  }
2437
2637
 
2438
2638
  // ../../packages/shared/dist/profile-switch/engine.js
@@ -2450,10 +2650,10 @@ function namedError3(name, message) {
2450
2650
  var UnknownProfileError = (profile, known) => namedError3("UnknownProfileError", `unknown profile "${profile}" \u2014 installed: ${known.length > 0 ? known.join(", ") : "none"}`);
2451
2651
  var NoHostsDetectedError = () => namedError3("NoHostsDetectedError", "no installed hosts found");
2452
2652
  function defaultStatePath(targetHome) {
2453
- return path10.join(targetHome, ".config", "massa-ai", "install-state.json");
2653
+ return path11.join(targetHome, ".config", "massa-ai", "install-state.json");
2454
2654
  }
2455
2655
  function resolveCommon(opts) {
2456
- const targetHome = opts.targetHome ?? os6.homedir();
2656
+ const targetHome = opts.targetHome ?? os7.homedir();
2457
2657
  const stateFilePath = opts.stateFilePath ?? defaultStatePath(targetHome);
2458
2658
  return { targetHome, stateFilePath };
2459
2659
  }
@@ -2461,7 +2661,7 @@ function marketplaceRoots(targetHome, state) {
2461
2661
  return state.platforms.claude?.installRoute === "marketplace" ? { claude: resolveClaudeMarketplaceRoot({ targetHome }) ?? undefined } : {};
2462
2662
  }
2463
2663
  function claudeMarketplaceUnresolvedReason(targetHome) {
2464
- const registryPath = path10.join(targetHome, ".claude", "plugins", "installed_plugins.json");
2664
+ const registryPath = path11.join(targetHome, ".claude", "plugins", "installed_plugins.json");
2465
2665
  return `claude installRoute is "marketplace" but no install root could be resolved from ${registryPath} ` + "\u2014 re-run the Claude plugin installer, or verify the plugin registry file";
2466
2666
  }
2467
2667
  function listProfiles(opts = {}) {
@@ -2469,6 +2669,12 @@ function listProfiles(opts = {}) {
2469
2669
  const state = readInstallState(stateFilePath);
2470
2670
  const roots = marketplaceRoots(targetHome, state);
2471
2671
  const universe = opts.hosts ?? HOSTS;
2672
+ const claudeDrift = universe.includes("claude") ? runtimeDriftReport({ targetHome, stateFilePath, state, env: opts.env }) : null;
2673
+ const claudeDriftFields = (host) => host === "claude" && claudeDrift !== null ? {
2674
+ liveRoot: claudeDrift.liveRoot,
2675
+ sourceVersion: claudeDrift.sourceVersion,
2676
+ envOverride: claudeDrift.envOverride ? `${claudeDrift.envOverride.name}=${claudeDrift.envOverride.value}` : null
2677
+ } : { liveRoot: null, sourceVersion: null, envOverride: null };
2472
2678
  const hosts = universe.map((host) => {
2473
2679
  if (host === "claude" && state.platforms.claude?.installRoute === "marketplace" && roots.claude === undefined) {
2474
2680
  const platform2 = state.platforms.claude;
@@ -2479,7 +2685,8 @@ function listProfiles(opts = {}) {
2479
2685
  skipReason: null,
2480
2686
  activeProfile: platform2.modelProfile?.profile ?? opts.hostDefaults?.[host] ?? "balanced",
2481
2687
  bundleVersion: platform2.plugin?.version ?? null,
2482
- availableProfiles: []
2688
+ availableProfiles: [],
2689
+ ...claudeDriftFields(host)
2483
2690
  };
2484
2691
  }
2485
2692
  const layout = resolveHostLayout(host, { targetHome, projectRoot: opts.projectRoot, marketplaceRoot: roots });
@@ -2491,10 +2698,11 @@ function listProfiles(opts = {}) {
2491
2698
  skipReason: layout.reason,
2492
2699
  activeProfile: null,
2493
2700
  bundleVersion: null,
2494
- availableProfiles: []
2701
+ availableProfiles: [],
2702
+ ...claudeDriftFields(host)
2495
2703
  };
2496
2704
  }
2497
- const installed = fs6.existsSync(layout.activeDir);
2705
+ const installed = fs7.existsSync(layout.activeDir);
2498
2706
  const availableProfiles = listVariantProfiles(layout);
2499
2707
  const platform = state.platforms[host];
2500
2708
  return {
@@ -2504,15 +2712,16 @@ function listProfiles(opts = {}) {
2504
2712
  skipReason: null,
2505
2713
  activeProfile: platform?.modelProfile?.profile ?? opts.hostDefaults?.[host] ?? "balanced",
2506
2714
  bundleVersion: platform?.plugin?.version ?? null,
2507
- availableProfiles
2715
+ availableProfiles,
2716
+ ...claudeDriftFields(host)
2508
2717
  };
2509
2718
  });
2510
2719
  return { hosts };
2511
2720
  }
2512
2721
  function listVariantProfiles(layout) {
2513
- if (!fs6.existsSync(layout.variantsRoot))
2722
+ if (!fs7.existsSync(layout.variantsRoot))
2514
2723
  return [];
2515
- return fs6.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
2724
+ return fs7.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
2516
2725
  }
2517
2726
  function matchesGlob(filename, glob) {
2518
2727
  const starIdx = glob.indexOf("*");
@@ -2523,7 +2732,7 @@ function matchesGlob(filename, glob) {
2523
2732
  return filename.length >= prefix.length + suffix.length && filename.startsWith(prefix) && filename.endsWith(suffix);
2524
2733
  }
2525
2734
  function matchingFileNames(dir, glob) {
2526
- return fs6.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && matchesGlob(e.name, glob)).map((e) => e.name);
2735
+ return fs7.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && matchesGlob(e.name, glob)).map((e) => e.name);
2527
2736
  }
2528
2737
  function detectGitAvailability(dir) {
2529
2738
  try {
@@ -2551,7 +2760,7 @@ function gitTrackedFileNames(dir, filenames) {
2551
2760
  var GUARD_PASS = { blocked: false, unchecked: false };
2552
2761
  var GUARD_UNCHECKED = { blocked: false, unchecked: true };
2553
2762
  function checkTrackedPathGuard(activeDir, filenames) {
2554
- if (filenames.length === 0 || !fs6.existsSync(activeDir))
2763
+ if (filenames.length === 0 || !fs7.existsSync(activeDir))
2555
2764
  return GUARD_PASS;
2556
2765
  const availability = detectGitAvailability(activeDir);
2557
2766
  if (availability === "no-git")
@@ -2562,53 +2771,53 @@ function checkTrackedPathGuard(activeDir, filenames) {
2562
2771
  if (tracked.size === 0)
2563
2772
  return GUARD_PASS;
2564
2773
  const offending = filenames.find((name) => tracked.has(name));
2565
- return { blocked: true, path: path10.join(activeDir, offending), unchecked: false };
2774
+ return { blocked: true, path: path11.join(activeDir, offending), unchecked: false };
2566
2775
  }
2567
2776
  function assertStateWritable(stateFilePath) {
2568
- const dir = path10.dirname(stateFilePath);
2777
+ const dir = path11.dirname(stateFilePath);
2569
2778
  try {
2570
- fs6.mkdirSync(dir, { recursive: true });
2779
+ fs7.mkdirSync(dir, { recursive: true });
2571
2780
  } catch (err) {
2572
2781
  throw UnwritableInstallStateError(stateFilePath, err.message);
2573
2782
  }
2574
- const checkPath = fs6.existsSync(stateFilePath) ? stateFilePath : dir;
2783
+ const checkPath = fs7.existsSync(stateFilePath) ? stateFilePath : dir;
2575
2784
  try {
2576
- fs6.accessSync(checkPath, fs6.constants.W_OK);
2785
+ fs7.accessSync(checkPath, fs7.constants.W_OK);
2577
2786
  } catch (err) {
2578
2787
  throw UnwritableInstallStateError(stateFilePath, err.message);
2579
2788
  }
2580
2789
  }
2581
2790
  function copyFileRouteVariant(layout, variantDir) {
2582
- fs6.mkdirSync(layout.activeDir, { recursive: true });
2791
+ fs7.mkdirSync(layout.activeDir, { recursive: true });
2583
2792
  let changed = 0;
2584
- for (const entry of fs6.readdirSync(variantDir, { withFileTypes: true })) {
2793
+ for (const entry of fs7.readdirSync(variantDir, { withFileTypes: true })) {
2585
2794
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
2586
2795
  continue;
2587
- fs6.copyFileSync(path10.join(variantDir, entry.name), path10.join(layout.activeDir, entry.name));
2796
+ fs7.copyFileSync(path11.join(variantDir, entry.name), path11.join(layout.activeDir, entry.name));
2588
2797
  changed++;
2589
2798
  }
2590
2799
  return changed;
2591
2800
  }
2592
2801
  function repointOpencodeVariant(layout, variantDir) {
2593
- fs6.mkdirSync(layout.activeDir, { recursive: true });
2802
+ fs7.mkdirSync(layout.activeDir, { recursive: true });
2594
2803
  let changed = 0;
2595
- for (const entry of fs6.readdirSync(variantDir, { withFileTypes: true })) {
2804
+ for (const entry of fs7.readdirSync(variantDir, { withFileTypes: true })) {
2596
2805
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
2597
2806
  continue;
2598
- const dest = path10.join(layout.activeDir, entry.name);
2599
- const target = path10.resolve(path10.join(variantDir, entry.name));
2807
+ const dest = path11.join(layout.activeDir, entry.name);
2808
+ const target = path11.resolve(path11.join(variantDir, entry.name));
2600
2809
  let destExists = true;
2601
2810
  let destIsSymlink = false;
2602
2811
  try {
2603
- destIsSymlink = fs6.lstatSync(dest).isSymbolicLink();
2812
+ destIsSymlink = fs7.lstatSync(dest).isSymbolicLink();
2604
2813
  } catch {
2605
2814
  destExists = false;
2606
2815
  }
2607
2816
  if (destExists && !destIsSymlink)
2608
2817
  continue;
2609
2818
  const tmp = `${dest}.massa-ai-switch.${crypto3.randomUUID()}`;
2610
- fs6.symlinkSync(target, tmp);
2611
- fs6.renameSync(tmp, dest);
2819
+ fs7.symlinkSync(target, tmp);
2820
+ fs7.renameSync(tmp, dest);
2612
2821
  changed++;
2613
2822
  }
2614
2823
  return changed;
@@ -2648,13 +2857,13 @@ function switchProfile(opts) {
2648
2857
  if (fileHosts.length === 0) {
2649
2858
  return { profile: opts.profile, dryRun, hosts: orderRows(universe, skipRows), restartRequired: false };
2650
2859
  }
2651
- const installedFileHosts = fileHosts.filter((h) => fs6.existsSync(h.layout.activeDir));
2860
+ const installedFileHosts = fileHosts.filter((h) => fs7.existsSync(h.layout.activeDir));
2652
2861
  if (installedFileHosts.length === 0)
2653
2862
  throw NoHostsDetectedError();
2654
2863
  const withAvailability = fileHosts.map((h) => {
2655
- const variantsRootExists = fs6.existsSync(h.layout.variantsRoot);
2864
+ const variantsRootExists = fs7.existsSync(h.layout.variantsRoot);
2656
2865
  const variantDir = h.layout.variantDir(opts.profile);
2657
- const available = variantsRootExists && fs6.existsSync(variantDir) && fs6.statSync(variantDir).isDirectory();
2866
+ const available = variantsRootExists && fs7.existsSync(variantDir) && fs7.statSync(variantDir).isDirectory();
2658
2867
  return { ...h, variantsRootExists, variantDir, available };
2659
2868
  });
2660
2869
  if (!withAvailability.some((h) => h.available)) {
@@ -2690,7 +2899,7 @@ function switchProfile(opts) {
2690
2899
  continue;
2691
2900
  }
2692
2901
  if (dryRun) {
2693
- rows.push({ host: h.host, status: "switched" });
2902
+ rows.push({ host: h.host, status: "would-switch" });
2694
2903
  continue;
2695
2904
  }
2696
2905
  const candidateNames = matchingFileNames(h.variantDir, h.layout.activeGlob);
@@ -2731,15 +2940,15 @@ function orderRows(universe, rows) {
2731
2940
  }
2732
2941
  // ../../packages/shared/dist/profile-switch/report.js
2733
2942
  function reportSucceeded(report) {
2734
- return report.hosts.every((h) => h.status === "switched" || h.status === "skipped");
2943
+ return report.hosts.every((h) => h.status === "switched" || h.status === "would-switch" || h.status === "skipped");
2735
2944
  }
2736
2945
  // ../../packages/shared/dist/profile-switch/variant-sync.js
2737
- import fs7 from "fs";
2738
- import path11 from "path";
2739
- import os7 from "os";
2946
+ import fs8 from "fs";
2947
+ import path12 from "path";
2948
+ import os8 from "os";
2740
2949
  import crypto4 from "crypto";
2741
2950
  function defaultStatePath2(targetHome) {
2742
- return path11.join(targetHome, ".config", "massa-ai", "install-state.json");
2951
+ return path12.join(targetHome, ".config", "massa-ai", "install-state.json");
2743
2952
  }
2744
2953
  function marketplaceRoots2(targetHome, state) {
2745
2954
  return state.platforms.claude?.installRoute === "marketplace" ? { claude: resolveClaudeMarketplaceRoot({ targetHome }) ?? undefined } : {};
@@ -2747,13 +2956,13 @@ function marketplaceRoots2(targetHome, state) {
2747
2956
  var tempFileCounter2 = 0;
2748
2957
  function writeFileIntoDirAtomically(destDir, destName, content) {
2749
2958
  const unique = `${process.pid}.${++tempFileCounter2}.${crypto4.randomBytes(6).toString("hex")}`;
2750
- const tempFile = path11.join(destDir, `.${destName}.${unique}.tmp`);
2959
+ const tempFile = path12.join(destDir, `.${destName}.${unique}.tmp`);
2751
2960
  try {
2752
- fs7.writeFileSync(tempFile, content);
2753
- fs7.renameSync(tempFile, path11.join(destDir, destName));
2961
+ fs8.writeFileSync(tempFile, content);
2962
+ fs8.renameSync(tempFile, path12.join(destDir, destName));
2754
2963
  } catch (error) {
2755
2964
  try {
2756
- fs7.unlinkSync(tempFile);
2965
+ fs8.unlinkSync(tempFile);
2757
2966
  } catch {}
2758
2967
  throw error;
2759
2968
  }
@@ -2761,20 +2970,20 @@ function writeFileIntoDirAtomically(destDir, destName, content) {
2761
2970
  function isSafeDirName(name) {
2762
2971
  if (name === "." || name === "..")
2763
2972
  return false;
2764
- if (name.includes("/") || name.includes("\\") || name.includes(path11.sep))
2973
+ if (name.includes("/") || name.includes("\\") || name.includes(path12.sep))
2765
2974
  return false;
2766
- return path11.basename(name) === name;
2975
+ return path12.basename(name) === name;
2767
2976
  }
2768
2977
  function syncHost(host, sourceRoot, targetHome, marketplaceRoot) {
2769
2978
  const layout = resolveHostLayout(host, { targetHome, marketplaceRoot });
2770
2979
  if (layout.route === "skip") {
2771
2980
  return { host, status: "skipped", profiles: [], retained: [], files: 0, reason: layout.reason };
2772
2981
  }
2773
- const srcDir = path11.join(sourceRoot, "apps", `${host}-plugin`, "agent-profiles");
2774
- if (!fs7.existsSync(srcDir) || !fs7.statSync(srcDir).isDirectory()) {
2982
+ const srcDir = path12.join(sourceRoot, "apps", `${host}-plugin`, "agent-profiles");
2983
+ if (!fs8.existsSync(srcDir) || !fs8.statSync(srcDir).isDirectory()) {
2775
2984
  return { host, status: "skipped", profiles: [], retained: [], files: 0, reason: "no generated variants for this host" };
2776
2985
  }
2777
- if (!fs7.existsSync(layout.variantsRoot)) {
2986
+ if (!fs8.existsSync(layout.variantsRoot)) {
2778
2987
  return {
2779
2988
  host,
2780
2989
  status: "skipped",
@@ -2786,24 +2995,24 @@ function syncHost(host, sourceRoot, targetHome, marketplaceRoot) {
2786
2995
  }
2787
2996
  const profiles = [];
2788
2997
  let files = 0;
2789
- for (const entry of fs7.readdirSync(srcDir, { withFileTypes: true })) {
2998
+ for (const entry of fs8.readdirSync(srcDir, { withFileTypes: true })) {
2790
2999
  if (!entry.isDirectory())
2791
3000
  continue;
2792
3001
  if (!isSafeDirName(entry.name))
2793
3002
  continue;
2794
- const srcProfileDir = path11.join(srcDir, entry.name);
2795
- const destProfileDir = path11.join(layout.variantsRoot, entry.name);
2796
- fs7.mkdirSync(destProfileDir, { recursive: true });
2797
- for (const fileEntry of fs7.readdirSync(srcProfileDir, { withFileTypes: true })) {
3003
+ const srcProfileDir = path12.join(srcDir, entry.name);
3004
+ const destProfileDir = path12.join(layout.variantsRoot, entry.name);
3005
+ fs8.mkdirSync(destProfileDir, { recursive: true });
3006
+ for (const fileEntry of fs8.readdirSync(srcProfileDir, { withFileTypes: true })) {
2798
3007
  if (!fileEntry.isFile())
2799
3008
  continue;
2800
- const content = fs7.readFileSync(path11.join(srcProfileDir, fileEntry.name));
3009
+ const content = fs8.readFileSync(path12.join(srcProfileDir, fileEntry.name));
2801
3010
  writeFileIntoDirAtomically(destProfileDir, fileEntry.name, content);
2802
3011
  files++;
2803
3012
  }
2804
3013
  profiles.push(entry.name);
2805
3014
  }
2806
- const retained = fs7.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && !profiles.includes(e.name)).map((e) => e.name).sort();
3015
+ const retained = fs8.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && !profiles.includes(e.name)).map((e) => e.name).sort();
2807
3016
  return { host, status: "synced", profiles: profiles.sort(), retained, files };
2808
3017
  }
2809
3018
  function syncGeneratedVariants(opts) {
@@ -2819,7 +3028,7 @@ function syncGeneratedVariants(opts) {
2819
3028
  }));
2820
3029
  }
2821
3030
  const sourceRoot = opts.sourceRoot;
2822
- const targetHome = opts.targetHome ?? os7.homedir();
3031
+ const targetHome = opts.targetHome ?? os8.homedir();
2823
3032
  const state = readInstallState(defaultStatePath2(targetHome));
2824
3033
  const roots = marketplaceRoots2(targetHome, state);
2825
3034
  return hosts.map((host) => {
@@ -2831,14 +3040,14 @@ function syncGeneratedVariants(opts) {
2831
3040
  });
2832
3041
  }
2833
3042
  // ../../packages/shared/dist/profile-switch/repo-root.js
2834
- import fs8 from "fs";
2835
- import path12 from "path";
3043
+ import fs9 from "fs";
3044
+ import path13 from "path";
2836
3045
  function findRepoRootWithMarker(startDir, marker, maxLevels) {
2837
3046
  let dir = startDir;
2838
3047
  for (let i = 0;i <= maxLevels; i++) {
2839
- if (fs8.existsSync(path12.join(dir, marker)))
3048
+ if (fs9.existsSync(path13.join(dir, marker)))
2840
3049
  return dir;
2841
- const parent = path12.dirname(dir);
3050
+ const parent = path13.dirname(dir);
2842
3051
  if (parent === dir)
2843
3052
  break;
2844
3053
  dir = parent;
@@ -2933,7 +3142,7 @@ function assertKnownRuleId(id) {
2933
3142
  }
2934
3143
  // ../../packages/shared/dist/bootstrap/state.js
2935
3144
  init_config_loader();
2936
- import fs9 from "fs";
3145
+ import fs10 from "fs";
2937
3146
  var BOOTSTRAP_STATE_KEY = "bootstrap";
2938
3147
  var BOOTSTRAP_RULES_KEY = "rules";
2939
3148
  var BOOTSTRAP_STATE_PATH = `${BOOTSTRAP_STATE_KEY}.${BOOTSTRAP_RULES_KEY}`;
@@ -2967,7 +3176,7 @@ function resolveBootstrapState(doc) {
2967
3176
  }
2968
3177
  function readConfigBytes() {
2969
3178
  try {
2970
- return fs9.readFileSync(getConfigPath(), "utf-8");
3179
+ return fs10.readFileSync(getConfigPath(), "utf-8");
2971
3180
  } catch (error) {
2972
3181
  if (error?.code === "ENOENT")
2973
3182
  return "";
@@ -3015,7 +3224,7 @@ function setBootstrapRuleEnabled(id, enabled) {
3015
3224
  };
3016
3225
  }
3017
3226
  // ../../packages/shared/dist/bootstrap/render.js
3018
- import path13 from "path";
3227
+ import path14 from "path";
3019
3228
  var BOOTSTRAP_BLOCK_START = "<!-- massa-ai:bootstrap:start -->";
3020
3229
  var BOOTSTRAP_BLOCK_END = "<!-- massa-ai:bootstrap:end -->";
3021
3230
  var CONTRACT_FILENAME = "MASSA-AI.md";
@@ -3047,19 +3256,19 @@ var HOST_CONFIG_DIR = {
3047
3256
  function resolveHostRoot(host, targetHome, hostRoot) {
3048
3257
  requireAbsoluteTargetHome(targetHome);
3049
3258
  if (hostRoot === undefined)
3050
- return path13.join(targetHome, ...HOST_CONFIG_DIR[host]);
3051
- const relative = path13.relative(targetHome, hostRoot);
3052
- if (!path13.isAbsolute(hostRoot) || relative === "" || relative.startsWith("..") || path13.isAbsolute(relative)) {
3259
+ return path14.join(targetHome, ...HOST_CONFIG_DIR[host]);
3260
+ const relative = path14.relative(targetHome, hostRoot);
3261
+ if (!path14.isAbsolute(hostRoot) || relative === "" || relative.startsWith("..") || path14.isAbsolute(relative)) {
3053
3262
  throw new BootstrapRenderError("HostRootOutsideTargetHomeError", `hostRoot must be an absolute directory inside targetHome, got "${hostRoot}" for targetHome "${targetHome}"`, [hostRoot, targetHome]);
3054
3263
  }
3055
3264
  return hostRoot;
3056
3265
  }
3057
3266
  function bootstrapContractPath(host, targetHome, hostRoot) {
3058
- return path13.join(resolveHostRoot(host, targetHome, hostRoot), CONTRACT_FILENAME);
3267
+ return path14.join(resolveHostRoot(host, targetHome, hostRoot), CONTRACT_FILENAME);
3059
3268
  }
3060
3269
  function bootstrapStateFilePath(targetHome) {
3061
3270
  requireAbsoluteTargetHome(targetHome);
3062
- return path13.join(targetHome, ".config", "massa-ai", "config.json");
3271
+ return path14.join(targetHome, ".config", "massa-ai", "config.json");
3063
3272
  }
3064
3273
  function renderBootstrap(options) {
3065
3274
  const { source, state, host, targetHome, hostRoot } = options;
@@ -3082,7 +3291,7 @@ ${body}`;
3082
3291
  return { contract, pointer };
3083
3292
  }
3084
3293
  function requireAbsoluteTargetHome(targetHome) {
3085
- if (!path13.isAbsolute(targetHome)) {
3294
+ if (!path14.isAbsolute(targetHome)) {
3086
3295
  throw new BootstrapRenderError("TargetHomeNotAbsoluteError", `targetHome must be an absolute path, got "${targetHome}"`, [targetHome]);
3087
3296
  }
3088
3297
  }
@@ -3235,8 +3444,8 @@ function buildBootstrapReport(input) {
3235
3444
  }
3236
3445
  // ../../packages/shared/dist/bootstrap/engine.js
3237
3446
  init_config_loader();
3238
- import fs10 from "fs";
3239
- import path14 from "path";
3447
+ import fs11 from "fs";
3448
+ import path15 from "path";
3240
3449
  var INSTALL_STATE_FILENAME = "install-state.json";
3241
3450
  var WIRING_REMEDY = "scripts/install-skills.sh --apply";
3242
3451
 
@@ -3253,7 +3462,7 @@ function applyBootstrapState(options) {
3253
3462
  const dryRun = options.dryRun ?? false;
3254
3463
  const warn = options.onWarning ?? ((message) => console.warn(message));
3255
3464
  const configPath = bootstrapStateFilePath(targetHome);
3256
- const installStatePath = path14.join(path14.dirname(configPath), INSTALL_STATE_FILENAME);
3465
+ const installStatePath = path15.join(path15.dirname(configPath), INSTALL_STATE_FILENAME);
3257
3466
  const { platforms } = readInstallState(installStatePath);
3258
3467
  const installed = HOSTS.filter((host) => platforms[host] !== undefined);
3259
3468
  if (installed.length === 0) {
@@ -3346,22 +3555,22 @@ function applyHost(input) {
3346
3555
  }
3347
3556
  function wiringArtifact(host, targetHome, hostRoot) {
3348
3557
  const root = resolveHostRoot(host, targetHome, hostRoot);
3349
- const contractPath = path14.join(root, CONTRACT_FILENAME);
3558
+ const contractPath = path15.join(root, CONTRACT_FILENAME);
3350
3559
  switch (host) {
3351
3560
  case "claude":
3352
- return { file: path14.join(root, "CLAUDE.md"), token: `@${CONTRACT_FILENAME}` };
3561
+ return { file: path15.join(root, "CLAUDE.md"), token: `@${CONTRACT_FILENAME}` };
3353
3562
  case "codex":
3354
3563
  case "cursor":
3355
- return { file: path14.join(root, "AGENTS.md"), token: contractPath };
3564
+ return { file: path15.join(root, "AGENTS.md"), token: contractPath };
3356
3565
  case "opencode":
3357
3566
  return { file: openCodeConfigPath(root), token: `"${contractPath}"` };
3358
3567
  }
3359
3568
  }
3360
3569
  function openCodeConfigPath(root) {
3361
- const json = path14.join(root, "opencode.json");
3362
- if (fs10.existsSync(json))
3570
+ const json = path15.join(root, "opencode.json");
3571
+ if (fs11.existsSync(json))
3363
3572
  return json;
3364
- return path14.join(root, "opencode.jsonc");
3573
+ return path15.join(root, "opencode.jsonc");
3365
3574
  }
3366
3575
  function isWired(host, targetHome, hostRoot) {
3367
3576
  const artifact = wiringArtifact(host, targetHome, hostRoot);
@@ -3374,7 +3583,7 @@ function notWiredReason(host, targetHome, hostRoot) {
3374
3583
  }
3375
3584
  function readFileOrNull(filePath) {
3376
3585
  try {
3377
- return fs10.readFileSync(filePath, "utf-8");
3586
+ return fs11.readFileSync(filePath, "utf-8");
3378
3587
  } catch {
3379
3588
  return null;
3380
3589
  }
@@ -3420,11 +3629,11 @@ function formatBootstrapReport(report) {
3420
3629
  init_config_loader();
3421
3630
  // src/config-cli.ts
3422
3631
  init_inference_providers();
3423
- import { promises as fs11 } from "fs";
3424
- import path15 from "path";
3425
- import os8 from "os";
3632
+ import { promises as fs12 } from "fs";
3633
+ import path16 from "path";
3634
+ import os9 from "os";
3426
3635
  import { fileURLToPath } from "url";
3427
- var __dirname2 = path15.dirname(fileURLToPath(import.meta.url));
3636
+ var __dirname2 = path16.dirname(fileURLToPath(import.meta.url));
3428
3637
  var WRITABLE_PROVIDERS = ["ollama", "lmstudio", "mistral", "openai", "google", "cohere"];
3429
3638
  var GENERATOR_MARKER = "scripts/generate-subagent-artifacts.ts";
3430
3639
  var GENERATOR_MARKER_MAX_LEVELS = 6;
@@ -3702,18 +3911,18 @@ Using defaults:`);
3702
3911
  return 1;
3703
3912
  }
3704
3913
  const scope = typeof options.project === "boolean" ? "project" : "user";
3705
- const agentsDir = scope === "project" ? path15.join(process.cwd(), ".opencode/agents") : path15.join(process.env.XDG_CONFIG_HOME && process.env.XDG_CONFIG_HOME.trim() || path15.join(os8.homedir(), ".config"), "opencode", "agents");
3706
- const sourceAgentsDir = path15.resolve(__dirname2, "..", "agents");
3914
+ const agentsDir = scope === "project" ? path16.join(process.cwd(), ".opencode/agents") : path16.join(process.env.XDG_CONFIG_HOME && process.env.XDG_CONFIG_HOME.trim() || path16.join(os9.homedir(), ".config"), "opencode", "agents");
3915
+ const sourceAgentsDir = path16.resolve(__dirname2, "..", "agents");
3707
3916
  if (subcommand === "install") {
3708
- await fs11.mkdir(agentsDir, { recursive: true });
3917
+ await fs12.mkdir(agentsDir, { recursive: true });
3709
3918
  let count = 0;
3710
- const entries = await fs11.readdir(sourceAgentsDir);
3919
+ const entries = await fs12.readdir(sourceAgentsDir);
3711
3920
  for (const entry of entries) {
3712
3921
  if (!entry.startsWith("massa-ai-") || !entry.endsWith(".md"))
3713
3922
  continue;
3714
- const src = path15.join(sourceAgentsDir, entry);
3715
- const dest = path15.join(agentsDir, entry);
3716
- await fs11.copyFile(src, dest);
3923
+ const src = path16.join(sourceAgentsDir, entry);
3924
+ const dest = path16.join(agentsDir, entry);
3925
+ await fs12.copyFile(src, dest);
3717
3926
  count++;
3718
3927
  }
3719
3928
  console.log(`+ ${count} subagent specialists (generated from skills/agents/*/SKILL.md)`);
@@ -3721,14 +3930,14 @@ Using defaults:`);
3721
3930
  } else {
3722
3931
  let removed = 0;
3723
3932
  try {
3724
- const entries = await fs11.readdir(agentsDir);
3933
+ const entries = await fs12.readdir(agentsDir);
3725
3934
  for (const entry of entries) {
3726
3935
  if (!entry.startsWith("massa-ai-") || !entry.endsWith(".md"))
3727
3936
  continue;
3728
- const filePath = path15.join(agentsDir, entry);
3729
- const content = await fs11.readFile(filePath, "utf8");
3937
+ const filePath = path16.join(agentsDir, entry);
3938
+ const content = await fs12.readFile(filePath, "utf8");
3730
3939
  if (content.includes("massa-ai-owned: true")) {
3731
- await fs11.unlink(filePath);
3940
+ await fs12.unlink(filePath);
3732
3941
  removed++;
3733
3942
  }
3734
3943
  }
@@ -3805,9 +4014,9 @@ Using defaults:`);
3805
4014
  return 1;
3806
4015
  }
3807
4016
  const targetOpt = typeof options.target === "string" ? options.target : undefined;
3808
- const targetHome = targetOpt === undefined ? os8.homedir() : path15.resolve(targetOpt);
3809
- if (targetHome !== os8.homedir() && options.yes !== true) {
3810
- console.error(`Error: --target ${targetHome} is not your home (${os8.homedir()}) \u2014 pass --yes to confirm writing there`);
4017
+ const targetHome = targetOpt === undefined ? os9.homedir() : path16.resolve(targetOpt);
4018
+ if (targetHome !== os9.homedir() && options.yes !== true) {
4019
+ console.error(`Error: --target ${targetHome} is not your home (${os9.homedir()}) \u2014 pass --yes to confirm writing there`);
3811
4020
  return 1;
3812
4021
  }
3813
4022
  const dryRun = options["dry-run"] === true;
@@ -3825,7 +4034,7 @@ Using defaults:`);
3825
4034
  const report = applyBootstrapState({
3826
4035
  targetHome,
3827
4036
  dryRun,
3828
- sourcePath: repoRoot === null ? undefined : path15.join(repoRoot, "skills", "AGENTS.md")
4037
+ sourcePath: repoRoot === null ? undefined : path16.join(repoRoot, "skills", "AGENTS.md")
3829
4038
  });
3830
4039
  console.log(formatBootstrapReport(report));
3831
4040
  return bootstrapReportSucceeded(report) ? 0 : 1;
package/dist/index.js CHANGED
@@ -492,13 +492,33 @@ var init_inference_providers = __esm(() => {
492
492
  },
493
493
  knownDimensions: {
494
494
  "text-embedding-nomic-embed-text-v1.5": 768,
495
- "text-embedding-qwen3-embedding-0.6b": 1024
495
+ "text-embedding-qwen3-embedding-0.6b": 1024,
496
+ "qwen3-embedding-0.6b-dwq": 1024
496
497
  },
497
498
  defaultModels: {
498
499
  embedding: "text-embedding-qwen3-embedding-0.6b",
499
500
  instruct: "qwen3-vl-8b-instruct",
500
501
  coding: "qwen2.5-coder-7b-instruct"
501
502
  },
503
+ mlxModels: {
504
+ embedding: {
505
+ repo: "mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ",
506
+ model: "qwen3-embedding-0.6b-dwq"
507
+ },
508
+ instruct: {
509
+ repo: "mlx-community/Qwen3-VL-8B-Instruct-4bit",
510
+ model: "qwen3-vl-8b-instruct"
511
+ },
512
+ coding: {
513
+ repo: "mlx-community/Qwen2.5-Coder-7B-Instruct-4bit",
514
+ model: "qwen2.5-coder-7b-instruct"
515
+ }
516
+ },
517
+ ggufRepos: {
518
+ embedding: "Qwen/Qwen3-Embedding-0.6B-GGUF",
519
+ instruct: "lmstudio-community/Qwen3-VL-8B-Instruct-GGUF",
520
+ coding: "lmstudio-community/Qwen2.5-Coder-7B-Instruct-GGUF"
521
+ },
502
522
  appliesContextPerRequest: false,
503
523
  embedBatchSize: 64,
504
524
  supportsOllamaVersionProbe: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massa-ai/opencode-plugin",
3
- "version": "1.59.0",
3
+ "version": "1.60.1",
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.59.0",
28
- "@massa-ai/shared": "^1.59.0"
27
+ "@massa-ai/core": "^1.60.1",
28
+ "@massa-ai/shared": "^1.60.1"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/node": "^22.10.5",