@harness-engineering/cli 1.10.0 → 1.12.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.
Files changed (59) hide show
  1. package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +4 -0
  2. package/dist/agents/skills/claude-code/harness-parallel-agents/SKILL.md +105 -20
  3. package/dist/agents/skills/claude-code/harness-pre-commit-review/SKILL.md +37 -0
  4. package/dist/agents/skills/gemini-cli/enforce-architecture/SKILL.md +4 -0
  5. package/dist/agents/skills/gemini-cli/harness-parallel-agents/SKILL.md +105 -20
  6. package/dist/agents/skills/gemini-cli/harness-pre-commit-review/SKILL.md +37 -0
  7. package/dist/{agents-md-EMRFLNBC.js → agents-md-KIS2RSMG.js} +1 -1
  8. package/dist/{architecture-5JNN5L3M.js → architecture-AJAUDRQQ.js} +2 -2
  9. package/dist/bin/harness-mcp.js +14 -14
  10. package/dist/bin/harness.js +20 -20
  11. package/dist/{check-phase-gate-WOKIYGAM.js → check-phase-gate-K7QCSYRJ.js} +4 -4
  12. package/dist/{chunk-FPIPT36X.js → chunk-2SWJ4VO7.js} +6 -6
  13. package/dist/{chunk-OPXH4CQN.js → chunk-2YPZKGAG.js} +1 -1
  14. package/dist/{chunk-B7HFEHWP.js → chunk-3WGJMBKH.js} +10 -0
  15. package/dist/{chunk-ECUJQS3B.js → chunk-6N4R6FVX.js} +3 -3
  16. package/dist/{chunk-LXU5M77O.js → chunk-747VBPA4.js} +390 -57
  17. package/dist/{chunk-NX6DSZSM.js → chunk-AE2OWWDH.js} +4497 -2640
  18. package/dist/{chunk-PAHHT2IK.js → chunk-B5SBNH4S.js} +2833 -918
  19. package/dist/{chunk-F4PTVZWA.js → chunk-CTTFXXKJ.js} +7 -7
  20. package/dist/{chunk-PSXF277V.js → chunk-EAURF4LH.js} +1 -1
  21. package/dist/chunk-EBJQ6N4M.js +39 -0
  22. package/dist/{chunk-4PFMY3H7.js → chunk-FLOEMHDF.js} +9 -9
  23. package/dist/{chunk-46YA6FI3.js → chunk-GNGELAXY.js} +2 -2
  24. package/dist/{chunk-EOLRW32Q.js → chunk-HD4IBGLA.js} +9 -1
  25. package/dist/{chunk-CWZ4Y2PO.js → chunk-JLXOEO5C.js} +4 -4
  26. package/dist/{chunk-F3YDAJFQ.js → chunk-L2KLU56K.js} +2 -2
  27. package/dist/{chunk-MO4YQOMB.js → chunk-OIGVQF5V.js} +3 -3
  28. package/dist/{chunk-PMTFPOCT.js → chunk-TJVVU3HB.js} +1 -1
  29. package/dist/{chunk-MDUK2J2O.js → chunk-VRFZWGMS.js} +2 -1
  30. package/dist/{chunk-FX7SQHGD.js → chunk-YXOG2277.js} +2 -2
  31. package/dist/{chunk-7X7ZAYMY.js → chunk-ZU2UBYBY.js} +102 -5
  32. package/dist/{ci-workflow-ZBBUNTHQ.js → ci-workflow-NBL4OT4A.js} +1 -1
  33. package/dist/create-skill-WPXHSLX2.js +11 -0
  34. package/dist/{dist-PBTNVK6K.js → dist-IJ4J4C5G.js} +103 -1
  35. package/dist/{dist-I7DB5VKB.js → dist-M6BQODWC.js} +1145 -0
  36. package/dist/{docs-PTJGD6XI.js → docs-CPTMH3VY.js} +2 -2
  37. package/dist/{engine-SCMZ3G3E.js → engine-BUWPAAGD.js} +1 -1
  38. package/dist/{entropy-YIUBGKY7.js → entropy-Z4FYVQ7L.js} +2 -2
  39. package/dist/{feedback-WEVQSLAA.js → feedback-TT6WF5YX.js} +1 -1
  40. package/dist/{generate-agent-definitions-BU5LOJTI.js → generate-agent-definitions-J5HANRNR.js} +4 -4
  41. package/dist/{graph-loader-RLO3KRIX.js → graph-loader-KO4GJ5N2.js} +1 -1
  42. package/dist/index.d.ts +355 -12
  43. package/dist/index.js +33 -21
  44. package/dist/{loader-6S6PVGSF.js → loader-PCU5YWRH.js} +1 -1
  45. package/dist/mcp-YM6QLHLZ.js +34 -0
  46. package/dist/{performance-5TVW6SA6.js → performance-YJVXOKIB.js} +2 -2
  47. package/dist/{review-pipeline-4JTQAWKW.js → review-pipeline-KGMIMLIE.js} +1 -1
  48. package/dist/{runtime-PXIM7UV6.js → runtime-F6R27LD6.js} +1 -1
  49. package/dist/{security-URYTKLGK.js → security-MX5VVXBC.js} +1 -1
  50. package/dist/skill-executor-RG45LUO5.js +8 -0
  51. package/dist/templates/orchestrator/WORKFLOW.md +48 -0
  52. package/dist/templates/orchestrator/template.json +6 -0
  53. package/dist/{validate-KSDUUK2M.js → validate-EFNMSFKD.js} +2 -2
  54. package/dist/{validate-cross-check-WZAX357V.js → validate-cross-check-LJX65SBS.js} +1 -1
  55. package/package.json +10 -6
  56. package/dist/chunk-HIOXKZYF.js +0 -15
  57. package/dist/create-skill-LUWO46WF.js +0 -11
  58. package/dist/mcp-BNLBTCXZ.js +0 -34
  59. package/dist/skill-executor-KVS47DAU.js +0 -8
@@ -32,18 +32,18 @@ async function handleCheckDocs(input) {
32
32
  const projectPath = sanitizePath(input.path);
33
33
  const scope = input.scope ?? "coverage";
34
34
  if (scope === "integrity") {
35
- const { validateKnowledgeMap } = await import("./dist-PBTNVK6K.js");
35
+ const { validateKnowledgeMap } = await import("./dist-IJ4J4C5G.js");
36
36
  const result2 = await validateKnowledgeMap(projectPath);
37
37
  return resultToMcpResponse(result2);
38
38
  }
39
39
  if (scope === "all") {
40
- const { checkDocCoverage: checkDocCoverage2, validateKnowledgeMap } = await import("./dist-PBTNVK6K.js");
40
+ const { checkDocCoverage: checkDocCoverage2, validateKnowledgeMap } = await import("./dist-IJ4J4C5G.js");
41
41
  const domain2 = input.domain ?? "src";
42
- const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-RLO3KRIX.js");
42
+ const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-KO4GJ5N2.js");
43
43
  const store2 = await loadGraphStore2(projectPath);
44
44
  let graphCoverage2;
45
45
  if (store2) {
46
- const { Assembler } = await import("./dist-I7DB5VKB.js");
46
+ const { Assembler } = await import("./dist-M6BQODWC.js");
47
47
  const assembler = new Assembler(store2);
48
48
  const report = assembler.checkCoverage();
49
49
  graphCoverage2 = {
@@ -76,13 +76,13 @@ async function handleCheckDocs(input) {
76
76
  }
77
77
  return resultToMcpResponse(Ok({ coverage, integrity }));
78
78
  }
79
- const { checkDocCoverage } = await import("./dist-PBTNVK6K.js");
79
+ const { checkDocCoverage } = await import("./dist-IJ4J4C5G.js");
80
80
  const domain = input.domain ?? "src";
81
- const { loadGraphStore } = await import("./graph-loader-RLO3KRIX.js");
81
+ const { loadGraphStore } = await import("./graph-loader-KO4GJ5N2.js");
82
82
  const store = await loadGraphStore(projectPath);
83
83
  let graphCoverage;
84
84
  if (store) {
85
- const { Assembler } = await import("./dist-I7DB5VKB.js");
85
+ const { Assembler } = await import("./dist-M6BQODWC.js");
86
86
  const assembler = new Assembler(store);
87
87
  const report = assembler.checkCoverage();
88
88
  graphCoverage = {
@@ -26,7 +26,7 @@ var runSecurityScanDefinition = {
26
26
  };
27
27
  async function handleRunSecurityScan(input) {
28
28
  try {
29
- const core = await import("./dist-PBTNVK6K.js");
29
+ const core = await import("./dist-IJ4J4C5G.js");
30
30
  const projectRoot = sanitizePath(input.path);
31
31
  let configData = {};
32
32
  try {
@@ -0,0 +1,39 @@
1
+ // src/output/logger.ts
2
+ import chalk from "chalk";
3
+ var logger = {
4
+ /**
5
+ * Logs an informational message with a blue 'i' icon.
6
+ * @param message - The message to log.
7
+ */
8
+ info: (message) => console.log(chalk.blue("i"), message),
9
+ /**
10
+ * Logs a success message with a green 'v' icon.
11
+ * @param message - The message to log.
12
+ */
13
+ success: (message) => console.log(chalk.green("v"), message),
14
+ /**
15
+ * Logs a warning message with a yellow '!' icon.
16
+ * @param message - The message to log.
17
+ */
18
+ warn: (message) => console.log(chalk.yellow("!"), message),
19
+ /**
20
+ * Logs an error message with a red 'x' icon to stderr.
21
+ * @param message - The message to log.
22
+ */
23
+ error: (message) => console.error(chalk.red("x"), message),
24
+ /**
25
+ * Logs a dimmed message.
26
+ * @param message - The message to log.
27
+ */
28
+ dim: (message) => console.log(chalk.dim(message)),
29
+ /**
30
+ * Logs raw data as a formatted JSON string.
31
+ * Useful for JSON output mode.
32
+ * @param data - The data to log.
33
+ */
34
+ raw: (data) => console.log(JSON.stringify(data, null, 2))
35
+ };
36
+
37
+ export {
38
+ logger
39
+ };
@@ -33,7 +33,7 @@ var createSelfReviewDefinition = {
33
33
  };
34
34
  async function handleCreateSelfReview(input) {
35
35
  try {
36
- const { parseDiff, createSelfReview } = await import("./dist-PBTNVK6K.js");
36
+ const { parseDiff, createSelfReview } = await import("./dist-IJ4J4C5G.js");
37
37
  const parseResult = parseDiff(input.diff);
38
38
  if (!parseResult.ok) {
39
39
  return resultToMcpResponse(parseResult);
@@ -53,11 +53,11 @@ async function handleCreateSelfReview(input) {
53
53
  ...input.maxFileCount !== void 0 ? { maxChangedFiles: input.maxFileCount } : {}
54
54
  }
55
55
  };
56
- const { loadGraphStore } = await import("./graph-loader-RLO3KRIX.js");
56
+ const { loadGraphStore } = await import("./graph-loader-KO4GJ5N2.js");
57
57
  const store = await loadGraphStore(projectPath);
58
58
  let graphData;
59
59
  if (store) {
60
- const { GraphFeedbackAdapter } = await import("./dist-I7DB5VKB.js");
60
+ const { GraphFeedbackAdapter } = await import("./dist-M6BQODWC.js");
61
61
  const adapter = new GraphFeedbackAdapter(store);
62
62
  const changedFiles = parseResult.value.files.map((f) => f.path);
63
63
  const impact = adapter.computeImpactData(changedFiles);
@@ -119,7 +119,7 @@ var analyzeDiffDefinition = {
119
119
  };
120
120
  async function handleAnalyzeDiff(input) {
121
121
  try {
122
- const { parseDiff, analyzeDiff } = await import("./dist-PBTNVK6K.js");
122
+ const { parseDiff, analyzeDiff } = await import("./dist-IJ4J4C5G.js");
123
123
  const parseResult = parseDiff(input.diff);
124
124
  if (!parseResult.ok) {
125
125
  return resultToMcpResponse(parseResult);
@@ -139,10 +139,10 @@ async function handleAnalyzeDiff(input) {
139
139
  let graphImpactData;
140
140
  if (input.path) {
141
141
  try {
142
- const { loadGraphStore } = await import("./graph-loader-RLO3KRIX.js");
142
+ const { loadGraphStore } = await import("./graph-loader-KO4GJ5N2.js");
143
143
  const store = await loadGraphStore(sanitizePath(input.path));
144
144
  if (store) {
145
- const { GraphFeedbackAdapter } = await import("./dist-I7DB5VKB.js");
145
+ const { GraphFeedbackAdapter } = await import("./dist-M6BQODWC.js");
146
146
  const adapter = new GraphFeedbackAdapter(store);
147
147
  const changedFiles = parseResult.value.files.map((f) => f.path);
148
148
  const impact = adapter.computeImpactData(changedFiles);
@@ -195,7 +195,7 @@ var requestPeerReviewDefinition = {
195
195
  };
196
196
  async function handleRequestPeerReview(input) {
197
197
  try {
198
- const { parseDiff, requestPeerReview } = await import("./dist-PBTNVK6K.js");
198
+ const { parseDiff, requestPeerReview } = await import("./dist-IJ4J4C5G.js");
199
199
  const parseResult = parseDiff(input.diff);
200
200
  if (!parseResult.ok) {
201
201
  return resultToMcpResponse(parseResult);
@@ -206,10 +206,10 @@ async function handleRequestPeerReview(input) {
206
206
  ...input.context ? { metadata: { context: input.context } } : {}
207
207
  };
208
208
  try {
209
- const { loadGraphStore } = await import("./graph-loader-RLO3KRIX.js");
209
+ const { loadGraphStore } = await import("./graph-loader-KO4GJ5N2.js");
210
210
  const store = await loadGraphStore(sanitizePath(input.path));
211
211
  if (store) {
212
- const { GraphFeedbackAdapter } = await import("./dist-I7DB5VKB.js");
212
+ const { GraphFeedbackAdapter } = await import("./dist-M6BQODWC.js");
213
213
  const adapter = new GraphFeedbackAdapter(store);
214
214
  const changedFiles = parseResult.value.files.map((f) => f.path);
215
215
  const impactData = adapter.computeImpactData(changedFiles);
@@ -14,12 +14,12 @@ import {
14
14
  import {
15
15
  resolvePersonasDir,
16
16
  resolveSkillsDir
17
- } from "./chunk-EOLRW32Q.js";
17
+ } from "./chunk-HD4IBGLA.js";
18
18
  import {
19
19
  CLIError,
20
20
  ExitCode,
21
21
  handleError
22
- } from "./chunk-B7HFEHWP.js";
22
+ } from "./chunk-3WGJMBKH.js";
23
23
 
24
24
  // src/commands/generate-agent-definitions.ts
25
25
  import { Command } from "commander";
@@ -62,11 +62,19 @@ function resolveGlobalSkillsDir() {
62
62
  }
63
63
  return path.join(__dirname, "agents", "skills", "claude-code");
64
64
  }
65
+ function resolveCommunitySkillsDir(platform = "claude-code") {
66
+ const agentsDir = findUpDir("agents", "skills");
67
+ if (agentsDir) {
68
+ return path.join(agentsDir, "skills", "community", platform);
69
+ }
70
+ return path.join(__dirname, "agents", "skills", "community", platform);
71
+ }
65
72
 
66
73
  export {
67
74
  resolveTemplatesDir,
68
75
  resolvePersonasDir,
69
76
  resolveSkillsDir,
70
77
  resolveProjectSkillsDir,
71
- resolveGlobalSkillsDir
78
+ resolveGlobalSkillsDir,
79
+ resolveCommunitySkillsDir
72
80
  };
@@ -10,10 +10,10 @@ import {
10
10
 
11
11
  // src/mcp/tools/entropy.ts
12
12
  async function loadEntropyGraphOptions(projectPath) {
13
- const { loadGraphStore } = await import("./graph-loader-RLO3KRIX.js");
13
+ const { loadGraphStore } = await import("./graph-loader-KO4GJ5N2.js");
14
14
  const store = await loadGraphStore(projectPath);
15
15
  if (!store) return void 0;
16
- const { GraphEntropyAdapter } = await import("./dist-I7DB5VKB.js");
16
+ const { GraphEntropyAdapter } = await import("./dist-M6BQODWC.js");
17
17
  const adapter = new GraphEntropyAdapter(store);
18
18
  const driftData = adapter.computeDriftData();
19
19
  const deadCodeData = adapter.computeDeadCodeData();
@@ -84,7 +84,7 @@ var detectEntropyDefinition = {
84
84
  };
85
85
  async function handleDetectEntropy(input) {
86
86
  try {
87
- const { EntropyAnalyzer } = await import("./dist-PBTNVK6K.js");
87
+ const { EntropyAnalyzer } = await import("./dist-IJ4J4C5G.js");
88
88
  const typeFilter = input.type ?? "all";
89
89
  const analyzer = new EntropyAnalyzer({
90
90
  rootDir: sanitizePath(input.path),
@@ -144,7 +144,7 @@ async function handleDetectEntropy(input) {
144
144
  return resultToMcpResponse(result);
145
145
  }
146
146
  if (!result.ok) return resultToMcpResponse(result);
147
- const { createFixes, applyFixes, generateSuggestions } = await import("./dist-PBTNVK6K.js");
147
+ const { createFixes, applyFixes, generateSuggestions } = await import("./dist-IJ4J4C5G.js");
148
148
  const report = result.value;
149
149
  const deadCode = report.deadCode;
150
150
  const fixTypesConfig = input.fixTypes ? { fixTypes: input.fixTypes } : void 0;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  resolveSkillsDir
3
- } from "./chunk-EOLRW32Q.js";
3
+ } from "./chunk-HD4IBGLA.js";
4
4
  import {
5
5
  SkillMetadataSchema
6
- } from "./chunk-MDUK2J2O.js";
6
+ } from "./chunk-VRFZWGMS.js";
7
7
 
8
8
  // src/persona/skill-executor.ts
9
9
  import * as fs from "fs";
@@ -38,7 +38,7 @@ async function handleCheckDependencies(input) {
38
38
  const configResult = resolveProjectConfig(projectPath);
39
39
  if (!configResult.ok) return resultToMcpResponse(configResult);
40
40
  try {
41
- const { validateDependencies, TypeScriptParser } = await import("./dist-PBTNVK6K.js");
41
+ const { validateDependencies, TypeScriptParser } = await import("./dist-IJ4J4C5G.js");
42
42
  const config = configResult.value;
43
43
  const rawLayers = Array.isArray(config.layers) ? config.layers : [];
44
44
  const layers = rawLayers.map((l) => ({
@@ -47,11 +47,11 @@ async function handleCheckDependencies(input) {
47
47
  allowedDependencies: l.allowedDependencies
48
48
  }));
49
49
  const parser = new TypeScriptParser();
50
- const { loadGraphStore } = await import("./graph-loader-RLO3KRIX.js");
50
+ const { loadGraphStore } = await import("./graph-loader-KO4GJ5N2.js");
51
51
  const store = await loadGraphStore(projectPath);
52
52
  let graphDependencyData;
53
53
  if (store) {
54
- const { GraphConstraintAdapter } = await import("./dist-I7DB5VKB.js");
54
+ const { GraphConstraintAdapter } = await import("./dist-M6BQODWC.js");
55
55
  const adapter = new GraphConstraintAdapter(store);
56
56
  const graphData = adapter.computeDependencyGraph();
57
57
  graphDependencyData = {
@@ -45,7 +45,7 @@ var runCodeReviewDefinition = {
45
45
  };
46
46
  async function handleRunCodeReview(input) {
47
47
  try {
48
- const { parseDiff, runReviewPipeline } = await import("./dist-PBTNVK6K.js");
48
+ const { parseDiff, runReviewPipeline } = await import("./dist-IJ4J4C5G.js");
49
49
  const parseResult = parseDiff(input.diff);
50
50
  if (!parseResult.ok) {
51
51
  return {
@@ -58,7 +58,8 @@ var SkillMetadataSchema = z.object({
58
58
  type: z.enum(["rigid", "flexible"]),
59
59
  phases: z.array(SkillPhaseSchema).optional(),
60
60
  state: SkillStateSchema.default({}),
61
- depends_on: z.array(z.string()).default([])
61
+ depends_on: z.array(z.string()).default([]),
62
+ repository: z.string().url().optional()
62
63
  });
63
64
 
64
65
  export {
@@ -49,7 +49,7 @@ async function handleValidateProject(input) {
49
49
  checks.config = "pass";
50
50
  const config = configResult.value;
51
51
  try {
52
- const core = await import("./dist-PBTNVK6K.js");
52
+ const core = await import("./dist-IJ4J4C5G.js");
53
53
  if (typeof core.validateFileStructure === "function" && Array.isArray(config.conventions)) {
54
54
  const conventions = config.conventions;
55
55
  const structureResult = await core.validateFileStructure(projectPath, conventions);
@@ -68,7 +68,7 @@ async function handleValidateProject(input) {
68
68
  } catch {
69
69
  }
70
70
  try {
71
- const core = await import("./dist-PBTNVK6K.js");
71
+ const core = await import("./dist-IJ4J4C5G.js");
72
72
  if (typeof core.validateAgentsMap === "function") {
73
73
  const agentsMapPath = path.join(projectPath, "AGENTS.md");
74
74
  const agentsResult = await core.validateAgentsMap(agentsMapPath);
@@ -1,10 +1,13 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-HIOXKZYF.js";
3
+ } from "./chunk-EBJQ6N4M.js";
4
4
  import {
5
5
  CLIError,
6
6
  ExitCode
7
- } from "./chunk-B7HFEHWP.js";
7
+ } from "./chunk-3WGJMBKH.js";
8
+ import {
9
+ ArchConfigSchema
10
+ } from "./chunk-AE2OWWDH.js";
8
11
  import {
9
12
  Err,
10
13
  Ok
@@ -22,67 +25,105 @@ import * as path from "path";
22
25
  // src/config/schema.ts
23
26
  import { z } from "zod";
24
27
  var LayerSchema = z.object({
28
+ /** Human-readable name of the layer */
25
29
  name: z.string(),
30
+ /** Glob pattern matching files in this layer */
26
31
  pattern: z.string(),
32
+ /** Names of other layers this layer is allowed to import from */
27
33
  allowedDependencies: z.array(z.string())
28
34
  });
29
35
  var ForbiddenImportSchema = z.object({
36
+ /** Glob pattern matching source files this rule applies to */
30
37
  from: z.string(),
38
+ /** List of modules or patterns that are not allowed to be imported */
31
39
  disallow: z.array(z.string()),
40
+ /** Optional custom message to display on violation */
32
41
  message: z.string().optional()
33
42
  });
34
43
  var BoundaryConfigSchema = z.object({
44
+ /** List of globs where files MUST have a corresponding schema/definition */
35
45
  requireSchema: z.array(z.string())
36
46
  });
37
47
  var AgentConfigSchema = z.object({
48
+ /** The execution environment for agents */
38
49
  executor: z.enum(["subprocess", "cloud", "noop"]).default("subprocess"),
50
+ /** Maximum execution time in milliseconds */
39
51
  timeout: z.number().default(3e5),
52
+ /** Optional list of skill IDs pre-authorized for the agent */
40
53
  skills: z.array(z.string()).optional()
41
54
  });
42
55
  var EntropyConfigSchema = z.object({
56
+ /** Patterns to exclude from entropy analysis */
43
57
  excludePatterns: z.array(z.string()).default(["**/node_modules/**", "**/*.test.ts"]),
58
+ /** Whether to automatically attempt to fix simple entropy issues */
44
59
  autoFix: z.boolean().default(false)
45
60
  });
46
61
  var PhaseGateMappingSchema = z.object({
62
+ /** Pattern for implementation files */
47
63
  implPattern: z.string(),
64
+ /** Pattern for corresponding specification files */
48
65
  specPattern: z.string()
49
66
  });
50
67
  var PhaseGatesConfigSchema = z.object({
68
+ /** Whether phase gate checks are enabled */
51
69
  enabled: z.boolean().default(false),
70
+ /** Severity level when a phase gate check fails */
52
71
  severity: z.enum(["error", "warning"]).default("error"),
72
+ /** List of implementation-to-spec mappings */
53
73
  mappings: z.array(PhaseGateMappingSchema).default([{ implPattern: "src/**/*.ts", specPattern: "docs/changes/{feature}/proposal.md" }])
54
74
  });
55
75
  var SecurityConfigSchema = z.object({
76
+ /** Whether security scanning is enabled */
56
77
  enabled: z.boolean().default(true),
78
+ /** Whether to fail on any security warning */
57
79
  strict: z.boolean().default(false),
80
+ /** Rule-specific severity overrides */
58
81
  rules: z.record(z.string(), z.enum(["off", "error", "warning", "info"])).optional(),
82
+ /** Patterns to exclude from security scans */
59
83
  exclude: z.array(z.string()).optional()
60
84
  }).passthrough();
61
85
  var PerformanceConfigSchema = z.object({
86
+ /** Complexity thresholds per module or pattern */
62
87
  complexity: z.record(z.unknown()).optional(),
88
+ /** Coupling limits between modules */
63
89
  coupling: z.record(z.unknown()).optional(),
90
+ /** Size budget for bundles or directories */
64
91
  sizeBudget: z.record(z.unknown()).optional()
65
92
  }).passthrough();
66
93
  var DesignConfigSchema = z.object({
94
+ /** Strictness of design system enforcement */
67
95
  strictness: z.enum(["strict", "standard", "permissive"]).default("standard"),
96
+ /** Supported target platforms */
68
97
  platforms: z.array(z.enum(["web", "mobile"])).default([]),
98
+ /** Path to design tokens (e.g. JSON or CSS) */
69
99
  tokenPath: z.string().optional(),
100
+ /** Brief description of the intended aesthetic direction */
70
101
  aestheticIntent: z.string().optional()
71
102
  });
72
103
  var I18nCoverageConfigSchema = z.object({
104
+ /** Minimum required translation percentage */
73
105
  minimumPercent: z.number().min(0).max(100).default(100),
106
+ /** Whether plural forms are required for all keys */
74
107
  requirePlurals: z.boolean().default(true),
108
+ /** Whether to detect untranslated strings in source code */
75
109
  detectUntranslated: z.boolean().default(true)
76
110
  });
77
111
  var I18nMcpConfigSchema = z.object({
112
+ /** Name or URL of the MCP server */
78
113
  server: z.string(),
114
+ /** Project ID on the remote i18n platform */
79
115
  projectId: z.string().optional()
80
116
  });
81
117
  var I18nConfigSchema = z.object({
118
+ /** Whether i18n management is enabled */
82
119
  enabled: z.boolean().default(false),
120
+ /** Strictness of i18n rule enforcement */
83
121
  strictness: z.enum(["strict", "standard", "permissive"]).default("standard"),
122
+ /** The primary language used for development */
84
123
  sourceLocale: z.string().default("en"),
124
+ /** List of locales that translations are required for */
85
125
  targetLocales: z.array(z.string()).default([]),
126
+ /** The i18n framework in use */
86
127
  framework: z.enum([
87
128
  "auto",
88
129
  "i18next",
@@ -93,46 +134,82 @@ var I18nConfigSchema = z.object({
93
134
  "android",
94
135
  "custom"
95
136
  ]).default("auto"),
137
+ /** Storage format for translation files */
96
138
  format: z.string().default("json"),
139
+ /** Syntax used for message formatting */
97
140
  messageFormat: z.enum(["icu", "i18next", "custom"]).default("icu"),
141
+ /** Convention for translation keys */
98
142
  keyConvention: z.enum(["dot-notation", "snake_case", "camelCase", "custom"]).default("dot-notation"),
143
+ /** Mapping of locales to their file paths */
99
144
  translationPaths: z.record(z.string(), z.string()).optional(),
145
+ /** Platforms targeted by this configuration */
100
146
  platforms: z.array(z.enum(["web", "mobile", "backend"])).default([]),
147
+ /** Industry vertical (for contextual translations) */
101
148
  industry: z.string().optional(),
149
+ /** Translation coverage requirements */
102
150
  coverage: I18nCoverageConfigSchema.optional(),
151
+ /** Locale used for pseudo-localization testing */
103
152
  pseudoLocale: z.string().optional(),
153
+ /** MCP server for AI-assisted translation */
104
154
  mcp: I18nMcpConfigSchema.optional()
105
155
  });
106
156
  var ModelTierConfigSchema = z.object({
157
+ /** Model ID to use for fast/cheap operations */
107
158
  fast: z.string().optional(),
159
+ /** Model ID to use for standard reasoning tasks */
108
160
  standard: z.string().optional(),
161
+ /** Model ID to use for complex/critical analysis */
109
162
  strong: z.string().optional()
110
163
  });
111
164
  var ReviewConfigSchema = z.object({
165
+ /** Custom model tier mappings for reviewers */
112
166
  model_tiers: ModelTierConfigSchema.optional()
113
167
  });
114
168
  var HarnessConfigSchema = z.object({
169
+ /** Configuration schema version */
115
170
  version: z.literal(1),
171
+ /** Human-readable name of the project */
116
172
  name: z.string().optional(),
173
+ /** Root directory of the project, relative to the config file */
117
174
  rootDir: z.string().default("."),
175
+ /** Layered architecture definitions */
118
176
  layers: z.array(LayerSchema).optional(),
177
+ /** Rules for forbidden cross-module imports */
119
178
  forbiddenImports: z.array(ForbiddenImportSchema).optional(),
179
+ /** Boundary enforcement settings */
120
180
  boundaries: BoundaryConfigSchema.optional(),
181
+ /** Path to the project's knowledge map (AGENTS.md) */
121
182
  agentsMapPath: z.string().default("./AGENTS.md"),
183
+ /** Directory containing project documentation */
122
184
  docsDir: z.string().default("./docs"),
185
+ /** Agent orchestration settings */
123
186
  agent: AgentConfigSchema.optional(),
187
+ /** Drift and stale code management settings */
124
188
  entropy: EntropyConfigSchema.optional(),
189
+ /** Security scanning configuration */
125
190
  security: SecurityConfigSchema.optional(),
191
+ /** Performance and complexity budget settings */
126
192
  performance: PerformanceConfigSchema.optional(),
193
+ /** Project template settings (used by 'harness init') */
127
194
  template: z.object({
195
+ /** Complexity level of the template */
128
196
  level: z.enum(["basic", "intermediate", "advanced"]),
197
+ /** Primary technology framework */
129
198
  framework: z.string().optional(),
199
+ /** Template version */
130
200
  version: z.number()
131
201
  }).optional(),
202
+ /** Phase gate and readiness check configuration */
132
203
  phaseGates: PhaseGatesConfigSchema.optional(),
204
+ /** Design system consistency settings */
133
205
  design: DesignConfigSchema.optional(),
206
+ /** Internationalization (i18n) settings */
134
207
  i18n: I18nConfigSchema.optional(),
208
+ /** Code review settings */
135
209
  review: ReviewConfigSchema.optional(),
210
+ /** General architectural enforcement settings */
211
+ architecture: ArchConfigSchema.optional(),
212
+ /** How often (in ms) to check for CLI updates */
136
213
  updateCheckInterval: z.number().int().min(0).optional()
137
214
  });
138
215
 
@@ -198,17 +275,29 @@ async function findFiles(pattern, cwd = process.cwd()) {
198
275
  // src/output/formatter.ts
199
276
  import chalk from "chalk";
200
277
  var OutputMode = {
278
+ /** Output as formatted JSON */
201
279
  JSON: "json",
280
+ /** Output as human-readable text */
202
281
  TEXT: "text",
282
+ /** Minimal output, only errors and successes */
203
283
  QUIET: "quiet",
284
+ /** Full output with detailed context and suggestions */
204
285
  VERBOSE: "verbose"
205
286
  };
206
287
  var OutputFormatter = class {
288
+ /**
289
+ * Creates a new OutputFormatter.
290
+ *
291
+ * @param mode - The output mode to use. Defaults to TEXT.
292
+ */
207
293
  constructor(mode = OutputMode.TEXT) {
208
294
  this.mode = mode;
209
295
  }
210
296
  /**
211
- * Format raw data (for JSON mode)
297
+ * Formats raw data for output.
298
+ *
299
+ * @param data - The data to format.
300
+ * @returns A string representation of the data based on the current mode.
212
301
  */
213
302
  format(data) {
214
303
  if (this.mode === OutputMode.JSON) {
@@ -217,7 +306,10 @@ var OutputFormatter = class {
217
306
  return String(data);
218
307
  }
219
308
  /**
220
- * Format validation result
309
+ * Formats a validation result into a user-friendly string.
310
+ *
311
+ * @param result - The validation result to format.
312
+ * @returns A formatted string containing the validation status and any issues.
221
313
  */
222
314
  formatValidation(result) {
223
315
  if (this.mode === OutputMode.JSON) {
@@ -245,7 +337,12 @@ var OutputFormatter = class {
245
337
  return lines.join("\n");
246
338
  }
247
339
  /**
248
- * Format a summary line
340
+ * Formats a summary line with a success/failure icon and label.
341
+ *
342
+ * @param label - The name of the field to summarize.
343
+ * @param value - The value to display.
344
+ * @param success - Whether the summary represents a success or failure state.
345
+ * @returns A formatted summary string, or an empty string in JSON or QUIET modes.
249
346
  */
250
347
  formatSummary(label, value, success) {
251
348
  if (this.mode === OutputMode.JSON || this.mode === OutputMode.QUIET) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  generateCIWorkflow
3
3
  } from "./chunk-VUCPTQ6G.js";
4
- import "./chunk-NX6DSZSM.js";
4
+ import "./chunk-AE2OWWDH.js";
5
5
  import "./chunk-MHBMTPW7.js";
6
6
  export {
7
7
  generateCIWorkflow
@@ -0,0 +1,11 @@
1
+ import {
2
+ createCreateSkillCommand,
3
+ generateSkillFiles
4
+ } from "./chunk-6N4R6FVX.js";
5
+ import "./chunk-EBJQ6N4M.js";
6
+ import "./chunk-3WGJMBKH.js";
7
+ import "./chunk-VRFZWGMS.js";
8
+ export {
9
+ createCreateSkillCommand,
10
+ generateSkillFiles
11
+ };