@harness-engineering/cli 2.7.0 → 2.7.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.
- package/dist/agents/skills/claude-code/naming-craft/SKILL.md +74 -2
- package/dist/agents/skills/codex/naming-craft/SKILL.md +74 -2
- package/dist/agents/skills/cursor/naming-craft/SKILL.md +74 -2
- package/dist/agents/skills/gemini-cli/naming-craft/SKILL.md +74 -2
- package/dist/{agents-md-267R2NUJ.js → agents-md-FKMKH6ZF.js} +3 -3
- package/dist/{analyzer-VY6DJVOU-WYKV3TTW.js → analyzer-H3AHBFSL-KPOPJYRB.js} +7 -7
- package/dist/{architecture-ZTEHGIHD.js → architecture-LUR2I67H.js} +4 -4
- package/dist/{assess-project-OKDW3YSK.js → assess-project-OJWECOP2.js} +1 -1
- package/dist/bin/harness-mcp.js +14 -14
- package/dist/bin/harness.js +23 -23
- package/dist/{check-phase-gate-YJWFDW66.js → check-phase-gate-HS5KYLRO.js} +4 -4
- package/dist/{chunk-MQG7FHXX.js → chunk-7AF6C5GE.js} +3 -3
- package/dist/{chunk-4EGPFB7V.js → chunk-7PLIWP7U.js} +961 -256
- package/dist/{chunk-WOXR6I3R.js → chunk-B2VAYLYI.js} +1 -1
- package/dist/{chunk-67RP7MLR.js → chunk-CZPOPMMI.js} +2 -2
- package/dist/{chunk-OLTVDPA2.js → chunk-FC4JPM6W.js} +2 -2
- package/dist/{chunk-CXAHK5PJ.js → chunk-FEKBXX2J.js} +6 -6
- package/dist/{chunk-B4OLYXZ4.js → chunk-FXZI6NJ2.js} +39 -4
- package/dist/{chunk-6T5AYG5S.js → chunk-GGSNWH7P.js} +2 -2
- package/dist/{chunk-ZKA3TGYS.js → chunk-INBTDBV2.js} +1 -1
- package/dist/{chunk-HMMSWRWR.js → chunk-KN3EMDZ5.js} +2 -2
- package/dist/{chunk-OQE6ME2Z.js → chunk-LECXPXS3.js} +1 -1
- package/dist/{chunk-HLPY3RHE.js → chunk-LGYXR2KZ.js} +799 -515
- package/dist/{chunk-QUPC37UB.js → chunk-LYIPI2SJ.js} +3 -3
- package/dist/{chunk-S7GEONXL.js → chunk-N5NSSLMU.js} +1 -1
- package/dist/{chunk-P7EO7USC.js → chunk-NIVWM7OW.js} +5 -5
- package/dist/{chunk-PARV3G2F.js → chunk-O2ASYKA6.js} +1 -1
- package/dist/{chunk-XTIPZUPR.js → chunk-PTHX545Q.js} +1 -1
- package/dist/{chunk-B3B64OPD.js → chunk-RJ2WEES5.js} +1 -1
- package/dist/{chunk-TIZ3L6CU.js → chunk-VI4IS55S.js} +6 -6
- package/dist/{chunk-VG6UK6G6.js → chunk-VSIRUZQP.js} +1 -1
- package/dist/{chunk-IY2TZLY5.js → chunk-WZY5U6NS.js} +4 -4
- package/dist/{chunk-W3PDVZ4I.js → chunk-Y4T6ENKQ.js} +8 -8
- package/dist/{chunk-Z2GUITAS.js → chunk-Z3TMCCZB.js} +3 -3
- package/dist/{ci-workflow-YGTQTNVC.js → ci-workflow-MDSTHJOY.js} +3 -3
- package/dist/{dist-XIJWWQ5N.js → dist-72ID44UE.js} +2 -2
- package/dist/{docs-KCTLXK2G.js → docs-2RFOJ6XY.js} +4 -4
- package/dist/{engine-J64WPH5K.js → engine-BSFKOGPN.js} +3 -3
- package/dist/{entropy-M27JUL3V.js → entropy-3UX6644G.js} +3 -3
- package/dist/{feedback-W25QO3OL.js → feedback-CVCFYND4.js} +1 -1
- package/dist/{generate-agent-definitions-RNMU5U5R.js → generate-agent-definitions-HZ3XENWO.js} +4 -4
- package/dist/index.d.ts +425 -6
- package/dist/index.js +23 -23
- package/dist/{loader-HZKJ5ABV.js → loader-6RHWU5FH.js} +3 -3
- package/dist/{mcp-NEAPIDTT.js → mcp-OYR26JDI.js} +14 -14
- package/dist/{performance-3AVQUDRG.js → performance-JJMIRXCH.js} +4 -4
- package/dist/{review-pipeline-KA7SGUXJ.js → review-pipeline-BHQZIXWZ.js} +3 -3
- package/dist/{runtime-IP6FVV5M.js → runtime-DALTAVTN.js} +3 -3
- package/dist/{security-EAR4FJWI.js → security-RMLMYFPB.js} +1 -1
- package/dist/{validate-EVH3UXIC.js → validate-R7DZRDFK.js} +4 -4
- package/dist/{validate-cross-check-SNE3SQOB.js → validate-cross-check-AUUZFNVL.js} +3 -3
- package/package.json +4 -4
|
@@ -84,9 +84,81 @@ Emit `NamingCraftOutput`:
|
|
|
84
84
|
## Harness Integration
|
|
85
85
|
|
|
86
86
|
- **`harness naming-craft`** — CLI entry. `--files <glob>` / `--kinds <variable|function|type|file>` / `--max-files <n>` / `--max-identifiers-per-file <n>` / `--json` / `--verbose`.
|
|
87
|
-
- **`mcp__harness__naming_craft`** — MCP tool.
|
|
87
|
+
- **`mcp__harness__naming_craft`** — MCP tool. Two modes (see "In-session flow" below).
|
|
88
|
+
- **`mcp__harness__naming_craft_finalize`** — MCP tool that completes the in-session flow.
|
|
88
89
|
- **Cross-cutting API:** `critiqueNamesInFile(file, opts)` exported from `packages/cli/src/naming-craft/index.ts`. Future craft skills (docs-craft, test-craft, code-craft) import and invoke this when they want naming critique on a file they're already processing — no project re-walk needed.
|
|
89
|
-
- **LLM provider
|
|
90
|
+
- **LLM provider:** configured in `harness.config.json`. The shared selector in `packages/cli/src/shared/craft/llm/provider.ts` reads two blocks:
|
|
91
|
+
- **`agent.backends`** — named backend definitions, shared with the orchestrator. Supported types: `claude`, `anthropic`, `openai`, `local`, `pi`, `mock`. (`local` and `pi` are OpenAI-compatible — point them at Ollama / LM Studio / vLLM / LiteLLM / any compliant server.)
|
|
92
|
+
- **`craft.llm`** — either `{ "backend": "<name>" }` to route through one of the entries above, or `{ "mode": "in-session" | "mock" }` for the non-backend modes. Default when nothing is set: `in-session` (host chat answers prompts via the two-step MCP flow).
|
|
93
|
+
- **`HARNESS_CRAFT_LLM`** env var overrides the file. Accepts `in-session`, `mock`, or the name of any entry in `agent.backends`.
|
|
94
|
+
|
|
95
|
+
### Migration from `harness.orchestrator.md`
|
|
96
|
+
|
|
97
|
+
If you already declared `agent.backends` in `harness.orchestrator.md`, the craft selector reads from it as a fallback and emits a one-time warning on first run. Run `harness migrate backends` (preview with `--dry-run`) to copy the entries into `harness.config.json` so both files share a single source of truth.
|
|
98
|
+
|
|
99
|
+
### Example
|
|
100
|
+
|
|
101
|
+
Example config snippet for routing craft skills to a local Ollama:
|
|
102
|
+
|
|
103
|
+
```jsonc
|
|
104
|
+
{
|
|
105
|
+
"agent": {
|
|
106
|
+
"backends": {
|
|
107
|
+
"ollama": {
|
|
108
|
+
"type": "local",
|
|
109
|
+
"endpoint": "http://localhost:11434/v1",
|
|
110
|
+
"model": ["deepseek-coder-v2", "qwen3:8b"],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
"craft": { "llm": { "backend": "ollama" } },
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## In-session flow (default)
|
|
119
|
+
|
|
120
|
+
When `HARNESS_CRAFT_LLM` is unset (or set to `in-session`), the MCP tool does **not** call any LLM. Instead it returns a list of prompts for the calling agent to answer with its own model. This is a two-step protocol:
|
|
121
|
+
|
|
122
|
+
**Step 1 — `mcp__harness__naming_craft({ path, ... })`** returns:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"status": "collected",
|
|
127
|
+
"runId": "<uuid>",
|
|
128
|
+
"pendingPrompts": [
|
|
129
|
+
{ "promptId": "p1", "systemPrompt": "...", "userPrompt": "..." },
|
|
130
|
+
...
|
|
131
|
+
],
|
|
132
|
+
"projection": { "promptCount": N, "budget": 100 }
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
If `projection.promptCount > budget`, `status` is `"budget-exceeded"` and `pendingPrompts` is empty — re-invoke with smaller `maxFiles` / `maxIdentifiersPerFile`, or pass `promptBudget` to raise the ceiling.
|
|
137
|
+
|
|
138
|
+
**Step 2** — for each pending prompt, generate the fenced-JSON response as if you were a senior engineer applying the rubric to the identifier. The required response shape (per prompt) is:
|
|
139
|
+
|
|
140
|
+
````
|
|
141
|
+
```json
|
|
142
|
+
null
|
|
143
|
+
```
|
|
144
|
+
````
|
|
145
|
+
|
|
146
|
+
if the rubric does not apply or the name is fine, OR:
|
|
147
|
+
|
|
148
|
+
````
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"tier": "foundational|polish|aspirational",
|
|
152
|
+
"impact": "small|medium|large",
|
|
153
|
+
"confidence": "high|medium|low",
|
|
154
|
+
"message": "<critique with suggested rename when possible>"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
````
|
|
158
|
+
|
|
159
|
+
**Step 3 — `mcp__harness__naming_craft_finalize({ path, runId, responses: [{ promptId, raw }, ...] })`** parses the responses, applies the same validation the inline path uses, and returns the standard `NamingCraftOutput`.
|
|
160
|
+
|
|
161
|
+
If you want the inline behavior (skill calls an LLM directly), pass `mode: 'inline'` to step 1 and set `HARNESS_CRAFT_LLM` to a non-`in-session` provider.
|
|
90
162
|
|
|
91
163
|
## Success Criteria
|
|
92
164
|
|
|
@@ -84,9 +84,81 @@ Emit `NamingCraftOutput`:
|
|
|
84
84
|
## Harness Integration
|
|
85
85
|
|
|
86
86
|
- **`harness naming-craft`** — CLI entry. `--files <glob>` / `--kinds <variable|function|type|file>` / `--max-files <n>` / `--max-identifiers-per-file <n>` / `--json` / `--verbose`.
|
|
87
|
-
- **`mcp__harness__naming_craft`** — MCP tool.
|
|
87
|
+
- **`mcp__harness__naming_craft`** — MCP tool. Two modes (see "In-session flow" below).
|
|
88
|
+
- **`mcp__harness__naming_craft_finalize`** — MCP tool that completes the in-session flow.
|
|
88
89
|
- **Cross-cutting API:** `critiqueNamesInFile(file, opts)` exported from `packages/cli/src/naming-craft/index.ts`. Future craft skills (docs-craft, test-craft, code-craft) import and invoke this when they want naming critique on a file they're already processing — no project re-walk needed.
|
|
89
|
-
- **LLM provider
|
|
90
|
+
- **LLM provider:** configured in `harness.config.json`. The shared selector in `packages/cli/src/shared/craft/llm/provider.ts` reads two blocks:
|
|
91
|
+
- **`agent.backends`** — named backend definitions, shared with the orchestrator. Supported types: `claude`, `anthropic`, `openai`, `local`, `pi`, `mock`. (`local` and `pi` are OpenAI-compatible — point them at Ollama / LM Studio / vLLM / LiteLLM / any compliant server.)
|
|
92
|
+
- **`craft.llm`** — either `{ "backend": "<name>" }` to route through one of the entries above, or `{ "mode": "in-session" | "mock" }` for the non-backend modes. Default when nothing is set: `in-session` (host chat answers prompts via the two-step MCP flow).
|
|
93
|
+
- **`HARNESS_CRAFT_LLM`** env var overrides the file. Accepts `in-session`, `mock`, or the name of any entry in `agent.backends`.
|
|
94
|
+
|
|
95
|
+
### Migration from `harness.orchestrator.md`
|
|
96
|
+
|
|
97
|
+
If you already declared `agent.backends` in `harness.orchestrator.md`, the craft selector reads from it as a fallback and emits a one-time warning on first run. Run `harness migrate backends` (preview with `--dry-run`) to copy the entries into `harness.config.json` so both files share a single source of truth.
|
|
98
|
+
|
|
99
|
+
### Example
|
|
100
|
+
|
|
101
|
+
Example config snippet for routing craft skills to a local Ollama:
|
|
102
|
+
|
|
103
|
+
```jsonc
|
|
104
|
+
{
|
|
105
|
+
"agent": {
|
|
106
|
+
"backends": {
|
|
107
|
+
"ollama": {
|
|
108
|
+
"type": "local",
|
|
109
|
+
"endpoint": "http://localhost:11434/v1",
|
|
110
|
+
"model": ["deepseek-coder-v2", "qwen3:8b"],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
"craft": { "llm": { "backend": "ollama" } },
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## In-session flow (default)
|
|
119
|
+
|
|
120
|
+
When `HARNESS_CRAFT_LLM` is unset (or set to `in-session`), the MCP tool does **not** call any LLM. Instead it returns a list of prompts for the calling agent to answer with its own model. This is a two-step protocol:
|
|
121
|
+
|
|
122
|
+
**Step 1 — `mcp__harness__naming_craft({ path, ... })`** returns:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"status": "collected",
|
|
127
|
+
"runId": "<uuid>",
|
|
128
|
+
"pendingPrompts": [
|
|
129
|
+
{ "promptId": "p1", "systemPrompt": "...", "userPrompt": "..." },
|
|
130
|
+
...
|
|
131
|
+
],
|
|
132
|
+
"projection": { "promptCount": N, "budget": 100 }
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
If `projection.promptCount > budget`, `status` is `"budget-exceeded"` and `pendingPrompts` is empty — re-invoke with smaller `maxFiles` / `maxIdentifiersPerFile`, or pass `promptBudget` to raise the ceiling.
|
|
137
|
+
|
|
138
|
+
**Step 2** — for each pending prompt, generate the fenced-JSON response as if you were a senior engineer applying the rubric to the identifier. The required response shape (per prompt) is:
|
|
139
|
+
|
|
140
|
+
````
|
|
141
|
+
```json
|
|
142
|
+
null
|
|
143
|
+
```
|
|
144
|
+
````
|
|
145
|
+
|
|
146
|
+
if the rubric does not apply or the name is fine, OR:
|
|
147
|
+
|
|
148
|
+
````
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"tier": "foundational|polish|aspirational",
|
|
152
|
+
"impact": "small|medium|large",
|
|
153
|
+
"confidence": "high|medium|low",
|
|
154
|
+
"message": "<critique with suggested rename when possible>"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
````
|
|
158
|
+
|
|
159
|
+
**Step 3 — `mcp__harness__naming_craft_finalize({ path, runId, responses: [{ promptId, raw }, ...] })`** parses the responses, applies the same validation the inline path uses, and returns the standard `NamingCraftOutput`.
|
|
160
|
+
|
|
161
|
+
If you want the inline behavior (skill calls an LLM directly), pass `mode: 'inline'` to step 1 and set `HARNESS_CRAFT_LLM` to a non-`in-session` provider.
|
|
90
162
|
|
|
91
163
|
## Success Criteria
|
|
92
164
|
|
|
@@ -84,9 +84,81 @@ Emit `NamingCraftOutput`:
|
|
|
84
84
|
## Harness Integration
|
|
85
85
|
|
|
86
86
|
- **`harness naming-craft`** — CLI entry. `--files <glob>` / `--kinds <variable|function|type|file>` / `--max-files <n>` / `--max-identifiers-per-file <n>` / `--json` / `--verbose`.
|
|
87
|
-
- **`mcp__harness__naming_craft`** — MCP tool.
|
|
87
|
+
- **`mcp__harness__naming_craft`** — MCP tool. Two modes (see "In-session flow" below).
|
|
88
|
+
- **`mcp__harness__naming_craft_finalize`** — MCP tool that completes the in-session flow.
|
|
88
89
|
- **Cross-cutting API:** `critiqueNamesInFile(file, opts)` exported from `packages/cli/src/naming-craft/index.ts`. Future craft skills (docs-craft, test-craft, code-craft) import and invoke this when they want naming critique on a file they're already processing — no project re-walk needed.
|
|
89
|
-
- **LLM provider
|
|
90
|
+
- **LLM provider:** configured in `harness.config.json`. The shared selector in `packages/cli/src/shared/craft/llm/provider.ts` reads two blocks:
|
|
91
|
+
- **`agent.backends`** — named backend definitions, shared with the orchestrator. Supported types: `claude`, `anthropic`, `openai`, `local`, `pi`, `mock`. (`local` and `pi` are OpenAI-compatible — point them at Ollama / LM Studio / vLLM / LiteLLM / any compliant server.)
|
|
92
|
+
- **`craft.llm`** — either `{ "backend": "<name>" }` to route through one of the entries above, or `{ "mode": "in-session" | "mock" }` for the non-backend modes. Default when nothing is set: `in-session` (host chat answers prompts via the two-step MCP flow).
|
|
93
|
+
- **`HARNESS_CRAFT_LLM`** env var overrides the file. Accepts `in-session`, `mock`, or the name of any entry in `agent.backends`.
|
|
94
|
+
|
|
95
|
+
### Migration from `harness.orchestrator.md`
|
|
96
|
+
|
|
97
|
+
If you already declared `agent.backends` in `harness.orchestrator.md`, the craft selector reads from it as a fallback and emits a one-time warning on first run. Run `harness migrate backends` (preview with `--dry-run`) to copy the entries into `harness.config.json` so both files share a single source of truth.
|
|
98
|
+
|
|
99
|
+
### Example
|
|
100
|
+
|
|
101
|
+
Example config snippet for routing craft skills to a local Ollama:
|
|
102
|
+
|
|
103
|
+
```jsonc
|
|
104
|
+
{
|
|
105
|
+
"agent": {
|
|
106
|
+
"backends": {
|
|
107
|
+
"ollama": {
|
|
108
|
+
"type": "local",
|
|
109
|
+
"endpoint": "http://localhost:11434/v1",
|
|
110
|
+
"model": ["deepseek-coder-v2", "qwen3:8b"],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
"craft": { "llm": { "backend": "ollama" } },
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## In-session flow (default)
|
|
119
|
+
|
|
120
|
+
When `HARNESS_CRAFT_LLM` is unset (or set to `in-session`), the MCP tool does **not** call any LLM. Instead it returns a list of prompts for the calling agent to answer with its own model. This is a two-step protocol:
|
|
121
|
+
|
|
122
|
+
**Step 1 — `mcp__harness__naming_craft({ path, ... })`** returns:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"status": "collected",
|
|
127
|
+
"runId": "<uuid>",
|
|
128
|
+
"pendingPrompts": [
|
|
129
|
+
{ "promptId": "p1", "systemPrompt": "...", "userPrompt": "..." },
|
|
130
|
+
...
|
|
131
|
+
],
|
|
132
|
+
"projection": { "promptCount": N, "budget": 100 }
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
If `projection.promptCount > budget`, `status` is `"budget-exceeded"` and `pendingPrompts` is empty — re-invoke with smaller `maxFiles` / `maxIdentifiersPerFile`, or pass `promptBudget` to raise the ceiling.
|
|
137
|
+
|
|
138
|
+
**Step 2** — for each pending prompt, generate the fenced-JSON response as if you were a senior engineer applying the rubric to the identifier. The required response shape (per prompt) is:
|
|
139
|
+
|
|
140
|
+
````
|
|
141
|
+
```json
|
|
142
|
+
null
|
|
143
|
+
```
|
|
144
|
+
````
|
|
145
|
+
|
|
146
|
+
if the rubric does not apply or the name is fine, OR:
|
|
147
|
+
|
|
148
|
+
````
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"tier": "foundational|polish|aspirational",
|
|
152
|
+
"impact": "small|medium|large",
|
|
153
|
+
"confidence": "high|medium|low",
|
|
154
|
+
"message": "<critique with suggested rename when possible>"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
````
|
|
158
|
+
|
|
159
|
+
**Step 3 — `mcp__harness__naming_craft_finalize({ path, runId, responses: [{ promptId, raw }, ...] })`** parses the responses, applies the same validation the inline path uses, and returns the standard `NamingCraftOutput`.
|
|
160
|
+
|
|
161
|
+
If you want the inline behavior (skill calls an LLM directly), pass `mode: 'inline'` to step 1 and set `HARNESS_CRAFT_LLM` to a non-`in-session` provider.
|
|
90
162
|
|
|
91
163
|
## Success Criteria
|
|
92
164
|
|
|
@@ -84,9 +84,81 @@ Emit `NamingCraftOutput`:
|
|
|
84
84
|
## Harness Integration
|
|
85
85
|
|
|
86
86
|
- **`harness naming-craft`** — CLI entry. `--files <glob>` / `--kinds <variable|function|type|file>` / `--max-files <n>` / `--max-identifiers-per-file <n>` / `--json` / `--verbose`.
|
|
87
|
-
- **`mcp__harness__naming_craft`** — MCP tool.
|
|
87
|
+
- **`mcp__harness__naming_craft`** — MCP tool. Two modes (see "In-session flow" below).
|
|
88
|
+
- **`mcp__harness__naming_craft_finalize`** — MCP tool that completes the in-session flow.
|
|
88
89
|
- **Cross-cutting API:** `critiqueNamesInFile(file, opts)` exported from `packages/cli/src/naming-craft/index.ts`. Future craft skills (docs-craft, test-craft, code-craft) import and invoke this when they want naming critique on a file they're already processing — no project re-walk needed.
|
|
89
|
-
- **LLM provider
|
|
90
|
+
- **LLM provider:** configured in `harness.config.json`. The shared selector in `packages/cli/src/shared/craft/llm/provider.ts` reads two blocks:
|
|
91
|
+
- **`agent.backends`** — named backend definitions, shared with the orchestrator. Supported types: `claude`, `anthropic`, `openai`, `local`, `pi`, `mock`. (`local` and `pi` are OpenAI-compatible — point them at Ollama / LM Studio / vLLM / LiteLLM / any compliant server.)
|
|
92
|
+
- **`craft.llm`** — either `{ "backend": "<name>" }` to route through one of the entries above, or `{ "mode": "in-session" | "mock" }` for the non-backend modes. Default when nothing is set: `in-session` (host chat answers prompts via the two-step MCP flow).
|
|
93
|
+
- **`HARNESS_CRAFT_LLM`** env var overrides the file. Accepts `in-session`, `mock`, or the name of any entry in `agent.backends`.
|
|
94
|
+
|
|
95
|
+
### Migration from `harness.orchestrator.md`
|
|
96
|
+
|
|
97
|
+
If you already declared `agent.backends` in `harness.orchestrator.md`, the craft selector reads from it as a fallback and emits a one-time warning on first run. Run `harness migrate backends` (preview with `--dry-run`) to copy the entries into `harness.config.json` so both files share a single source of truth.
|
|
98
|
+
|
|
99
|
+
### Example
|
|
100
|
+
|
|
101
|
+
Example config snippet for routing craft skills to a local Ollama:
|
|
102
|
+
|
|
103
|
+
```jsonc
|
|
104
|
+
{
|
|
105
|
+
"agent": {
|
|
106
|
+
"backends": {
|
|
107
|
+
"ollama": {
|
|
108
|
+
"type": "local",
|
|
109
|
+
"endpoint": "http://localhost:11434/v1",
|
|
110
|
+
"model": ["deepseek-coder-v2", "qwen3:8b"],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
"craft": { "llm": { "backend": "ollama" } },
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## In-session flow (default)
|
|
119
|
+
|
|
120
|
+
When `HARNESS_CRAFT_LLM` is unset (or set to `in-session`), the MCP tool does **not** call any LLM. Instead it returns a list of prompts for the calling agent to answer with its own model. This is a two-step protocol:
|
|
121
|
+
|
|
122
|
+
**Step 1 — `mcp__harness__naming_craft({ path, ... })`** returns:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"status": "collected",
|
|
127
|
+
"runId": "<uuid>",
|
|
128
|
+
"pendingPrompts": [
|
|
129
|
+
{ "promptId": "p1", "systemPrompt": "...", "userPrompt": "..." },
|
|
130
|
+
...
|
|
131
|
+
],
|
|
132
|
+
"projection": { "promptCount": N, "budget": 100 }
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
If `projection.promptCount > budget`, `status` is `"budget-exceeded"` and `pendingPrompts` is empty — re-invoke with smaller `maxFiles` / `maxIdentifiersPerFile`, or pass `promptBudget` to raise the ceiling.
|
|
137
|
+
|
|
138
|
+
**Step 2** — for each pending prompt, generate the fenced-JSON response as if you were a senior engineer applying the rubric to the identifier. The required response shape (per prompt) is:
|
|
139
|
+
|
|
140
|
+
````
|
|
141
|
+
```json
|
|
142
|
+
null
|
|
143
|
+
```
|
|
144
|
+
````
|
|
145
|
+
|
|
146
|
+
if the rubric does not apply or the name is fine, OR:
|
|
147
|
+
|
|
148
|
+
````
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"tier": "foundational|polish|aspirational",
|
|
152
|
+
"impact": "small|medium|large",
|
|
153
|
+
"confidence": "high|medium|low",
|
|
154
|
+
"message": "<critique with suggested rename when possible>"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
````
|
|
158
|
+
|
|
159
|
+
**Step 3 — `mcp__harness__naming_craft_finalize({ path, runId, responses: [{ promptId, raw }, ...] })`** parses the responses, applies the same validation the inline path uses, and returns the standard `NamingCraftOutput`.
|
|
160
|
+
|
|
161
|
+
If you want the inline behavior (skill calls an LLM directly), pass `mode: 'inline'` to step 1 and set `HARNESS_CRAFT_LLM` to a non-`in-session` provider.
|
|
90
162
|
|
|
91
163
|
## Success Criteria
|
|
92
164
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateAgentsMd
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-LECXPXS3.js";
|
|
4
|
+
import "./chunk-WZY5U6NS.js";
|
|
5
|
+
import "./chunk-Y4T6ENKQ.js";
|
|
6
6
|
import "./chunk-OH3NXXUY.js";
|
|
7
7
|
import "./chunk-H2ZJOJ7A.js";
|
|
8
8
|
import "./chunk-QCLOIUMX.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EntropyAnalyzer,
|
|
3
|
-
|
|
3
|
+
init_chunk_I2JUTTPH,
|
|
4
4
|
init_chunk_MUWJHO2S
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-Y4T6ENKQ.js";
|
|
6
6
|
import "./chunk-OH3NXXUY.js";
|
|
7
7
|
import "./chunk-H2ZJOJ7A.js";
|
|
8
8
|
import {
|
|
@@ -12,15 +12,15 @@ import {
|
|
|
12
12
|
__esm
|
|
13
13
|
} from "./chunk-KFQGP6VL.js";
|
|
14
14
|
|
|
15
|
-
// ../core/dist/analyzer-
|
|
16
|
-
var
|
|
17
|
-
"../core/dist/analyzer-
|
|
18
|
-
|
|
15
|
+
// ../core/dist/analyzer-H3AHBFSL.mjs
|
|
16
|
+
var init_analyzer_H3AHBFSL = __esm({
|
|
17
|
+
"../core/dist/analyzer-H3AHBFSL.mjs"() {
|
|
18
|
+
init_chunk_I2JUTTPH();
|
|
19
19
|
init_chunk_MUWJHO2S();
|
|
20
20
|
init_chunk_7P6ASYW6();
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
|
-
|
|
23
|
+
init_analyzer_H3AHBFSL();
|
|
24
24
|
export {
|
|
25
25
|
EntropyAnalyzer
|
|
26
26
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
checkDependenciesDefinition,
|
|
3
3
|
handleCheckDependencies
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-GGSNWH7P.js";
|
|
5
|
+
import "./chunk-VSIRUZQP.js";
|
|
6
6
|
import "./chunk-RC3OI5NK.js";
|
|
7
7
|
import "./chunk-W6Y7ZW3Y.js";
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-WZY5U6NS.js";
|
|
9
|
+
import "./chunk-Y4T6ENKQ.js";
|
|
10
10
|
import "./chunk-OH3NXXUY.js";
|
|
11
11
|
import "./chunk-H2ZJOJ7A.js";
|
|
12
12
|
import "./chunk-QCLOIUMX.js";
|
package/dist/bin/harness-mcp.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startServer
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-7PLIWP7U.js";
|
|
5
|
+
import "../chunk-CZPOPMMI.js";
|
|
6
|
+
import "../chunk-KN3EMDZ5.js";
|
|
7
|
+
import "../chunk-VI4IS55S.js";
|
|
8
|
+
import "../chunk-LYIPI2SJ.js";
|
|
9
|
+
import "../chunk-FEKBXX2J.js";
|
|
10
10
|
import "../chunk-IOW3MW2K.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-Z3TMCCZB.js";
|
|
12
12
|
import "../chunk-3ISINLYT.js";
|
|
13
13
|
import "../chunk-TIH53QXY.js";
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-7AF6C5GE.js";
|
|
15
|
+
import "../chunk-GGSNWH7P.js";
|
|
16
|
+
import "../chunk-VSIRUZQP.js";
|
|
17
|
+
import "../chunk-NIVWM7OW.js";
|
|
18
18
|
import "../chunk-RC3OI5NK.js";
|
|
19
19
|
import "../chunk-W6Y7ZW3Y.js";
|
|
20
20
|
import "../chunk-27AJKSQY.js";
|
|
21
21
|
import "../chunk-6B6UN6SG.js";
|
|
22
22
|
import "../chunk-HIK6OEUF.js";
|
|
23
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-FXZI6NJ2.js";
|
|
24
24
|
import "../chunk-ZCZD7FHU.js";
|
|
25
25
|
import "../chunk-EBJQ6N4M.js";
|
|
26
26
|
import "../chunk-3WGJMBKH.js";
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
27
|
+
import "../chunk-WZY5U6NS.js";
|
|
28
|
+
import "../chunk-Y4T6ENKQ.js";
|
|
29
29
|
import "../chunk-OH3NXXUY.js";
|
|
30
30
|
import "../chunk-H2ZJOJ7A.js";
|
|
31
31
|
import "../chunk-QCLOIUMX.js";
|
package/dist/bin/harness.js
CHANGED
|
@@ -3,38 +3,38 @@ import {
|
|
|
3
3
|
createProgram,
|
|
4
4
|
installCommandTelemetry,
|
|
5
5
|
printFirstRunWelcome
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-LGYXR2KZ.js";
|
|
7
|
+
import "../chunk-N5NSSLMU.js";
|
|
8
|
+
import "../chunk-LECXPXS3.js";
|
|
9
|
+
import "../chunk-RJ2WEES5.js";
|
|
10
|
+
import "../chunk-O2ASYKA6.js";
|
|
11
|
+
import "../chunk-INBTDBV2.js";
|
|
12
12
|
import "../chunk-KET4QQZB.js";
|
|
13
13
|
import "../chunk-6UHDQP2N.js";
|
|
14
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-B2VAYLYI.js";
|
|
15
15
|
import "../chunk-CQ553GZO.js";
|
|
16
16
|
import "../chunk-ZP5E7YET.js";
|
|
17
|
-
import "../chunk-
|
|
17
|
+
import "../chunk-PTHX545Q.js";
|
|
18
18
|
import "../chunk-GISMXMVL.js";
|
|
19
19
|
import "../chunk-WWACIIBA.js";
|
|
20
20
|
import "../chunk-TEFCFC4H.js";
|
|
21
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-FC4JPM6W.js";
|
|
22
22
|
import {
|
|
23
23
|
dispatchSkillsFromGit
|
|
24
|
-
} from "../chunk-
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
29
|
-
import "../chunk-
|
|
24
|
+
} from "../chunk-7PLIWP7U.js";
|
|
25
|
+
import "../chunk-CZPOPMMI.js";
|
|
26
|
+
import "../chunk-KN3EMDZ5.js";
|
|
27
|
+
import "../chunk-VI4IS55S.js";
|
|
28
|
+
import "../chunk-LYIPI2SJ.js";
|
|
29
|
+
import "../chunk-FEKBXX2J.js";
|
|
30
30
|
import "../chunk-IOW3MW2K.js";
|
|
31
|
-
import "../chunk-
|
|
31
|
+
import "../chunk-Z3TMCCZB.js";
|
|
32
32
|
import "../chunk-3ISINLYT.js";
|
|
33
33
|
import "../chunk-TIH53QXY.js";
|
|
34
|
-
import "../chunk-
|
|
35
|
-
import "../chunk-
|
|
36
|
-
import "../chunk-
|
|
37
|
-
import "../chunk-
|
|
34
|
+
import "../chunk-7AF6C5GE.js";
|
|
35
|
+
import "../chunk-GGSNWH7P.js";
|
|
36
|
+
import "../chunk-VSIRUZQP.js";
|
|
37
|
+
import "../chunk-NIVWM7OW.js";
|
|
38
38
|
import "../chunk-RC3OI5NK.js";
|
|
39
39
|
import "../chunk-W6Y7ZW3Y.js";
|
|
40
40
|
import "../chunk-27AJKSQY.js";
|
|
@@ -43,7 +43,7 @@ import "../chunk-HIK6OEUF.js";
|
|
|
43
43
|
import {
|
|
44
44
|
findConfigFile,
|
|
45
45
|
loadConfig
|
|
46
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-FXZI6NJ2.js";
|
|
47
47
|
import "../chunk-ZCZD7FHU.js";
|
|
48
48
|
import "../chunk-EBJQ6N4M.js";
|
|
49
49
|
import {
|
|
@@ -56,11 +56,11 @@ import {
|
|
|
56
56
|
readCheckState,
|
|
57
57
|
shouldRunCheck,
|
|
58
58
|
spawnBackgroundCheck
|
|
59
|
-
} from "../chunk-
|
|
59
|
+
} from "../chunk-WZY5U6NS.js";
|
|
60
60
|
import {
|
|
61
61
|
CLI_VERSION
|
|
62
62
|
} from "../chunk-BM3PWGXQ.js";
|
|
63
|
-
import "../chunk-
|
|
63
|
+
import "../chunk-Y4T6ENKQ.js";
|
|
64
64
|
import "../chunk-OH3NXXUY.js";
|
|
65
65
|
import "../chunk-H2ZJOJ7A.js";
|
|
66
66
|
import "../chunk-QCLOIUMX.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createCheckPhaseGateCommand,
|
|
3
3
|
runCheckPhaseGate
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-FC4JPM6W.js";
|
|
5
|
+
import "./chunk-FXZI6NJ2.js";
|
|
6
6
|
import "./chunk-ZCZD7FHU.js";
|
|
7
7
|
import "./chunk-EBJQ6N4M.js";
|
|
8
8
|
import "./chunk-3WGJMBKH.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-WZY5U6NS.js";
|
|
10
|
+
import "./chunk-Y4T6ENKQ.js";
|
|
11
11
|
import "./chunk-OH3NXXUY.js";
|
|
12
12
|
import "./chunk-H2ZJOJ7A.js";
|
|
13
13
|
import "./chunk-QCLOIUMX.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveProjectConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VSIRUZQP.js";
|
|
4
4
|
import {
|
|
5
5
|
sanitizePath
|
|
6
6
|
} from "./chunk-W6Y7ZW3Y.js";
|
|
@@ -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-
|
|
52
|
+
const core = await import("./dist-72ID44UE.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-
|
|
71
|
+
const core = await import("./dist-72ID44UE.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);
|