@lesliechan721/aw 0.1.0-beta.64 → 0.1.0-beta.65

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 (302) hide show
  1. package/dist/authoring/assets/aw-runtime-config.mjs +3 -3
  2. package/dist/authoring/assets/aw-runtime-config.mjs.map +1 -1
  3. package/dist/authoring/scripts/add-skill.mjs +3 -17
  4. package/dist/authoring/scripts/add-skill.mjs.map +1 -1
  5. package/dist/authoring/scripts/init-plugin.mjs +1 -0
  6. package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
  7. package/dist/authoring/scripts/lib/plugin-version-check.mjs +1 -1
  8. package/dist/authoring/scripts/lib/skill-scaffold.d.mts +2 -0
  9. package/dist/authoring/scripts/lib/skill-scaffold.mjs +2 -0
  10. package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -1
  11. package/dist/authoring/scripts/validate-plugin.mjs +95 -698
  12. package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
  13. package/dist/scripts/aw-skill-eval-materializer.d.ts +2 -0
  14. package/dist/scripts/aw-skill-eval-materializer.js +74 -44
  15. package/dist/scripts/aw-skill-eval-materializer.js.map +1 -1
  16. package/dist/scripts/bundle-plugins.js +10 -2
  17. package/dist/scripts/bundle-plugins.js.map +1 -1
  18. package/dist/scripts/plugin-staging.d.ts +1 -1
  19. package/dist/scripts/plugin-staging.js +1 -1
  20. package/dist/scripts/plugin-staging.js.map +1 -1
  21. package/dist/scripts/test-plugin-scripts.js +31 -31
  22. package/dist/scripts/test-plugin-scripts.js.map +1 -1
  23. package/dist/src/commands/aw-capabilities.d.ts +1 -1
  24. package/dist/src/commands/aw-capabilities.js +2 -0
  25. package/dist/src/commands/aw-capabilities.js.map +1 -1
  26. package/dist/src/commands/console.js +4 -3
  27. package/dist/src/commands/console.js.map +1 -1
  28. package/dist/src/commands/intent-command.d.ts +30 -0
  29. package/dist/src/commands/intent-command.js +164 -0
  30. package/dist/src/commands/intent-command.js.map +1 -0
  31. package/dist/src/commands/operation-plan.d.ts +2 -0
  32. package/dist/src/commands/operation-plan.js +2 -1
  33. package/dist/src/commands/operation-plan.js.map +1 -1
  34. package/dist/src/commands/options.d.ts +3 -11
  35. package/dist/src/commands/options.js +11 -17
  36. package/dist/src/commands/options.js.map +1 -1
  37. package/dist/src/commands/plugin-capabilities.js +27 -33
  38. package/dist/src/commands/plugin-capabilities.js.map +1 -1
  39. package/dist/src/commands/rebuild-command.d.ts +108 -6
  40. package/dist/src/commands/rebuild-command.js +617 -1549
  41. package/dist/src/commands/rebuild-command.js.map +1 -1
  42. package/dist/src/commands/rebuild-integration.d.ts +19 -3
  43. package/dist/src/commands/rebuild-integration.js +500 -459
  44. package/dist/src/commands/rebuild-integration.js.map +1 -1
  45. package/dist/src/commands/rebuild-operations.js +1 -2
  46. package/dist/src/commands/rebuild-operations.js.map +1 -1
  47. package/dist/src/commands/review-inspection.d.ts +2 -2
  48. package/dist/src/commands/review-inspection.js +30 -86
  49. package/dist/src/commands/review-inspection.js.map +1 -1
  50. package/dist/src/commands/review-preparation.js +16 -7
  51. package/dist/src/commands/review-preparation.js.map +1 -1
  52. package/dist/src/commands/skill-eval.d.ts +2 -0
  53. package/dist/src/commands/skill-eval.js +15 -9
  54. package/dist/src/commands/skill-eval.js.map +1 -1
  55. package/dist/src/commands/status-v6.d.ts +38 -5
  56. package/dist/src/commands/status-v6.js +269 -102
  57. package/dist/src/commands/status-v6.js.map +1 -1
  58. package/dist/src/commands/targets-command.d.ts +27 -0
  59. package/dist/src/commands/targets-command.js +77 -0
  60. package/dist/src/commands/targets-command.js.map +1 -0
  61. package/dist/src/commands/write-commands.js +5 -5
  62. package/dist/src/commands/write-commands.js.map +1 -1
  63. package/dist/src/eval/manifest-v1.d.ts +2 -0
  64. package/dist/src/eval/manifest-v1.js +7 -2
  65. package/dist/src/eval/manifest-v1.js.map +1 -1
  66. package/dist/src/generators/local-plugin.d.ts +2 -1
  67. package/dist/src/generators/local-plugin.js +111 -108
  68. package/dist/src/generators/local-plugin.js.map +1 -1
  69. package/dist/src/index.d.ts +10 -17
  70. package/dist/src/index.js +585 -1349
  71. package/dist/src/index.js.map +1 -1
  72. package/dist/src/intent/deployment-preferences.d.ts +63 -0
  73. package/dist/src/intent/deployment-preferences.js +170 -0
  74. package/dist/src/intent/deployment-preferences.js.map +1 -0
  75. package/dist/src/intent/diagnostics.d.ts +11 -0
  76. package/dist/src/intent/diagnostics.js +14 -0
  77. package/dist/src/intent/diagnostics.js.map +1 -0
  78. package/dist/src/intent/intent-codec.d.ts +19 -0
  79. package/dist/src/intent/intent-codec.js +117 -0
  80. package/dist/src/intent/intent-codec.js.map +1 -0
  81. package/dist/src/intent/intent-store.d.ts +43 -0
  82. package/dist/src/intent/intent-store.js +118 -0
  83. package/dist/src/intent/intent-store.js.map +1 -0
  84. package/dist/src/intent/scope-context.d.ts +33 -0
  85. package/dist/src/intent/scope-context.js +145 -0
  86. package/dist/src/intent/scope-context.js.map +1 -0
  87. package/dist/src/intent/work-context.d.ts +13 -0
  88. package/dist/src/intent/work-context.js +22 -0
  89. package/dist/src/intent/work-context.js.map +1 -0
  90. package/dist/src/output/command-receipt.js +16 -9
  91. package/dist/src/output/command-receipt.js.map +1 -1
  92. package/dist/src/portable/commands.d.ts +18 -8
  93. package/dist/src/portable/commands.js +46 -562
  94. package/dist/src/portable/commands.js.map +1 -1
  95. package/dist/src/portable/historical-materialization.d.ts +22 -0
  96. package/dist/src/portable/historical-materialization.js +124 -0
  97. package/dist/src/portable/historical-materialization.js.map +1 -0
  98. package/dist/src/portable/materializer.d.ts +8 -0
  99. package/dist/src/portable/materializer.js +75 -44
  100. package/dist/src/portable/materializer.js.map +1 -1
  101. package/dist/src/portable/recovery-layout.d.ts +17 -0
  102. package/dist/src/portable/recovery-layout.js +55 -0
  103. package/dist/src/portable/recovery-layout.js.map +1 -0
  104. package/dist/src/portable/recovery.d.ts +143 -0
  105. package/dist/src/portable/recovery.js +339 -0
  106. package/dist/src/portable/recovery.js.map +1 -0
  107. package/dist/src/portable/writer.d.ts +64 -0
  108. package/dist/src/portable/writer.js +316 -0
  109. package/dist/src/portable/writer.js.map +1 -0
  110. package/dist/src/recovery/coordinator.d.ts +137 -0
  111. package/dist/src/recovery/coordinator.js +1198 -0
  112. package/dist/src/recovery/coordinator.js.map +1 -0
  113. package/dist/src/recovery/demand.d.ts +44 -0
  114. package/dist/src/recovery/demand.js +178 -0
  115. package/dist/src/recovery/demand.js.map +1 -0
  116. package/dist/src/recovery/joint-coordinator.d.ts +24 -0
  117. package/dist/src/recovery/joint-coordinator.js +770 -0
  118. package/dist/src/recovery/joint-coordinator.js.map +1 -0
  119. package/dist/src/recovery/joint-demand.d.ts +68 -0
  120. package/dist/src/recovery/joint-demand.js +166 -0
  121. package/dist/src/recovery/joint-demand.js.map +1 -0
  122. package/dist/src/recovery/receipt.d.ts +81 -0
  123. package/dist/src/recovery/receipt.js +2 -0
  124. package/dist/src/recovery/receipt.js.map +1 -0
  125. package/dist/src/recovery/retirement.d.ts +45 -0
  126. package/dist/src/recovery/retirement.js +366 -0
  127. package/dist/src/recovery/retirement.js.map +1 -0
  128. package/dist/src/recovery/status.d.ts +108 -0
  129. package/dist/src/recovery/status.js +417 -0
  130. package/dist/src/recovery/status.js.map +1 -0
  131. package/dist/src/recovery/types.d.ts +86 -0
  132. package/dist/src/recovery/types.js +2 -0
  133. package/dist/src/recovery/types.js.map +1 -0
  134. package/dist/src/review/review-profile.d.ts +2 -1
  135. package/dist/src/review/review-profile.js +15 -15
  136. package/dist/src/review/review-profile.js.map +1 -1
  137. package/dist/src/review/review-selection.d.ts +1 -2
  138. package/dist/src/review/review-selection.js +40 -114
  139. package/dist/src/review/review-selection.js.map +1 -1
  140. package/dist/src/review/review-types.d.ts +4 -4
  141. package/dist/src/review/review-types.js.map +1 -1
  142. package/dist/src/review/skill-materialization.js +15 -6
  143. package/dist/src/review/skill-materialization.js.map +1 -1
  144. package/dist/src/review/source-binding.d.ts +14 -4
  145. package/dist/src/review/source-binding.js +62 -117
  146. package/dist/src/review/source-binding.js.map +1 -1
  147. package/dist/src/tui/agent-management.d.ts +23 -0
  148. package/dist/src/tui/agent-management.js +217 -0
  149. package/dist/src/tui/agent-management.js.map +1 -0
  150. package/dist/src/tui/agent-settings.d.ts +44 -0
  151. package/dist/src/tui/agent-settings.js +98 -0
  152. package/dist/src/tui/agent-settings.js.map +1 -0
  153. package/dist/src/tui/components.d.ts +3 -0
  154. package/dist/src/tui/components.js +10 -1
  155. package/dist/src/tui/components.js.map +1 -1
  156. package/dist/src/tui/config-references.d.ts +6 -3
  157. package/dist/src/tui/config-references.js +17 -12
  158. package/dist/src/tui/config-references.js.map +1 -1
  159. package/dist/src/tui/console-app-v4.d.ts +1 -2
  160. package/dist/src/tui/console-app-v4.js +1533 -1047
  161. package/dist/src/tui/console-app-v4.js.map +1 -1
  162. package/dist/src/tui/controller-runtime.d.ts +2 -1
  163. package/dist/src/tui/controller-runtime.js +405 -1626
  164. package/dist/src/tui/controller-runtime.js.map +1 -1
  165. package/dist/src/tui/controller.d.ts +131 -81
  166. package/dist/src/tui/controller.js +307 -227
  167. package/dist/src/tui/controller.js.map +1 -1
  168. package/dist/src/tui/entity-cards.d.ts +2 -2
  169. package/dist/src/tui/entity-cards.js +98 -20
  170. package/dist/src/tui/entity-cards.js.map +1 -1
  171. package/dist/src/tui/glossary.d.ts +2 -0
  172. package/dist/src/tui/glossary.js +20 -0
  173. package/dist/src/tui/glossary.js.map +1 -1
  174. package/dist/src/tui/model.d.ts +28 -10
  175. package/dist/src/tui/model.js +41 -41
  176. package/dist/src/tui/model.js.map +1 -1
  177. package/dist/src/tui/operation-review-planner.d.ts +2 -0
  178. package/dist/src/tui/operation-review-planner.js +58 -122
  179. package/dist/src/tui/operation-review-planner.js.map +1 -1
  180. package/dist/src/tui/plugin-content.js +7 -4
  181. package/dist/src/tui/plugin-content.js.map +1 -1
  182. package/dist/src/tui/plugin-detail.d.ts +22 -3
  183. package/dist/src/tui/plugin-detail.js +113 -26
  184. package/dist/src/tui/plugin-detail.js.map +1 -1
  185. package/dist/src/tui/reader.d.ts +1 -0
  186. package/dist/src/tui/reader.js +3 -1
  187. package/dist/src/tui/reader.js.map +1 -1
  188. package/dist/src/tui/router.d.ts +23 -33
  189. package/dist/src/tui/router.js.map +1 -1
  190. package/dist/src/tui/scoped-flow.d.ts +45 -0
  191. package/dist/src/tui/scoped-flow.js +96 -0
  192. package/dist/src/tui/scoped-flow.js.map +1 -0
  193. package/dist/src/tui/scoped-inventory.d.ts +122 -0
  194. package/dist/src/tui/scoped-inventory.js +225 -0
  195. package/dist/src/tui/scoped-inventory.js.map +1 -0
  196. package/dist/src/tui/screen-registry.d.ts +25 -25
  197. package/dist/src/tui/screen-registry.js +3 -7
  198. package/dist/src/tui/screen-registry.js.map +1 -1
  199. package/dist/src/tui/session-console-app.js +1 -1
  200. package/dist/src/tui/session-console-app.js.map +1 -1
  201. package/dist/src/tui/session-host.js +12 -2
  202. package/dist/src/tui/session-host.js.map +1 -1
  203. package/dist/src/types.d.ts +15 -12
  204. package/dist/src/types.js.map +1 -1
  205. package/dist/src/utils/agent-version.js +2 -0
  206. package/dist/src/utils/agent-version.js.map +1 -1
  207. package/dist/src/utils/artifact-plan.js +13 -6
  208. package/dist/src/utils/artifact-plan.js.map +1 -1
  209. package/dist/src/utils/artifact-renderer.d.ts +6 -3
  210. package/dist/src/utils/artifact-renderer.js +27 -32
  211. package/dist/src/utils/artifact-renderer.js.map +1 -1
  212. package/dist/src/utils/artifact-request.d.ts +1 -0
  213. package/dist/src/utils/artifact-request.js +22 -12
  214. package/dist/src/utils/artifact-request.js.map +1 -1
  215. package/dist/src/utils/artifact-sources.d.ts +2 -2
  216. package/dist/src/utils/bundle-layout.js +18 -16
  217. package/dist/src/utils/bundle-layout.js.map +1 -1
  218. package/dist/src/utils/catalog-digests.js +2 -0
  219. package/dist/src/utils/catalog-digests.js.map +1 -1
  220. package/dist/src/utils/catalog-runtime-projection.d.ts +4 -3
  221. package/dist/src/utils/catalog-runtime-projection.js.map +1 -1
  222. package/dist/src/utils/catalog-source-references.d.ts +5 -0
  223. package/dist/src/utils/catalog-source-references.js +42 -57
  224. package/dist/src/utils/catalog-source-references.js.map +1 -1
  225. package/dist/src/utils/claude-native-render-receipt.d.ts +14 -0
  226. package/dist/src/utils/claude-native-render-receipt.js +26 -0
  227. package/dist/src/utils/claude-native-render-receipt.js.map +1 -0
  228. package/dist/src/utils/claude-skills-root.js +14 -3
  229. package/dist/src/utils/claude-skills-root.js.map +1 -1
  230. package/dist/src/utils/codex-manager.js +6 -12
  231. package/dist/src/utils/codex-manager.js.map +1 -1
  232. package/dist/src/utils/codex-native-observation.js +29 -13
  233. package/dist/src/utils/codex-native-observation.js.map +1 -1
  234. package/dist/src/utils/codex-reconciler.d.ts +2 -5
  235. package/dist/src/utils/codex-reconciler.js +25 -1
  236. package/dist/src/utils/codex-reconciler.js.map +1 -1
  237. package/dist/src/utils/codex-surface-analysis.js +5 -3
  238. package/dist/src/utils/codex-surface-analysis.js.map +1 -1
  239. package/dist/src/utils/local-marketplace.d.ts +14 -2
  240. package/dist/src/utils/local-marketplace.js +209 -42
  241. package/dist/src/utils/local-marketplace.js.map +1 -1
  242. package/dist/src/utils/managed-command-evidence.js +1 -1
  243. package/dist/src/utils/managed-command-evidence.js.map +1 -1
  244. package/dist/src/utils/managed-command-materialization.d.ts +4 -0
  245. package/dist/src/utils/managed-command-materialization.js +15 -6
  246. package/dist/src/utils/managed-command-materialization.js.map +1 -1
  247. package/dist/src/utils/managed-command-store.d.ts +15 -0
  248. package/dist/src/utils/managed-command-store.js +73 -8
  249. package/dist/src/utils/managed-command-store.js.map +1 -1
  250. package/dist/src/utils/native-cli.d.ts +2 -0
  251. package/dist/src/utils/native-cli.js +22 -0
  252. package/dist/src/utils/native-cli.js.map +1 -1
  253. package/dist/src/utils/native-demand.d.ts +10 -0
  254. package/dist/src/utils/native-demand.js +4 -0
  255. package/dist/src/utils/native-demand.js.map +1 -0
  256. package/dist/src/utils/ownership.js +2 -0
  257. package/dist/src/utils/ownership.js.map +1 -1
  258. package/dist/src/utils/paths.js +1 -1
  259. package/dist/src/utils/paths.js.map +1 -1
  260. package/dist/src/utils/platform-support.d.ts +1 -1
  261. package/dist/src/utils/platform-support.js +1 -1
  262. package/dist/src/utils/platform-support.js.map +1 -1
  263. package/dist/src/utils/plugin-config-impact.d.ts +3 -0
  264. package/dist/src/utils/plugin-config-impact.js +115 -273
  265. package/dist/src/utils/plugin-config-impact.js.map +1 -1
  266. package/dist/src/utils/plugin-config-references.d.ts +9 -2
  267. package/dist/src/utils/plugin-config-references.js +75 -85
  268. package/dist/src/utils/plugin-config-references.js.map +1 -1
  269. package/dist/src/utils/plugin-config-write.d.ts +58 -1
  270. package/dist/src/utils/plugin-config-write.js +756 -809
  271. package/dist/src/utils/plugin-config-write.js.map +1 -1
  272. package/dist/src/utils/plugin-config.d.ts +47 -46
  273. package/dist/src/utils/plugin-config.js +292 -833
  274. package/dist/src/utils/plugin-config.js.map +1 -1
  275. package/dist/src/utils/plugin-scripts.d.ts +11 -6
  276. package/dist/src/utils/plugin-scripts.js +52 -35
  277. package/dist/src/utils/plugin-scripts.js.map +1 -1
  278. package/dist/src/utils/runtime-config.js +5 -4
  279. package/dist/src/utils/runtime-config.js.map +1 -1
  280. package/dist/src/utils/runtime-skill-closure.d.ts +2 -2
  281. package/dist/src/utils/runtime-skill-closure.js.map +1 -1
  282. package/dist/src/utils/state-paths.d.ts +8 -3
  283. package/dist/src/utils/state-paths.js +53 -16
  284. package/dist/src/utils/state-paths.js.map +1 -1
  285. package/dist/src/utils/windows-npm-shim.d.ts +2 -0
  286. package/dist/src/utils/windows-npm-shim.js +5 -7
  287. package/dist/src/utils/windows-npm-shim.js.map +1 -1
  288. package/dist/vitest.config.js +1 -0
  289. package/dist/vitest.config.js.map +1 -1
  290. package/package.json +3 -3
  291. package/dist/src/commands/sync-command.d.ts +0 -40
  292. package/dist/src/commands/sync-command.js +0 -254
  293. package/dist/src/commands/sync-command.js.map +0 -1
  294. package/dist/src/portable/skills-cli.d.ts +0 -51
  295. package/dist/src/portable/skills-cli.js +0 -202
  296. package/dist/src/portable/skills-cli.js.map +0 -1
  297. package/dist/src/tui/project-inventory.d.ts +0 -68
  298. package/dist/src/tui/project-inventory.js +0 -203
  299. package/dist/src/tui/project-inventory.js.map +0 -1
  300. package/dist/src/utils/plugin-intent-state.d.ts +0 -49
  301. package/dist/src/utils/plugin-intent-state.js +0 -320
  302. package/dist/src/utils/plugin-intent-state.js.map +0 -1
@@ -1,3 +1,5 @@
1
+ import { selectAgents } from '../intent/deployment-preferences.js';
2
+ import { readDemand, demandNativeProjection } from '../recovery/demand.js';
1
3
  import fs from 'node:fs';
2
4
  import path from 'node:path';
3
5
  import { analyzeCodexSurface } from '../utils/codex-surface-analysis.js';
@@ -14,13 +16,13 @@ import { parsePlatformValue, parseScopeValue } from './options.js';
14
16
  import { inspectCodexPluginRegistrationLive, inspectCodexSharedNativeLive, inspectRebuildTarget, } from './rebuild-integration.js';
15
17
  import { createNoopReporter } from '../output/reporter.js';
16
18
  import { createNoopDebugLogger } from '../output/debug-log.js';
17
- import { getDefaultNativeCliRunner } from '../utils/native-cli.js';
19
+ import { bindNativeCliRunnerSignal, getDefaultNativeCliRunner } from '../utils/native-cli.js';
18
20
  import { createCodexNativeObservationSession, } from '../utils/codex-native-observation.js';
19
21
  import { resolveAwHome } from '../utils/paths.js';
20
- import { codexProjectConfigAliasesUserHome, createProjectLocationKey, getClaudeHome, getCodexHome, resolveCanonicalRepoProjectKey, } from '../utils/state-paths.js';
22
+ import { codexProjectConfigAliasesUserHome, createProjectLocationKey, getClaudeHome, getCodexHome, resolveRequiredCanonicalRepoRoot, } from '../utils/state-paths.js';
21
23
  import { resolveEffectivePluginConfig, resolveProjectArtifactRenderConfig, } from '../utils/plugin-config.js';
22
24
  import { readCodexConfigFile } from '../utils/codex-config.js';
23
- import { observePluginIntentState, } from '../utils/plugin-intent-state.js';
25
+ import { createEmptyNativeDemandView } from '../utils/native-demand.js';
24
26
  import { IMPLEMENTED_AW_CAPABILITIES } from './aw-capabilities.js';
25
27
  import { createDependencyPlacementPlan } from './dependency-operation-plan.js';
26
28
  import { getCodexOperationRequirement } from '../utils/agent-version.js';
@@ -44,6 +46,16 @@ export function statusTargetPlacements(target) {
44
46
  export function flattenStatusTargets(targets) {
45
47
  return targets.flatMap(statusTargetPlacements);
46
48
  }
49
+ /** Existing output evidence is required before config apply can refresh a target. */
50
+ export function statusTargetHasLiveConfigConsumer(target) {
51
+ return target.components.some((component) => component.kind === 'ownership'
52
+ && (target.platform !== 'codex' || (component.key !== 'native'
53
+ && !component.key.startsWith('activation-') && !component.key.startsWith('marketplace-')))
54
+ && ['present', 'partial'].includes(component.state))
55
+ || (target.sharedComponents?.some((component) => component.kind === 'sharedNative' && ['usable', 'replaceable'].includes(component.state)) === true
56
+ && target.components.some((component) => component.kind === 'activation'
57
+ && component.key === target.scope && component.state === 'enabled'));
58
+ }
47
59
  export function projectStatusSharedNativeReasons(sharedNative, existingReasonCodes = [], desiredEnabled = false) {
48
60
  if (!sharedNative)
49
61
  return [];
@@ -297,14 +309,7 @@ function selectedPlatforms(value) {
297
309
  function selectedScopes(value) {
298
310
  return value === undefined ? ['user', 'project'] : [parseScopeValue(value)];
299
311
  }
300
- function emptyIntent() {
301
- return {
302
- schemaVersion: 2,
303
- kind: 'aw-plugin-intents',
304
- roots: [],
305
- dependencyScopeOverrides: [],
306
- };
307
- }
312
+ const emptyIntent = createEmptyNativeDemandView;
308
313
  function desiredTargetKey(pluginId, platform) {
309
314
  return `${pluginId}\0${platform}`;
310
315
  }
@@ -396,7 +401,7 @@ function calculateDesiredTargetStates(options) {
396
401
  nodes,
397
402
  roots,
398
403
  dependencyEdges: edges,
399
- scopeOverrides: intent.dependencyScopeOverrides.filter((override) => nodeIds.has(override.pluginId)
404
+ scopeOverrides: (intent.dependencyScopeOverrides ?? []).filter((override) => nodeIds.has(override.pluginId)
400
405
  && (override.platform === undefined || override.platform === platform)),
401
406
  });
402
407
  for (const target of plan.targets) {
@@ -476,7 +481,7 @@ export function statusRecovery(options) {
476
481
  }] : []),
477
482
  {
478
483
  command: 'manual',
479
- description: `共享内容已损坏。先明确选择 user 或 project 使用范围,再运行 aw install ${options.pluginId} --platform codex --scope <user|project> 重建。`,
484
+ description: `共享内容已损坏。先确认本机 Agent 选择,明确 user 或 project 使用范围,再运行 aw plugin install ${options.pluginId} --scope <user|project> 重建。`,
480
485
  },
481
486
  ];
482
487
  }
@@ -502,7 +507,7 @@ export function statusRecovery(options) {
502
507
  return (options.conflictRoots?.[scope] ?? []).map((rootPluginId) => ({
503
508
  command: 'uninstall',
504
509
  scope,
505
- description: `运行 aw uninstall ${rootPluginId} --platform ${options.platform} --scope ${scope},再运行 aw sync ${retainedRoot} --platform ${options.platform} --scope ${retainedScope}。`,
510
+ description: `运行 aw plugin intent remove ${rootPluginId} --scope ${scope},再运行 aw plugin cleanup ${rootPluginId} --target ${options.platform} --scope ${scope},最后运行 aw plugin sync ${retainedRoot} --target ${options.platform} --context ${retainedScope}。`,
506
511
  }));
507
512
  });
508
513
  }
@@ -512,17 +517,16 @@ export function statusRecovery(options) {
512
517
  return [
513
518
  {
514
519
  command: 'sync',
515
- description: `先移除或重命名 ${collision},再运行 aw sync ${options.pluginId} --platform ${options.platform}。cleanup 会保留 foreign 内容,不会删除该冲突。`,
520
+ description: `先移除或重命名 ${collision},再运行 aw plugin sync ${options.pluginId} --target ${options.platform} --context ${options.scope ?? 'user'}。cleanup 会保留 foreign 内容,不会删除该冲突。`,
516
521
  },
517
522
  ];
518
523
  }
519
524
  if (options.dependencyMoves?.length) {
520
525
  const rootScope = options.desired.scopes[0] ?? 'project';
521
- const removeDependencies = options.dependencyMoves.map((move) => `aw cleanup ${move.pluginId} --platform ${options.platform} --scope ${move.fromScope}`);
522
- const dependencyScopes = options.dependencyMoves.map((move) => `--dependency-scope ${move.pluginId}#${options.platform}=${move.toScope}`);
526
+ const removeDependencies = options.dependencyMoves.map((move) => `aw plugin cleanup ${move.pluginId} --target ${options.platform} --scope ${move.fromScope}`);
523
527
  return [{
524
528
  command: 'manual',
525
- description: `先按依赖保护提示依次移除 ${options.dependencyMoves.map((move) => move.pluginId).join('、')} 的所有直接和间接依赖者;若命令报告 dependencyStillRequired,继续处理提示的其他依赖者。再运行 ${removeDependencies.join(',再运行 ')} 移除依赖旧位置。最后逐个按原平台和 scope 重新添加全部已移除 root,并在安装时选择新的依赖 scope;当前 root 的示例命令是 aw install ${options.pluginId} --platform ${options.platform} --scope ${rootScope} ${dependencyScopes.join(' ')}。`,
529
+ description: `先按依赖保护提示依次移除 ${options.dependencyMoves.map((move) => move.pluginId).join('、')} 的所有直接和间接依赖者;若命令报告 dependencyStillRequired,继续处理提示的其他依赖者。再运行 ${removeDependencies.join(',再运行 ')} 移除依赖旧位置。最后确认本机 Agent 选择,逐个按原 scope 重新添加全部已移除 root,由联合需求重新确定提供位置;当前 root 的示例命令是 aw plugin install ${options.pluginId} --scope ${rootScope}。`,
526
530
  }];
527
531
  }
528
532
  return [{
@@ -679,15 +683,72 @@ function collisionRootIssueId(options) {
679
683
  ].join(':');
680
684
  }
681
685
  async function statusCommandV8InSession(options) {
686
+ const throwIfCancelled = (error) => {
687
+ if (error instanceof Error && error.name === 'AbortError')
688
+ throw error;
689
+ options.signal?.throwIfAborted();
690
+ };
691
+ throwIfCancelled();
682
692
  const env = options.env ?? process.env;
683
693
  const dependencyPluginCache = new Map();
684
694
  const dependencyInspectionCache = new Map();
685
695
  const cliVersion = options.cliVersion ?? assertStrictSemVer(JSON.parse(fs.readFileSync(path.join(resolveCliPackageRoot(), 'package.json'), 'utf8')).version, 'packages/cli/package.json version');
686
696
  const snapshot = await readCatalogSourcesConfigSnapshot(env);
697
+ throwIfCancelled();
698
+ const scope = options.scope === 'project' ? 'project' : 'user';
699
+ const demand = options.recoveryDemand ?? await readDemand({
700
+ scope, cwd: options.cwd, env, catalogOperationContext: options.catalogOperationContext, signal: options.signal,
701
+ });
702
+ throwIfCancelled();
703
+ const observedDemands = new Map([[scope, demand]]);
704
+ if (options.scope !== 'user') {
705
+ const otherScope = scope === 'user' ? 'project' : 'user';
706
+ try {
707
+ observedDemands.set(otherScope, await readDemand({ scope: otherScope, cwd: options.cwd,
708
+ env, catalogOperationContext: options.catalogOperationContext, signal: options.signal }));
709
+ }
710
+ catch (error) {
711
+ throwIfCancelled(error); /* The other scope remains unknown; current scope stays readable. */
712
+ }
713
+ }
714
+ const selectedPlatformsByScope = new Map();
715
+ for (const [demandScope, scopedDemand] of observedDemands) {
716
+ try {
717
+ selectedPlatformsByScope.set(demandScope, selectAgents({
718
+ preferences: scopedDemand.preferences,
719
+ ...(demandScope === scope ? options.recoverySelection : {}),
720
+ }).agents.flatMap((agent) => agent === 'codex' ? ['codex']
721
+ : agent === 'claude' ? ['claude'] : []));
722
+ }
723
+ catch {
724
+ selectedPlatformsByScope.set(demandScope, []);
725
+ }
726
+ }
727
+ const projectObservationPlatforms = selectedPlatformsByScope.get('project') ?? [];
687
728
  const intentErrors = [];
688
729
  const readIntent = async (scope) => {
689
- const observation = await observePluginIntentState({ scope, cwd: options.cwd, env });
690
- if (observation.state === 'invalid' || observation.state === 'unavailable') {
730
+ let observation;
731
+ const scopedDemand = observedDemands.get(scope);
732
+ if (scopedDemand) {
733
+ try {
734
+ const protective = demandNativeProjection(scopedDemand);
735
+ // A protective execution view includes every supported Native platform. Status
736
+ // demand is limited to selected Agents; live residue is observed separately.
737
+ const value = { ...protective, roots: protective.roots.flatMap((root) => {
738
+ const platforms = root.platforms.filter((platform) => selectedPlatformsByScope.get(scope)?.includes(platform));
739
+ return platforms.length ? [{ ...root, platforms }] : [];
740
+ }) };
741
+ observation = scopedDemand.intent.state === 'absent' ? { state: 'absent' }
742
+ : { state: 'ready', value };
743
+ }
744
+ catch {
745
+ observation = { state: 'invalid', code: 'pluginIntentStateInvalid', message: '声明或偏好无效。' };
746
+ }
747
+ }
748
+ else
749
+ observation = options.scope === 'user' ? { state: 'absent' }
750
+ : { state: 'unavailable', code: 'pluginIntentStateUnavailable', message: '另一范围需求不可读。' };
751
+ if (observation.state === 'invalid') {
691
752
  intentErrors.push({
692
753
  code: 'pluginIntentStateInvalid',
693
754
  message: `pluginIntentStateInvalid: ${scope} plugin intent state is invalid.`,
@@ -721,26 +782,25 @@ async function statusCommandV8InSession(options) {
721
782
  const codexScopePathsAlias = codexProjectConfigAliasesUserHome(options.cwd, env);
722
783
  const [userCodexConfig, projectCodexConfig] = await Promise.all([
723
784
  readActivationConfig('user'),
724
- codexScopePathsAlias ? undefined : readActivationConfig('project'),
785
+ options.scope === 'user' || codexScopePathsAlias ? undefined : readActivationConfig('project'),
725
786
  ]);
726
787
  let projectRoot;
727
788
  try {
728
- projectRoot = await resolveCanonicalRepoProjectKey(options.cwd);
789
+ projectRoot = await resolveRequiredCanonicalRepoRoot(options.cwd);
729
790
  }
730
791
  catch (error) {
731
792
  if (error instanceof Error && error.name === 'AbortError')
732
793
  throw error;
733
- projectIntentObservation = {
734
- state: 'unavailable',
735
- code: 'pluginIntentStateUnavailable',
736
- message: '无法确定当前项目位置,不能读取插件声明。',
737
- };
738
- projectIntent = emptyIntent();
739
- if (!intentErrors.some((error) => error.message.includes('project plugin intent'))) {
740
- intentErrors.push({
741
- code: 'pluginIntentStateInvalid',
742
- message: 'pluginIntentStateInvalid: project plugin intent state is unavailable.',
743
- });
794
+ if (options.scope === 'project') {
795
+ projectIntentObservation = {
796
+ state: 'unavailable', code: 'pluginIntentStateUnavailable',
797
+ message: '无法确定当前项目位置,不能读取插件声明。',
798
+ };
799
+ projectIntent = emptyIntent();
800
+ if (!intentErrors.some((error) => error.message.includes('project plugin intent'))) {
801
+ intentErrors.push({ code: 'pluginIntentStateInvalid',
802
+ message: 'pluginIntentStateInvalid: project plugin intent state is unavailable.' });
803
+ }
744
804
  }
745
805
  }
746
806
  const currentProjectKey = projectRoot;
@@ -749,13 +809,18 @@ async function statusCommandV8InSession(options) {
749
809
  const inventoryErrors = [];
750
810
  const readInventory = options.inventoryCatalogSourceReferences
751
811
  ?? inventoryCatalogSourceReferences;
752
- const ownerInventory = await readInventory({ cwd: options.cwd, env }).catch(async (error) => {
812
+ const ownerInventory = await readInventory({ cwd: options.cwd, env,
813
+ ...(options.scope === 'user' ? { scope: 'user' } : { includeProjectAgentSkills: true }) }).catch(async (error) => {
814
+ throwIfCancelled(error);
753
815
  inventoryErrors.push(projectStateInventoryError(error, env, options.cwd));
754
- return inventoryLegacyOwnerReferences({ cwd: options.cwd, env }).catch((fallbackError) => {
816
+ return inventoryLegacyOwnerReferences({ cwd: options.cwd, env,
817
+ ...(options.scope === 'user' ? { scope: 'user' } : { includeProjectAgentSkills: true }) }).catch((fallbackError) => {
818
+ throwIfCancelled(fallbackError);
755
819
  inventoryErrors.push(projectStateInventoryError(fallbackError, env, options.cwd));
756
820
  return { inventorySchemaVersion: 1, references: [], errors: [] };
757
821
  });
758
822
  });
823
+ throwIfCancelled();
759
824
  for (const error of ownerInventory.errors ?? []) {
760
825
  const code = error.kind === 'nativeStateRead' ? 'nativeStateUnreadable' : 'stateInventoryFailed';
761
826
  inventoryErrors.push({
@@ -767,6 +832,7 @@ async function statusCommandV8InSession(options) {
767
832
  const nativeCliRunner = options.nativeCliRunner ?? getDefaultNativeCliRunner();
768
833
  const codexSystemConsumerInspections = new Map();
769
834
  const inspectCodexSystemConsumer = (scope) => {
835
+ throwIfCancelled();
770
836
  let inspection = codexSystemConsumerInspections.get(scope);
771
837
  if (!inspection) {
772
838
  inspection = inspectSystemCodex({
@@ -774,7 +840,7 @@ async function statusCommandV8InSession(options) {
774
840
  cwd: options.cwd,
775
841
  env,
776
842
  operationRequirement: getCodexOperationRequirement(scope),
777
- });
843
+ }).then((result) => { throwIfCancelled(); return result; });
778
844
  codexSystemConsumerInspections.set(scope, inspection);
779
845
  }
780
846
  return inspection;
@@ -782,6 +848,7 @@ async function statusCommandV8InSession(options) {
782
848
  const codexRegistrationCache = new Map();
783
849
  const inspectCodexRegistration = async (pluginId, scope) => {
784
850
  const consumer = await inspectCodexSystemConsumer(scope);
851
+ throwIfCancelled();
785
852
  if (consumer.state !== 'compatible') {
786
853
  return {
787
854
  observation: { state: 'unobserved' },
@@ -917,9 +984,14 @@ async function statusCommandV8InSession(options) {
917
984
  scopes,
918
985
  currentProjectLocationKey,
919
986
  }));
920
- const plannedSourceIds = requested.length === 0
987
+ const selectorSourceIds = requested.length === 0
921
988
  ? undefined
922
989
  : planPluginSelectorSourceIds(plannedSelectors.map((selector) => selector.parsed));
990
+ const plannedSourceIds = selectorSourceIds === undefined ? undefined : [...new Set([
991
+ ...selectorSourceIds,
992
+ ...(options.catalogOperationContext ? [] : [...observedDemands.values()].flatMap((entry) => entry.roots ?? []))
993
+ .map((root) => root.sourceId).filter((id) => configured.has(id)),
994
+ ])];
923
995
  const selectedConfiguredSources = plannedSourceIds === undefined
924
996
  ? snapshot.config.sources
925
997
  : plannedSourceIds.map((sourceId) => configured.get(sourceId));
@@ -943,11 +1015,13 @@ async function statusCommandV8InSession(options) {
943
1015
  ? { operationContext: options.catalogOperationContext }
944
1016
  : {}),
945
1017
  env,
1018
+ signal: options.signal,
946
1019
  consume: async (resolution) => ({
947
1020
  primarySourceId: resolution.primarySourceId,
948
1021
  configDigest: resolution.configDigest,
949
1022
  compositeDigest: resolution.compositeDigest,
950
1023
  sources: await Promise.all(resolution.sources.map(async (item) => {
1024
+ throwIfCancelled();
951
1025
  const source = configured.get(item.sourceId);
952
1026
  const identity = identities.get(item.sourceId);
953
1027
  const base = {
@@ -1032,11 +1106,14 @@ async function statusCommandV8InSession(options) {
1032
1106
  sourceId: item.resolution.sourceId,
1033
1107
  pluginName: entry.name,
1034
1108
  });
1035
- if (sourceDesired.get(desiredTargetKey(pluginId, 'codex'))?.scopes.includes('user')) {
1109
+ if (options.scope === 'project'
1110
+ ? userCodexConfig?.snapshot.plugins[`${entry.name}@${desiredMarketplaceName}`]?.enabled === true
1111
+ : sourceDesired.get(desiredTargetKey(pluginId, 'codex'))?.scopes.includes('user')) {
1036
1112
  codexDesiredUserActivationIds.add(`${entry.name}@${desiredMarketplaceName}`);
1037
1113
  }
1038
1114
  }
1039
1115
  const plugins = await Promise.all(item.resolution.manifest.entries.map(async (entry) => {
1116
+ throwIfCancelled();
1040
1117
  const capabilitySupport = checkAwCapabilitySupport(entry.requires.aw.capabilities ?? [], IMPLEMENTED_AW_CAPABILITIES);
1041
1118
  if (!capabilitySupport.supported) {
1042
1119
  const supportedPlatforms = resolveCatalogEntrySupportedPlatforms(entry.policy);
@@ -1087,57 +1164,65 @@ async function statusCommandV8InSession(options) {
1087
1164
  let configDiagnostic;
1088
1165
  if (plugin.manifest.config?.fields) {
1089
1166
  const issues = new Map();
1090
- for (const scope of scopes) {
1091
- try {
1092
- const resolved = scope === 'project'
1093
- ? await resolveProjectArtifactRenderConfig({
1094
- sourceId: plugin.sourceId,
1095
- sourceIdentity: plugin.sourceIdentity,
1096
- logicalIdentity: plugin.catalogLogicalIdentity,
1097
- pluginName: plugin.manifest.name,
1098
- manifest: plugin.manifest,
1099
- cwd: options.cwd,
1100
- env,
1101
- })
1102
- : await resolveEffectivePluginConfig({
1103
- sourceId: plugin.sourceId,
1104
- sourceIdentity: plugin.sourceIdentity,
1105
- logicalIdentity: plugin.catalogLogicalIdentity,
1106
- pluginName: plugin.manifest.name,
1107
- manifest: plugin.manifest,
1108
- targetScope: 'user',
1109
- cwd: options.cwd,
1110
- env,
1111
- });
1112
- for (const issue of resolved.issues) {
1113
- const source = issue.source ?? 'missing';
1114
- const configIssue = {
1115
- scope,
1116
- type: issue.type,
1117
- key: issue.key,
1118
- title: plugin.manifest.config.fields[issue.key]?.title ?? issue.key,
1119
- source,
1120
- };
1121
- issues.set(`${scope}\0${configIssue.type}\0${configIssue.key}\0${configIssue.source}`, configIssue);
1167
+ for (const platform of ['codex', 'claude']) {
1168
+ if (!supportsPlatform(plugin.manifest, platform))
1169
+ continue;
1170
+ for (const scope of scopes) {
1171
+ try {
1172
+ const resolved = scope === 'project'
1173
+ ? await resolveProjectArtifactRenderConfig({
1174
+ sourceId: plugin.sourceId,
1175
+ sourceIdentity: plugin.sourceIdentity,
1176
+ logicalIdentity: plugin.catalogLogicalIdentity,
1177
+ pluginName: plugin.manifest.name,
1178
+ manifest: plugin.manifest,
1179
+ platform,
1180
+ cwd: options.cwd,
1181
+ env,
1182
+ })
1183
+ : await resolveEffectivePluginConfig({
1184
+ sourceId: plugin.sourceId,
1185
+ sourceIdentity: plugin.sourceIdentity,
1186
+ logicalIdentity: plugin.catalogLogicalIdentity,
1187
+ pluginName: plugin.manifest.name,
1188
+ manifest: plugin.manifest,
1189
+ platform,
1190
+ targetScope: 'user',
1191
+ cwd: options.cwd,
1192
+ env,
1193
+ });
1194
+ for (const issue of resolved.issues) {
1195
+ const source = issue.source ?? 'missing';
1196
+ const configIssue = {
1197
+ scope,
1198
+ platform,
1199
+ type: issue.type,
1200
+ key: issue.key,
1201
+ title: resolved.schema[issue.key]?.title ?? issue.key,
1202
+ source,
1203
+ };
1204
+ issues.set(`${platform}\0${scope}\0${configIssue.type}\0${configIssue.key}\0${configIssue.source}`, configIssue);
1205
+ }
1206
+ for (const override of resolved.unsupportedLayerOverrides) {
1207
+ const configIssue = {
1208
+ scope,
1209
+ platform,
1210
+ type: override.type,
1211
+ key: override.key,
1212
+ title: resolved.schema[override.key]?.title ?? override.key,
1213
+ source: override.source,
1214
+ };
1215
+ issues.set(`${platform}\0${scope}\0${configIssue.type}\0${configIssue.key}\0${configIssue.source}`, configIssue);
1216
+ }
1122
1217
  }
1123
- for (const override of resolved.unsupportedLayerOverrides) {
1124
- const configIssue = {
1218
+ catch {
1219
+ configDiagnostic ??= {
1125
1220
  scope,
1126
- type: override.type,
1127
- key: override.key,
1128
- title: plugin.manifest.config.fields[override.key]?.title ?? override.key,
1129
- source: override.source,
1221
+ code: 'configReadFailed',
1222
+ message: '插件设置当前不可读。未读取或显示设置值。',
1130
1223
  };
1131
- issues.set(`${scope}\0${configIssue.type}\0${configIssue.key}\0${configIssue.source}`, configIssue);
1132
1224
  }
1133
1225
  }
1134
- catch {
1135
- configDiagnostic ??= {
1136
- scope,
1137
- code: 'configReadFailed',
1138
- message: '插件设置当前不可读。未读取或显示设置值。',
1139
- };
1140
- }
1141
1226
  }
1142
1227
  configIssues = [...issues.values()];
1143
1228
  }
@@ -1166,6 +1251,7 @@ async function statusCommandV8InSession(options) {
1166
1251
  for (const platform of ['codex', 'claude']) {
1167
1252
  states[platform] = {};
1168
1253
  for (const scope of ['user', 'project']) {
1254
+ throwIfCancelled();
1169
1255
  if (platform === 'codex'
1170
1256
  && scope === 'project'
1171
1257
  && codexScopePathsAlias
@@ -1470,18 +1556,24 @@ async function statusCommandV8InSession(options) {
1470
1556
  }
1471
1557
  }
1472
1558
  return { state: 'ready', dependencyScope };
1473
- })().catch(() => ({
1474
- state: 'error',
1475
- dependencyScope,
1476
- rootIssueId: `diagnostic:${dependencyId}:${platform}:${dependencyScope}`,
1477
- rootIssueCode: 'diagnostic',
1478
- issuePluginId: dependencyId,
1479
- issueScope: dependencyScope,
1480
- }));
1559
+ })().catch((error) => {
1560
+ throwIfCancelled(error);
1561
+ return {
1562
+ state: 'error',
1563
+ dependencyScope,
1564
+ rootIssueId: `diagnostic:${dependencyId}:${platform}:${dependencyScope}`,
1565
+ rootIssueCode: 'diagnostic',
1566
+ issuePluginId: dependencyId,
1567
+ issueScope: dependencyScope,
1568
+ };
1569
+ });
1481
1570
  dependencyInspectionCache.set(inspectionCacheKey, inspection);
1482
1571
  return inspection;
1483
1572
  }
1484
- if (directDependencies.length > 0
1573
+ // Inspect dependencies for returned live placements and selected project Agents.
1574
+ const dependencyObservationRequested = platforms.includes(platform) && scopes.includes(scope)
1575
+ || scope === 'project' && projectObservationPlatforms.includes(platform);
1576
+ if (dependencyObservationRequested && directDependencies.length > 0
1485
1577
  && (desiredInScope
1486
1578
  || actualCodexActivation
1487
1579
  || hasScopedExtensionResidue
@@ -1628,10 +1720,10 @@ async function statusCommandV8InSession(options) {
1628
1720
  }
1629
1721
  states[platform][scope] = {
1630
1722
  state: liveState,
1631
- errors: [...inspected.inspection.errors.map((error) => finalizeTargetError({
1723
+ errors: [...inspected.inspection.errors.map((error) => projectTargetError({
1632
1724
  code: 'componentInspectionFailed',
1633
1725
  message: `${error.label}: ${error.message}`,
1634
- }, liveState)), ...collisionErrors, ...dependencyErrors],
1726
+ }, env, options.cwd, liveState)), ...collisionErrors, ...dependencyErrors],
1635
1727
  ...(dependencyReadiness.length > 0 ? { dependencyReadiness } : {}),
1636
1728
  components: inspected.inspection.components.map((component) => {
1637
1729
  const projectedError = component.collision
@@ -1658,6 +1750,7 @@ async function statusCommandV8InSession(options) {
1658
1750
  };
1659
1751
  }
1660
1752
  catch (error) {
1753
+ throwIfCancelled(error);
1661
1754
  const message = error instanceof Error ? error.message : String(error);
1662
1755
  const configErrorCode = platform === 'codex' && codexConfigErrors.length > 0
1663
1756
  ? codexSurface.nativeKinds.length > 0
@@ -1665,17 +1758,17 @@ async function statusCommandV8InSession(options) {
1665
1758
  : 'codexActivationDrift'
1666
1759
  : undefined;
1667
1760
  const code = configErrorCode
1668
- ?? message.split(':', 1)[0]
1761
+ ?? /^([A-Za-z][A-Za-z0-9]*):/u.exec(message)?.[1]
1669
1762
  ?? 'targetInspectionFailed';
1670
1763
  states[platform][scope] = {
1671
1764
  state: 'error',
1672
1765
  components: [],
1673
- errors: [finalizeTargetError({
1766
+ errors: [projectTargetError({
1674
1767
  code,
1675
1768
  message: configErrorCode
1676
1769
  ? `${configErrorCode}: Codex activation state is unreadable.`
1677
1770
  : message,
1678
- }, 'error')],
1771
+ }, env, options.cwd, 'error')],
1679
1772
  };
1680
1773
  }
1681
1774
  }
@@ -1699,8 +1792,7 @@ async function statusCommandV8InSession(options) {
1699
1792
  };
1700
1793
  let residueFailed = false;
1701
1794
  const hasNativeRenderTargets = (plugin.manifest.artifacts?.targets ?? []).some((target) => target.platform === 'codex'
1702
- && target.target === 'codex.skill'
1703
- && target.delivery?.mode === 'codex-native');
1795
+ && target.target === 'codex.skill');
1704
1796
  const sharedInspection = codexSurface.nativeKinds.length > 0
1705
1797
  ? await inspectCodexSharedNativeLive({
1706
1798
  pluginName: entry.name,
@@ -1714,7 +1806,8 @@ async function statusCommandV8InSession(options) {
1714
1806
  nativeCliRunner,
1715
1807
  pluginRegistration,
1716
1808
  ...(hasNativeRenderTargets ? { nativeRenderPlugin: plugin } : {}),
1717
- }).catch(() => {
1809
+ }).catch((error) => {
1810
+ throwIfCancelled(error);
1718
1811
  residueFailed = true;
1719
1812
  return undefined;
1720
1813
  })
@@ -1790,6 +1883,7 @@ async function statusCommandV8InSession(options) {
1790
1883
  shortDescription: plugin.manifest.interface?.shortDescription
1791
1884
  ?? plugin.manifest.description,
1792
1885
  description: plugin.manifest.description,
1886
+ platforms: [...resolveSupportedPlatforms(plugin.manifest)],
1793
1887
  ...(plugin.manifest.config?.fields
1794
1888
  ? { configSchema: plugin.manifest.config.fields }
1795
1889
  : {}),
@@ -1819,6 +1913,7 @@ async function statusCommandV8InSession(options) {
1819
1913
  };
1820
1914
  }
1821
1915
  catch (error) {
1916
+ throwIfCancelled(error);
1822
1917
  const sanitized = sanitizeCatalogSourceError(error, env);
1823
1918
  return {
1824
1919
  ...base,
@@ -1834,6 +1929,7 @@ async function statusCommandV8InSession(options) {
1834
1929
  : []);
1835
1930
  const removedProjectionReferences = [];
1836
1931
  for (const source of catalog.sources) {
1932
+ throwIfCancelled();
1837
1933
  if (!('plugins' in source))
1838
1934
  continue;
1839
1935
  const marketplaceRoot = path.join(resolveAwHome(env), 'marketplaces', source.id);
@@ -1907,6 +2003,7 @@ async function statusCommandV8InSession(options) {
1907
2003
  }
1908
2004
  }
1909
2005
  catch (error) {
2006
+ throwIfCancelled(error);
1910
2007
  const projected = projectStateInventoryError(error, env, options.cwd);
1911
2008
  selectedInventoryErrors.push({ ...projected, relevance: { sourceId: source.id, global: false } });
1912
2009
  }
@@ -2682,6 +2779,61 @@ async function statusCommandV8InSession(options) {
2682
2779
  pluginName: entry.name,
2683
2780
  ...issue,
2684
2781
  })));
2782
+ const nativeObservations = available.flatMap((entry) => ['codex', 'claude'].map((platform) => {
2783
+ const observed = entry.states[platform]?.[scope];
2784
+ const blockers = (observed?.errors ?? []).map((error) => ({
2785
+ code: error.code, message: `${error.code}: 项目 Native 目标尚未满足。`,
2786
+ }));
2787
+ const nativeInventoryErrors = inventoryErrors.filter((error) => inventoryErrorMatchesSelection({
2788
+ error,
2789
+ selectors: [{ raw: `${entry.source.id}/${entry.name}`, parsed: {
2790
+ sourceId: entry.source.id, pluginName: entry.name,
2791
+ } }],
2792
+ platformExplicit: true, scopeExplicit: true, platforms: [platform], scopes: [scope],
2793
+ currentProjectLocationKey,
2794
+ }));
2795
+ blockers.push(...nativeInventoryErrors.map((error) => ({
2796
+ code: error.code, message: `${error.code}: 无法读取项目 Native 现场。`,
2797
+ })));
2798
+ if (platform === 'codex' && codexConfigErrors.some((error) => error.scope === scope
2799
+ || scope === 'project' && error.scope === 'user')) {
2800
+ blockers.push({ code: 'nativeStateUnreadable', message: '无法读取 Codex 激活配置。' });
2801
+ }
2802
+ if (entry.configDiagnostic)
2803
+ blockers.push({ code: 'configReadFailed', message: '无法读取插件配置。' });
2804
+ if (entry.configIssues?.some((issue) => issue.scope === scope)) {
2805
+ blockers.push({ code: 'configInvalid', message: '项目配置需要处理。' });
2806
+ }
2807
+ if (observed?.state === 'error' && !blockers.some((error) => /Unsupported$|collision|conflict|foreign/iu.test(error.code))) {
2808
+ blockers.push({ code: 'nativeObservationFailed', message: '无法完成项目 Native 现场观察。' });
2809
+ }
2810
+ let content = !observed ? 'unknown'
2811
+ : observed.state === 'absent' ? 'absent'
2812
+ : observed.state === 'present' ? 'satisfied'
2813
+ : observed.state === 'partial' ? 'drifted' : 'unknown';
2814
+ if (blockers.some((blocker) => /collision|conflict|foreign/iu.test(blocker.code)))
2815
+ content = 'conflict';
2816
+ if (platform === 'codex' && entry.codex?.nativeKinds.length) {
2817
+ const shared = entry.codex.sharedNative;
2818
+ if (shared?.state === 'missing')
2819
+ content = 'absent';
2820
+ else if (shared?.state === 'replaceable')
2821
+ content = 'drifted';
2822
+ else if (shared?.state === 'blocked')
2823
+ content = shared.reason === 'foreign' ? 'conflict' : 'unknown';
2824
+ else if (!shared || shared.state === 'unobserved')
2825
+ content = 'unknown';
2826
+ if (content === 'satisfied' && entry.codex.activation.effective !== true)
2827
+ content = 'absent';
2828
+ }
2829
+ return {
2830
+ pluginId: `${entry.source.id}/${entry.name}`, platform, content, blockers,
2831
+ backend: flattenStatusTargets(projectedTargets).find((target) => target.pluginId === `${entry.source.id}/${entry.name}`
2832
+ && target.platform === platform && target.scope === scope),
2833
+ ...(platform === 'codex' && entry.codex?.activation.evidence === 'assumed'
2834
+ ? { assumedActivation: true } : {}),
2835
+ };
2836
+ }));
2685
2837
  const payload = {
2686
2838
  schemaVersion: 8,
2687
2839
  catalog: {
@@ -2716,6 +2868,15 @@ async function statusCommandV8InSession(options) {
2716
2868
  output: options.json ? JSON.stringify(payload) : renderStatusV8(payload, options.verbose === true),
2717
2869
  hasErrors,
2718
2870
  targetRevisions,
2871
+ nativeObservations,
2872
+ nativeExtraObserved: ownerInventory.references.flatMap((reference) => {
2873
+ if (!reference.sourceId || !reference.pluginName || reference.scope !== scope
2874
+ || !['namespacedOwner', 'namespacedConfig', 'namespacedMarketplace'].includes(reference.kind))
2875
+ return [];
2876
+ return [{ pluginId: `${reference.sourceId}/${reference.pluginName}`,
2877
+ ...(reference.platform === 'codex' || reference.platform === 'claude'
2878
+ ? { platform: reference.platform } : {}), scope, reference }];
2879
+ }),
2719
2880
  ...(projectRoot ? { projectRoot } : {}),
2720
2881
  projectIntentObservation,
2721
2882
  pluginSummaries: available.map((entry) => {
@@ -2748,6 +2909,7 @@ async function statusCommandV8InSession(options) {
2748
2909
  codex: ['user', 'project'].filter((scope) => entry.targets.codex[scope]),
2749
2910
  claude: ['user', 'project'].filter((scope) => entry.targets.claude[scope]),
2750
2911
  },
2912
+ ...(entry.platforms ? { platforms: entry.platforms } : {}),
2751
2913
  configFieldCount: Object.keys(entry.configSchema ?? {}).length,
2752
2914
  ...(entry.configSchema ? { configSchema: entry.configSchema } : {}),
2753
2915
  ...(entry.configIssues ? { configIssues: entry.configIssues } : {}),
@@ -2763,6 +2925,8 @@ async function statusCommandV8InSession(options) {
2763
2925
  };
2764
2926
  }
2765
2927
  export async function statusCommandV8(options) {
2928
+ options.signal?.throwIfAborted();
2929
+ options = { ...options, nativeCliRunner: bindNativeCliRunnerSignal(options.nativeCliRunner ?? getDefaultNativeCliRunner(), options.signal) };
2766
2930
  if (options.codexObservationSession) {
2767
2931
  return statusCommandV8InSession({
2768
2932
  ...options,
@@ -2776,7 +2940,10 @@ export async function statusCommandV8(options) {
2776
2940
  runner: options.nativeCliRunner ?? getDefaultNativeCliRunner(),
2777
2941
  });
2778
2942
  try {
2779
- return await statusCommandV8InSession({ ...options, codexObservationSession: session });
2943
+ options.signal?.throwIfAborted();
2944
+ const result = await statusCommandV8InSession({ ...options, codexObservationSession: session });
2945
+ options.signal?.throwIfAborted();
2946
+ return result;
2780
2947
  }
2781
2948
  finally {
2782
2949
  await session.dispose();