@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.
Files changed (92) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/cli-utilities/tool-packs.md +83 -0
  3. package/assets/docs/contributing/skills.md +42 -7
  4. package/assets/docs/provider-sync/manifest-and-drift.md +105 -0
  5. package/assets/public-package-versions.json +4 -4
  6. package/assets/skills/create-agnostic-skill/SKILL.md +9 -7
  7. package/assets/skills/create-agnostic-skill/references/skill-template.md +9 -7
  8. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -0
  9. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -0
  10. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -0
  11. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +1 -0
  12. package/assets/skills/oat-project-pr-final/SKILL.md +281 -6
  13. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -0
  14. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -0
  15. package/dist/agents/canonical/resolve.d.ts.map +1 -1
  16. package/dist/agents/canonical/resolve.js +25 -4
  17. package/dist/commands/doctor/index.d.ts +7 -0
  18. package/dist/commands/doctor/index.d.ts.map +1 -1
  19. package/dist/commands/doctor/index.js +10 -2
  20. package/dist/commands/init/tools/index.d.ts.map +1 -1
  21. package/dist/commands/init/tools/index.js +68 -36
  22. package/dist/commands/shared/frontmatter.d.ts +51 -0
  23. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  24. package/dist/commands/shared/frontmatter.js +118 -6
  25. package/dist/commands/status/index.d.ts.map +1 -1
  26. package/dist/commands/status/index.js +5 -3
  27. package/dist/commands/sync/index.d.ts +14 -0
  28. package/dist/commands/sync/index.d.ts.map +1 -1
  29. package/dist/commands/sync/index.js +21 -0
  30. package/dist/commands/tools/info/index.d.ts.map +1 -1
  31. package/dist/commands/tools/info/index.js +14 -1
  32. package/dist/commands/tools/info/info-tool.d.ts +12 -0
  33. package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
  34. package/dist/commands/tools/info/info-tool.js +54 -6
  35. package/dist/commands/tools/info/skill-views.d.ts +86 -0
  36. package/dist/commands/tools/info/skill-views.d.ts.map +1 -0
  37. package/dist/commands/tools/info/skill-views.js +383 -0
  38. package/dist/commands/tools/install/index.d.ts.map +1 -1
  39. package/dist/commands/tools/install/index.js +3 -25
  40. package/dist/commands/tools/list/list-tools.d.ts +2 -0
  41. package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
  42. package/dist/commands/tools/list/list-tools.js +23 -4
  43. package/dist/commands/tools/remove/index.d.ts.map +1 -1
  44. package/dist/commands/tools/remove/index.js +35 -42
  45. package/dist/commands/tools/remove/remove-tools.d.ts +3 -2
  46. package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
  47. package/dist/commands/tools/remove/remove-tools.js +14 -4
  48. package/dist/commands/tools/shared/auto-sync.d.ts +12 -1
  49. package/dist/commands/tools/shared/auto-sync.d.ts.map +1 -1
  50. package/dist/commands/tools/shared/auto-sync.js +20 -4
  51. package/dist/commands/tools/shared/format-pack-inventory.d.ts +12 -1
  52. package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
  53. package/dist/commands/tools/shared/format-pack-inventory.js +48 -6
  54. package/dist/commands/tools/shared/in-process-sync.d.ts +11 -0
  55. package/dist/commands/tools/shared/in-process-sync.d.ts.map +1 -0
  56. package/dist/commands/tools/shared/in-process-sync.js +79 -0
  57. package/dist/commands/tools/shared/pack-evidence.d.ts +78 -2
  58. package/dist/commands/tools/shared/pack-evidence.d.ts.map +1 -1
  59. package/dist/commands/tools/shared/pack-evidence.js +96 -2
  60. package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +11 -0
  61. package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -1
  62. package/dist/commands/tools/shared/pack-lifecycle-outcome.js +24 -3
  63. package/dist/commands/tools/shared/pack-provider-evidence.d.ts +73 -0
  64. package/dist/commands/tools/shared/pack-provider-evidence.d.ts.map +1 -0
  65. package/dist/commands/tools/shared/pack-provider-evidence.js +161 -0
  66. package/dist/commands/tools/shared/provider-context.d.ts +88 -0
  67. package/dist/commands/tools/shared/provider-context.d.ts.map +1 -0
  68. package/dist/commands/tools/shared/provider-context.js +77 -0
  69. package/dist/commands/tools/shared/provider-reachability.d.ts +93 -0
  70. package/dist/commands/tools/shared/provider-reachability.d.ts.map +1 -0
  71. package/dist/commands/tools/shared/provider-reachability.js +358 -0
  72. package/dist/commands/tools/shared/sync-evidence.d.ts +57 -0
  73. package/dist/commands/tools/shared/sync-evidence.d.ts.map +1 -0
  74. package/dist/commands/tools/shared/sync-evidence.js +147 -0
  75. package/dist/commands/tools/update/index.d.ts +0 -4
  76. package/dist/commands/tools/update/index.d.ts.map +1 -1
  77. package/dist/commands/tools/update/index.js +22 -40
  78. package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
  79. package/dist/commands/tools/update/update-tools.js +23 -8
  80. package/dist/config/json.d.ts +36 -0
  81. package/dist/config/json.d.ts.map +1 -1
  82. package/dist/config/json.js +135 -3
  83. package/dist/drift/index.d.ts +2 -0
  84. package/dist/drift/index.d.ts.map +1 -1
  85. package/dist/drift/index.js +1 -0
  86. package/dist/drift/skill-view-diagnostic.d.ts +197 -0
  87. package/dist/drift/skill-view-diagnostic.d.ts.map +1 -0
  88. package/dist/drift/skill-view-diagnostic.js +343 -0
  89. package/dist/validation/skills.d.ts +1 -0
  90. package/dist/validation/skills.d.ts.map +1 -1
  91. package/dist/validation/skills.js +181 -19
  92. 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
- }).then((canonical) => ({
32
- canonical,
33
- evidence: projectRenderablePackEvidence(canonical, packRoots),
34
- }), (error) => ({
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":"AAUA,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,kCAAkC,CAAC;AAW1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAEL,KAAK,uBAAuB,EAM7B,MAAM,gBAAgB,CAAC;AAqExB,wBAAgB,wBAAwB,CACtC,YAAY,GAAE,uBAA6C,EAC3D,gBAAgB,GAAE,oBAA8C,GAC/D,OAAO,CAkOT"}
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
- if (relevant.length === 0 || relevant.every(({ synced }) => synced)) {
253
- return relevant.length === 0
254
- ? outcome
255
- : {
256
- ...outcome,
257
- sync: {
258
- scopes: [...new Set(relevant.flatMap(({ scopes }) => scopes))],
259
- status: 'complete',
260
- providers: [],
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 = relevant.find((result) => result.error)?.error;
261
+ const error = merged.error ?? undefined;
265
262
  return {
266
263
  ...outcome,
267
- sync: {
268
- scopes: [...new Set(relevant.flatMap(({ scopes }) => scopes))],
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 { PackLifecycleOutcome } from '../../tools/shared/pack-lifecycle-outcome.js';
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":"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"}
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
- sync: { scopes: [], status: 'not-run', providers: [] },
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: { scopes: [], status: 'not-run', providers: [] },
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: { scopes: [], status: 'not-run', providers: [] },
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;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;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,CAsBzB"}
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
- return { synced: false, scopes, error: message };
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
- export declare function projectRenderablePackEvidence(canonical: PackInventory, roots: PackPathRoots): ToolPackEvidence;
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;AAClE,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,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,aAAa,GACnB,gBAAgB,CAiClB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC,mBAAmB,CAQrB;AAUD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV"}
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
- export function projectRenderablePackEvidence(canonical, roots) {
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
- const providerDiagnostics = redacted.scopes.flatMap((scoped) => scoped.diagnostics
66
- .filter(({ code }) => code === 'user-agent-unmaterialized')
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, ...providerDiagnostics],
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: diagnostics.length > 0 ? 'partial' : 'ok',
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
+ };