@harness-engineering/cli 2.1.1 → 2.2.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.
@@ -32,7 +32,7 @@ import {
32
32
  import {
33
33
  createGenerateAgentDefinitionsCommand,
34
34
  generateAgentDefinitions
35
- } from "./chunk-SVC7THFK.js";
35
+ } from "./chunk-OJMO4JBQ.js";
36
36
  import {
37
37
  toKebabCase
38
38
  } from "./chunk-KET4QQZB.js";
@@ -57,7 +57,7 @@ import {
57
57
  loadCachedSnapshot,
58
58
  persistToolingConfig,
59
59
  recommend
60
- } from "./chunk-7XQYOXTB.js";
60
+ } from "./chunk-L2IDE7WS.js";
61
61
  import {
62
62
  loadGraphStore
63
63
  } from "./chunk-KTWKW6KJ.js";
@@ -2410,6 +2410,22 @@ function writeMcpEntry(filePath, name, entry) {
2410
2410
  config.mcpServers[name] = entry;
2411
2411
  writeJson(filePath, config);
2412
2412
  }
2413
+ function readOpencodeConfig(filePath) {
2414
+ const config = readJsonSafe(filePath);
2415
+ if (!config) return { mcp: {} };
2416
+ if (!config.mcp) config.mcp = {};
2417
+ return config;
2418
+ }
2419
+ function writeOpencodeMcpEntry(filePath, name, entry) {
2420
+ const config = readOpencodeConfig(filePath);
2421
+ config.mcp[name] = {
2422
+ type: "local",
2423
+ command: [entry.command, ...entry.args ?? []],
2424
+ enabled: true,
2425
+ ...entry.env ? { environment: entry.env } : {}
2426
+ };
2427
+ writeJson(filePath, config);
2428
+ }
2413
2429
  function removeMcpEntry(filePath, name) {
2414
2430
  if (!fs6.existsSync(filePath)) return;
2415
2431
  const config = readMcpConfig(filePath);
@@ -4106,6 +4122,16 @@ function setupMcp(cwd, client) {
4106
4122
  configured.push("Cursor");
4107
4123
  }
4108
4124
  }
4125
+ if (client === "all" || client === "opencode") {
4126
+ const configPath = path26.join(cwd, "opencode.json");
4127
+ const existing = readJsonFile(configPath);
4128
+ if (existing?.mcp?.["harness"]) {
4129
+ skipped.push("OpenCode");
4130
+ } else {
4131
+ writeOpencodeMcpEntry(configPath, "harness", { command: "harness", args: ["mcp"] });
4132
+ configured.push("OpenCode");
4133
+ }
4134
+ }
4109
4135
  return { configured, skipped, trustedFolder };
4110
4136
  }
4111
4137
  async function resolveCursorWithPicker(cwd, pick) {
@@ -4155,7 +4181,11 @@ function printMcpResult(configured, skipped, trustedFolder) {
4155
4181
  console.log("");
4156
4182
  }
4157
4183
  function createSetupMcpCommand() {
4158
- return new Command34("setup-mcp").description("Configure MCP server for AI agent integration").option("--client <client>", "Client to configure (claude, gemini, codex, cursor, all)", "all").option("--pick", "Launch interactive tool picker (Cursor only)").option("--yes", "Bypass interactive picker and use curated 25-tool set (Cursor only)").action(async (opts, cmd) => {
4184
+ return new Command34("setup-mcp").description("Configure MCP server for AI agent integration").option(
4185
+ "--client <client>",
4186
+ "Client to configure (claude, gemini, codex, cursor, opencode, all)",
4187
+ "all"
4188
+ ).option("--pick", "Launch interactive tool picker (Cursor only)").option("--yes", "Bypass interactive picker and use curated 25-tool set (Cursor only)").action(async (opts, cmd) => {
4159
4189
  const globalOpts = cmd.optsWithGlobals();
4160
4190
  const cwd = process.cwd();
4161
4191
  let configured;
@@ -5775,7 +5805,7 @@ function createMcpCommand() {
5775
5805
  parseBudget
5776
5806
  ).action(async (opts) => {
5777
5807
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
5778
- import("./mcp-QFZDPFNP.js"),
5808
+ import("./mcp-JDJGELGD.js"),
5779
5809
  import("./tool-tiers-7QGZ3FKY.js")
5780
5810
  ]);
5781
5811
  if (opts.tools && opts.tools.length > 0) {
@@ -7302,7 +7332,13 @@ async function runMcpSetup(cwd) {
7302
7332
  configTarget: ".gemini/settings.json"
7303
7333
  },
7304
7334
  { name: "Codex CLI", dir: ".codex", client: "codex", configTarget: ".codex/config.toml" },
7305
- { name: "Cursor", dir: ".cursor", client: "cursor", configTarget: ".cursor/mcp.json" }
7335
+ { name: "Cursor", dir: ".cursor", client: "cursor", configTarget: ".cursor/mcp.json" },
7336
+ {
7337
+ name: "OpenCode",
7338
+ dir: path47.join(".config", "opencode"),
7339
+ client: "opencode",
7340
+ configTarget: "opencode.json"
7341
+ }
7306
7342
  ];
7307
7343
  for (const { name, dir, client, configTarget } of clients) {
7308
7344
  if (!detectClient(dir)) {
@@ -7350,6 +7386,13 @@ function configureTier0Integrations(cwd) {
7350
7386
  }
7351
7387
  }
7352
7388
  }
7389
+ const opencodePath = path47.join(cwd, "opencode.json");
7390
+ const opencodeGlobalDir = path47.join(os7.homedir(), ".config", "opencode");
7391
+ if (fs29.existsSync(opencodePath) || fs29.existsSync(opencodeGlobalDir)) {
7392
+ for (const integration of tier0) {
7393
+ writeOpencodeMcpEntry(opencodePath, integration.name, integration.mcpConfig);
7394
+ }
7395
+ }
7353
7396
  if (added.length === 0) {
7354
7397
  return { status: "pass", message: "Tier 0 MCP integrations already configured" };
7355
7398
  }
@@ -2251,6 +2251,36 @@ function renderClaudeCode(spec) {
2251
2251
  return lines.join("\n");
2252
2252
  }
2253
2253
 
2254
+ // src/slash-commands/render-cursor-command.ts
2255
+ function renderCursorCommand(spec) {
2256
+ const lines = ["---"];
2257
+ lines.push(`name: ${spec.fullName}`);
2258
+ lines.push(`description: ${spec.description}`);
2259
+ lines.push("---");
2260
+ lines.push("");
2261
+ lines.push(GENERATED_HEADER_CURSOR);
2262
+ lines.push("");
2263
+ lines.push("<context>");
2264
+ lines.push(spec.prompt.context);
2265
+ lines.push("</context>");
2266
+ lines.push("");
2267
+ lines.push("<objective>");
2268
+ lines.push(spec.prompt.objective);
2269
+ lines.push("</objective>");
2270
+ lines.push("");
2271
+ if (spec.prompt.executionContext) {
2272
+ lines.push("<execution_context>");
2273
+ lines.push(spec.prompt.executionContext);
2274
+ lines.push("</execution_context>");
2275
+ lines.push("");
2276
+ }
2277
+ lines.push("<process>");
2278
+ lines.push(spec.prompt.process);
2279
+ lines.push("</process>");
2280
+ lines.push("");
2281
+ return lines.join("\n");
2282
+ }
2283
+
2254
2284
  // src/slash-commands/render-gemini.ts
2255
2285
  function escapeTomlLiteral(content) {
2256
2286
  return content.replace(/'''/g, "''\\'''");
@@ -2473,8 +2503,11 @@ function resolveAbsoluteExecutionContext(spec) {
2473
2503
  }
2474
2504
  };
2475
2505
  }
2476
- function renderSpec(platform, spec, useAbsolutePaths) {
2506
+ function renderSpec(platform, spec, useAbsolutePaths, cursorMode = "rules") {
2477
2507
  if (platform === "cursor") {
2508
+ if (cursorMode === "commands") {
2509
+ return [`${spec.name}.md`, renderCursorCommand(spec)];
2510
+ }
2478
2511
  const mdPath2 = path14.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
2479
2512
  const skillMd = fs12.existsSync(mdPath2) ? fs12.readFileSync(mdPath2, "utf-8") : "";
2480
2513
  return [`${spec.skillYamlName}.mdc`, renderCursor(spec, skillMd, spec.cursor)];
@@ -2503,7 +2536,7 @@ function generateForPlatform(platform, outputDir, specs, opts) {
2503
2536
  const parentRendered = /* @__PURE__ */ new Map();
2504
2537
  const customNamespaceRendered = /* @__PURE__ */ new Map();
2505
2538
  for (const spec of specs) {
2506
- const [filename, content] = renderSpec(platform, spec, opts.global);
2539
+ const [filename, content] = renderSpec(platform, spec, opts.global, opts.cursorMode);
2507
2540
  if (spec.commandName && (platform === "claude-code" || platform === "gemini-cli")) {
2508
2541
  parentRendered.set(filename, content);
2509
2542
  } else if (spec.customNamespace && (platform === "claude-code" || platform === "gemini-cli")) {
@@ -2633,10 +2666,20 @@ ${result.platform} \u2192 ${result.outputDir}`);
2633
2666
  function createGenerateSlashCommandsCommand() {
2634
2667
  return new Command("generate-slash-commands").description(
2635
2668
  "Generate native commands for Claude Code, Gemini CLI, Codex CLI, and Cursor from skill metadata"
2636
- ).option("--platforms <list>", "Target platforms (comma-separated)", "claude-code,gemini-cli").option("--global", "Write to global config directories", false).option("--include-global", "Include built-in global skills alongside project skills", false).option("--output <dir>", "Custom output directory").option("--skills-dir <path>", "Skills directory to scan").option("--dry-run", "Show what would change without writing", false).option("--yes", "Skip deletion confirmation prompts", false).action(async (opts, cmd) => {
2669
+ ).option("--platforms <list>", "Target platforms (comma-separated)", "claude-code,gemini-cli").option("--global", "Write to global config directories", false).option("--include-global", "Include built-in global skills alongside project skills", false).option("--output <dir>", "Custom output directory").option("--skills-dir <path>", "Skills directory to scan").option("--dry-run", "Show what would change without writing", false).option("--yes", "Skip deletion confirmation prompts", false).option(
2670
+ "--cursor-mode <mode>",
2671
+ 'For cursor platform: "rules" (.mdc with description/globs/alwaysApply, default) or "commands" (.md with name/description for plugin commands/ dir)',
2672
+ "rules"
2673
+ ).action(async (opts, cmd) => {
2637
2674
  const globalOpts = cmd.optsWithGlobals();
2638
2675
  try {
2639
2676
  const platforms = validatePlatforms(opts.platforms.split(",").map((p) => p.trim()));
2677
+ if (opts.cursorMode !== "rules" && opts.cursorMode !== "commands") {
2678
+ throw new CLIError(
2679
+ `Invalid --cursor-mode "${opts.cursorMode}". Expected "rules" or "commands".`,
2680
+ ExitCode.VALIDATION_FAILED
2681
+ );
2682
+ }
2640
2683
  const generateOpts = {
2641
2684
  platforms,
2642
2685
  global: opts.global,
@@ -2644,7 +2687,8 @@ function createGenerateSlashCommandsCommand() {
2644
2687
  output: opts.output,
2645
2688
  skillsDir: opts.skillsDir ?? "",
2646
2689
  dryRun: opts.dryRun,
2647
- yes: opts.yes
2690
+ yes: opts.yes,
2691
+ cursorMode: opts.cursorMode
2648
2692
  };
2649
2693
  const results = generateSlashCommands(generateOpts);
2650
2694
  if (globalOpts.json) {
@@ -3734,7 +3778,7 @@ var generateAgentDefinitionsDefinition = {
3734
3778
  }
3735
3779
  };
3736
3780
  async function handleGenerateAgentDefinitions(input) {
3737
- const { generateAgentDefinitions } = await import("./generate-agent-definitions-ZHFFS6YG.js");
3781
+ const { generateAgentDefinitions } = await import("./generate-agent-definitions-GFNXJCBY.js");
3738
3782
  const platforms = input.platform === "all" || !input.platform ? ["claude-code", "gemini-cli"] : [input.platform];
3739
3783
  const results = generateAgentDefinitions({
3740
3784
  platforms: [...platforms],
@@ -175,16 +175,67 @@ function renderGeminiAgent(def) {
175
175
  return lines.join("\n");
176
176
  }
177
177
 
178
+ // src/agent-definitions/render-cursor.ts
179
+ function formatStep3(step, index) {
180
+ if ("command" in step && step.command) {
181
+ const cmd = step.command;
182
+ const when = step.when ?? "always";
183
+ return `${index + 1}. Run \`harness ${cmd}\` (${when})`;
184
+ }
185
+ if ("skill" in step && step.skill) {
186
+ const skill = step.skill;
187
+ const when = step.when ?? "always";
188
+ return `${index + 1}. Execute ${skill} skill (${when})`;
189
+ }
190
+ return `${index + 1}. Unknown step`;
191
+ }
192
+ function renderCursorAgent(def) {
193
+ const lines = ["---"];
194
+ lines.push(`name: ${def.name}`);
195
+ lines.push(`description: >`);
196
+ lines.push(` ${def.description}`);
197
+ lines.push("---");
198
+ lines.push("");
199
+ lines.push(GENERATED_HEADER_AGENT);
200
+ lines.push("");
201
+ lines.push("## Role");
202
+ lines.push("");
203
+ lines.push(def.role);
204
+ lines.push("");
205
+ lines.push("## Skills");
206
+ lines.push("");
207
+ for (const skill of def.skills) {
208
+ lines.push(`- ${skill}`);
209
+ }
210
+ lines.push("");
211
+ lines.push("## Steps");
212
+ lines.push("");
213
+ def.steps.forEach((step, i) => {
214
+ lines.push(formatStep3(step, i));
215
+ });
216
+ lines.push("");
217
+ if (def.methodology) {
218
+ lines.push("## Methodology");
219
+ lines.push("");
220
+ lines.push(def.methodology);
221
+ lines.push("");
222
+ }
223
+ return lines.join("\n");
224
+ }
225
+
178
226
  // src/commands/generate-agent-definitions.ts
179
227
  function resolveOutputDir(platform, opts) {
180
228
  if (opts.output) {
181
- return platform === "claude-code" ? path.join(opts.output, "claude-code") : path.join(opts.output, "gemini-cli");
229
+ return path.join(opts.output, platform);
182
230
  }
183
231
  if (opts.global) {
184
232
  const home = os.homedir();
185
- return platform === "claude-code" ? path.join(home, ".claude", "agents") : path.join(home, ".gemini", "agents");
233
+ if (platform === "claude-code") return path.join(home, ".claude", "agents");
234
+ if (platform === "gemini-cli") return path.join(home, ".gemini", "agents");
235
+ if (platform === "cursor") return path.join(home, ".cursor", "agents");
236
+ return path.join(home, ".codex", "agents");
186
237
  }
187
- return platform === "claude-code" ? path.join("agents", "agents", "claude-code") : path.join("agents", "agents", "gemini-cli");
238
+ return path.join("agents", "agents", platform);
188
239
  }
189
240
  function loadSkillContent(skillName) {
190
241
  const skillsDir = resolveSkillsDir();
@@ -193,7 +244,9 @@ function loadSkillContent(skillName) {
193
244
  return fs.readFileSync(skillMdPath, "utf-8");
194
245
  }
195
246
  function getRenderer(platform) {
196
- return platform === "claude-code" ? renderClaudeCodeAgent : renderGeminiAgent;
247
+ if (platform === "claude-code") return renderClaudeCodeAgent;
248
+ if (platform === "cursor") return renderCursorAgent;
249
+ return renderGeminiAgent;
197
250
  }
198
251
  function generateAgentDefinitions(opts) {
199
252
  const personasDir = resolvePersonasDir();
@@ -265,7 +318,9 @@ ${result.platform} \u2192 ${result.outputDir}`);
265
318
  }
266
319
  }
267
320
  function createGenerateAgentDefinitionsCommand() {
268
- return new Command("generate-agent-definitions").description("Generate agent definition files from personas for Claude Code and Gemini CLI").option("--platforms <list>", "Target platforms (comma-separated)", "claude-code,gemini-cli").option("--global", "Write to global agent directories", false).option("--output <dir>", "Custom output directory").option("--dry-run", "Show what would change without writing", false).action(async (opts, cmd) => {
321
+ return new Command("generate-agent-definitions").description(
322
+ "Generate agent definition files from personas for Claude Code, Gemini CLI, and Cursor"
323
+ ).option("--platforms <list>", "Target platforms (comma-separated)", "claude-code,gemini-cli").option("--global", "Write to global agent directories", false).option("--output <dir>", "Custom output directory").option("--dry-run", "Show what would change without writing", false).action(async (opts, cmd) => {
269
324
  const globalOpts = cmd.optsWithGlobals();
270
325
  try {
271
326
  const platforms = parsePlatforms(opts.platforms);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createGenerateAgentDefinitionsCommand,
3
3
  generateAgentDefinitions
4
- } from "./chunk-SVC7THFK.js";
4
+ } from "./chunk-OJMO4JBQ.js";
5
5
  import "./chunk-KET4QQZB.js";
6
6
  import "./chunk-VJQLUS5I.js";
7
7
  import "./chunk-3ISINLYT.js";
@@ -33,7 +33,7 @@ function main() {
33
33
  process.exit(0);
34
34
  }
35
35
 
36
- if (/--no-verify/.test(command) || /\bgit\b.*\bcommit\b.*\s-n\b/.test(command)) {
36
+ if (containsHookBypass(command)) {
37
37
  process.stderr.write(
38
38
  'BLOCKED: --no-verify flag detected. Hooks must not be bypassed.\n'
39
39
  );
@@ -47,4 +47,22 @@ function main() {
47
47
  }
48
48
  }
49
49
 
50
+ // Strip heredoc bodies, quoted strings, and shell comments so flag detection
51
+ // runs against argv tokens only — not text the user is just talking about.
52
+ function stripStringsAndComments(cmd) {
53
+ let s = cmd;
54
+ s = s.replace(/<<-?\s*['"]?(\w+)['"]?[\s\S]*?\n\s*\1\b/g, ' ');
55
+ s = s.replace(/'[^']*'/g, ' ');
56
+ s = s.replace(/"(?:[^"\\]|\\.)*"/g, ' ');
57
+ s = s.replace(/(^|[\s;&|`(])#[^\n]*/g, '$1');
58
+ return s;
59
+ }
60
+
61
+ function containsHookBypass(command) {
62
+ const stripped = stripStringsAndComments(command);
63
+ if (/(?:^|\s)--no-verify(?=\s|$)/.test(stripped)) return true;
64
+ if (/\bgit\s+(?:[\w-]+\s+)*?commit\b[^\n]*?(?:^|\s)-n(?=\s|$)/.test(stripped)) return true;
65
+ return false;
66
+ }
67
+
50
68
  main();
package/dist/index.d.ts CHANGED
@@ -148,6 +148,14 @@ interface GeneratedFiles {
148
148
  declare function generateSkillFiles(opts: CreateSkillOptions): GeneratedFiles;
149
149
 
150
150
  type Platform = 'claude-code' | 'gemini-cli' | 'codex' | 'cursor';
151
+ /**
152
+ * For the `cursor` platform, decides whether output is rendered as Cursor
153
+ * rules (`.mdc` with description/globs/alwaysApply — for `~/.cursor/rules/`)
154
+ * or as Cursor plugin commands (`.md` with name/description — for
155
+ * `<plugin>/commands/`). Defaults to `rules` for backward compatibility
156
+ * with `harness setup`.
157
+ */
158
+ type CursorRenderMode = 'rules' | 'commands';
151
159
  interface GenerateOptions {
152
160
  platforms: Platform[];
153
161
  global: boolean;
@@ -156,6 +164,7 @@ interface GenerateOptions {
156
164
  skillsDir: string;
157
165
  dryRun: boolean;
158
166
  yes: boolean;
167
+ cursorMode?: CursorRenderMode;
159
168
  }
160
169
 
161
170
  interface SkillSource {
@@ -779,14 +788,14 @@ declare const HarnessConfigSchema: z.ZodObject<{
779
788
  modules: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodEnum<["circular-deps", "layer-violations", "complexity", "coupling", "forbidden-imports", "module-size", "dependency-depth"]>, z.ZodUnion<[z.ZodNumber, z.ZodRecord<z.ZodString, z.ZodNumber>]>>>>;
780
789
  }, "strip", z.ZodTypeAny, {
781
790
  enabled: boolean;
782
- thresholds: Partial<Record<"complexity" | "coupling" | "circular-deps" | "layer-violations" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>;
783
- modules: Record<string, Partial<Record<"complexity" | "coupling" | "circular-deps" | "layer-violations" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>>;
784
791
  baselinePath: string;
792
+ thresholds: Partial<Record<"circular-deps" | "layer-violations" | "complexity" | "coupling" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>;
793
+ modules: Record<string, Partial<Record<"circular-deps" | "layer-violations" | "complexity" | "coupling" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>>;
785
794
  }, {
786
795
  enabled?: boolean | undefined;
787
- thresholds?: Partial<Record<"complexity" | "coupling" | "circular-deps" | "layer-violations" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>> | undefined;
788
- modules?: Record<string, Partial<Record<"complexity" | "coupling" | "circular-deps" | "layer-violations" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>> | undefined;
789
796
  baselinePath?: string | undefined;
797
+ thresholds?: Partial<Record<"circular-deps" | "layer-violations" | "complexity" | "coupling" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>> | undefined;
798
+ modules?: Record<string, Partial<Record<"circular-deps" | "layer-violations" | "complexity" | "coupling" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>> | undefined;
790
799
  }>>;
791
800
  /** Skill loading, suggestion, and tier override settings */
792
801
  skills: z.ZodOptional<z.ZodObject<{
@@ -1040,9 +1049,9 @@ declare const HarnessConfigSchema: z.ZodObject<{
1040
1049
  } | undefined;
1041
1050
  architecture?: {
1042
1051
  enabled: boolean;
1043
- thresholds: Partial<Record<"complexity" | "coupling" | "circular-deps" | "layer-violations" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>;
1044
- modules: Record<string, Partial<Record<"complexity" | "coupling" | "circular-deps" | "layer-violations" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>>;
1045
1052
  baselinePath: string;
1053
+ thresholds: Partial<Record<"circular-deps" | "layer-violations" | "complexity" | "coupling" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>;
1054
+ modules: Record<string, Partial<Record<"circular-deps" | "layer-violations" | "complexity" | "coupling" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>>;
1046
1055
  } | undefined;
1047
1056
  traceability?: {
1048
1057
  enabled: boolean;
@@ -1198,9 +1207,9 @@ declare const HarnessConfigSchema: z.ZodObject<{
1198
1207
  } | undefined;
1199
1208
  architecture?: {
1200
1209
  enabled?: boolean | undefined;
1201
- thresholds?: Partial<Record<"complexity" | "coupling" | "circular-deps" | "layer-violations" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>> | undefined;
1202
- modules?: Record<string, Partial<Record<"complexity" | "coupling" | "circular-deps" | "layer-violations" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>> | undefined;
1203
1210
  baselinePath?: string | undefined;
1211
+ thresholds?: Partial<Record<"circular-deps" | "layer-violations" | "complexity" | "coupling" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>> | undefined;
1212
+ modules?: Record<string, Partial<Record<"circular-deps" | "layer-violations" | "complexity" | "coupling" | "forbidden-imports" | "module-size" | "dependency-depth", number | Record<string, number>>>> | undefined;
1204
1213
  } | undefined;
1205
1214
  traceability?: {
1206
1215
  enabled?: boolean | undefined;
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  runSnapshotCapture,
13
13
  runUninstall,
14
14
  runUninstallConstraints
15
- } from "./chunk-FNCJ3UCU.js";
15
+ } from "./chunk-GOOTYTTV.js";
16
16
  import {
17
17
  generateRuntime
18
18
  } from "./chunk-TNZYQTEE.js";
@@ -52,7 +52,7 @@ import {
52
52
  generateAgentDefinitions,
53
53
  renderClaudeCodeAgent,
54
54
  renderGeminiAgent
55
- } from "./chunk-SVC7THFK.js";
55
+ } from "./chunk-OJMO4JBQ.js";
56
56
  import "./chunk-KET4QQZB.js";
57
57
  import {
58
58
  listPersonas,
@@ -66,7 +66,7 @@ import {
66
66
  generateSlashCommands,
67
67
  getToolDefinitions,
68
68
  startServer
69
- } from "./chunk-7XQYOXTB.js";
69
+ } from "./chunk-L2IDE7WS.js";
70
70
  import "./chunk-36X7TRUI.js";
71
71
  import "./chunk-YWD6WXXM.js";
72
72
  import "./chunk-IOW3MW2K.js";
@@ -2,7 +2,7 @@ import {
2
2
  createHarnessServer,
3
3
  getToolDefinitions,
4
4
  startServer
5
- } from "./chunk-7XQYOXTB.js";
5
+ } from "./chunk-L2IDE7WS.js";
6
6
  import "./chunk-36X7TRUI.js";
7
7
  import "./chunk-YWD6WXXM.js";
8
8
  import "./chunk-IOW3MW2K.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harness-engineering/cli",
3
- "version": "2.1.1",
3
+ "version": "2.2.1",
4
4
  "description": "CLI for Harness Engineering toolkit",
5
5
  "type": "module",
6
6
  "bin": {
@@ -39,10 +39,10 @@
39
39
  "yaml": "^2.8.3",
40
40
  "zod": "^3.25.76",
41
41
  "@harness-engineering/core": "0.23.8",
42
- "@harness-engineering/dashboard": "0.5.2",
43
42
  "@harness-engineering/graph": "0.8.0",
44
43
  "@harness-engineering/linter-gen": "0.1.7",
45
44
  "@harness-engineering/orchestrator": "0.3.2",
45
+ "@harness-engineering/dashboard": "0.5.2",
46
46
  "@harness-engineering/types": "0.11.0"
47
47
  },
48
48
  "peerDependencies": {