@open-agent-toolkit/cli 0.2.63 → 0.2.64
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/tool-packs.md +83 -0
- package/assets/docs/contributing/skills.md +42 -7
- package/assets/docs/provider-sync/manifest-and-drift.md +105 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/create-agnostic-skill/SKILL.md +9 -7
- package/assets/skills/create-agnostic-skill/references/skill-template.md +9 -7
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -0
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -0
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -0
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +1 -0
- package/assets/skills/oat-project-pr-final/SKILL.md +281 -6
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -0
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -0
- package/dist/agents/canonical/resolve.d.ts.map +1 -1
- package/dist/agents/canonical/resolve.js +25 -4
- package/dist/commands/doctor/index.d.ts +7 -0
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +10 -2
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +68 -36
- package/dist/commands/shared/frontmatter.d.ts +51 -0
- package/dist/commands/shared/frontmatter.d.ts.map +1 -1
- package/dist/commands/shared/frontmatter.js +118 -6
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +5 -3
- package/dist/commands/sync/index.d.ts +14 -0
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +21 -0
- package/dist/commands/tools/info/index.d.ts.map +1 -1
- package/dist/commands/tools/info/index.js +14 -1
- package/dist/commands/tools/info/info-tool.d.ts +12 -0
- package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
- package/dist/commands/tools/info/info-tool.js +54 -6
- package/dist/commands/tools/info/skill-views.d.ts +86 -0
- package/dist/commands/tools/info/skill-views.d.ts.map +1 -0
- package/dist/commands/tools/info/skill-views.js +383 -0
- package/dist/commands/tools/install/index.d.ts.map +1 -1
- package/dist/commands/tools/install/index.js +3 -25
- package/dist/commands/tools/list/list-tools.d.ts +2 -0
- package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
- package/dist/commands/tools/list/list-tools.js +23 -4
- package/dist/commands/tools/remove/index.d.ts.map +1 -1
- package/dist/commands/tools/remove/index.js +35 -42
- package/dist/commands/tools/remove/remove-tools.d.ts +3 -2
- package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
- package/dist/commands/tools/remove/remove-tools.js +14 -4
- package/dist/commands/tools/shared/auto-sync.d.ts +12 -1
- package/dist/commands/tools/shared/auto-sync.d.ts.map +1 -1
- package/dist/commands/tools/shared/auto-sync.js +20 -4
- package/dist/commands/tools/shared/format-pack-inventory.d.ts +12 -1
- package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/format-pack-inventory.js +48 -6
- package/dist/commands/tools/shared/in-process-sync.d.ts +11 -0
- package/dist/commands/tools/shared/in-process-sync.d.ts.map +1 -0
- package/dist/commands/tools/shared/in-process-sync.js +79 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts +78 -2
- package/dist/commands/tools/shared/pack-evidence.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-evidence.js +96 -2
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +11 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-lifecycle-outcome.js +24 -3
- package/dist/commands/tools/shared/pack-provider-evidence.d.ts +73 -0
- package/dist/commands/tools/shared/pack-provider-evidence.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-provider-evidence.js +161 -0
- package/dist/commands/tools/shared/provider-context.d.ts +88 -0
- package/dist/commands/tools/shared/provider-context.d.ts.map +1 -0
- package/dist/commands/tools/shared/provider-context.js +77 -0
- package/dist/commands/tools/shared/provider-reachability.d.ts +93 -0
- package/dist/commands/tools/shared/provider-reachability.d.ts.map +1 -0
- package/dist/commands/tools/shared/provider-reachability.js +358 -0
- package/dist/commands/tools/shared/sync-evidence.d.ts +57 -0
- package/dist/commands/tools/shared/sync-evidence.d.ts.map +1 -0
- package/dist/commands/tools/shared/sync-evidence.js +147 -0
- package/dist/commands/tools/update/index.d.ts +0 -4
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +22 -40
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/commands/tools/update/update-tools.js +23 -8
- package/dist/config/json.d.ts +36 -0
- package/dist/config/json.d.ts.map +1 -1
- package/dist/config/json.js +135 -3
- package/dist/drift/index.d.ts +2 -0
- package/dist/drift/index.d.ts.map +1 -1
- package/dist/drift/index.js +1 -0
- package/dist/drift/skill-view-diagnostic.d.ts +197 -0
- package/dist/drift/skill-view-diagnostic.d.ts.map +1 -0
- package/dist/drift/skill-view-diagnostic.js +343 -0
- package/dist/validation/skills.d.ts +1 -0
- package/dist/validation/skills.d.ts.map +1 -1
- package/dist/validation/skills.js +181 -19
- package/package.json +2 -2
|
@@ -2,6 +2,8 @@ import { resolveConcreteScopes } from '../../shared/shared.utils.js';
|
|
|
2
2
|
import { formatPackEvidenceDetails, formatPackInventoryDetails, packEvidenceBlock, projectRenderablePackEvidence, unavailablePackEvidence, } from '../../tools/shared/format-pack-inventory.js';
|
|
3
3
|
import { inventoryPack, } from '../../tools/shared/pack-inventory.js';
|
|
4
4
|
import { PACK_MANIFEST } from '../../tools/shared/pack-manifest.js';
|
|
5
|
+
import { applyUserAgentCoverage } from '../../tools/shared/pack-provider-evidence.js';
|
|
6
|
+
import { resolvePackProviderSurface, } from '../../tools/shared/provider-context.js';
|
|
5
7
|
export async function runListTools(context, dependencies) {
|
|
6
8
|
const { logger } = context;
|
|
7
9
|
const scopes = resolveConcreteScopes(context.scope);
|
|
@@ -23,15 +25,32 @@ export async function runListTools(context, dependencies) {
|
|
|
23
25
|
userRoot: roots.user,
|
|
24
26
|
};
|
|
25
27
|
const inspectPack = dependencies.inventoryPack ?? inventoryPack;
|
|
28
|
+
// `list` reports the same packs as `status` and `doctor`, so it resolves the
|
|
29
|
+
// same config-aware provider surface. Without it, `list` reported user
|
|
30
|
+
// agents as unmaterialized that an active Codex or Cursor adapter supplies.
|
|
31
|
+
const providerSurface = await resolvePackProviderSurface({
|
|
32
|
+
scopeRoots: roots,
|
|
33
|
+
...(dependencies.providerContext
|
|
34
|
+
? { dependencies: dependencies.providerContext }
|
|
35
|
+
: {}),
|
|
36
|
+
});
|
|
26
37
|
const inspected = await Promise.all(PACK_MANIFEST.map(({ name }) => inspectPack({
|
|
27
38
|
pack: name,
|
|
28
39
|
assetsRoot,
|
|
29
40
|
projectRoot: roots.project,
|
|
30
41
|
userRoot: roots.user,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
42
|
+
...(roots.user
|
|
43
|
+
? {
|
|
44
|
+
userManagedRoleMaterialization: providerSurface.userAgentCoverage !== 'none',
|
|
45
|
+
}
|
|
46
|
+
: {}),
|
|
47
|
+
}).then((raw) => {
|
|
48
|
+
const canonical = applyUserAgentCoverage(raw, providerSurface.userAgentCoverage);
|
|
49
|
+
return {
|
|
50
|
+
canonical,
|
|
51
|
+
evidence: projectRenderablePackEvidence(canonical, packRoots, providerSurface.contexts),
|
|
52
|
+
};
|
|
53
|
+
}, (error) => ({
|
|
35
54
|
canonical: null,
|
|
36
55
|
evidence: unavailablePackEvidence({
|
|
37
56
|
pack: name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/index.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,kCAAkC,CAAC;AAkB1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAEL,KAAK,uBAAuB,EAM7B,MAAM,gBAAgB,CAAC;AAkDxB,wBAAgB,wBAAwB,CACtC,YAAY,GAAE,uBAA6C,EAC3D,gBAAgB,GAAE,oBAA8C,GAC/D,OAAO,CAmPT"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { execFile } from 'node:child_process';
|
|
2
1
|
import { lstat, rm } from 'node:fs/promises';
|
|
3
2
|
import { relative } from 'node:path';
|
|
4
3
|
import { buildCommandContext } from '../../../app/command-context.js';
|
|
5
4
|
import { withScopeOption } from '../../shared/scope-option.js';
|
|
6
5
|
import { readGlobalOptions, resolveConcreteScopes, } from '../../shared/shared.utils.js';
|
|
7
6
|
import { autoSync, } from '../../tools/shared/auto-sync.js';
|
|
7
|
+
import { inProcessSyncDependencies } from '../../tools/shared/in-process-sync.js';
|
|
8
8
|
import { inventoryScopedPack } from '../../tools/shared/pack-inventory.js';
|
|
9
|
+
import { providerSyncOutcomeFromAutoSync, } from '../../tools/shared/pack-lifecycle-outcome.js';
|
|
10
|
+
import { withLifecycleProviderEvidence } from '../../tools/shared/pack-provider-evidence.js';
|
|
11
|
+
import { resolveProviderScopeContexts } from '../../tools/shared/provider-context.js';
|
|
12
|
+
import { applySyncEvidence } from '../../tools/shared/provider-reachability.js';
|
|
9
13
|
import { scanTools } from '../../tools/shared/scan-tools.js';
|
|
10
14
|
import { hasScopedPackOwnershipEvidence, writeScopedPackIntent, } from '../../tools/shared/scoped-pack-intent.js';
|
|
11
15
|
import { resolveAssetsRoot } from '../../../fs/assets.js';
|
|
@@ -45,28 +49,7 @@ const defaultDependencies = {
|
|
|
45
49
|
inventoryScopedPack,
|
|
46
50
|
writeScopedPackIntent,
|
|
47
51
|
};
|
|
48
|
-
const defaultSyncDependencies =
|
|
49
|
-
runSync: async ({ scope, cwd, removedCanonicalPaths }) => {
|
|
50
|
-
const args = [
|
|
51
|
-
...process.execArgv,
|
|
52
|
-
process.argv[1],
|
|
53
|
-
'sync',
|
|
54
|
-
'--scope',
|
|
55
|
-
scope,
|
|
56
|
-
];
|
|
57
|
-
for (const canonicalPath of removedCanonicalPaths ?? []) {
|
|
58
|
-
args.push('--remove-canonical', canonicalPath);
|
|
59
|
-
}
|
|
60
|
-
await new Promise((resolve, reject) => {
|
|
61
|
-
execFile(process.execPath, args, { cwd }, (error) => {
|
|
62
|
-
if (error)
|
|
63
|
-
reject(error);
|
|
64
|
-
else
|
|
65
|
-
resolve();
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
},
|
|
69
|
-
};
|
|
52
|
+
const defaultSyncDependencies = inProcessSyncDependencies;
|
|
70
53
|
const VALID_PACKS = [
|
|
71
54
|
'core',
|
|
72
55
|
'ideas',
|
|
@@ -164,7 +147,12 @@ export function createToolsRemoveCommand(dependencies = defaultDependencies, syn
|
|
|
164
147
|
}));
|
|
165
148
|
}
|
|
166
149
|
}
|
|
167
|
-
result.lifecycle = removalLifecycleOutcomes(selectedPacks(target), scopes, result.packOutcomes, false, finalInventories
|
|
150
|
+
result.lifecycle = removalLifecycleOutcomes(selectedPacks(target), scopes, result.packOutcomes, false, finalInventories, await resolveProviderScopeContexts({
|
|
151
|
+
scopeRoots: Object.fromEntries(await Promise.all(scopes.map(async (scope) => [
|
|
152
|
+
scope,
|
|
153
|
+
await dependencies.resolveScopeRoot(scope, context.cwd, context.home),
|
|
154
|
+
]))),
|
|
155
|
+
}));
|
|
168
156
|
}
|
|
169
157
|
}
|
|
170
158
|
catch (error) {
|
|
@@ -249,27 +237,32 @@ function finalizeRemovalLifecycle(lifecycle, syncResults) {
|
|
|
249
237
|
return lifecycle;
|
|
250
238
|
return lifecycle.map((outcome) => {
|
|
251
239
|
const relevant = syncResults.filter(({ scopes }) => scopes.some((scope) => outcome.selection.targetScopes.includes(scope)));
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
240
|
+
const merged = {
|
|
241
|
+
synced: relevant.every(({ synced }) => synced),
|
|
242
|
+
scopes: [...new Set(relevant.flatMap(({ scopes }) => scopes))],
|
|
243
|
+
error: relevant.find((result) => result.error)?.error ?? null,
|
|
244
|
+
evidence: relevant.flatMap(({ evidence }) => evidence),
|
|
245
|
+
};
|
|
246
|
+
const providers = applySyncEvidence(outcome.sync.providers, {
|
|
247
|
+
syncRan: merged.evidence.some(({ ran }) => ran),
|
|
248
|
+
syncOperationResults: merged.evidence.flatMap(({ operationResults }) => operationResults),
|
|
249
|
+
extensionResults: merged.evidence.flatMap(({ extensionResults }) => extensionResults),
|
|
250
|
+
});
|
|
251
|
+
if (relevant.length === 0)
|
|
252
|
+
return outcome;
|
|
253
|
+
// The status comes from the shared severity-matrix rule rather than from
|
|
254
|
+
// `synced` alone: a sync that returned successfully can still carry an
|
|
255
|
+
// observed provider materialization failure, which is a `partial`.
|
|
256
|
+
const sync = providerSyncOutcomeFromAutoSync(merged, providers);
|
|
257
|
+
const finalEvidence = withLifecycleProviderEvidence(outcome.finalEvidence, providers);
|
|
258
|
+
if (sync.status === 'complete') {
|
|
259
|
+
return { ...outcome, sync, finalEvidence };
|
|
263
260
|
}
|
|
264
|
-
const error =
|
|
261
|
+
const error = merged.error ?? undefined;
|
|
265
262
|
return {
|
|
266
263
|
...outcome,
|
|
267
|
-
sync
|
|
268
|
-
|
|
269
|
-
status: 'failed',
|
|
270
|
-
providers: [],
|
|
271
|
-
...(error ? { error } : {}),
|
|
272
|
-
},
|
|
264
|
+
sync,
|
|
265
|
+
finalEvidence,
|
|
273
266
|
status: 'partial',
|
|
274
267
|
recovery: [
|
|
275
268
|
...outcome.recovery,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type InventoryScopedPackInput, type ScopedPackInventory } from '../../tools/shared/pack-inventory.js';
|
|
2
2
|
import { type PackLifecycleRequest, type PackLifecycleResult } from '../../tools/shared/pack-lifecycle.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type PackLifecycleOutcome } from '../../tools/shared/pack-lifecycle-outcome.js';
|
|
4
4
|
import type { ScanToolsOptions } from '../../tools/shared/scan-tools.js';
|
|
5
5
|
import type { PackName, ToolInfo } from '../../tools/shared/types.js';
|
|
6
|
+
import type { ProviderScopeContext } from '../../../providers/shared/registry.js';
|
|
6
7
|
import type { ConcreteScope } from '../../../shared/types.js';
|
|
7
8
|
export type RemoveTarget = {
|
|
8
9
|
kind: 'name';
|
|
@@ -72,7 +73,7 @@ export declare function selectedPacks(target: Exclude<RemoveTarget, {
|
|
|
72
73
|
kind: 'name';
|
|
73
74
|
}>): PackName[];
|
|
74
75
|
export declare function removeTools(target: RemoveTarget, scopes: ConcreteScope[], cwd: string, home: string, dryRun: boolean, deps: RemoveToolsDependencies): Promise<RemoveResult>;
|
|
75
|
-
export declare function removalLifecycleOutcomes(packs: readonly PackName[], scopes: readonly ConcreteScope[], outcomes: readonly PackRemovalOutcome[], dryRun: boolean, finalInventories: readonly ScopedPackInventory[]): PackLifecycleOutcome[];
|
|
76
|
+
export declare function removalLifecycleOutcomes(packs: readonly PackName[], scopes: readonly ConcreteScope[], outcomes: readonly PackRemovalOutcome[], dryRun: boolean, finalInventories: readonly ScopedPackInventory[], providerContexts?: readonly ProviderScopeContext[]): PackLifecycleOutcome[];
|
|
76
77
|
export declare function failedRemovalLifecycleOutcomes(target: Exclude<RemoveTarget, {
|
|
77
78
|
kind: 'name';
|
|
78
79
|
}>, scopes: readonly ConcreteScope[], error: unknown): PackLifecycleOutcome[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/remove-tools.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"remove-tools.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/remove/remove-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,9 @@ import { join } from 'node:path';
|
|
|
2
2
|
import { packScopeFactsFromInventory, projectPackEvidence, } from '../../tools/shared/pack-evidence.js';
|
|
3
3
|
import { hasScopedPackPlacementEvidence, } from '../../tools/shared/pack-inventory.js';
|
|
4
4
|
import {} from '../../tools/shared/pack-lifecycle.js';
|
|
5
|
+
import { notRunProviderSyncOutcome, } from '../../tools/shared/pack-lifecycle-outcome.js';
|
|
5
6
|
import { PACK_MANIFEST } from '../../tools/shared/pack-manifest.js';
|
|
7
|
+
import { lifecycleProviderEvidence } from '../../tools/shared/pack-provider-evidence.js';
|
|
6
8
|
import { resolveSharedOwnerRetentions } from '../../tools/shared/pack-reconcile.js';
|
|
7
9
|
import { resolveManagedScopeRoots, validateManagedPath, } from '../../../fs/paths.js';
|
|
8
10
|
function matchesTarget(tool, target) {
|
|
@@ -286,7 +288,7 @@ export async function removeTools(target, scopes, cwd, home, dryRun, deps) {
|
|
|
286
288
|
lifecycle: removalLifecycleOutcomes(selectedPacks(target), scopes, packOutcomes, dryRun, finalInventories),
|
|
287
289
|
};
|
|
288
290
|
}
|
|
289
|
-
export function removalLifecycleOutcomes(packs, scopes, outcomes, dryRun, finalInventories) {
|
|
291
|
+
export function removalLifecycleOutcomes(packs, scopes, outcomes, dryRun, finalInventories, providerContexts = []) {
|
|
290
292
|
if (finalInventories.length === 0)
|
|
291
293
|
return [];
|
|
292
294
|
return packs.map((pack) => {
|
|
@@ -333,7 +335,15 @@ export function removalLifecycleOutcomes(packs, scopes, outcomes, dryRun, finalI
|
|
|
333
335
|
status: removed && !dryRun ? 'applied' : 'unchanged',
|
|
334
336
|
results: [],
|
|
335
337
|
},
|
|
336
|
-
|
|
338
|
+
// After a completed removal the pack has no realized assets, so the
|
|
339
|
+
// mapper legitimately produces no rows; a retained or dry-run pack still
|
|
340
|
+
// reports its providers.
|
|
341
|
+
sync: notRunProviderSyncOutcome(lifecycleProviderEvidence({
|
|
342
|
+
pack,
|
|
343
|
+
scopedInventories: packInventories,
|
|
344
|
+
providerContexts,
|
|
345
|
+
scopes,
|
|
346
|
+
}), 'Auto-sync has not run for this operation'),
|
|
337
347
|
finalEvidence,
|
|
338
348
|
status: verified ? 'complete' : inventoryVerified ? 'partial' : 'failed',
|
|
339
349
|
recovery,
|
|
@@ -353,7 +363,7 @@ export function failedRemovalLifecycleOutcomes(target, scopes, error) {
|
|
|
353
363
|
targetScopes: scopes,
|
|
354
364
|
},
|
|
355
365
|
canonical: { status: 'failed', results: [] },
|
|
356
|
-
sync:
|
|
366
|
+
sync: notRunProviderSyncOutcome([], 'Canonical removal failed before auto-sync'),
|
|
357
367
|
finalEvidence: null,
|
|
358
368
|
status: 'failed',
|
|
359
369
|
recovery: [{ code: 'canonical-apply-failed', message }],
|
|
@@ -383,7 +393,7 @@ export function failedPostRemovalLifecycleOutcomes(target, scopes, outcomes, sta
|
|
|
383
393
|
status: canonicalApplied ? 'applied' : 'unchanged',
|
|
384
394
|
results: [],
|
|
385
395
|
},
|
|
386
|
-
sync:
|
|
396
|
+
sync: notRunProviderSyncOutcome([], `Auto-sync did not run because the ${stageLabel}`),
|
|
387
397
|
finalEvidence: null,
|
|
388
398
|
status: 'failed',
|
|
389
399
|
recovery: scopes.map((scope) => ({
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import type { ConcreteScope } from '../../../shared/types.js';
|
|
2
2
|
import type { CliLogger } from '../../../ui/logger.js';
|
|
3
|
+
import { type SyncRunEvidence } from './sync-evidence.js';
|
|
3
4
|
export interface AutoSyncDependencies {
|
|
5
|
+
/**
|
|
6
|
+
* Runs one scope's sync and returns its normalized evidence.
|
|
7
|
+
*
|
|
8
|
+
* The production implementation runs sync in-process and consumes the
|
|
9
|
+
* evidence object directly; it does not spawn `oat sync --json` and parse
|
|
10
|
+
* stdout. Returning `void` is still accepted so an injected test double or a
|
|
11
|
+
* caller that only needs the success/failure signal stays valid.
|
|
12
|
+
*/
|
|
4
13
|
runSync: (options: {
|
|
5
14
|
scope: ConcreteScope;
|
|
6
15
|
cwd: string;
|
|
7
16
|
home: string;
|
|
8
17
|
installedCanonicalPaths?: string[];
|
|
9
18
|
removedCanonicalPaths?: string[];
|
|
10
|
-
}) => Promise<void>;
|
|
19
|
+
}) => Promise<SyncRunEvidence | void>;
|
|
11
20
|
}
|
|
12
21
|
export interface AutoSyncResult {
|
|
13
22
|
synced: boolean;
|
|
14
23
|
scopes: ConcreteScope[];
|
|
15
24
|
error: string | null;
|
|
25
|
+
/** One entry per scope the run reached, in the order it ran them. */
|
|
26
|
+
evidence: readonly SyncRunEvidence[];
|
|
16
27
|
}
|
|
17
28
|
export interface AutoSyncOptions {
|
|
18
29
|
installedCanonicalPaths?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/auto-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,CAAC,OAAO,EAAE;QACjB,KAAK,EAAE,aAAa,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;QACnC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;KAClC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"auto-sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/auto-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE7E,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,OAAO,EAAE,CAAC,OAAO,EAAE;QACjB,KAAK,EAAE,aAAa,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;QACnC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;KAClC,KAAK,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,qEAAqE;IACrE,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,aAAa,EAAE,EACvB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,oBAAoB,EAClC,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CAwCzB"}
|
|
@@ -1,23 +1,39 @@
|
|
|
1
|
+
import { emptySyncRunEvidence } from './sync-evidence.js';
|
|
1
2
|
export async function autoSync(scopes, cwd, home, logger, dependencies, options) {
|
|
2
3
|
if (scopes.length === 0) {
|
|
3
|
-
return { synced: false, scopes: [], error: null };
|
|
4
|
+
return { synced: false, scopes: [], error: null, evidence: [] };
|
|
4
5
|
}
|
|
6
|
+
const evidence = [];
|
|
5
7
|
try {
|
|
6
8
|
for (const scope of scopes) {
|
|
7
|
-
await dependencies.runSync({
|
|
9
|
+
const result = await dependencies.runSync({
|
|
8
10
|
scope,
|
|
9
11
|
cwd,
|
|
10
12
|
home,
|
|
11
13
|
installedCanonicalPaths: options?.installedCanonicalPaths,
|
|
12
14
|
removedCanonicalPaths: options?.removedCanonicalPaths,
|
|
13
15
|
});
|
|
16
|
+
evidence.push(result ?? { ...emptySyncRunEvidence(scope), ran: true });
|
|
17
|
+
}
|
|
18
|
+
// A sync can fail without throwing: `runSyncApply` reports failed
|
|
19
|
+
// operations and returns normally. Treating that as success is what let a
|
|
20
|
+
// failed sync print `Auto-sync completed.` and exit 0. The evidence is
|
|
21
|
+
// kept either way so the failed provider rows survive.
|
|
22
|
+
const failedOperations = evidence.reduce((total, run) => total + run.failedOperations, 0);
|
|
23
|
+
if (failedOperations > 0) {
|
|
24
|
+
const message = `oat sync reported ${failedOperations} failed operation(s)`;
|
|
25
|
+
logger.warn(`Auto-sync failed: ${message}`);
|
|
26
|
+
return { synced: false, scopes, error: message, evidence };
|
|
14
27
|
}
|
|
15
28
|
logger.info('Auto-sync completed.');
|
|
16
|
-
return { synced: true, scopes, error: null };
|
|
29
|
+
return { synced: true, scopes, error: null, evidence };
|
|
17
30
|
}
|
|
18
31
|
catch (err) {
|
|
19
32
|
const message = err instanceof Error ? err.message : String(err);
|
|
20
33
|
logger.warn(`Auto-sync failed: ${message}`);
|
|
21
|
-
|
|
34
|
+
// Evidence collected before the failure is preserved: a two-scope run that
|
|
35
|
+
// failed on the second scope still reached the first, and discarding that
|
|
36
|
+
// would report a reachable provider as unknown.
|
|
37
|
+
return { synced: false, scopes, error: message, evidence };
|
|
22
38
|
}
|
|
23
39
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProviderScopeContext } from '../../../providers/shared/registry.js';
|
|
1
2
|
import type { ConcreteScope } from '../../../shared/types.js';
|
|
2
3
|
import { type PackEvidenceDiagnostic, type ToolPackEvidence } from './pack-evidence.js';
|
|
3
4
|
import type { PackInventory } from './pack-inventory.js';
|
|
@@ -15,7 +16,17 @@ export declare function unavailablePackEvidence(input: {
|
|
|
15
16
|
reason: string;
|
|
16
17
|
roots?: PackPathRoots;
|
|
17
18
|
}): ToolPackEvidence;
|
|
18
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Projects a renderable pack evidence item.
|
|
21
|
+
*
|
|
22
|
+
* `providerContexts` is the config-aware provider context per scope. When it
|
|
23
|
+
* is supplied, provider reachability is mapped from the registry and the
|
|
24
|
+
* resulting `provider-materialization-missing` diagnostics name the provider.
|
|
25
|
+
* When it is absent — a surface that could not resolve a sync config — the
|
|
26
|
+
* unattributed inventory-derived diagnostic is emitted instead, so the
|
|
27
|
+
* warning is never silently lost.
|
|
28
|
+
*/
|
|
29
|
+
export declare function projectRenderablePackEvidence(canonical: PackInventory, roots: PackPathRoots, providerContexts?: readonly ProviderScopeContext[]): ToolPackEvidence;
|
|
19
30
|
export declare function packEvidenceBlock(items: readonly ToolPackEvidence[]): PackEvidenceBlockV1;
|
|
20
31
|
export declare function formatPackEvidenceDetails(evidence: ToolPackEvidence, indent?: string): string[];
|
|
21
32
|
export declare function formatPackInventoryDetails(inventory: PackInventory, indent?: string): string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/format-pack-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"format-pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/format-pack-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,CAAC,CAAC;IACjB,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAChD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,GAAG,gBAAgB,CAoBnB;AA4CD;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,aAAa,EACpB,gBAAgB,CAAC,EAAE,SAAS,oBAAoB,EAAE,GACjD,gBAAgB,CAyDlB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC,mBAAmB,CAerB;AAUD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,SAAO,GACZ,MAAM,EAAE,CAiCV;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { packScopeFactsFromInventory, projectPackEvidence, unavailablePackScopeFacts, } from './pack-evidence.js';
|
|
2
2
|
import { formatPackPath } from './pack-paths.js';
|
|
3
|
+
import { packProviderEvidence } from './pack-provider-evidence.js';
|
|
3
4
|
export function unavailablePackEvidence(input) {
|
|
4
5
|
const reason = redactPackText(input.reason, input.roots ?? {});
|
|
5
6
|
const facts = input.scopes.map((scope) => unavailablePackScopeFacts({
|
|
@@ -56,14 +57,42 @@ function redactPackInventory(inventory, roots) {
|
|
|
56
57
|
})),
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Projects a renderable pack evidence item.
|
|
62
|
+
*
|
|
63
|
+
* `providerContexts` is the config-aware provider context per scope. When it
|
|
64
|
+
* is supplied, provider reachability is mapped from the registry and the
|
|
65
|
+
* resulting `provider-materialization-missing` diagnostics name the provider.
|
|
66
|
+
* When it is absent — a surface that could not resolve a sync config — the
|
|
67
|
+
* unattributed inventory-derived diagnostic is emitted instead, so the
|
|
68
|
+
* warning is never silently lost.
|
|
69
|
+
*/
|
|
70
|
+
export function projectRenderablePackEvidence(canonical, roots, providerContexts) {
|
|
60
71
|
const redacted = redactPackInventory(canonical, roots);
|
|
72
|
+
const providers = providerContexts && providerContexts.length > 0
|
|
73
|
+
? packProviderEvidence({
|
|
74
|
+
pack: redacted.pack,
|
|
75
|
+
scopedInventories: redacted.scopes,
|
|
76
|
+
providerContexts,
|
|
77
|
+
mode: 'inventory',
|
|
78
|
+
})
|
|
79
|
+
: [];
|
|
61
80
|
const evidence = projectPackEvidence({
|
|
62
81
|
canonical: redacted,
|
|
63
82
|
scopes: redacted.scopes.map(packScopeFactsFromInventory),
|
|
83
|
+
providers,
|
|
84
|
+
providerMode: 'inventory',
|
|
64
85
|
});
|
|
65
|
-
|
|
66
|
-
|
|
86
|
+
// Assets a provider row already reports as missing are covered by the
|
|
87
|
+
// named diagnostic. Anything left over has no responsible active provider,
|
|
88
|
+
// so the unattributed pack-level warning is still the only report of it and
|
|
89
|
+
// must not be dropped just because provider rows exist.
|
|
90
|
+
const attributedAssets = new Set(providers
|
|
91
|
+
.filter(({ materialization }) => materialization.state === 'missing')
|
|
92
|
+
.flatMap(({ assets }) => assets));
|
|
93
|
+
const legacyDiagnostics = redacted.scopes.flatMap((scoped) => scoped.diagnostics
|
|
94
|
+
.filter(({ code, paths }) => code === 'user-agent-unmaterialized' &&
|
|
95
|
+
paths.some((path) => !attributedAssets.has(path)))
|
|
67
96
|
.map((diagnostic) => ({
|
|
68
97
|
code: 'provider-materialization-missing',
|
|
69
98
|
severity: 'warning',
|
|
@@ -83,14 +112,19 @@ export function projectRenderablePackEvidence(canonical, roots) {
|
|
|
83
112
|
})));
|
|
84
113
|
return {
|
|
85
114
|
...evidence,
|
|
86
|
-
diagnostics: [...evidence.diagnostics, ...
|
|
115
|
+
diagnostics: [...evidence.diagnostics, ...legacyDiagnostics],
|
|
87
116
|
};
|
|
88
117
|
}
|
|
89
118
|
export function packEvidenceBlock(items) {
|
|
90
119
|
const diagnostics = items.flatMap(({ diagnostics: values }) => values);
|
|
120
|
+
// Severity, never the diagnostic count, decides the block status. `info`
|
|
121
|
+
// rows (an inactive provider, an unsupported content kind, a host that
|
|
122
|
+
// needs a catalog refresh) are reportable facts about a healthy install,
|
|
123
|
+
// so counting them would turn every correctly configured host `partial`.
|
|
124
|
+
const actionable = diagnostics.some(({ severity }) => severity === 'warning' || severity === 'error');
|
|
91
125
|
return {
|
|
92
126
|
schemaVersion: 1,
|
|
93
|
-
status:
|
|
127
|
+
status: actionable ? 'partial' : 'ok',
|
|
94
128
|
items,
|
|
95
129
|
diagnostics,
|
|
96
130
|
};
|
|
@@ -108,8 +142,16 @@ export function formatPackEvidenceDetails(evidence, indent = ' ') {
|
|
|
108
142
|
lines.push(`${indent} Inventory: ${scoped.inventory.reason}`);
|
|
109
143
|
}
|
|
110
144
|
}
|
|
145
|
+
// Human output names the provider; the structured evidence stays in JSON.
|
|
146
|
+
// The materialization detail is rendered alongside the state because
|
|
147
|
+
// `not-applicable` alone collapses two different situations: a provider
|
|
148
|
+
// that is inactive or cannot project this content, and an active provider
|
|
149
|
+
// on a read-only surface that simply observed no sync.
|
|
150
|
+
for (const provider of evidence.providers) {
|
|
151
|
+
lines.push(`${indent}${provider.provider} [${provider.scope} ${provider.contentKind}]: ${provider.activation.state}; capability=${provider.capability.support}; projection=${provider.projection.state}; materialization=${provider.materialization.state} (${provider.materialization.detail}); visibility=${provider.visibility.state}`);
|
|
152
|
+
}
|
|
111
153
|
for (const diagnostic of evidence.diagnostics) {
|
|
112
|
-
lines.push(`${indent}${diagnostic.code}: ${diagnostic.detail}`, ...(diagnostic.affectedAssets.length > 0
|
|
154
|
+
lines.push(`${indent}${diagnostic.code}${diagnostic.provider ? ` [${diagnostic.provider}]` : ''}: ${diagnostic.detail}`, ...(diagnostic.affectedAssets.length > 0
|
|
113
155
|
? [`${indent} Affected: ${diagnostic.affectedAssets.join(', ')}`]
|
|
114
156
|
: []), ...diagnostic.recovery.map(({ command, message }) => `${indent} Fix: ${message}${command ? ` (${command})` : ''}`));
|
|
115
157
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AutoSyncDependencies } from './auto-sync.js';
|
|
2
|
+
/**
|
|
3
|
+
* The production auto-sync seam for every pack lifecycle command.
|
|
4
|
+
*
|
|
5
|
+
* Runs sync in-process and consumes the evidence object the sync run already
|
|
6
|
+
* builds, rather than spawning `oat sync --json` and parsing stdout. The
|
|
7
|
+
* subprocess it replaces discarded that evidence entirely, which is why every
|
|
8
|
+
* lifecycle outcome carried an empty provider array.
|
|
9
|
+
*/
|
|
10
|
+
export declare const inProcessSyncDependencies: AutoSyncDependencies;
|
|
11
|
+
//# sourceMappingURL=in-process-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-process-sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/in-process-sync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAyBxD;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,oBAqDvC,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { runSyncInProcess } from '../../sync/index.js';
|
|
2
|
+
import { normalizeSyncEvidence } from './sync-evidence.js';
|
|
3
|
+
/**
|
|
4
|
+
* Silent logger that captures the sync run's JSON payload.
|
|
5
|
+
*
|
|
6
|
+
* Auto-sync has never surfaced the child sync's output — the previous
|
|
7
|
+
* subprocess implementation captured and discarded its stdout — so keeping
|
|
8
|
+
* every channel silent preserves the lifecycle command's human output exactly
|
|
9
|
+
* while making the evidence object available to the caller.
|
|
10
|
+
*/
|
|
11
|
+
function capturingSyncLogger(sink) {
|
|
12
|
+
const noop = () => { };
|
|
13
|
+
return {
|
|
14
|
+
debug: noop,
|
|
15
|
+
info: noop,
|
|
16
|
+
warn: noop,
|
|
17
|
+
error: noop,
|
|
18
|
+
success: noop,
|
|
19
|
+
json(payload) {
|
|
20
|
+
sink.payload = payload;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The production auto-sync seam for every pack lifecycle command.
|
|
26
|
+
*
|
|
27
|
+
* Runs sync in-process and consumes the evidence object the sync run already
|
|
28
|
+
* builds, rather than spawning `oat sync --json` and parsing stdout. The
|
|
29
|
+
* subprocess it replaces discarded that evidence entirely, which is why every
|
|
30
|
+
* lifecycle outcome carried an empty provider array.
|
|
31
|
+
*/
|
|
32
|
+
export const inProcessSyncDependencies = {
|
|
33
|
+
runSync: async ({ scope, cwd, home, installedCanonicalPaths, removedCanonicalPaths, }) => {
|
|
34
|
+
const sink = { payload: null };
|
|
35
|
+
const context = {
|
|
36
|
+
scope,
|
|
37
|
+
dryRun: false,
|
|
38
|
+
verbose: false,
|
|
39
|
+
json: true,
|
|
40
|
+
cwd,
|
|
41
|
+
home,
|
|
42
|
+
interactive: false,
|
|
43
|
+
logger: capturingSyncLogger(sink),
|
|
44
|
+
};
|
|
45
|
+
// `runSyncApply` assigns `process.exitCode` for its own run. In a
|
|
46
|
+
// subprocess that was the child's exit status and never reached the
|
|
47
|
+
// parent command; in-process it would overwrite the parent's own result,
|
|
48
|
+
// including resetting a failure to 0, so the parent's value is restored.
|
|
49
|
+
//
|
|
50
|
+
// That exit code is also the only signal sync gives for a run that failed
|
|
51
|
+
// without throwing: `runSyncApply` sets 1 when operations failed and
|
|
52
|
+
// returns normally. The subprocess this replaces surfaced that as an
|
|
53
|
+
// `execFile` rejection, which auto-sync recorded as a failed sync. Reading
|
|
54
|
+
// it before restoring keeps that contract instead of reporting a failed
|
|
55
|
+
// sync as `Auto-sync completed.` with exit 0.
|
|
56
|
+
const priorExitCode = process.exitCode;
|
|
57
|
+
let syncExitCode;
|
|
58
|
+
try {
|
|
59
|
+
await runSyncInProcess(context, {
|
|
60
|
+
...(installedCanonicalPaths ? { installedCanonicalPaths } : {}),
|
|
61
|
+
...(removedCanonicalPaths ? { removedCanonicalPaths } : {}),
|
|
62
|
+
});
|
|
63
|
+
syncExitCode = process.exitCode;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
process.exitCode = priorExitCode;
|
|
67
|
+
}
|
|
68
|
+
const evidence = normalizeSyncEvidence(scope, sink.payload);
|
|
69
|
+
// The failure is reported through the evidence rather than by throwing:
|
|
70
|
+
// a throw would discard the very rows that describe which provider
|
|
71
|
+
// failed, and those rows are what emit `provider-materialization-failed`.
|
|
72
|
+
// A non-zero exit with no counted operation (a rejected collection is a
|
|
73
|
+
// failure but not a planned operation) still records one.
|
|
74
|
+
const exitedNonZero = typeof syncExitCode === 'number' && syncExitCode !== 0;
|
|
75
|
+
return exitedNonZero && evidence.failedOperations === 0
|
|
76
|
+
? { ...evidence, failedOperations: 1 }
|
|
77
|
+
: evidence;
|
|
78
|
+
},
|
|
79
|
+
};
|