@mstar-harness/cli 0.3.0 → 0.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/mstar-harness.js +179 -48
- package/package.json +2 -2
package/dist/mstar-harness.js
CHANGED
|
@@ -2344,8 +2344,8 @@ var require_commander = __commonJS((exports) => {
|
|
|
2344
2344
|
});
|
|
2345
2345
|
|
|
2346
2346
|
// src/index.ts
|
|
2347
|
-
import
|
|
2348
|
-
import
|
|
2347
|
+
import fs5 from "fs";
|
|
2348
|
+
import path7 from "path";
|
|
2349
2349
|
import { fileURLToPath } from "url";
|
|
2350
2350
|
|
|
2351
2351
|
// ../../node_modules/@inquirer/core/dist/lib/key.js
|
|
@@ -4240,13 +4240,13 @@ function buildModelAssignments(selections) {
|
|
|
4240
4240
|
return { ...assignments, ...pickRandom(others, selections.others) };
|
|
4241
4241
|
}
|
|
4242
4242
|
|
|
4243
|
-
// src/adapters/
|
|
4244
|
-
import
|
|
4243
|
+
// src/adapters/codex.ts
|
|
4244
|
+
import fs2 from "node:fs";
|
|
4245
4245
|
import os from "node:os";
|
|
4246
4246
|
import path3 from "node:path";
|
|
4247
|
-
import { execFileSync } from "node:child_process";
|
|
4248
4247
|
|
|
4249
4248
|
// src/utils.ts
|
|
4249
|
+
import fs from "node:fs";
|
|
4250
4250
|
import path2 from "node:path";
|
|
4251
4251
|
function normalizeModelList(raw) {
|
|
4252
4252
|
return raw.split(`
|
|
@@ -4257,6 +4257,25 @@ function ensureObject(value) {
|
|
|
4257
4257
|
return value;
|
|
4258
4258
|
return {};
|
|
4259
4259
|
}
|
|
4260
|
+
function readJson(filePath) {
|
|
4261
|
+
if (!fs.existsSync(filePath))
|
|
4262
|
+
return {};
|
|
4263
|
+
const content = fs.readFileSync(filePath, "utf8").trim();
|
|
4264
|
+
if (!content)
|
|
4265
|
+
return {};
|
|
4266
|
+
try {
|
|
4267
|
+
return JSON.parse(content);
|
|
4268
|
+
} catch (error) {
|
|
4269
|
+
throw new Error(`Invalid JSON in ${filePath}: ${error.message}`);
|
|
4270
|
+
}
|
|
4271
|
+
}
|
|
4272
|
+
function writeJson(filePath, value) {
|
|
4273
|
+
const parent = path2.dirname(filePath);
|
|
4274
|
+
if (!fs.existsSync(parent))
|
|
4275
|
+
fs.mkdirSync(parent, { recursive: true });
|
|
4276
|
+
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
|
|
4277
|
+
`, "utf8");
|
|
4278
|
+
}
|
|
4260
4279
|
function resolveProjectRoot() {
|
|
4261
4280
|
const candidate = process.env.MSTAR_CLI_PROJECT_ROOT || process.env.INIT_CWD || process.env.PWD;
|
|
4262
4281
|
if (candidate && candidate.trim())
|
|
@@ -4264,21 +4283,132 @@ function resolveProjectRoot() {
|
|
|
4264
4283
|
return process.cwd();
|
|
4265
4284
|
}
|
|
4266
4285
|
|
|
4286
|
+
// src/adapters/codex.ts
|
|
4287
|
+
var MARKETPLACE_NAME = "personal";
|
|
4288
|
+
var MARKETPLACE_DISPLAY_NAME = "Personal";
|
|
4289
|
+
var MARKETPLACE_PATH = path3.join(os.homedir(), ".agents", "plugins", "marketplace.json");
|
|
4290
|
+
var PLUGIN_NAME = "morning-star-harness";
|
|
4291
|
+
var PLUGIN_URL = "https://github.com/btspoony/mstar-harness.git";
|
|
4292
|
+
var PLUGIN_REF = "main";
|
|
4293
|
+
var PLUGIN_CATEGORY = "Productivity";
|
|
4294
|
+
function mstarEntry() {
|
|
4295
|
+
return {
|
|
4296
|
+
name: PLUGIN_NAME,
|
|
4297
|
+
source: {
|
|
4298
|
+
source: "url",
|
|
4299
|
+
url: PLUGIN_URL,
|
|
4300
|
+
ref: PLUGIN_REF
|
|
4301
|
+
},
|
|
4302
|
+
policy: {
|
|
4303
|
+
installation: "AVAILABLE",
|
|
4304
|
+
authentication: "ON_INSTALL"
|
|
4305
|
+
},
|
|
4306
|
+
category: PLUGIN_CATEGORY
|
|
4307
|
+
};
|
|
4308
|
+
}
|
|
4309
|
+
function normalizeMarketplace(raw) {
|
|
4310
|
+
const next = ensureObject(raw);
|
|
4311
|
+
next.name = MARKETPLACE_NAME;
|
|
4312
|
+
const iface = ensureObject(next.interface);
|
|
4313
|
+
if (typeof iface.displayName !== "string" || !iface.displayName.trim()) {
|
|
4314
|
+
iface.displayName = MARKETPLACE_DISPLAY_NAME;
|
|
4315
|
+
}
|
|
4316
|
+
next.interface = iface;
|
|
4317
|
+
if (!Array.isArray(next.plugins)) {
|
|
4318
|
+
next.plugins = [];
|
|
4319
|
+
}
|
|
4320
|
+
return next;
|
|
4321
|
+
}
|
|
4322
|
+
function upsertEntry(raw) {
|
|
4323
|
+
const next = normalizeMarketplace(raw);
|
|
4324
|
+
const plugins = next.plugins.filter((entry) => {
|
|
4325
|
+
return !(entry && typeof entry === "object" && !Array.isArray(entry) && entry.name === PLUGIN_NAME);
|
|
4326
|
+
});
|
|
4327
|
+
plugins.push(mstarEntry());
|
|
4328
|
+
next.plugins = plugins;
|
|
4329
|
+
return next;
|
|
4330
|
+
}
|
|
4331
|
+
function findEntry(raw) {
|
|
4332
|
+
const plugins = Array.isArray(raw.plugins) ? raw.plugins : [];
|
|
4333
|
+
return plugins.find((entry) => {
|
|
4334
|
+
return entry && typeof entry === "object" && !Array.isArray(entry) && entry.name === PLUGIN_NAME;
|
|
4335
|
+
});
|
|
4336
|
+
}
|
|
4337
|
+
function validateEntryShape(entry) {
|
|
4338
|
+
const errors2 = [];
|
|
4339
|
+
if (!entry) {
|
|
4340
|
+
errors2.push(`Missing ${PLUGIN_NAME} entry in ${MARKETPLACE_PATH}.`);
|
|
4341
|
+
return errors2;
|
|
4342
|
+
}
|
|
4343
|
+
const source = ensureObject(entry.source);
|
|
4344
|
+
if (source.source !== "url")
|
|
4345
|
+
errors2.push("Codex marketplace entry source.source must be `url`.");
|
|
4346
|
+
if (source.url !== PLUGIN_URL)
|
|
4347
|
+
errors2.push(`Codex marketplace entry source.url must be ${PLUGIN_URL}.`);
|
|
4348
|
+
if (source.ref !== PLUGIN_REF)
|
|
4349
|
+
errors2.push(`Codex marketplace entry source.ref must be ${PLUGIN_REF}.`);
|
|
4350
|
+
const policy = ensureObject(entry.policy);
|
|
4351
|
+
if (policy.installation !== "AVAILABLE")
|
|
4352
|
+
errors2.push("Codex marketplace entry policy.installation must be AVAILABLE.");
|
|
4353
|
+
if (policy.authentication !== "ON_INSTALL")
|
|
4354
|
+
errors2.push("Codex marketplace entry policy.authentication must be ON_INSTALL.");
|
|
4355
|
+
if (entry.category !== PLUGIN_CATEGORY)
|
|
4356
|
+
errors2.push(`Codex marketplace entry category must be ${PLUGIN_CATEGORY}.`);
|
|
4357
|
+
return errors2;
|
|
4358
|
+
}
|
|
4359
|
+
function runInit(dryRun) {
|
|
4360
|
+
const current = readJson(MARKETPLACE_PATH);
|
|
4361
|
+
const next = upsertEntry(current);
|
|
4362
|
+
const existingEntry = findEntry(current);
|
|
4363
|
+
if (!dryRun)
|
|
4364
|
+
writeJson(MARKETPLACE_PATH, next);
|
|
4365
|
+
return {
|
|
4366
|
+
location: MARKETPLACE_PATH,
|
|
4367
|
+
notes: [
|
|
4368
|
+
existingEntry ? `Updated ${PLUGIN_NAME} entry in personal Codex marketplace.` : `Added ${PLUGIN_NAME} entry to personal Codex marketplace.`,
|
|
4369
|
+
`Source URL: ${PLUGIN_URL}#${PLUGIN_REF}`,
|
|
4370
|
+
`Install after init: codex plugin add ${PLUGIN_NAME} --marketplace ${String(next.name)}`
|
|
4371
|
+
]
|
|
4372
|
+
};
|
|
4373
|
+
}
|
|
4374
|
+
function runDoctor() {
|
|
4375
|
+
const errors2 = [];
|
|
4376
|
+
if (!fs2.existsSync(MARKETPLACE_PATH)) {
|
|
4377
|
+
return { location: MARKETPLACE_PATH, errors: [`Missing Codex personal marketplace: ${MARKETPLACE_PATH}`] };
|
|
4378
|
+
}
|
|
4379
|
+
const marketplace = readJson(MARKETPLACE_PATH);
|
|
4380
|
+
if (marketplace.name !== MARKETPLACE_NAME) {
|
|
4381
|
+
errors2.push(`Codex personal marketplace name must be ${MARKETPLACE_NAME}.`);
|
|
4382
|
+
}
|
|
4383
|
+
errors2.push(...validateEntryShape(findEntry(marketplace)));
|
|
4384
|
+
return { location: MARKETPLACE_PATH, errors: errors2 };
|
|
4385
|
+
}
|
|
4386
|
+
var codexAdapter = {
|
|
4387
|
+
target: "codex",
|
|
4388
|
+
mode: "install",
|
|
4389
|
+
runInstallInit: (_scope, dryRun) => runInit(dryRun),
|
|
4390
|
+
runInstallDoctor: () => runDoctor()
|
|
4391
|
+
};
|
|
4392
|
+
|
|
4267
4393
|
// src/adapters/cursor.ts
|
|
4394
|
+
import fs3 from "node:fs";
|
|
4395
|
+
import os2 from "node:os";
|
|
4396
|
+
import path4 from "node:path";
|
|
4397
|
+
import { execFileSync } from "node:child_process";
|
|
4268
4398
|
var REPO_URL = "https://github.com/btspoony/mstar-harness.git";
|
|
4269
4399
|
var CURSOR_PLUGIN_NAME = "mstar-harness";
|
|
4270
4400
|
var CURSOR_PLUGIN_MARKER = ".cursor-plugin/plugin.json";
|
|
4271
4401
|
function globalInstallPath() {
|
|
4272
|
-
return
|
|
4402
|
+
return path4.join(os2.homedir(), ".cursor", "plugins", "local", CURSOR_PLUGIN_NAME);
|
|
4273
4403
|
}
|
|
4274
4404
|
function projectInstallPath() {
|
|
4275
|
-
return
|
|
4405
|
+
return path4.join(resolveProjectRoot(), ".cursor", "plugins", CURSOR_PLUGIN_NAME);
|
|
4276
4406
|
}
|
|
4277
4407
|
function ensureDir(dirPath, dryRun) {
|
|
4278
4408
|
if (dryRun)
|
|
4279
4409
|
return;
|
|
4280
|
-
if (!
|
|
4281
|
-
|
|
4410
|
+
if (!fs3.existsSync(dirPath))
|
|
4411
|
+
fs3.mkdirSync(dirPath, { recursive: true });
|
|
4282
4412
|
}
|
|
4283
4413
|
function runCommand(command, cwd, dryRun) {
|
|
4284
4414
|
if (dryRun)
|
|
@@ -4288,12 +4418,12 @@ function runCommand(command, cwd, dryRun) {
|
|
|
4288
4418
|
function globalInit(dryRun) {
|
|
4289
4419
|
const location = globalInstallPath();
|
|
4290
4420
|
const notes = [];
|
|
4291
|
-
if (
|
|
4421
|
+
if (fs3.existsSync(location)) {
|
|
4292
4422
|
notes.push(`Plugin already exists at ${location}`);
|
|
4293
4423
|
return { location, notes };
|
|
4294
4424
|
}
|
|
4295
|
-
ensureDir(
|
|
4296
|
-
runCommand(["git", "clone", REPO_URL, location],
|
|
4425
|
+
ensureDir(path4.dirname(location), dryRun);
|
|
4426
|
+
runCommand(["git", "clone", REPO_URL, location], path4.dirname(location), dryRun);
|
|
4297
4427
|
notes.push(`Cloned ${REPO_URL} to ${location}`);
|
|
4298
4428
|
return { location, notes };
|
|
4299
4429
|
}
|
|
@@ -4301,12 +4431,12 @@ function projectInit(dryRun) {
|
|
|
4301
4431
|
const projectRoot = resolveProjectRoot();
|
|
4302
4432
|
const location = projectInstallPath();
|
|
4303
4433
|
const notes = [];
|
|
4304
|
-
if (
|
|
4434
|
+
if (fs3.existsSync(location)) {
|
|
4305
4435
|
notes.push(`Submodule path already exists at ${location}`);
|
|
4306
4436
|
return { location, notes };
|
|
4307
4437
|
}
|
|
4308
4438
|
runCommand(["git", "rev-parse", "--is-inside-work-tree"], projectRoot, dryRun);
|
|
4309
|
-
ensureDir(
|
|
4439
|
+
ensureDir(path4.join(projectRoot, ".cursor", "plugins"), dryRun);
|
|
4310
4440
|
runCommand(["git", "submodule", "add", REPO_URL, ".cursor/plugins/mstar-harness"], projectRoot, dryRun);
|
|
4311
4441
|
notes.push("Added mstar-harness as git submodule at .cursor/plugins/mstar-harness");
|
|
4312
4442
|
return { location, notes };
|
|
@@ -4314,12 +4444,12 @@ function projectInit(dryRun) {
|
|
|
4314
4444
|
function globalDoctor() {
|
|
4315
4445
|
const location = globalInstallPath();
|
|
4316
4446
|
const errors2 = [];
|
|
4317
|
-
if (!
|
|
4447
|
+
if (!fs3.existsSync(location)) {
|
|
4318
4448
|
errors2.push(`Missing plugin directory: ${location}`);
|
|
4319
4449
|
return { location, errors: errors2 };
|
|
4320
4450
|
}
|
|
4321
|
-
const marker =
|
|
4322
|
-
if (!
|
|
4451
|
+
const marker = path4.join(location, CURSOR_PLUGIN_MARKER);
|
|
4452
|
+
if (!fs3.existsSync(marker)) {
|
|
4323
4453
|
errors2.push(`Missing Cursor plugin marker file: ${marker}`);
|
|
4324
4454
|
}
|
|
4325
4455
|
return { location, errors: errors2 };
|
|
@@ -4328,15 +4458,15 @@ function projectDoctor() {
|
|
|
4328
4458
|
const projectRoot = resolveProjectRoot();
|
|
4329
4459
|
const location = projectInstallPath();
|
|
4330
4460
|
const errors2 = [];
|
|
4331
|
-
if (!
|
|
4461
|
+
if (!fs3.existsSync(location)) {
|
|
4332
4462
|
errors2.push(`Missing submodule directory: ${location}`);
|
|
4333
4463
|
}
|
|
4334
|
-
const gitmodulesPath =
|
|
4335
|
-
if (!
|
|
4464
|
+
const gitmodulesPath = path4.join(projectRoot, ".gitmodules");
|
|
4465
|
+
if (!fs3.existsSync(gitmodulesPath)) {
|
|
4336
4466
|
errors2.push("Missing .gitmodules (expected cursor plugin submodule entry).");
|
|
4337
4467
|
return { location, errors: errors2 };
|
|
4338
4468
|
}
|
|
4339
|
-
const gitmodules =
|
|
4469
|
+
const gitmodules = fs3.readFileSync(gitmodulesPath, "utf8");
|
|
4340
4470
|
if (!gitmodules.includes("path = .cursor/plugins/mstar-harness")) {
|
|
4341
4471
|
errors2.push("Missing .cursor/plugins/mstar-harness entry in .gitmodules.");
|
|
4342
4472
|
}
|
|
@@ -4358,8 +4488,8 @@ var cursorAdapter = {
|
|
|
4358
4488
|
};
|
|
4359
4489
|
|
|
4360
4490
|
// src/adapters/opencode.ts
|
|
4361
|
-
import
|
|
4362
|
-
import
|
|
4491
|
+
import os3 from "node:os";
|
|
4492
|
+
import path5 from "node:path";
|
|
4363
4493
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
4364
4494
|
var OPENCODE_CONFIG_SCHEMA = "https://opencode.ai/config.json";
|
|
4365
4495
|
var MSTAR_OPENCODE_PLUGIN = "@mstar-harness/opencode@latest";
|
|
@@ -4388,11 +4518,11 @@ function getOpencodeModels() {
|
|
|
4388
4518
|
function resolveOpencodeConfigPath(scope, outputPath) {
|
|
4389
4519
|
if (outputPath && outputPath.trim()) {
|
|
4390
4520
|
const raw = outputPath.trim();
|
|
4391
|
-
return
|
|
4521
|
+
return path5.isAbsolute(raw) ? raw : path5.join(resolveProjectRoot(), raw);
|
|
4392
4522
|
}
|
|
4393
4523
|
if (scope === "global")
|
|
4394
|
-
return
|
|
4395
|
-
return
|
|
4524
|
+
return path5.join(os3.homedir(), ".config", "opencode", "opencode.json");
|
|
4525
|
+
return path5.join(resolveProjectRoot(), "opencode.json");
|
|
4396
4526
|
}
|
|
4397
4527
|
function ensureConfigSchema(config) {
|
|
4398
4528
|
const next = ensureObject(config);
|
|
@@ -4486,7 +4616,8 @@ var opencodeAdapter = {
|
|
|
4486
4616
|
// src/adapters/index.ts
|
|
4487
4617
|
var adapters = {
|
|
4488
4618
|
opencode: opencodeAdapter,
|
|
4489
|
-
cursor: cursorAdapter
|
|
4619
|
+
cursor: cursorAdapter,
|
|
4620
|
+
codex: codexAdapter
|
|
4490
4621
|
};
|
|
4491
4622
|
function getAdapter(target) {
|
|
4492
4623
|
const adapter = adapters[target];
|
|
@@ -4496,20 +4627,20 @@ function getAdapter(target) {
|
|
|
4496
4627
|
}
|
|
4497
4628
|
|
|
4498
4629
|
// src/types.ts
|
|
4499
|
-
var SUPPORTED_TARGETS = ["opencode", "cursor"];
|
|
4630
|
+
var SUPPORTED_TARGETS = ["opencode", "cursor", "codex"];
|
|
4500
4631
|
|
|
4501
4632
|
// src/utils.ts
|
|
4502
|
-
import
|
|
4503
|
-
import
|
|
4633
|
+
import fs4 from "node:fs";
|
|
4634
|
+
import path6 from "node:path";
|
|
4504
4635
|
function parseCsv(raw) {
|
|
4505
4636
|
if (!raw)
|
|
4506
4637
|
return;
|
|
4507
4638
|
return raw.split(",").map((item) => item.trim()).filter(Boolean);
|
|
4508
4639
|
}
|
|
4509
|
-
function
|
|
4510
|
-
if (!
|
|
4640
|
+
function readJson2(filePath) {
|
|
4641
|
+
if (!fs4.existsSync(filePath))
|
|
4511
4642
|
return {};
|
|
4512
|
-
const content =
|
|
4643
|
+
const content = fs4.readFileSync(filePath, "utf8").trim();
|
|
4513
4644
|
if (!content)
|
|
4514
4645
|
return {};
|
|
4515
4646
|
try {
|
|
@@ -4518,19 +4649,19 @@ function readJson(filePath) {
|
|
|
4518
4649
|
throw new Error(`Invalid JSON in ${filePath}: ${error.message}`);
|
|
4519
4650
|
}
|
|
4520
4651
|
}
|
|
4521
|
-
function
|
|
4522
|
-
const parent =
|
|
4523
|
-
if (!
|
|
4524
|
-
|
|
4525
|
-
|
|
4652
|
+
function writeJson2(filePath, value) {
|
|
4653
|
+
const parent = path6.dirname(filePath);
|
|
4654
|
+
if (!fs4.existsSync(parent))
|
|
4655
|
+
fs4.mkdirSync(parent, { recursive: true });
|
|
4656
|
+
fs4.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
|
|
4526
4657
|
`, "utf8");
|
|
4527
4658
|
}
|
|
4528
4659
|
|
|
4529
4660
|
// src/index.ts
|
|
4530
|
-
var packageJsonPath =
|
|
4661
|
+
var packageJsonPath = path7.resolve(path7.dirname(fileURLToPath(import.meta.url)), "../package.json");
|
|
4531
4662
|
var packageVersion = (() => {
|
|
4532
4663
|
try {
|
|
4533
|
-
const parsed = JSON.parse(
|
|
4664
|
+
const parsed = JSON.parse(fs5.readFileSync(packageJsonPath, "utf8"));
|
|
4534
4665
|
return parsed.version || "0.0.0";
|
|
4535
4666
|
} catch {
|
|
4536
4667
|
return "0.0.0";
|
|
@@ -4609,7 +4740,7 @@ async function resolveSelections(options, models) {
|
|
|
4609
4740
|
})
|
|
4610
4741
|
};
|
|
4611
4742
|
}
|
|
4612
|
-
async function
|
|
4743
|
+
async function runInit2(options) {
|
|
4613
4744
|
const target = options.target || (options.yes ? "opencode" : await pickTargetInteractive());
|
|
4614
4745
|
const scope = options.scope || "project";
|
|
4615
4746
|
const adapter = getAdapter(target);
|
|
@@ -4641,7 +4772,7 @@ async function runInit(options) {
|
|
|
4641
4772
|
const configPath = adapter.resolveConfigPath?.(scope, options.output);
|
|
4642
4773
|
if (!configPath)
|
|
4643
4774
|
throw new Error(`Adapter ${target} does not implement config path resolution.`);
|
|
4644
|
-
const current =
|
|
4775
|
+
const current = readJson2(configPath);
|
|
4645
4776
|
const updated = adapter.mutateConfigForInit?.(current, assignments);
|
|
4646
4777
|
if (!updated)
|
|
4647
4778
|
throw new Error(`Adapter ${target} does not implement init mutation.`);
|
|
@@ -4653,8 +4784,8 @@ async function runInit(options) {
|
|
|
4653
4784
|
- `)}`);
|
|
4654
4785
|
}
|
|
4655
4786
|
if (!options.dryRun) {
|
|
4656
|
-
|
|
4657
|
-
const persistedErrors = adapter.validateConfig?.(
|
|
4787
|
+
writeJson2(configPath, updated);
|
|
4788
|
+
const persistedErrors = adapter.validateConfig?.(readJson2(configPath)) || [];
|
|
4658
4789
|
if (persistedErrors.length) {
|
|
4659
4790
|
throw new Error(`Post-write verification failed:
|
|
4660
4791
|
- ${persistedErrors.join(`
|
|
@@ -4671,7 +4802,7 @@ async function runInit(options) {
|
|
|
4671
4802
|
console.log(` - ${roleId}: ${modelId}`);
|
|
4672
4803
|
}
|
|
4673
4804
|
}
|
|
4674
|
-
function
|
|
4805
|
+
function runDoctor2(options) {
|
|
4675
4806
|
const target = options.target || "opencode";
|
|
4676
4807
|
const adapter = getAdapter(target);
|
|
4677
4808
|
const scope = options.scope || "project";
|
|
@@ -4696,7 +4827,7 @@ function runDoctor(options) {
|
|
|
4696
4827
|
if (!configPath) {
|
|
4697
4828
|
throw new Error(`Adapter ${target} does not implement config doctor flow.`);
|
|
4698
4829
|
}
|
|
4699
|
-
const config =
|
|
4830
|
+
const config = readJson2(configPath);
|
|
4700
4831
|
const errors2 = adapter.validateConfig?.(config) || [];
|
|
4701
4832
|
console.log(`Config file: ${configPath}`);
|
|
4702
4833
|
if (!errors2.length) {
|
|
@@ -4716,10 +4847,10 @@ function runDoctor(options) {
|
|
|
4716
4847
|
}
|
|
4717
4848
|
program2.name("mstar-harness").description("Morning Star harness CLI for target-based agent bootstrap").version(packageVersion);
|
|
4718
4849
|
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>", "Model for project-manager").option("--strategic-models <a,b,c>", "Models for architect/product-manager/prompt-engineer").option("--dev-models <a,b,c>", "Models for fullstack-dev/fullstack-dev-2/frontend-dev").option("--qc-models <a,b,c>", "Models for qc trio").option("--other-models <a,b,c>", "Models for random assignment to remaining roles").action(async (options) => {
|
|
4719
|
-
await
|
|
4850
|
+
await runInit2(options);
|
|
4720
4851
|
});
|
|
4721
4852
|
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) => {
|
|
4722
|
-
|
|
4853
|
+
runDoctor2(options);
|
|
4723
4854
|
});
|
|
4724
4855
|
program2.parseAsync(process.argv).catch((error) => {
|
|
4725
4856
|
console.error(import_picocolors.default.red(`Setup failed: ${error.message}`));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mstar-harness/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Morning Star harness installer CLI (OpenCode, Cursor).",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Morning Star harness installer CLI (OpenCode, Cursor, Codex).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|