@mstar-harness/cli 1.5.6 → 1.6.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.
Files changed (2) hide show
  1. package/dist/mstar-harness.js +222 -19
  2. package/package.json +1 -1
@@ -2344,8 +2344,8 @@ var require_commander = __commonJS((exports) => {
2344
2344
  });
2345
2345
 
2346
2346
  // src/index.ts
2347
- import fs6 from "fs";
2348
- import path8 from "path";
2347
+ import fs7 from "fs";
2348
+ import path9 from "path";
2349
2349
  import { fileURLToPath } from "url";
2350
2350
 
2351
2351
  // ../../node_modules/@inquirer/core/dist/lib/key.js
@@ -4070,7 +4070,7 @@ import { execFileSync } from "node:child_process";
4070
4070
  var REPO_URL = "https://github.com/btspoony/mstar-harness.git";
4071
4071
  var PLUGIN_NAME = "morning-star-harness";
4072
4072
  var HARNESS_REPO_PATH = path3.join(os.homedir(), ".mstar", "harness");
4073
- var HARNESS_MARKERS = [".codex-plugin/plugin.json"];
4073
+ var HARNESS_MARKERS = [".codex-plugin/plugin.json", ".zcode-plugin/plugin.json"];
4074
4074
  function harnessMarkerPath() {
4075
4075
  for (const marker of HARNESS_MARKERS) {
4076
4076
  const candidate = path3.join(HARNESS_REPO_PATH, marker);
@@ -4697,11 +4697,214 @@ var opencodeAdapter = {
4697
4697
  }
4698
4698
  };
4699
4699
 
4700
+ // src/adapters/zcode.ts
4701
+ import fs5 from "node:fs";
4702
+ import os5 from "node:os";
4703
+ import path7 from "node:path";
4704
+ var MARKETPLACE_ID = "mstar-local";
4705
+ var MARKETPLACE_NAME2 = "mstar-local";
4706
+ var MARKETPLACE_DESCRIPTION = "Morning Star harness marketplace (GitHub source).";
4707
+ var PLUGIN_DESCRIPTION = "Multi-agent code harness framework with unified skills for OpenCode, Cursor, Codex, Kimi Code, and ZCode.";
4708
+ var PLUGIN_VERSION = "1.6.0";
4709
+ var PLUGIN_CATEGORY2 = "Productivity";
4710
+ var GITHUB_REPO = "btspoony/mstar-harness";
4711
+ var GITHUB_REF = "main";
4712
+ var ZCODE_PLUGIN_MARKER = ".zcode-plugin/plugin.json";
4713
+ var ZCODE_PLUGIN_CHECKOUT_PROJECT = ".zcode/plugin-checkout";
4714
+ var ZCODE_AGENT_SMOKE_NAMES = ["fullstack-dev", "qc-specialist"];
4715
+ var ZCODE_PLUGINS_ROOT = path7.join(os5.homedir(), ".zcode", "cli", "plugins");
4716
+ var KNOWN_MARKETPLACES_PATH = path7.join(ZCODE_PLUGINS_ROOT, "known_marketplaces.json");
4717
+ var MARKETPLACE_DIR = path7.join(ZCODE_PLUGINS_ROOT, "marketplaces", MARKETPLACE_ID);
4718
+ var MARKETPLACE_JSON_PATH = path7.join(MARKETPLACE_DIR, "marketplace.json");
4719
+ var GITHUB_SOURCE = { source: "github", repo: GITHUB_REPO, ref: GITHUB_REF };
4720
+ function nowIso() {
4721
+ return new Date().toISOString();
4722
+ }
4723
+ function marketplacePluginEntry() {
4724
+ return {
4725
+ name: PLUGIN_NAME,
4726
+ source: { ...GITHUB_SOURCE },
4727
+ description: PLUGIN_DESCRIPTION,
4728
+ version: PLUGIN_VERSION,
4729
+ category: PLUGIN_CATEGORY2
4730
+ };
4731
+ }
4732
+ function knownMarketplaceEntry(existing) {
4733
+ const previous = existing && typeof existing.addedAt === "string" && existing.addedAt || nowIso();
4734
+ return {
4735
+ id: MARKETPLACE_ID,
4736
+ source: { ...GITHUB_SOURCE },
4737
+ name: MARKETPLACE_NAME2,
4738
+ description: MARKETPLACE_DESCRIPTION,
4739
+ addedAt: previous,
4740
+ pluginCount: 1,
4741
+ lastUpdated: nowIso()
4742
+ };
4743
+ }
4744
+ function upsertKnownMarketplace(raw) {
4745
+ const next = ensureObject(raw);
4746
+ if (typeof next.version !== "number")
4747
+ next.version = 1;
4748
+ if (!Array.isArray(next.marketplaces))
4749
+ next.marketplaces = [];
4750
+ const existing = next.marketplaces.find((entry) => {
4751
+ return entry && typeof entry === "object" && !Array.isArray(entry) && entry.id === MARKETPLACE_ID;
4752
+ });
4753
+ const marketplaces = next.marketplaces.filter((entry) => {
4754
+ return !(entry && typeof entry === "object" && !Array.isArray(entry) && entry.id === MARKETPLACE_ID);
4755
+ });
4756
+ marketplaces.push(knownMarketplaceEntry(existing));
4757
+ next.marketplaces = marketplaces;
4758
+ return next;
4759
+ }
4760
+ function findKnownMarketplace(raw) {
4761
+ const marketplaces = Array.isArray(raw.marketplaces) ? raw.marketplaces : [];
4762
+ return marketplaces.find((entry) => {
4763
+ return entry && typeof entry === "object" && !Array.isArray(entry) && entry.id === MARKETPLACE_ID;
4764
+ });
4765
+ }
4766
+ function findMarketplacePlugin(raw) {
4767
+ const plugins = Array.isArray(raw.plugins) ? raw.plugins : [];
4768
+ return plugins.find((entry) => {
4769
+ return entry && typeof entry === "object" && !Array.isArray(entry) && entry.name === PLUGIN_NAME;
4770
+ });
4771
+ }
4772
+ function validateMarketplaceJson() {
4773
+ const errors2 = [];
4774
+ if (!fs5.existsSync(MARKETPLACE_JSON_PATH)) {
4775
+ errors2.push(`Missing ZCode marketplace: ${MARKETPLACE_JSON_PATH}`);
4776
+ return errors2;
4777
+ }
4778
+ const raw = readJson(MARKETPLACE_JSON_PATH);
4779
+ if (raw.name !== MARKETPLACE_NAME2) {
4780
+ errors2.push(`ZCode marketplace name must be ${MARKETPLACE_NAME2} (in ${MARKETPLACE_JSON_PATH}).`);
4781
+ }
4782
+ const entry = findMarketplacePlugin(raw);
4783
+ if (!entry) {
4784
+ errors2.push(`Missing ${PLUGIN_NAME} plugin entry in ${MARKETPLACE_JSON_PATH}.`);
4785
+ return errors2;
4786
+ }
4787
+ const expected = marketplacePluginEntry();
4788
+ const source = ensureObject(entry.source);
4789
+ if (source.source !== "github") {
4790
+ errors2.push("ZCode marketplace plugin source.source must be `github`.");
4791
+ }
4792
+ if (source.repo !== expected.source.repo) {
4793
+ errors2.push(`ZCode marketplace plugin source.repo must be ${expected.source.repo}.`);
4794
+ }
4795
+ if (entry.version !== PLUGIN_VERSION) {
4796
+ errors2.push(`ZCode marketplace plugin version must be ${PLUGIN_VERSION}.`);
4797
+ }
4798
+ return errors2;
4799
+ }
4800
+ function validateKnownMarketplaces() {
4801
+ const errors2 = [];
4802
+ if (!fs5.existsSync(KNOWN_MARKETPLACES_PATH)) {
4803
+ errors2.push(`Missing ZCode known_marketplaces.json: ${KNOWN_MARKETPLACES_PATH}`);
4804
+ return errors2;
4805
+ }
4806
+ const raw = readJson(KNOWN_MARKETPLACES_PATH);
4807
+ const entry = findKnownMarketplace(raw);
4808
+ if (!entry) {
4809
+ errors2.push(`Missing ${MARKETPLACE_ID} entry in ${KNOWN_MARKETPLACES_PATH}.`);
4810
+ return errors2;
4811
+ }
4812
+ if (entry.id !== MARKETPLACE_ID)
4813
+ errors2.push(`known_marketplaces entry id must be ${MARKETPLACE_ID}.`);
4814
+ const source = ensureObject(entry.source);
4815
+ if (source.source !== "github") {
4816
+ errors2.push(`known_marketplaces entry source.source must be github.`);
4817
+ }
4818
+ if (source.repo !== GITHUB_REPO) {
4819
+ errors2.push(`known_marketplaces entry source.repo must be ${GITHUB_REPO}.`);
4820
+ }
4821
+ return errors2;
4822
+ }
4823
+ function validatePluginAgents2(pluginRoot) {
4824
+ const errors2 = [];
4825
+ const agentsDir = path7.join(pluginRoot, "agents");
4826
+ if (!fs5.existsSync(agentsDir)) {
4827
+ errors2.push(`Missing plugin agents directory: ${agentsDir}`);
4828
+ return errors2;
4829
+ }
4830
+ for (const agentName of ZCODE_AGENT_SMOKE_NAMES) {
4831
+ const agentPath = path7.join(agentsDir, `${agentName}.md`);
4832
+ if (!fs5.existsSync(agentPath)) {
4833
+ errors2.push(`Missing plugin agent file: ${agentPath}`);
4834
+ }
4835
+ }
4836
+ return errors2;
4837
+ }
4838
+ function buildMarketplaceJson() {
4839
+ return {
4840
+ name: MARKETPLACE_NAME2,
4841
+ description: MARKETPLACE_DESCRIPTION,
4842
+ plugins: [marketplacePluginEntry()]
4843
+ };
4844
+ }
4845
+ function runInit2(scope, dryRun) {
4846
+ const notes = ensureLocalHarnessRepo(dryRun);
4847
+ const projectRoot = resolveProjectRoot();
4848
+ if (scope === "project") {
4849
+ const checkoutPath = path7.join(projectRoot, ZCODE_PLUGIN_CHECKOUT_PROJECT);
4850
+ notes.push(...ensureGitCheckout(REPO_URL, checkoutPath, dryRun));
4851
+ notes.push(...appendGitignore(projectRoot, [ZCODE_PLUGIN_CHECKOUT_PROJECT], dryRun));
4852
+ notes.push(...appendHarnessProjectGitignore(projectRoot, dryRun));
4853
+ notes.push(`Materialized local ZCode plugin checkout at ${ZCODE_PLUGIN_CHECKOUT_PROJECT} for smoke checks (the registered marketplace still points at the github repo).`);
4854
+ }
4855
+ if (!dryRun) {
4856
+ if (!fs5.existsSync(MARKETPLACE_DIR))
4857
+ fs5.mkdirSync(MARKETPLACE_DIR, { recursive: true });
4858
+ writeJson(MARKETPLACE_JSON_PATH, buildMarketplaceJson());
4859
+ }
4860
+ notes.push(`Wrote ZCode marketplace: ${MARKETPLACE_JSON_PATH}`);
4861
+ const knownRaw = readJson(KNOWN_MARKETPLACES_PATH);
4862
+ const knownNext = upsertKnownMarketplace(knownRaw);
4863
+ if (!dryRun)
4864
+ writeJson(KNOWN_MARKETPLACES_PATH, knownNext);
4865
+ notes.push(`Registered ${MARKETPLACE_ID} marketplace in ${KNOWN_MARKETPLACES_PATH}`);
4866
+ notes.push(`Then in ZCode: Settings → Plugin Management → Discover → install ${PLUGIN_NAME} from the ${MARKETPLACE_ID} marketplace.`);
4867
+ return {
4868
+ location: KNOWN_MARKETPLACES_PATH,
4869
+ notes
4870
+ };
4871
+ }
4872
+ function runDoctor2(scope) {
4873
+ const errors2 = [];
4874
+ errors2.push(...validateLocalHarnessRepo());
4875
+ if (scope === "project") {
4876
+ const projectRoot = resolveProjectRoot();
4877
+ const checkoutPath = path7.join(projectRoot, ZCODE_PLUGIN_CHECKOUT_PROJECT);
4878
+ errors2.push(...validateGitCheckout(checkoutPath, ZCODE_PLUGIN_MARKER));
4879
+ const gitignorePath = path7.join(projectRoot, ".gitignore");
4880
+ const gitignore = fs5.existsSync(gitignorePath) ? fs5.readFileSync(gitignorePath, "utf8") : "";
4881
+ if (!gitignore.split(/\r?\n/).includes(ZCODE_PLUGIN_CHECKOUT_PROJECT)) {
4882
+ errors2.push(`Missing .gitignore entry: ${ZCODE_PLUGIN_CHECKOUT_PROJECT}`);
4883
+ }
4884
+ for (const entry of missingHarnessProcessGitignoreEntries(gitignore)) {
4885
+ errors2.push(`Missing .gitignore entry: ${entry}`);
4886
+ }
4887
+ errors2.push(...validatePluginAgents2(checkoutPath));
4888
+ } else {
4889
+ errors2.push(...validatePluginAgents2(HARNESS_REPO_PATH));
4890
+ }
4891
+ errors2.push(...validateKnownMarketplaces());
4892
+ errors2.push(...validateMarketplaceJson());
4893
+ return { location: KNOWN_MARKETPLACES_PATH, errors: errors2 };
4894
+ }
4895
+ var zcodeAdapter = {
4896
+ target: "zcode",
4897
+ mode: "install",
4898
+ runInstallInit: (scope, dryRun) => runInit2(scope, dryRun),
4899
+ runInstallDoctor: (scope) => runDoctor2(scope)
4900
+ };
4901
+
4700
4902
  // src/adapters/index.ts
4701
4903
  var adapters = {
4702
4904
  opencode: opencodeAdapter,
4703
4905
  cursor: cursorAdapter,
4704
- codex: codexAdapter
4906
+ codex: codexAdapter,
4907
+ zcode: zcodeAdapter
4705
4908
  };
4706
4909
  function getAdapter(target) {
4707
4910
  const adapter = adapters[target];
@@ -4711,20 +4914,20 @@ function getAdapter(target) {
4711
4914
  }
4712
4915
 
4713
4916
  // src/types.ts
4714
- var SUPPORTED_TARGETS = ["opencode", "cursor", "codex"];
4917
+ var SUPPORTED_TARGETS = ["opencode", "cursor", "codex", "zcode"];
4715
4918
 
4716
4919
  // src/utils.ts
4717
- import fs5 from "node:fs";
4718
- import path7 from "node:path";
4920
+ import fs6 from "node:fs";
4921
+ import path8 from "node:path";
4719
4922
  function parseCsv(raw) {
4720
4923
  if (!raw)
4721
4924
  return;
4722
4925
  return raw.split(",").map((item) => item.trim()).filter(Boolean);
4723
4926
  }
4724
4927
  function readJson2(filePath) {
4725
- if (!fs5.existsSync(filePath))
4928
+ if (!fs6.existsSync(filePath))
4726
4929
  return {};
4727
- const content = fs5.readFileSync(filePath, "utf8").trim();
4930
+ const content = fs6.readFileSync(filePath, "utf8").trim();
4728
4931
  if (!content)
4729
4932
  return {};
4730
4933
  try {
@@ -4734,18 +4937,18 @@ function readJson2(filePath) {
4734
4937
  }
4735
4938
  }
4736
4939
  function writeJson2(filePath, value) {
4737
- const parent = path7.dirname(filePath);
4738
- if (!fs5.existsSync(parent))
4739
- fs5.mkdirSync(parent, { recursive: true });
4740
- fs5.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
4940
+ const parent = path8.dirname(filePath);
4941
+ if (!fs6.existsSync(parent))
4942
+ fs6.mkdirSync(parent, { recursive: true });
4943
+ fs6.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
4741
4944
  `, "utf8");
4742
4945
  }
4743
4946
 
4744
4947
  // src/index.ts
4745
- var packageJsonPath = path8.resolve(path8.dirname(fileURLToPath(import.meta.url)), "../package.json");
4948
+ var packageJsonPath = path9.resolve(path9.dirname(fileURLToPath(import.meta.url)), "../package.json");
4746
4949
  var packageVersion = (() => {
4747
4950
  try {
4748
- const parsed = JSON.parse(fs6.readFileSync(packageJsonPath, "utf8"));
4951
+ const parsed = JSON.parse(fs7.readFileSync(packageJsonPath, "utf8"));
4749
4952
  return parsed.version || "0.0.0";
4750
4953
  } catch {
4751
4954
  return "0.0.0";
@@ -4783,7 +4986,7 @@ function resolveExplicitModelAssignments(options) {
4783
4986
  others: allow("other-models", parseCsv(options.otherModels), 3, true)
4784
4987
  });
4785
4988
  }
4786
- async function runInit2(options) {
4989
+ async function runInit3(options) {
4787
4990
  const target = options.target || (options.yes ? "opencode" : await pickTargetInteractive());
4788
4991
  const scope = options.scope || "project";
4789
4992
  const adapter = getAdapter(target);
@@ -4846,7 +5049,7 @@ async function runInit2(options) {
4846
5049
  }
4847
5050
  }
4848
5051
  }
4849
- function runDoctor2(options) {
5052
+ function runDoctor3(options) {
4850
5053
  const target = options.target || "opencode";
4851
5054
  const adapter = getAdapter(target);
4852
5055
  const scope = options.scope || "project";
@@ -4891,10 +5094,10 @@ function runDoctor2(options) {
4891
5094
  }
4892
5095
  program2.name("mstar-harness").description("Morning Star harness CLI for target-based agent bootstrap").version(packageVersion);
4893
5096
  program2.command("init").description("Interactive/non-interactive setup for target agent bootstrap").option("-y, --yes", "Non-interactive mode").option("--target <target>", "Install target", "opencode").option("--scope <scope>", "Config scope: global|project (default: project)").option("--output <path>", "Config file path override, relative to project root").option("--dry-run", "Preview result without writing config").option("--pm-model <model>", "Optional: model for project-manager (advanced override)").option("--strategic-models <a,b,c>", "Optional: models for architect/product-manager/prompt-engineer").option("--dev-models <a,b,c>", "Optional: models for fullstack-dev/fullstack-dev-2/frontend-dev").option("--qc-models <a,b,c>", "Optional: models for qc trio").option("--other-models <a,b,c>", "Optional: models for remaining roles").action(async (options) => {
4894
- await runInit2(options);
5097
+ await runInit3(options);
4895
5098
  });
4896
5099
  program2.command("doctor").description("Validate Morning Star setup for a target agent config").option("--target <target>", "Target agent for doctor checks", "opencode").option("--scope <scope>", "Config scope: global|project", "project").option("--output <path>", "Config file path override, relative to project root").action((options) => {
4897
- runDoctor2(options);
5100
+ runDoctor3(options);
4898
5101
  });
4899
5102
  program2.parseAsync(process.argv).catch((error) => {
4900
5103
  console.error(import_picocolors.default.red(`Setup failed: ${error.message}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mstar-harness/cli",
3
- "version": "1.5.6",
3
+ "version": "1.6.1",
4
4
  "description": "Morning Star harness installer CLI (OpenCode, Cursor, Codex).",
5
5
  "license": "MIT",
6
6
  "repository": {