harness-everything 0.20.2 → 0.20.4

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.
@@ -10,7 +10,7 @@
10
10
  "name": "harness-everything",
11
11
  "source": "./",
12
12
  "description": "Harness OS: an orchestrated agent operating system — tier routing, circuit breaker guardrails, verification gates, WAL session memory, and self-evolving workspace rules.",
13
- "version": "0.20.2",
13
+ "version": "0.20.4",
14
14
  "author": {
15
15
  "name": "Miya Daniel"
16
16
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "harness-everything",
3
3
  "description": "Harness OS: an orchestrated agent operating system — tier routing, circuit breaker guardrails, verification gates, WAL session memory, and self-evolving workspace rules.",
4
- "version": "0.20.2",
4
+ "version": "0.20.4",
5
5
  "author": {
6
6
  "name": "Miya Daniel"
7
7
  },
@@ -68,3 +68,11 @@ jobs:
68
68
  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
69
69
  NPM_CONFIG_PROVENANCE: "true"
70
70
  run: npx --no-install semantic-release
71
+
72
+ - name: Upload release SBOM artifact
73
+ if: ${{ hashFiles('sbom.cdx.json') != '' }}
74
+ uses: actions/upload-artifact@v4
75
+ with:
76
+ name: release-sbom
77
+ path: sbom.cdx.json
78
+ if-no-files-found: error
package/.releaserc.json CHANGED
@@ -103,6 +103,12 @@
103
103
  [
104
104
  "@semantic-release/github",
105
105
  {
106
+ "assets": [
107
+ {
108
+ "path": "sbom.cdx.json",
109
+ "label": "CycloneDX SBOM"
110
+ }
111
+ ],
106
112
  "successComment": false,
107
113
  "failTitle": false,
108
114
  "labels": false,
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## [0.20.4](https://github.com/dyphn1/Harness-everything/compare/v0.20.3...v0.20.4) (2026-09-22)
6
+
7
+ ### Bug Fixes
8
+
9
+ * **release:** publish sbom release artifacts ([83eeb96](https://github.com/dyphn1/Harness-everything/commit/83eeb96c1746ccbffcdcba478ba6b54c522887a0)), closes [#222](https://github.com/dyphn1/Harness-everything/issues/222)
10
+
11
+ ## [0.20.3](https://github.com/dyphn1/Harness-everything/compare/v0.20.2...v0.20.3) (2026-09-22)
12
+
13
+ ### Bug Fixes
14
+
15
+ * **distribution:** support windows cli shims ([f634e6d](https://github.com/dyphn1/Harness-everything/commit/f634e6d84fd8d0751604efa1d9b8acd5e7d90b8b)), closes [#221](https://github.com/dyphn1/Harness-everything/issues/221)
16
+
5
17
  ## [0.20.2](https://github.com/dyphn1/Harness-everything/compare/v0.20.1...v0.20.2) (2026-09-22)
6
18
 
7
19
  ### Bug Fixes
package/RELEASING.md CHANGED
@@ -40,9 +40,9 @@ A push to `main` runs the full reusable CI gate and then semantic-release. A man
40
40
  6. Run `scripts/sync-release-version.js` to synchronize package, Claude, OpenAI/Codex, OpenCode, lockfile, and changed canonical skill version fields.
41
41
  7. Regenerate and verify plugin packages, then generate and validate the release-only `sbom.cdx.json` CycloneDX 1.7 file.
42
42
  8. Update `CHANGELOG.md` and create `chore(release): X.Y.Z [skip ci]`.
43
- 9. Create tag `vX.Y.Z`, publish npm with provenance (including the generated SBOM), and create the GitHub Release.
43
+ 9. Create tag `vX.Y.Z`, publish npm with provenance (including the generated SBOM), create the GitHub Release with the SBOM attached, and retain the same file as an Actions artifact.
44
44
 
45
- The SBOM is generated from the release `package.json`/`package-lock.json` as CycloneDX 1.7, the current 1.x format, to satisfy consumers and regulatory baselines requiring CycloneDX 1.6 or later. It is intentionally not committed to Git. npm packaging is tested to ensure `sbom.cdx.json` is included in the published tarball.
45
+ The SBOM is generated from the release `package.json`/`package-lock.json` as CycloneDX 1.7, the current 1.x format, to satisfy consumers and regulatory baselines requiring CycloneDX 1.6 or later. It is intentionally not committed to Git. The release publishes `sbom.cdx.json` in the npm tarball and as a GitHub Release asset, while the workflow also retains it as an Actions artifact.
46
46
 
47
47
  Release concurrency is serialized so two updates to `main` cannot publish competing versions.
48
48
 
@@ -90,7 +90,8 @@ The release workflow runs the reusable CI gate before semantic-release. After pu
90
90
  ```text
91
91
  gh run list --workflow release.yml --limit 5
92
92
  gh run view <run-id> --json conclusion,headSha,jobs
93
- gh release view v<version> --json tagName,publishedAt,url
93
+ gh release view v<version> --json tagName,publishedAt,url,assets
94
+ gh run view <run-id> --json conclusion,headSha,jobs,artifacts
94
95
  npm view harness-everything version dist-tags --json
95
96
  ```
96
97
 
@@ -2,8 +2,10 @@
2
2
 
3
3
  const assert = require('assert');
4
4
  const fs = require('fs');
5
+ const os = require('os');
5
6
  const path = require('path');
6
7
  const {
8
+ createContext,
7
9
  findMarketplace,
8
10
  findPlugin,
9
11
  parseJsonOutput,
@@ -178,6 +180,21 @@ assert.strictEqual(findPlugin({ plugins: [{ id: 'harness-everything@harness-ever
178
180
  assert.strictEqual(result.failed, 0);
179
181
  }
180
182
 
183
+ if (process.platform === 'win32') {
184
+ const fixtureDir = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-plugin-sync-command-'));
185
+ const originalPath = process.env.PATH;
186
+ try {
187
+ fs.writeFileSync(path.join(fixtureDir, 'harness-codex-fixture.cmd'), '@echo off\r\necho codex-cli fixture\r\n');
188
+ process.env.PATH = `${fixtureDir};${originalPath || ''}`;
189
+ const context = createContext();
190
+ assert.strictEqual(context.commandAvailable('harness-codex-fixture'), true, 'Windows .cmd CLI shims must be detected');
191
+ } finally {
192
+ if (originalPath === undefined) delete process.env.PATH;
193
+ else process.env.PATH = originalPath;
194
+ fs.rmSync(fixtureDir, { recursive: true, force: true });
195
+ }
196
+ }
197
+
181
198
  for (const wrapper of ['scripts/plugin-sync.sh', 'scripts/plugin-sync.ps1']) {
182
199
  const text = fs.readFileSync(path.join(ROOT, wrapper), 'utf8');
183
200
  assert.match(text, /plugin-sync\.js/);
@@ -24,6 +24,22 @@ assert.ok(execPlugin, 'semantic-release exec plugin is required for SBOM generat
24
24
  assert.match(execPlugin[1].prepareCmd, /generate-sbom\.js --output sbom\.cdx\.json --version \$\{nextRelease\.version\}/);
25
25
  assert.match(execPlugin[1].prepareCmd, /generate-sbom\.js --validate sbom\.cdx\.json --version \$\{nextRelease\.version\}/);
26
26
 
27
+ const githubPlugin = releaseConfig.plugins.find(plugin => Array.isArray(plugin) && plugin[0] === '@semantic-release/github');
28
+ assert.ok(githubPlugin, 'semantic-release github plugin is required for release publication');
29
+ assert.ok(Array.isArray(githubPlugin[1].assets), 'GitHub Release assets must be configured');
30
+ assert.ok(
31
+ githubPlugin[1].assets.some(asset => asset && typeof asset === 'object' && asset.path === 'sbom.cdx.json'),
32
+ 'GitHub Release must publish the generated SBOM as an asset'
33
+ );
34
+
35
+ const releaseWorkflow = fs.readFileSync(path.join(ROOT, '.github/workflows/release.yml'), 'utf8');
36
+ assert.match(releaseWorkflow, /uses:\s+actions\/upload-artifact@v4/,
37
+ 'release workflow must retain the generated SBOM as an Actions artifact');
38
+ assert.match(releaseWorkflow, /if:\s+\$\{\{\s*hashFiles\('sbom\.cdx\.json'\)\s*!=\s*''\s*\}\}/,
39
+ 'release workflow must skip artifact upload when semantic-release has no release');
40
+ assert.match(releaseWorkflow, /path:\s+sbom\.cdx\.json/,
41
+ 'release workflow artifact must point at the generated SBOM');
42
+
27
43
  const bom = buildBom(ROOT, {
28
44
  version: packageJson.version,
29
45
  timestamp: '2026-09-21T00:00:00.000Z',
@@ -84,6 +84,8 @@ The command detects Claude Code and Codex independently, ensures the Harness mar
84
84
 
85
85
  The installed branch is intentionally an update branch even when the current release is already the newest version; the host command may report “already latest.” Codex marketplace upgrade is the current native refresh operation; the command does not edit private cache paths or `config.toml`. These are deterministic command/state tests, not live-host evidence, so `liveHostVerification` remains `Unknown` in the matrix.
86
86
 
87
+ On Windows, the synchronizer retries through `ComSpec` when Node cannot directly start a CLI shim, so npm-installed `codex.cmd` and `claude.cmd` commands remain discoverable when the wrapper is launched from Git Bash.
88
+
87
89
  ### Explicit Codex user-hook compatibility fallback
88
90
 
89
91
  Current Codex documentation supports plugin-bundled hooks, so native plugin mounting remains the preferred path. Some host/source combinations have nevertheless failed to expose enabled plugin hooks for review/entry attribution (#122 and upstream Codex reports). Harness therefore provides an **explicit compatibility fallback**, not an automatic replacement for native plugin hooks:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "harness-enforcement",
3
3
  "description": "Repository inventory for the opencode enforcement plugin and its standalone helper",
4
- "version": "0.20.2",
4
+ "version": "0.20.4",
5
5
  "runtime": "index.mjs",
6
6
  "hooks": {
7
7
  "verify": "hooks/verify.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harness-everything",
3
- "version": "0.20.2",
3
+ "version": "0.20.4",
4
4
  "description": "Harness OS: An Orchestrated Agent Operating System for AI-driven Development",
5
5
  "main": "harness-everything/scripts/bootstrap.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harness-everything",
3
- "version": "0.20.2",
3
+ "version": "0.20.4",
4
4
  "description": "Invariant-first engineering harness for routing, verification, and failure recovery while preserving agent autonomy.",
5
5
  "author": {
6
6
  "name": "Miya Daniel",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "harness-everything",
4
- "version": "0.20.2",
4
+ "version": "0.20.4",
5
5
  "description": "Invariant-first engineering harness for routing, verification, and failure recovery while preserving agent autonomy.",
6
6
  "author": {
7
7
  "name": "Miya Daniel",
package/sbom.cdx.json CHANGED
@@ -2,23 +2,23 @@
2
2
  "$schema": "https://cyclonedx.org/schema/bom-1.7.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.7",
5
- "serialNumber": "urn:uuid:338bfdd5-e2e1-5e75-b6b1-f114ba76e2f5",
5
+ "serialNumber": "urn:uuid:478ab7f0-6aaf-55ae-9e1a-9e950ea30f9d",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-09-22T01:26:05.707Z",
8
+ "timestamp": "2026-09-22T02:13:44.851Z",
9
9
  "tools": [
10
10
  {
11
11
  "vendor": "Harness Everything",
12
12
  "name": "generate-sbom.js",
13
- "version": "0.20.2"
13
+ "version": "0.20.4"
14
14
  }
15
15
  ],
16
16
  "component": {
17
17
  "type": "application",
18
- "bom-ref": "pkg:npm/harness-everything@0.20.2",
18
+ "bom-ref": "pkg:npm/harness-everything@0.20.4",
19
19
  "name": "harness-everything",
20
- "version": "0.20.2",
21
- "purl": "pkg:npm/harness-everything@0.20.2"
20
+ "version": "0.20.4",
21
+ "purl": "pkg:npm/harness-everything@0.20.4"
22
22
  }
23
23
  },
24
24
  "components": [
@@ -1999,7 +1999,7 @@
1999
1999
  ]
2000
2000
  },
2001
2001
  {
2002
- "ref": "pkg:npm/harness-everything@0.20.2",
2002
+ "ref": "pkg:npm/harness-everything@0.20.4",
2003
2003
  "dependsOn": [
2004
2004
  "pkg:npm/%40commitlint/cli@19.8.1",
2005
2005
  "pkg:npm/%40commitlint/config-conventional@19.8.1",
@@ -20,11 +20,21 @@ const DEFAULTS = Object.freeze({
20
20
  });
21
21
 
22
22
  function defaultRunner(command, args) {
23
- const result = spawnSync(command, args, {
23
+ const options = {
24
24
  encoding: 'utf8',
25
25
  stdio: ['ignore', 'pipe', 'pipe'],
26
26
  windowsHide: true
27
- });
27
+ };
28
+ let result = spawnSync(command, args, options);
29
+
30
+ // npm-installed Windows CLIs are often .cmd shims. Node can report those
31
+ // shims as an executable-resolution error when this script is launched from
32
+ // Git Bash, even though the same command is available to the shell.
33
+ if (process.platform === 'win32' && result.error && ['EACCES', 'EINVAL', 'ENOENT'].includes(result.error.code)) {
34
+ const comspec = process.env.ComSpec || process.env.COMSPEC || 'cmd.exe';
35
+ result = spawnSync(comspec, ['/d', '/c', command, ...args], options);
36
+ }
37
+
28
38
  return {
29
39
  status: result.status === null ? 1 : result.status,
30
40
  stdout: result.stdout || '',