@lesliechan721/aw 0.1.0-beta.54 → 0.1.0-beta.56

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 (109) hide show
  1. package/dist/authoring/scripts/lib/plugin-version-check.mjs +1 -1
  2. package/dist/authoring/scripts/validate-plugin.mjs +208 -31
  3. package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
  4. package/dist/scripts/bundle-plugins.js +8 -3
  5. package/dist/scripts/bundle-plugins.js.map +1 -1
  6. package/dist/src/adapters/helpers.d.ts +7 -0
  7. package/dist/src/adapters/helpers.js.map +1 -1
  8. package/dist/src/commands/aw-capabilities.d.ts +1 -1
  9. package/dist/src/commands/aw-capabilities.js +2 -0
  10. package/dist/src/commands/aw-capabilities.js.map +1 -1
  11. package/dist/src/commands/managed-commands.d.ts +26 -0
  12. package/dist/src/commands/managed-commands.js +277 -0
  13. package/dist/src/commands/managed-commands.js.map +1 -0
  14. package/dist/src/commands/operation-plan.d.ts +30 -1
  15. package/dist/src/commands/operation-plan.js.map +1 -1
  16. package/dist/src/commands/operation-planner.d.ts +1 -0
  17. package/dist/src/commands/operation-planner.js +1 -0
  18. package/dist/src/commands/operation-planner.js.map +1 -1
  19. package/dist/src/commands/plugin-capabilities.js +29 -1
  20. package/dist/src/commands/plugin-capabilities.js.map +1 -1
  21. package/dist/src/commands/rebuild-command.d.ts +2 -1
  22. package/dist/src/commands/rebuild-command.js +66 -26
  23. package/dist/src/commands/rebuild-command.js.map +1 -1
  24. package/dist/src/commands/rebuild-integration.d.ts +13 -1
  25. package/dist/src/commands/rebuild-integration.js +535 -61
  26. package/dist/src/commands/rebuild-integration.js.map +1 -1
  27. package/dist/src/commands/rebuild-operations.d.ts +3 -1
  28. package/dist/src/commands/rebuild-operations.js +9 -5
  29. package/dist/src/commands/rebuild-operations.js.map +1 -1
  30. package/dist/src/generators/local-plugin.js +16 -0
  31. package/dist/src/generators/local-plugin.js.map +1 -1
  32. package/dist/src/generators/permissions.d.ts +5 -2
  33. package/dist/src/generators/permissions.js +28 -15
  34. package/dist/src/generators/permissions.js.map +1 -1
  35. package/dist/src/index.js +11 -0
  36. package/dist/src/index.js.map +1 -1
  37. package/dist/src/output/command-receipt.d.ts +3 -1
  38. package/dist/src/output/command-receipt.js +30 -9
  39. package/dist/src/output/command-receipt.js.map +1 -1
  40. package/dist/src/output/rebuild-progress.js +14 -0
  41. package/dist/src/output/rebuild-progress.js.map +1 -1
  42. package/dist/src/portable/materializer.js +3 -0
  43. package/dist/src/portable/materializer.js.map +1 -1
  44. package/dist/src/review/skill-materialization.d.ts +14 -1
  45. package/dist/src/review/skill-materialization.js +138 -0
  46. package/dist/src/review/skill-materialization.js.map +1 -1
  47. package/dist/src/tui/console-app-v4.js +19 -7
  48. package/dist/src/tui/console-app-v4.js.map +1 -1
  49. package/dist/src/tui/controller-runtime.js +23 -9
  50. package/dist/src/tui/controller-runtime.js.map +1 -1
  51. package/dist/src/tui/controller.d.ts +5 -1
  52. package/dist/src/tui/controller.js +24 -3
  53. package/dist/src/tui/controller.js.map +1 -1
  54. package/dist/src/tui/diagnostic-projection.js +34 -6
  55. package/dist/src/tui/diagnostic-projection.js.map +1 -1
  56. package/dist/src/tui/operation-review-planner.js +102 -16
  57. package/dist/src/tui/operation-review-planner.js.map +1 -1
  58. package/dist/src/types.d.ts +22 -2
  59. package/dist/src/types.js.map +1 -1
  60. package/dist/src/utils/artifact-plan.d.ts +4 -3
  61. package/dist/src/utils/artifact-plan.js +50 -7
  62. package/dist/src/utils/artifact-plan.js.map +1 -1
  63. package/dist/src/utils/artifact-renderer.d.ts +7 -3
  64. package/dist/src/utils/artifact-renderer.js +19 -6
  65. package/dist/src/utils/artifact-renderer.js.map +1 -1
  66. package/dist/src/utils/artifact-request.d.ts +16 -5
  67. package/dist/src/utils/artifact-request.js +27 -15
  68. package/dist/src/utils/artifact-request.js.map +1 -1
  69. package/dist/src/utils/artifact-sources.d.ts +4 -0
  70. package/dist/src/utils/artifact-sources.js +17 -0
  71. package/dist/src/utils/artifact-sources.js.map +1 -1
  72. package/dist/src/utils/bundle-layout.js +7 -0
  73. package/dist/src/utils/bundle-layout.js.map +1 -1
  74. package/dist/src/utils/claude-skills-root.d.ts +8 -0
  75. package/dist/src/utils/claude-skills-root.js +76 -0
  76. package/dist/src/utils/claude-skills-root.js.map +1 -0
  77. package/dist/src/utils/codex-skills-root.d.ts +4 -0
  78. package/dist/src/utils/codex-skills-root.js +25 -0
  79. package/dist/src/utils/codex-skills-root.js.map +1 -0
  80. package/dist/src/utils/dynamic-skill-tree.d.ts +1 -0
  81. package/dist/src/utils/dynamic-skill-tree.js +25 -6
  82. package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
  83. package/dist/src/utils/local-marketplace.d.ts +9 -0
  84. package/dist/src/utils/local-marketplace.js +170 -90
  85. package/dist/src/utils/local-marketplace.js.map +1 -1
  86. package/dist/src/utils/managed-command-closure.d.ts +3 -0
  87. package/dist/src/utils/managed-command-closure.js +35 -0
  88. package/dist/src/utils/managed-command-closure.js.map +1 -0
  89. package/dist/src/utils/managed-command-evidence.d.ts +7 -0
  90. package/dist/src/utils/managed-command-evidence.js +86 -0
  91. package/dist/src/utils/managed-command-evidence.js.map +1 -0
  92. package/dist/src/utils/managed-command-materialization.d.ts +106 -0
  93. package/dist/src/utils/managed-command-materialization.js +307 -0
  94. package/dist/src/utils/managed-command-materialization.js.map +1 -0
  95. package/dist/src/utils/managed-command-runtime.d.ts +32 -0
  96. package/dist/src/utils/managed-command-runtime.js +110 -0
  97. package/dist/src/utils/managed-command-runtime.js.map +1 -0
  98. package/dist/src/utils/managed-command-store.d.ts +124 -0
  99. package/dist/src/utils/managed-command-store.js +576 -0
  100. package/dist/src/utils/managed-command-store.js.map +1 -0
  101. package/dist/src/utils/ownership.d.ts +2 -0
  102. package/dist/src/utils/plugin-config-impact.d.ts +8 -1
  103. package/dist/src/utils/plugin-config-impact.js +101 -26
  104. package/dist/src/utils/plugin-config-impact.js.map +1 -1
  105. package/dist/src/utils/plugin-config-write.js +142 -60
  106. package/dist/src/utils/plugin-config-write.js.map +1 -1
  107. package/dist/src/utils/rendered-contract.js +18 -1
  108. package/dist/src/utils/rendered-contract.js.map +1 -1
  109. package/package.json +3 -3
@@ -1,9 +1,11 @@
1
+ import { getCommandPackageId } from '@lesliechan721/aw-plugin-core/manifest';
1
2
  import { flattenStatusTargets, statusCommandV8, statusTargetIntent, } from '../commands/status-v6.js';
2
3
  import { syncWriteCommand } from '../commands/write-commands.js';
3
4
  import { CONFIG_MUTATION_RECEIPT_SCHEMA_VERSION, } from '../types.js';
4
5
  import { getDefaultNativeCliRunner } from './native-cli.js';
5
6
  import { assertReadyPluginConfigStore, assertPluginConfigMutationCandidate, assertSafePluginConfigSegment, codexNativeRefreshKeys, coercePluginConfigUpdates, patchPluginConfigStore, readPluginConfigStore, readNamespacedPluginConfigStoreIdentity, resetPluginConfigStore, resolveConfigRead, resolveEffectivePluginConfig, resolvePluginConfigStorePath, resolvePluginConfigSchemaAccess, summarizeEffectivePluginConfig, } from './plugin-config.js';
6
- import { analyzePluginConfigMutationImpact } from './plugin-config-impact.js';
7
+ import { analyzePluginConfigMutationImpact, pluginSharedNativeConfigTargets } from './plugin-config-impact.js';
8
+ import { discoverInstalledPluginManagedCommandPackages, syncPluginManagedCommandPackage, } from './managed-command-materialization.js';
7
9
  import { collectSensitivePluginConfigValues, redactPluginScriptOutput, } from './plugin-scripts.js';
8
10
  import { resolveClaudeProjectKey, resolveCodexProjectKey } from './paths.js';
9
11
  import { withAwHomeMutationLock, } from './aw-home-mutation-lock.js';
@@ -51,7 +53,7 @@ function markConfigWriteFailed(error) {
51
53
  function skippedApply(reason) {
52
54
  return { state: 'skipped', reason, targetResults: [] };
53
55
  }
54
- function unavailableApply(reason, stage, targetResults = []) {
56
+ function unavailableApply(reason, stage, targetResults = [], commandPackages = []) {
55
57
  const messages = {
56
58
  invalidConfig: 'The effective config is invalid for every visible target.',
57
59
  schemaUnavailable: 'The config schema is unavailable after the config commit.',
@@ -63,6 +65,12 @@ function unavailableApply(reason, stage, targetResults = []) {
63
65
  state: 'unavailable',
64
66
  reason,
65
67
  targetResults,
68
+ ...(commandPackages.length > 0 ? { commandResults: commandPackages.map((target) => ({
69
+ producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
70
+ errors: [{ code: reason, message: messages[reason] }],
71
+ recoveryActions: [`aw command package sync ${target.producer.sourceId}/${target.producer.pluginName} ${target.packageKey} --scope ${target.producer.scope} --yes`,
72
+ `aw command package remove ${target.packageId} --yes`],
73
+ })) } : {}),
66
74
  error: { stage, code: reason, message: messages[reason] },
67
75
  };
68
76
  }
@@ -133,22 +141,21 @@ async function discoverVisibleTargets(options) {
133
141
  }
134
142
  async function reinstallVisibleTargets(options) {
135
143
  const nativeCliRunner = options.nativeCliRunner ?? getDefaultNativeCliRunner();
136
- const discovered = options.discovered ?? (options.applyTargets === undefined
137
- ? await discoverVisibleTargets({
138
- pluginName: options.plugin.manifest.name,
139
- plugin: options.plugin,
140
- scope: options.scope,
141
- cwd: options.cwd,
142
- env: options.env,
143
- nativeCliRunner,
144
- rebuildRuntime: options.rebuildRuntime,
145
- })
146
- : { targets: dedupeTargets(options.applyTargets), failures: [] });
144
+ const discovered = options.discovered ?? await resolveConfigApplyTargets(options);
147
145
  const targetResults = [...discovered.failures];
148
- let runtimeFailed = discovered.failures.length > 0;
146
+ const commandResults = new Map();
147
+ const managedCommandProducerCache = options.rebuildRuntime?.managedCommandProducerCache
148
+ ?? new Map();
149
+ let runtimeFailed = discovered.failures.length > 0
150
+ || (discovered.commandDiscoveryErrors?.length ?? 0) > 0;
149
151
  let invalidTargets = 0;
150
152
  let unavailableTargets = 0;
151
153
  const errors = [];
154
+ if ((discovered.commandDiscoveryErrors?.length ?? 0) > 0) {
155
+ errors.push(...discovered.commandDiscoveryErrors.map((error) => ({
156
+ stage: 'targetDiscovery', code: error.code, message: error.message,
157
+ })));
158
+ }
152
159
  const reinstall = options.reinstallCommandImpl ?? syncWriteCommand;
153
160
  if (options.plugin.sourceId && !options.plugin.pluginId) {
154
161
  throw new Error(`Plugin "${options.plugin.manifest.name}" is missing its namespaced plugin ID.`);
@@ -273,6 +280,7 @@ async function reinstallVisibleTargets(options) {
273
280
  nativeCliRunner,
274
281
  preApplyConfirmed: options.preApplyConfirmed === true,
275
282
  preApplyExecutionCache,
283
+ managedCommandProducerCache,
276
284
  ...(debugLogger ? {
277
285
  debugLogger: {
278
286
  ...debugLogger,
@@ -287,6 +295,11 @@ async function reinstallVisibleTargets(options) {
287
295
  } : {}),
288
296
  });
289
297
  options.rebuildRuntime?.operationDiagnosticSink?.(result.rebuildResults);
298
+ for (const producer of result.commandResults ?? []) {
299
+ commandResults.set(getCommandPackageId(producer.producer), producer);
300
+ if (producer.state !== 'completed')
301
+ runtimeFailed = true;
302
+ }
290
303
  if (result.overallState !== 'succeeded')
291
304
  runtimeFailed = true;
292
305
  targetResults.push(...await Promise.all(result.targetResults.map(async (entry) => ({
@@ -311,14 +324,63 @@ async function reinstallVisibleTargets(options) {
311
324
  });
312
325
  }
313
326
  }
314
- if (discovered.targets.length === 0 && discovered.failures.length === 0) {
327
+ for (const target of discovered.commandPackages ?? []) {
328
+ await options.rebuildRuntime?.reporter?.event({
329
+ type: 'managed-command:producer',
330
+ source: { plugin: options.plugin.manifest.name, scope: target.producer.scope },
331
+ data: { packageKey: target.packageKey, phase: 'start' },
332
+ });
333
+ let result;
334
+ if (!target.declared) {
335
+ result = {
336
+ producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
337
+ errors: [{ code: 'commandPackageDeclarationMissing',
338
+ message: 'The installed command package is no longer declared by this plugin.' }],
339
+ recoveryActions: [`aw command package remove ${target.packageId} --yes`],
340
+ };
341
+ }
342
+ else {
343
+ try {
344
+ result = await syncPluginManagedCommandPackage({
345
+ plugin: options.plugin, packageKey: target.packageKey, scope: target.producer.scope,
346
+ cwd: options.cwd, env: options.env, managedCommandProducerCache,
347
+ event: options.changedConfigKeys?.length ? 'refresh' : 'install',
348
+ changedConfigKeys: options.changedConfigKeys ?? [],
349
+ });
350
+ }
351
+ catch {
352
+ result = {
353
+ producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
354
+ errors: [{ code: 'commandPackageApplyFailed', message: 'The managed command package could not be refreshed.' }],
355
+ recoveryActions: [`aw command package sync ${selector} ${target.packageKey} --scope ${target.producer.scope} --yes`,
356
+ `aw command package remove ${target.packageId} --yes`],
357
+ };
358
+ }
359
+ }
360
+ result = { ...result, errors: await Promise.all(result.errors.map(async (error) => ({
361
+ ...error, message: await sanitizeFailure(error.message, { scope: target.producer.scope,
362
+ ...(target.producer.projectRoot ? { projectKey: target.producer.projectRoot } : {}) }),
363
+ }))) };
364
+ commandResults.set(getCommandPackageId(result.producer), result);
365
+ await options.rebuildRuntime?.reporter?.event({
366
+ type: 'managed-command:producer',
367
+ source: { plugin: options.plugin.manifest.name, scope: target.producer.scope },
368
+ data: { packageKey: target.packageKey, phase: result.state === 'completed' ? 'success' : 'failure' },
369
+ });
370
+ if (result.state !== 'completed')
371
+ runtimeFailed = true;
372
+ }
373
+ const commands = commandResults.size > 0 ? { commandResults: [...commandResults.values()] } : {};
374
+ const commandTargetCount = (discovered.commandPackages?.length ?? 0);
375
+ if (discovered.targets.length === 0 && discovered.failures.length === 0
376
+ && commandTargetCount === 0 && !runtimeFailed) {
315
377
  return skippedApply('noVisibleTarget');
316
378
  }
317
- if (discovered.targets.length > 0 && invalidTargets === discovered.targets.length) {
318
- return unavailableApply('invalidConfig', 'targetValidation', targetResults);
379
+ if (discovered.targets.length > 0 && invalidTargets === discovered.targets.length && commandTargetCount === 0) {
380
+ return { ...unavailableApply('invalidConfig', 'targetValidation', targetResults), ...commands };
319
381
  }
320
- if (discovered.targets.length > 0 && unavailableTargets === discovered.targets.length) {
321
- return unavailableApply('effectiveConfigUnavailable', 'targetValidation', targetResults);
382
+ if (discovered.targets.length > 0 && unavailableTargets === discovered.targets.length && commandTargetCount === 0) {
383
+ return { ...unavailableApply('effectiveConfigUnavailable', 'targetValidation', targetResults), ...commands };
322
384
  }
323
385
  if (runtimeFailed
324
386
  || invalidTargets > 0
@@ -327,30 +389,33 @@ async function reinstallVisibleTargets(options) {
327
389
  return {
328
390
  state: 'partial',
329
391
  targetResults,
392
+ ...commands,
330
393
  ...(errors.length > 0 ? { errors } : {}),
331
394
  };
332
395
  }
333
- return { state: 'succeeded', targetResults };
396
+ return { state: 'succeeded', targetResults, ...commands };
334
397
  }
335
398
  async function resolveConfigApplyTargets(options) {
336
- if (options.applyTargets !== undefined) {
337
- return { targets: dedupeTargets(options.applyTargets), failures: [] };
338
- }
339
- return discoverVisibleTargets({
340
- pluginName: options.plugin.manifest.name,
341
- plugin: options.plugin,
342
- scope: options.scope,
343
- cwd: options.cwd,
344
- env: options.env,
345
- nativeCliRunner: options.nativeCliRunner ?? getDefaultNativeCliRunner(),
346
- rebuildRuntime: options.rebuildRuntime,
399
+ const platformTargets = options.applyTargets !== undefined
400
+ ? { targets: dedupeTargets(options.applyTargets), failures: [] }
401
+ : await discoverVisibleTargets({
402
+ pluginName: options.plugin.manifest.name,
403
+ plugin: options.plugin,
404
+ scope: options.scope,
405
+ cwd: options.cwd,
406
+ env: options.env,
407
+ nativeCliRunner: options.nativeCliRunner ?? getDefaultNativeCliRunner(),
408
+ rebuildRuntime: options.rebuildRuntime,
409
+ });
410
+ const commands = await discoverInstalledPluginManagedCommandPackages({
411
+ plugin: options.plugin, scope: options.scope, cwd: options.cwd, env: options.env,
412
+ platformTargets: platformTargets.targets,
347
413
  });
414
+ return { ...platformTargets, commandPackages: commands.packages, commandDiscoveryErrors: commands.errors };
348
415
  }
349
- async function configApplyHasValidCodexTarget(options) {
350
- const codexScopes = new Set(options.targets
351
- .filter((target) => target.platform === 'codex')
352
- .map((target) => target.scope));
353
- for (const scope of codexScopes) {
416
+ async function configApplyHasValidSharedNativeTarget(options) {
417
+ const sharedTargets = pluginSharedNativeConfigTargets(options.plugin);
418
+ if (options.targets.some((target) => sharedTargets.some((shared) => (shared.platform ?? 'codex') === target.platform))) {
354
419
  const effective = await resolveEffectivePluginConfig({
355
420
  ...(options.plugin.sourceId ? {
356
421
  sourceId: options.plugin.sourceId,
@@ -359,7 +424,7 @@ async function configApplyHasValidCodexTarget(options) {
359
424
  } : {}),
360
425
  pluginName: options.plugin.manifest.name,
361
426
  manifest: options.plugin.manifest,
362
- targetScope: scope,
427
+ targetScope: 'user',
363
428
  cwd: options.cwd,
364
429
  env: options.env,
365
430
  });
@@ -383,6 +448,7 @@ async function applyConfigToVisibleTargets(options) {
383
448
  }
384
449
  if (discovered.targets.length === 0
385
450
  && discovered.failures.length === 0
451
+ && (discovered.commandPackages?.length ?? 0) === 0
386
452
  && options.noVisibleTargetHasInvalidConfig) {
387
453
  return unavailableApply('invalidConfig', 'targetValidation');
388
454
  }
@@ -577,11 +643,13 @@ export async function replayConfigRuntimeWrites(options) {
577
643
  };
578
644
  }
579
645
  discovered = {
646
+ ...discovered,
580
647
  targets: preApplyAuthorization.availableApplyTargets,
581
648
  failures: [...discovered.failures, ...preApplyAuthorization.unavailableTargetResults],
582
649
  };
583
650
  if (discovered.targets.length === 0
584
- && preApplyAuthorization.unavailableTargetResults.length > 0) {
651
+ && preApplyAuthorization.unavailableTargetResults.length > 0
652
+ && (discovered.commandPackages?.length ?? 0) === 0) {
585
653
  const apply = unavailableApply('sourceUnavailable', 'source', preApplyAuthorization.unavailableTargetResults);
586
654
  return {
587
655
  configWrite: 'succeeded',
@@ -593,7 +661,7 @@ export async function replayConfigRuntimeWrites(options) {
593
661
  if (options.scope === 'user'
594
662
  && options.sharedNativeApplyConfirmed !== true
595
663
  && pluginHasSharedNativeRefreshKeys(options.plugin)
596
- && await configApplyHasValidCodexTarget({
664
+ && await configApplyHasValidSharedNativeTarget({
597
665
  plugin: options.plugin,
598
666
  targets: discovered.targets,
599
667
  cwd: options.cwd,
@@ -623,13 +691,10 @@ export async function replayConfigRuntimeWrites(options) {
623
691
  });
624
692
  }
625
693
  function pluginHasSharedNativeRefreshKeys(plugin) {
626
- return (plugin.manifest.artifacts?.targets ?? []).some((target) => target.platform === 'codex'
627
- && target.target === 'codex.skill'
628
- && target.delivery?.mode === 'codex-native'
629
- && target.refreshKeys.length > 0);
694
+ return pluginSharedNativeConfigTargets(plugin).length > 0;
630
695
  }
631
696
  function throwSharedNativeApplyConfirmationRequired() {
632
- const error = new Error('sharedNativeConfigApplyConfirmationRequired: Applying this user config changes a shared Codex native artifact. Re-run with --yes.');
697
+ const error = new Error('sharedNativeConfigApplyConfirmationRequired: Applying this user config changes a shared native artifact. Re-run with --yes.');
633
698
  error.code = 'sharedNativeConfigApplyConfirmationRequired';
634
699
  throw error;
635
700
  }
@@ -713,6 +778,9 @@ async function applyPluginConfigWriteUnlocked(options) {
713
778
  cwd: options.cwd,
714
779
  env: options.env,
715
780
  visibleTargets: discovered?.targets ?? [],
781
+ ...(discovered ? { commandDiscovery: {
782
+ packages: discovered.commandPackages ?? [], errors: discovered.commandDiscoveryErrors ?? [],
783
+ } } : {}),
716
784
  mutation: {
717
785
  kind: 'patch',
718
786
  updates: requestedUpdates,
@@ -735,7 +803,8 @@ async function applyPluginConfigWriteUnlocked(options) {
735
803
  let preApplyUnavailableReason;
736
804
  let preApplyUnavailableTargetResults = [];
737
805
  let applyDiscovery = discovered
738
- ? { targets: impact.affectedTargets, failures: discovered.failures }
806
+ ? { ...discovered, targets: impact.affectedTargets, failures: discovered.failures,
807
+ commandPackages: impact.affectedCommandPackages }
739
808
  : undefined;
740
809
  const shouldApply = options.apply !== false && impact.storeChanged && !impact.noEffectiveChange;
741
810
  if (shouldApply && pluginMayRunPreApply(schemaPlugin)) {
@@ -759,10 +828,12 @@ async function applyPluginConfigWriteUnlocked(options) {
759
828
  }
760
829
  preApplyUnavailableTargetResults = preApplyAuthorization.unavailableTargetResults;
761
830
  applyDiscovery = {
831
+ ...applyDiscovery,
762
832
  targets: preApplyAuthorization.availableApplyTargets,
763
833
  failures: [...applyDiscovery.failures, ...preApplyUnavailableTargetResults],
764
834
  };
765
- if (applyDiscovery.targets.length === 0 && preApplyUnavailableTargetResults.length > 0) {
835
+ if (applyDiscovery.targets.length === 0 && preApplyUnavailableTargetResults.length > 0
836
+ && (applyDiscovery.commandPackages?.length ?? 0) === 0) {
766
837
  preApplyUnavailableReason = 'sourceUnavailable';
767
838
  }
768
839
  }
@@ -770,8 +841,8 @@ async function applyPluginConfigWriteUnlocked(options) {
770
841
  if (options.apply !== false
771
842
  && options.scope === 'user'
772
843
  && options.sharedNativeApplyConfirmed !== true
773
- && impact.sharedNativeRenderTargets.length > 0
774
- && impact.affectedTargets.some((target) => target.platform === 'codex')) {
844
+ && impact.sharedNativeRenderTargets.some((shared) => impact.affectedTargets
845
+ .some((target) => target.platform === (shared.platform ?? 'codex')))) {
775
846
  throwSharedNativeApplyConfirmationRequired();
776
847
  }
777
848
  if (impact.storeChanged) {
@@ -804,7 +875,7 @@ async function applyPluginConfigWriteUnlocked(options) {
804
875
  }));
805
876
  }
806
877
  catch {
807
- const apply = unavailableApply('effectiveConfigUnavailable', 'effectiveConfig');
878
+ const apply = unavailableApply('effectiveConfigUnavailable', 'effectiveConfig', [], impact.affectedCommandPackages);
808
879
  const otherProjectsMayRequireSync = options.scope === 'user' && impact.storeChanged;
809
880
  if (otherProjectsMayRequireSync)
810
881
  warnings.push(...otherProjectsWarning(options.scope));
@@ -831,7 +902,7 @@ async function applyPluginConfigWriteUnlocked(options) {
831
902
  : targetDiscoveryFailed
832
903
  ? unavailableApply('targetDiscoveryFailed', 'targetDiscovery')
833
904
  : impact.noEffectiveChange
834
- && ((discovered?.targets.length ?? 0) > 0
905
+ && ((discovered?.targets.length ?? 0) + impact.commandPackages.length > 0
835
906
  || staleRemovedKeys.length === impact.changedKeys.length)
836
907
  ? skippedApply('noEffectiveConfigChange')
837
908
  : preApplyUnavailableReason
@@ -849,6 +920,7 @@ async function applyPluginConfigWriteUnlocked(options) {
849
920
  && effective.issues.length > 0,
850
921
  preApplyConfirmed: options.preApplyConfirmed,
851
922
  discovered: applyDiscovery,
923
+ changedConfigKeys: impact.changedKeys,
852
924
  });
853
925
  }
854
926
  catch (error) {
@@ -1017,10 +1089,11 @@ async function resetPluginConfigWithHelperUnlocked(options) {
1017
1089
  let impact;
1018
1090
  let targetDiscoveryFailed = false;
1019
1091
  let visibleTargets = [];
1092
+ let discovered;
1020
1093
  if (options.plugin) {
1021
1094
  if (options.apply !== false) {
1022
1095
  try {
1023
- visibleTargets = (await resolveConfigApplyTargets({
1096
+ discovered = await resolveConfigApplyTargets({
1024
1097
  plugin: options.plugin,
1025
1098
  scope: options.scope,
1026
1099
  cwd: options.cwd,
@@ -1028,7 +1101,8 @@ async function resetPluginConfigWithHelperUnlocked(options) {
1028
1101
  applyTargets: options.applyTargets,
1029
1102
  nativeCliRunner: options.nativeCliRunner,
1030
1103
  rebuildRuntime: options.rebuildRuntime,
1031
- })).targets;
1104
+ });
1105
+ visibleTargets = discovered.targets;
1032
1106
  }
1033
1107
  catch {
1034
1108
  targetDiscoveryFailed = true;
@@ -1041,6 +1115,9 @@ async function resetPluginConfigWithHelperUnlocked(options) {
1041
1115
  cwd: options.cwd,
1042
1116
  env: options.env,
1043
1117
  visibleTargets,
1118
+ ...(discovered ? { commandDiscovery: {
1119
+ packages: discovered.commandPackages ?? [], errors: discovered.commandDiscoveryErrors ?? [],
1120
+ } } : {}),
1044
1121
  mutation: { kind: 'reset' },
1045
1122
  });
1046
1123
  removedKeys = impact.removedKeys;
@@ -1052,7 +1129,9 @@ async function resetPluginConfigWithHelperUnlocked(options) {
1052
1129
  let preApplyUnavailableReason;
1053
1130
  let preApplyUnavailableTargetResults = [];
1054
1131
  let applyDiscovery = options.plugin && !targetDiscoveryFailed
1055
- ? { targets: impact?.affectedTargets ?? visibleTargets, failures: [] }
1132
+ ? { targets: impact?.affectedTargets ?? visibleTargets, failures: [],
1133
+ commandPackages: impact?.affectedCommandPackages ?? discovered?.commandPackages,
1134
+ commandDiscoveryErrors: impact?.commandDiscoveryErrors ?? discovered?.commandDiscoveryErrors }
1056
1135
  : undefined;
1057
1136
  if (options.plugin
1058
1137
  && options.apply !== false
@@ -1079,10 +1158,12 @@ async function resetPluginConfigWithHelperUnlocked(options) {
1079
1158
  }
1080
1159
  preApplyUnavailableTargetResults = preApplyAuthorization.unavailableTargetResults;
1081
1160
  applyDiscovery = {
1161
+ ...applyDiscovery,
1082
1162
  targets: preApplyAuthorization.availableApplyTargets,
1083
1163
  failures: preApplyUnavailableTargetResults,
1084
1164
  };
1085
- if (applyDiscovery.targets.length === 0 && preApplyUnavailableTargetResults.length > 0) {
1165
+ if (applyDiscovery.targets.length === 0 && preApplyUnavailableTargetResults.length > 0
1166
+ && (applyDiscovery.commandPackages?.length ?? 0) === 0) {
1086
1167
  preApplyUnavailableReason = 'sourceUnavailable';
1087
1168
  }
1088
1169
  }
@@ -1091,10 +1172,10 @@ async function resetPluginConfigWithHelperUnlocked(options) {
1091
1172
  && options.scope === 'user'
1092
1173
  && options.sharedNativeApplyConfirmed !== true
1093
1174
  && (impact
1094
- ? impact.sharedNativeRenderTargets.length > 0
1095
- && impact.affectedTargets.some((target) => target.platform === 'codex')
1096
- : pluginHasSharedNativeRefreshKeys(options.plugin))
1097
- && visibleTargets.some((target) => target.platform === 'codex')) {
1175
+ ? impact.sharedNativeRenderTargets.some((shared) => impact.affectedTargets
1176
+ .some((target) => target.platform === (shared.platform ?? 'codex')))
1177
+ : pluginSharedNativeConfigTargets(options.plugin).some((shared) => visibleTargets
1178
+ .some((target) => target.platform === (shared.platform ?? 'codex'))))) {
1098
1179
  throwSharedNativeApplyConfirmationRequired();
1099
1180
  }
1100
1181
  let reset;
@@ -1142,14 +1223,14 @@ async function resetPluginConfigWithHelperUnlocked(options) {
1142
1223
  }
1143
1224
  catch {
1144
1225
  if (reset.deleted && options.apply !== false) {
1145
- apply = unavailableApply('effectiveConfigUnavailable', 'effectiveConfig');
1226
+ apply = unavailableApply('effectiveConfigUnavailable', 'effectiveConfig', [], impact?.affectedCommandPackages);
1146
1227
  }
1147
1228
  }
1148
1229
  if (reset.deleted
1149
1230
  && options.apply !== false
1150
1231
  && apply.state === 'skipped'
1151
1232
  && impact?.noEffectiveChange
1152
- && visibleTargets.length > 0) {
1233
+ && visibleTargets.length + (impact?.commandPackages.length ?? 0) > 0) {
1153
1234
  apply = skippedApply('noEffectiveConfigChange');
1154
1235
  }
1155
1236
  else if (reset.deleted
@@ -1173,6 +1254,7 @@ async function resetPluginConfigWithHelperUnlocked(options) {
1173
1254
  noVisibleTargetHasInvalidConfig: (effective?.issues.length ?? 0) > 0,
1174
1255
  preApplyConfirmed: options.preApplyConfirmed,
1175
1256
  discovered: applyDiscovery,
1257
+ changedConfigKeys: impact?.changedKeys ?? removedKeys,
1176
1258
  });
1177
1259
  }
1178
1260
  }