@harness-engineering/cli 1.25.2 → 1.25.3

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startServer
4
- } from "../chunk-TBGIHPNA.js";
4
+ } from "../chunk-IAMXXLUT.js";
5
5
  import "../chunk-FES2YEQU.js";
6
6
  import "../chunk-UV3BZMGT.js";
7
7
  import "../chunk-F23H3U5U.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  createProgram,
4
4
  printFirstRunWelcome
5
- } from "../chunk-5I3W4J5X.js";
5
+ } from "../chunk-6WFSSYZG.js";
6
6
  import "../chunk-5BQ5BOJL.js";
7
7
  import "../chunk-EHRZMOQ2.js";
8
8
  import "../chunk-XTITAVUR.js";
@@ -19,7 +19,7 @@ import "../chunk-P7PANON5.js";
19
19
  import "../chunk-4NK7Z3BP.js";
20
20
  import {
21
21
  dispatchSkillsFromGit
22
- } from "../chunk-TBGIHPNA.js";
22
+ } from "../chunk-IAMXXLUT.js";
23
23
  import "../chunk-FES2YEQU.js";
24
24
  import "../chunk-UV3BZMGT.js";
25
25
  import "../chunk-F23H3U5U.js";
@@ -56,7 +56,7 @@ import {
56
56
  loadOrRebuildIndex,
57
57
  persistToolingConfig,
58
58
  recommend
59
- } from "./chunk-TBGIHPNA.js";
59
+ } from "./chunk-IAMXXLUT.js";
60
60
  import {
61
61
  findConfigFile,
62
62
  resolveConfig
@@ -5423,7 +5423,7 @@ function createMcpCommand() {
5423
5423
  parseBudget
5424
5424
  ).action(async (opts) => {
5425
5425
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
5426
- import("./mcp-W3FLXSFF.js"),
5426
+ import("./mcp-PMMA53ZX.js"),
5427
5427
  import("./tool-tiers-7QGZ3FKY.js")
5428
5428
  ]);
5429
5429
  if (opts.tools && opts.tools.length > 0) {
@@ -5449,7 +5449,7 @@ import * as path39 from "path";
5449
5449
  import { Orchestrator, WorkflowLoader, launchTUI } from "@harness-engineering/orchestrator";
5450
5450
  function createOrchestratorCommand() {
5451
5451
  const orchestrator = new Command47("orchestrator");
5452
- orchestrator.command("run").description("Run the orchestrator daemon").option("-w, --workflow <path>", "Path to WORKFLOW.md", "WORKFLOW.md").option("--headless", "Run without TUI (server-only mode for use with web dashboard)").action(async (opts) => {
5452
+ orchestrator.command("run").description("Run the orchestrator daemon").option("-w, --workflow <path>", "Path to harness.orchestrator.md", "harness.orchestrator.md").option("--headless", "Run without TUI (server-only mode for use with web dashboard)").action(async (opts) => {
5453
5453
  const workflowPath = path39.resolve(process.cwd(), opts.workflow);
5454
5454
  const loader = new WorkflowLoader();
5455
5455
  const result = await loader.loadWorkflow(workflowPath);
@@ -122,6 +122,203 @@ import {
122
122
  ReadResourceRequestSchema
123
123
  } from "@modelcontextprotocol/sdk/types.js";
124
124
 
125
+ // src/templates/post-write.ts
126
+ import * as fs from "fs";
127
+ import * as path from "path";
128
+
129
+ // src/templates/agents-append.ts
130
+ var FRAMEWORK_SECTIONS = {
131
+ nextjs: {
132
+ title: "Next.js Conventions",
133
+ content: [
134
+ "- Use the App Router (`src/app/`) for all routes",
135
+ '- Server Components by default; add `"use client"` only when needed',
136
+ "- Use `next/image` for images and `next/link` for navigation",
137
+ "- API routes go in `src/app/api/`",
138
+ "- Run `next dev` for development, `next build` for production"
139
+ ].join("\n")
140
+ },
141
+ "react-vite": {
142
+ title: "React + Vite Conventions",
143
+ content: [
144
+ "- Component files use `.tsx` extension in `src/`",
145
+ "- Use Vite for dev server and bundling (`npm run dev`)",
146
+ "- Prefer function components with hooks",
147
+ "- CSS modules or styled-components for styling",
148
+ "- Tests use Vitest (`npm test`)"
149
+ ].join("\n")
150
+ },
151
+ vue: {
152
+ title: "Vue Conventions",
153
+ content: [
154
+ "- Single File Components (`.vue`) in `src/`",
155
+ "- Use `<script setup>` with Composition API",
156
+ "- Vite for dev server and bundling (`npm run dev`)",
157
+ "- Vue Router for routing, Pinia for state management",
158
+ "- Tests use Vitest (`npm test`)"
159
+ ].join("\n")
160
+ },
161
+ express: {
162
+ title: "Express Conventions",
163
+ content: [
164
+ "- Entry point at `src/app.ts`",
165
+ "- Routes in `src/routes/`, middleware in `src/middleware/`",
166
+ "- Use `express.json()` for body parsing",
167
+ "- Error handling via centralized error middleware",
168
+ "- Tests use Vitest with supertest (`npm test`)"
169
+ ].join("\n")
170
+ },
171
+ nestjs: {
172
+ title: "NestJS Conventions",
173
+ content: [
174
+ "- Module-based architecture: each feature in its own module",
175
+ "- Use decorators (`@Controller`, `@Injectable`, `@Module`)",
176
+ "- Entry point at `src/main.ts`, root module at `src/app.module.ts`",
177
+ "- Use Nest CLI for generating components (`nest g`)",
178
+ "- Tests use Vitest (`npm test`)"
179
+ ].join("\n")
180
+ },
181
+ fastapi: {
182
+ title: "FastAPI Conventions",
183
+ content: [
184
+ "- Entry point at `src/main.py` with FastAPI app instance",
185
+ "- Use Pydantic models for request/response validation",
186
+ "- Async endpoints preferred; sync is acceptable for CPU-bound work",
187
+ "- Run with `uvicorn src.main:app --reload` for development",
188
+ "- Tests use pytest (`pytest`)"
189
+ ].join("\n")
190
+ },
191
+ django: {
192
+ title: "Django Conventions",
193
+ content: [
194
+ "- Settings at `src/settings.py`, URLs at `src/urls.py`",
195
+ "- Use `manage.py` for management commands",
196
+ "- Apps in `src/` directory; each app has models, views, urls",
197
+ "- Run with `python manage.py runserver` for development",
198
+ "- Tests use pytest with pytest-django (`pytest`)"
199
+ ].join("\n")
200
+ },
201
+ gin: {
202
+ title: "Gin Conventions",
203
+ content: [
204
+ "- Entry point at `main.go` with Gin router setup",
205
+ "- Group routes by feature using `router.Group()`",
206
+ "- Use middleware for logging, auth, error recovery",
207
+ "- Run with `go run main.go` for development",
208
+ "- Tests use `go test ./...`"
209
+ ].join("\n")
210
+ },
211
+ axum: {
212
+ title: "Axum Conventions",
213
+ content: [
214
+ "- Entry point at `src/main.rs` with Axum router",
215
+ "- Use extractors for request parsing (`Path`, `Query`, `Json`)",
216
+ "- Shared state via `Extension` or `State`",
217
+ "- Run with `cargo run` for development",
218
+ "- Tests use `cargo test`"
219
+ ].join("\n")
220
+ },
221
+ "spring-boot": {
222
+ title: "Spring Boot Conventions",
223
+ content: [
224
+ "- Entry point annotated with `@SpringBootApplication`",
225
+ "- Controllers in `controller/` package, services in `service/`",
226
+ "- Use constructor injection for dependencies",
227
+ "- Run with `mvn spring-boot:run` for development",
228
+ "- Tests use JUnit 5 with Spring Boot Test (`mvn test`)"
229
+ ].join("\n")
230
+ }
231
+ };
232
+ function buildFrameworkSection(framework) {
233
+ const entry = FRAMEWORK_SECTIONS[framework];
234
+ if (!entry) return "";
235
+ return `## ${entry.title}
236
+
237
+ <!-- framework: ${framework} -->
238
+ ${entry.content}
239
+ `;
240
+ }
241
+ function appendFrameworkSection(existingContent, framework, _language) {
242
+ if (!framework) return existingContent;
243
+ const startMarker = `<!-- harness:framework-conventions:${framework} -->`;
244
+ const endMarker = `<!-- /harness:framework-conventions:${framework} -->`;
245
+ if (existingContent.includes(startMarker)) return existingContent;
246
+ const section = buildFrameworkSection(framework);
247
+ if (!section) return existingContent;
248
+ const block = `
249
+ ${startMarker}
250
+ ${section}${endMarker}
251
+ `;
252
+ return existingContent.trimEnd() + "\n" + block;
253
+ }
254
+
255
+ // src/templates/post-write.ts
256
+ function persistToolingConfig(targetDir, resolveResult, framework) {
257
+ const configPath = path.join(targetDir, "harness.config.json");
258
+ if (!fs.existsSync(configPath)) return;
259
+ try {
260
+ const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
261
+ const overlayMeta = resolveResult.overlayMetadata;
262
+ if (framework) {
263
+ config.template = config.template || {};
264
+ config.template.framework = framework;
265
+ }
266
+ if (overlayMeta?.tooling) {
267
+ config.tooling = { ...config.tooling, ...overlayMeta.tooling };
268
+ delete config.tooling.lockFile;
269
+ } else if (resolveResult.metadata.tooling && !config.tooling) {
270
+ config.tooling = { ...resolveResult.metadata.tooling };
271
+ delete config.tooling.lockFile;
272
+ }
273
+ if (config.template?.level === null || config.template?.level === void 0) {
274
+ delete config.template.level;
275
+ }
276
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
277
+ } catch {
278
+ }
279
+ }
280
+ function ensureHarnessGitignore(targetDir) {
281
+ const gitignorePath = path.join(targetDir, ".harness", ".gitignore");
282
+ const content = `# Runtime artifacts (generated, ephemeral, session-scoped)
283
+ graph/
284
+ debug/
285
+ hooks/
286
+ security/
287
+ sessions/
288
+ state.json
289
+ state/
290
+ handoff.json
291
+ handoff-*.json
292
+ autopilot-state.json
293
+ session-taint-*.json
294
+ dispatch-last-head.txt
295
+ health-snapshot.json
296
+ release-readiness.json
297
+ skills-index.json
298
+ stack-profile.json
299
+ metrics/
300
+ events.jsonl
301
+ .install-id
302
+ telemetry.json
303
+ .telemetry-notice-shown
304
+ `;
305
+ fs.mkdirSync(path.dirname(gitignorePath), { recursive: true });
306
+ fs.writeFileSync(gitignorePath, content);
307
+ }
308
+ function appendFrameworkAgents(targetDir, framework, language) {
309
+ if (!framework) return;
310
+ const agentsPath = path.join(targetDir, "AGENTS.md");
311
+ if (!fs.existsSync(agentsPath)) return;
312
+ try {
313
+ const existing = fs.readFileSync(agentsPath, "utf-8");
314
+ const updated = appendFrameworkSection(existing, framework, language);
315
+ if (updated !== existing) {
316
+ fs.writeFileSync(agentsPath, updated);
317
+ }
318
+ } catch {
319
+ }
320
+ }
321
+
125
322
  // src/mcp/middleware/injection-guard.ts
126
323
  init_dist();
127
324
  import { realpathSync } from "fs";
@@ -402,206 +599,6 @@ async function handleValidateLinterConfig(input) {
402
599
  // src/mcp/tools/init.ts
403
600
  import * as path2 from "path";
404
601
  import * as fs2 from "fs";
405
-
406
- // src/templates/post-write.ts
407
- import * as fs from "fs";
408
- import * as path from "path";
409
-
410
- // src/templates/agents-append.ts
411
- var FRAMEWORK_SECTIONS = {
412
- nextjs: {
413
- title: "Next.js Conventions",
414
- content: [
415
- "- Use the App Router (`src/app/`) for all routes",
416
- '- Server Components by default; add `"use client"` only when needed',
417
- "- Use `next/image` for images and `next/link` for navigation",
418
- "- API routes go in `src/app/api/`",
419
- "- Run `next dev` for development, `next build` for production"
420
- ].join("\n")
421
- },
422
- "react-vite": {
423
- title: "React + Vite Conventions",
424
- content: [
425
- "- Component files use `.tsx` extension in `src/`",
426
- "- Use Vite for dev server and bundling (`npm run dev`)",
427
- "- Prefer function components with hooks",
428
- "- CSS modules or styled-components for styling",
429
- "- Tests use Vitest (`npm test`)"
430
- ].join("\n")
431
- },
432
- vue: {
433
- title: "Vue Conventions",
434
- content: [
435
- "- Single File Components (`.vue`) in `src/`",
436
- "- Use `<script setup>` with Composition API",
437
- "- Vite for dev server and bundling (`npm run dev`)",
438
- "- Vue Router for routing, Pinia for state management",
439
- "- Tests use Vitest (`npm test`)"
440
- ].join("\n")
441
- },
442
- express: {
443
- title: "Express Conventions",
444
- content: [
445
- "- Entry point at `src/app.ts`",
446
- "- Routes in `src/routes/`, middleware in `src/middleware/`",
447
- "- Use `express.json()` for body parsing",
448
- "- Error handling via centralized error middleware",
449
- "- Tests use Vitest with supertest (`npm test`)"
450
- ].join("\n")
451
- },
452
- nestjs: {
453
- title: "NestJS Conventions",
454
- content: [
455
- "- Module-based architecture: each feature in its own module",
456
- "- Use decorators (`@Controller`, `@Injectable`, `@Module`)",
457
- "- Entry point at `src/main.ts`, root module at `src/app.module.ts`",
458
- "- Use Nest CLI for generating components (`nest g`)",
459
- "- Tests use Vitest (`npm test`)"
460
- ].join("\n")
461
- },
462
- fastapi: {
463
- title: "FastAPI Conventions",
464
- content: [
465
- "- Entry point at `src/main.py` with FastAPI app instance",
466
- "- Use Pydantic models for request/response validation",
467
- "- Async endpoints preferred; sync is acceptable for CPU-bound work",
468
- "- Run with `uvicorn src.main:app --reload` for development",
469
- "- Tests use pytest (`pytest`)"
470
- ].join("\n")
471
- },
472
- django: {
473
- title: "Django Conventions",
474
- content: [
475
- "- Settings at `src/settings.py`, URLs at `src/urls.py`",
476
- "- Use `manage.py` for management commands",
477
- "- Apps in `src/` directory; each app has models, views, urls",
478
- "- Run with `python manage.py runserver` for development",
479
- "- Tests use pytest with pytest-django (`pytest`)"
480
- ].join("\n")
481
- },
482
- gin: {
483
- title: "Gin Conventions",
484
- content: [
485
- "- Entry point at `main.go` with Gin router setup",
486
- "- Group routes by feature using `router.Group()`",
487
- "- Use middleware for logging, auth, error recovery",
488
- "- Run with `go run main.go` for development",
489
- "- Tests use `go test ./...`"
490
- ].join("\n")
491
- },
492
- axum: {
493
- title: "Axum Conventions",
494
- content: [
495
- "- Entry point at `src/main.rs` with Axum router",
496
- "- Use extractors for request parsing (`Path`, `Query`, `Json`)",
497
- "- Shared state via `Extension` or `State`",
498
- "- Run with `cargo run` for development",
499
- "- Tests use `cargo test`"
500
- ].join("\n")
501
- },
502
- "spring-boot": {
503
- title: "Spring Boot Conventions",
504
- content: [
505
- "- Entry point annotated with `@SpringBootApplication`",
506
- "- Controllers in `controller/` package, services in `service/`",
507
- "- Use constructor injection for dependencies",
508
- "- Run with `mvn spring-boot:run` for development",
509
- "- Tests use JUnit 5 with Spring Boot Test (`mvn test`)"
510
- ].join("\n")
511
- }
512
- };
513
- function buildFrameworkSection(framework) {
514
- const entry = FRAMEWORK_SECTIONS[framework];
515
- if (!entry) return "";
516
- return `## ${entry.title}
517
-
518
- <!-- framework: ${framework} -->
519
- ${entry.content}
520
- `;
521
- }
522
- function appendFrameworkSection(existingContent, framework, _language) {
523
- if (!framework) return existingContent;
524
- const startMarker = `<!-- harness:framework-conventions:${framework} -->`;
525
- const endMarker = `<!-- /harness:framework-conventions:${framework} -->`;
526
- if (existingContent.includes(startMarker)) return existingContent;
527
- const section = buildFrameworkSection(framework);
528
- if (!section) return existingContent;
529
- const block = `
530
- ${startMarker}
531
- ${section}${endMarker}
532
- `;
533
- return existingContent.trimEnd() + "\n" + block;
534
- }
535
-
536
- // src/templates/post-write.ts
537
- function persistToolingConfig(targetDir, resolveResult, framework) {
538
- const configPath = path.join(targetDir, "harness.config.json");
539
- if (!fs.existsSync(configPath)) return;
540
- try {
541
- const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
542
- const overlayMeta = resolveResult.overlayMetadata;
543
- if (framework) {
544
- config.template = config.template || {};
545
- config.template.framework = framework;
546
- }
547
- if (overlayMeta?.tooling) {
548
- config.tooling = { ...config.tooling, ...overlayMeta.tooling };
549
- delete config.tooling.lockFile;
550
- } else if (resolveResult.metadata.tooling && !config.tooling) {
551
- config.tooling = { ...resolveResult.metadata.tooling };
552
- delete config.tooling.lockFile;
553
- }
554
- if (config.template?.level === null || config.template?.level === void 0) {
555
- delete config.template.level;
556
- }
557
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
558
- } catch {
559
- }
560
- }
561
- function ensureHarnessGitignore(targetDir) {
562
- const gitignorePath = path.join(targetDir, ".harness", ".gitignore");
563
- if (fs.existsSync(gitignorePath)) return;
564
- const content = `# Runtime artifacts (generated, ephemeral, session-scoped)
565
- graph/
566
- debug/
567
- hooks/
568
- security/
569
- sessions/
570
- state.json
571
- state/
572
- handoff.json
573
- handoff-*.json
574
- autopilot-state.json
575
- session-taint-*.json
576
- dispatch-last-head.txt
577
- health-snapshot.json
578
- release-readiness.json
579
- skills-index.json
580
- stack-profile.json
581
- metrics/
582
- events.jsonl
583
- .install-id
584
- telemetry.json
585
- .telemetry-notice-shown
586
- `;
587
- fs.mkdirSync(path.dirname(gitignorePath), { recursive: true });
588
- fs.writeFileSync(gitignorePath, content);
589
- }
590
- function appendFrameworkAgents(targetDir, framework, language) {
591
- if (!framework) return;
592
- const agentsPath = path.join(targetDir, "AGENTS.md");
593
- if (!fs.existsSync(agentsPath)) return;
594
- try {
595
- const existing = fs.readFileSync(agentsPath, "utf-8");
596
- const updated = appendFrameworkSection(existing, framework, language);
597
- if (updated !== existing) {
598
- fs.writeFileSync(agentsPath, updated);
599
- }
600
- } catch {
601
- }
602
- }
603
-
604
- // src/mcp/tools/init.ts
605
602
  var initProjectDefinition = {
606
603
  name: "init_project",
607
604
  description: "Scaffold a new harness engineering project from a template",
@@ -7514,6 +7511,7 @@ async function handleReadResource(uri, resolvedRoot) {
7514
7511
  }
7515
7512
  function createHarnessServer(projectRoot, toolFilter) {
7516
7513
  const resolvedRoot = projectRoot ?? process.cwd();
7514
+ ensureHarnessGitignore(resolvedRoot);
7517
7515
  const { definitions, handlers } = buildFilteredTools(toolFilter);
7518
7516
  const trustedOutputTools = new Set(
7519
7517
  definitions.filter((t) => t.trustedOutput === true).map((t) => t.name)
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  runSnapshotCapture,
13
13
  runUninstall,
14
14
  runUninstallConstraints
15
- } from "./chunk-5I3W4J5X.js";
15
+ } from "./chunk-6WFSSYZG.js";
16
16
  import {
17
17
  generateAgentsMd
18
18
  } from "./chunk-5BQ5BOJL.js";
@@ -66,7 +66,7 @@ import {
66
66
  generateSlashCommands,
67
67
  getToolDefinitions,
68
68
  startServer
69
- } from "./chunk-TBGIHPNA.js";
69
+ } from "./chunk-IAMXXLUT.js";
70
70
  import "./chunk-FES2YEQU.js";
71
71
  import "./chunk-UV3BZMGT.js";
72
72
  import "./chunk-F23H3U5U.js";
@@ -2,7 +2,7 @@ import {
2
2
  createHarnessServer,
3
3
  getToolDefinitions,
4
4
  startServer
5
- } from "./chunk-TBGIHPNA.js";
5
+ } from "./chunk-IAMXXLUT.js";
6
6
  import "./chunk-FES2YEQU.js";
7
7
  import "./chunk-UV3BZMGT.js";
8
8
  import "./chunk-F23H3U5U.js";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orchestrator",
3
- "description": "Standard WORKFLOW.md for the Harness Orchestrator",
3
+ "description": "Standard harness.orchestrator.md for the Harness Orchestrator",
4
4
  "level": "basic",
5
5
  "extends": "base",
6
6
  "version": 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harness-engineering/cli",
3
- "version": "1.25.2",
3
+ "version": "1.25.3",
4
4
  "description": "CLI for Harness Engineering toolkit",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,11 +38,11 @@
38
38
  "yaml": "^2.8.3",
39
39
  "zod": "^3.25.76",
40
40
  "@harness-engineering/core": "0.22.0",
41
- "@harness-engineering/dashboard": "0.1.5",
42
41
  "@harness-engineering/graph": "0.4.3",
43
42
  "@harness-engineering/linter-gen": "0.1.6",
44
- "@harness-engineering/orchestrator": "0.2.8",
45
- "@harness-engineering/types": "0.9.2"
43
+ "@harness-engineering/orchestrator": "0.2.9",
44
+ "@harness-engineering/types": "0.9.2",
45
+ "@harness-engineering/dashboard": "0.1.5"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/node": "^22.19.15",