harness-everything 0.20.0 → 0.20.2
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +12 -0
- package/ci/mechanism-2ao-plugin-sync.test.js +29 -1
- package/opencode-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
- package/plugins/harness-everything/plugin.json +1 -1
- package/sbom.cdx.json +7 -7
- package/scripts/plugin-sync.js +42 -6
|
@@ -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.
|
|
13
|
+
"version": "0.20.2",
|
|
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.
|
|
4
|
+
"version": "0.20.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Miya Daniel"
|
|
7
7
|
},
|
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.2](https://github.com/dyphn1/Harness-everything/compare/v0.20.1...v0.20.2) (2026-09-22)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
* **distribution:** handle legacy claude flags ([2e09915](https://github.com/dyphn1/Harness-everything/commit/2e09915cff6c7cbf7cd10b08587df18264403a01)), closes [#221](https://github.com/dyphn1/Harness-everything/issues/221)
|
|
10
|
+
|
|
11
|
+
## [0.20.1](https://github.com/dyphn1/Harness-everything/compare/v0.20.0...v0.20.1) (2026-09-22)
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **distribution:** support older claude plugin clis ([e00e665](https://github.com/dyphn1/Harness-everything/commit/e00e665eeebf6d1f6fc0469eed435ec0562bc226)), closes [#221](https://github.com/dyphn1/Harness-everything/issues/221)
|
|
16
|
+
|
|
5
17
|
## [0.20.0](https://github.com/dyphn1/Harness-everything/compare/v0.19.1...v0.20.0) (2026-09-21)
|
|
6
18
|
|
|
7
19
|
### Features
|
|
@@ -12,7 +12,7 @@ const {
|
|
|
12
12
|
|
|
13
13
|
const ROOT = path.resolve(__dirname, '..');
|
|
14
14
|
|
|
15
|
-
function fakeHost({ claudeInstalled = false, codexInstalled = false, claudeMarketplace = true, codexMarketplace = true, unknownClaudePluginState = false } = {}) {
|
|
15
|
+
function fakeHost({ claudeInstalled = false, codexInstalled = false, claudeMarketplace = true, codexMarketplace = true, unknownClaudePluginState = false, unknownClaudeYesFlag = false, unknownClaudeJsonFlag = false } = {}) {
|
|
16
16
|
const calls = [];
|
|
17
17
|
const state = {
|
|
18
18
|
claudeInstalled,
|
|
@@ -44,6 +44,12 @@ function fakeHost({ claudeInstalled = false, codexInstalled = false, claudeMarke
|
|
|
44
44
|
if (unknownClaudePluginState) return { status: 1, stdout: '', stderr: 'unsupported list' };
|
|
45
45
|
return { status: 0, stdout: state.claudeInstalled ? 'harness-everything@harness-everything\n' : '', stderr: '' };
|
|
46
46
|
}
|
|
47
|
+
if (unknownClaudeYesFlag && joined.includes('--yes')) {
|
|
48
|
+
return { status: 1, stdout: '', stderr: "error: unknown option '--yes'" };
|
|
49
|
+
}
|
|
50
|
+
if (unknownClaudeJsonFlag && joined.includes('--json')) {
|
|
51
|
+
return { status: 1, stdout: '', stderr: "error: unknown option '--json'" };
|
|
52
|
+
}
|
|
47
53
|
if (joined.startsWith('plugin install') || joined.startsWith('plugin update')) {
|
|
48
54
|
state.claudeInstalled = true;
|
|
49
55
|
return { status: 0, stdout: '{}', stderr: '' };
|
|
@@ -118,6 +124,28 @@ assert.strictEqual(findPlugin({ plugins: [{ id: 'harness-everything@harness-ever
|
|
|
118
124
|
assert.strictEqual(callsFor(fake.calls, 'claude', 'plugin install').length, 0, 'installed Claude plugin must not reinstall');
|
|
119
125
|
}
|
|
120
126
|
|
|
127
|
+
{
|
|
128
|
+
const fake = fakeHost({ claudeInstalled: true, unknownClaudeYesFlag: true });
|
|
129
|
+
const result = runHost('claude', fake);
|
|
130
|
+
const updateCalls = callsFor(fake.calls, 'claude', 'plugin update');
|
|
131
|
+
assert.strictEqual(result.failed, 0, 'unsupported Claude --yes must fall back to a compatible update command');
|
|
132
|
+
assert.strictEqual(result.results[0].action, 'update');
|
|
133
|
+
assert.strictEqual(updateCalls.length, 2, 'unsupported --yes must cause one compatibility retry');
|
|
134
|
+
assert.ok(updateCalls[0].args.includes('--yes'), 'first update attempt should use the current non-interactive flag');
|
|
135
|
+
assert.ok(!updateCalls[1].args.includes('--yes'), 'compatibility retry must omit unsupported --yes');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
{
|
|
139
|
+
const fake = fakeHost({ claudeInstalled: true, unknownClaudeYesFlag: true, unknownClaudeJsonFlag: true });
|
|
140
|
+
const result = runHost('claude', fake);
|
|
141
|
+
const updateCalls = callsFor(fake.calls, 'claude', 'plugin update');
|
|
142
|
+
assert.strictEqual(result.failed, 0, 'unsupported Claude --yes and --json must fall back to a compatible update command');
|
|
143
|
+
assert.strictEqual(updateCalls.length, 3, 'each unsupported option must cause one compatibility retry');
|
|
144
|
+
assert.ok(updateCalls[0].args.includes('--yes') && updateCalls[0].args.includes('--json'), 'first update attempt should use current flags');
|
|
145
|
+
assert.ok(!updateCalls[1].args.includes('--yes') && updateCalls[1].args.includes('--json'), 'second attempt should omit only unsupported --yes');
|
|
146
|
+
assert.ok(!updateCalls[2].args.includes('--yes') && !updateCalls[2].args.includes('--json'), 'final attempt must omit both unsupported flags');
|
|
147
|
+
}
|
|
148
|
+
|
|
121
149
|
{
|
|
122
150
|
const fake = fakeHost({ codexInstalled: false });
|
|
123
151
|
const result = runHost('codex', fake);
|
package/package.json
CHANGED
|
@@ -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.
|
|
4
|
+
"version": "0.20.2",
|
|
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:
|
|
5
|
+
"serialNumber": "urn:uuid:338bfdd5-e2e1-5e75-b6b1-f114ba76e2f5",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-09-
|
|
8
|
+
"timestamp": "2026-09-22T01:26:05.707Z",
|
|
9
9
|
"tools": [
|
|
10
10
|
{
|
|
11
11
|
"vendor": "Harness Everything",
|
|
12
12
|
"name": "generate-sbom.js",
|
|
13
|
-
"version": "0.20.
|
|
13
|
+
"version": "0.20.2"
|
|
14
14
|
}
|
|
15
15
|
],
|
|
16
16
|
"component": {
|
|
17
17
|
"type": "application",
|
|
18
|
-
"bom-ref": "pkg:npm/harness-everything@0.20.
|
|
18
|
+
"bom-ref": "pkg:npm/harness-everything@0.20.2",
|
|
19
19
|
"name": "harness-everything",
|
|
20
|
-
"version": "0.20.
|
|
21
|
-
"purl": "pkg:npm/harness-everything@0.20.
|
|
20
|
+
"version": "0.20.2",
|
|
21
|
+
"purl": "pkg:npm/harness-everything@0.20.2"
|
|
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.
|
|
2002
|
+
"ref": "pkg:npm/harness-everything@0.20.2",
|
|
2003
2003
|
"dependsOn": [
|
|
2004
2004
|
"pkg:npm/%40commitlint/cli@19.8.1",
|
|
2005
2005
|
"pkg:npm/%40commitlint/config-conventional@19.8.1",
|
package/scripts/plugin-sync.js
CHANGED
|
@@ -162,14 +162,14 @@ function createContext(options = {}) {
|
|
|
162
162
|
return context;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
function invoke(context, command, args, { mutate = false, label = command } = {}) {
|
|
165
|
+
function invoke(context, command, args, { mutate = false, label = command, warnOnFailure = true } = {}) {
|
|
166
166
|
const rendered = commandLine(command, args);
|
|
167
167
|
if (mutate && context.dryRun) {
|
|
168
168
|
context.log(`[dry-run] ${rendered}`);
|
|
169
169
|
return { status: 0, stdout: '', stderr: '', dryRun: true };
|
|
170
170
|
}
|
|
171
171
|
const result = context.runner(command, args, { label });
|
|
172
|
-
if (!result || result.status !== 0) {
|
|
172
|
+
if (warnOnFailure && (!result || result.status !== 0)) {
|
|
173
173
|
context.warn(`[failed] ${rendered}\n ${resultError(result)}`);
|
|
174
174
|
}
|
|
175
175
|
return result || { status: 1, stdout: '', stderr: 'runner returned no result' };
|
|
@@ -179,6 +179,41 @@ function query(context, command, args) {
|
|
|
179
179
|
return context.runner(command, args, { query: true }) || { status: 1, stdout: '', stderr: 'runner returned no result' };
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
function hasUnknownOption(result, option) {
|
|
183
|
+
const output = [result && result.stderr, result && result.stdout, result && result.error && result.error.message]
|
|
184
|
+
.map(value => String(value || ''))
|
|
185
|
+
.join('\n');
|
|
186
|
+
return new RegExp(`unknown option\\s+['"]?${escapeRegExp(option)}['"]?`, 'i').test(output);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function runClaudePluginMutation(context, action, pluginId) {
|
|
190
|
+
const baseArgs = [
|
|
191
|
+
'plugin', action, pluginId,
|
|
192
|
+
'--scope', 'user'
|
|
193
|
+
];
|
|
194
|
+
let args = [...baseArgs, '--yes', '--json'];
|
|
195
|
+
let attempt = 0;
|
|
196
|
+
|
|
197
|
+
while (true) {
|
|
198
|
+
const result = invoke(context, 'claude', args, {
|
|
199
|
+
mutate: true,
|
|
200
|
+
label: attempt === 0 ? `claude plugin ${action}` : `claude plugin ${action} compatibility retry`,
|
|
201
|
+
warnOnFailure: false
|
|
202
|
+
});
|
|
203
|
+
if (result.status === 0) return result;
|
|
204
|
+
|
|
205
|
+
const unsupported = ['--yes', '--json'].find(option => args.includes(option) && hasUnknownOption(result, option));
|
|
206
|
+
if (!unsupported) {
|
|
207
|
+
context.warn(`[failed] ${commandLine('claude', args)}\n ${resultError(result)}`);
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
args = args.filter(arg => arg !== unsupported);
|
|
212
|
+
attempt += 1;
|
|
213
|
+
context.warn(`[notice] Claude CLI does not support ${unsupported}; retrying ${action} without that option.`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
182
217
|
function listState(context, { command, jsonArgs, plainArgs, detectJson, detectText }) {
|
|
183
218
|
const jsonResult = query(context, command, jsonArgs);
|
|
184
219
|
if (jsonResult.status === 0) {
|
|
@@ -314,10 +349,11 @@ function syncClaude(context) {
|
|
|
314
349
|
if (!refreshed.ok) return { host: 'claude', status: 'failed', error: refreshed.error };
|
|
315
350
|
|
|
316
351
|
const action = installed.value ? 'update' : 'install';
|
|
317
|
-
const result =
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
352
|
+
const result = runClaudePluginMutation(
|
|
353
|
+
context,
|
|
354
|
+
action,
|
|
355
|
+
`${context.plugin}@${context.marketplace}`
|
|
356
|
+
);
|
|
321
357
|
if (result.status !== 0) return { host: 'claude', status: 'failed', error: resultError(result) };
|
|
322
358
|
|
|
323
359
|
const verification = verifyPlugin(context, 'Claude', queryClaudePlugin);
|