@lesliechan721/aw 0.1.0-beta.35 → 0.1.0-beta.36

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 (72) hide show
  1. package/dist/src/commands/operation-plan.d.ts +19 -0
  2. package/dist/src/commands/operation-plan.js.map +1 -1
  3. package/dist/src/commands/rebuild-command.d.ts +1 -0
  4. package/dist/src/commands/rebuild-command.js +890 -8
  5. package/dist/src/commands/rebuild-command.js.map +1 -1
  6. package/dist/src/commands/rebuild-integration.d.ts +12 -0
  7. package/dist/src/commands/rebuild-integration.js +88 -2
  8. package/dist/src/commands/rebuild-integration.js.map +1 -1
  9. package/dist/src/commands/status-v6.js +109 -19
  10. package/dist/src/commands/status-v6.js.map +1 -1
  11. package/dist/src/commands/wizard.d.ts +5 -1
  12. package/dist/src/commands/wizard.js +4 -2
  13. package/dist/src/commands/wizard.js.map +1 -1
  14. package/dist/src/commands/write-commands.js +3 -0
  15. package/dist/src/commands/write-commands.js.map +1 -1
  16. package/dist/src/index.js +57 -4
  17. package/dist/src/index.js.map +1 -1
  18. package/dist/src/tui/components.d.ts +20 -1
  19. package/dist/src/tui/components.js +41 -20
  20. package/dist/src/tui/components.js.map +1 -1
  21. package/dist/src/tui/console-app-v4.js +1323 -1165
  22. package/dist/src/tui/console-app-v4.js.map +1 -1
  23. package/dist/src/tui/content-item-card.d.ts +13 -0
  24. package/dist/src/tui/content-item-card.js +51 -0
  25. package/dist/src/tui/content-item-card.js.map +1 -0
  26. package/dist/src/tui/controller-runtime.js +18 -2
  27. package/dist/src/tui/controller-runtime.js.map +1 -1
  28. package/dist/src/tui/controller.d.ts +3 -0
  29. package/dist/src/tui/controller.js +57 -8
  30. package/dist/src/tui/controller.js.map +1 -1
  31. package/dist/src/tui/dependency-graph-view.d.ts +39 -0
  32. package/dist/src/tui/dependency-graph-view.js +121 -0
  33. package/dist/src/tui/dependency-graph-view.js.map +1 -0
  34. package/dist/src/tui/dependency-graph.js +16 -19
  35. package/dist/src/tui/dependency-graph.js.map +1 -1
  36. package/dist/src/tui/entity-cards.d.ts +55 -0
  37. package/dist/src/tui/entity-cards.js +220 -0
  38. package/dist/src/tui/entity-cards.js.map +1 -0
  39. package/dist/src/tui/input-display.js +10 -1
  40. package/dist/src/tui/input-display.js.map +1 -1
  41. package/dist/src/tui/model.d.ts +2 -0
  42. package/dist/src/tui/model.js +10 -2
  43. package/dist/src/tui/model.js.map +1 -1
  44. package/dist/src/tui/operation-diagnostic-screens.d.ts +2 -18
  45. package/dist/src/tui/operation-diagnostic-screens.js +16 -69
  46. package/dist/src/tui/operation-diagnostic-screens.js.map +1 -1
  47. package/dist/src/tui/operation-review-planner.js +44 -3
  48. package/dist/src/tui/operation-review-planner.js.map +1 -1
  49. package/dist/src/tui/plugin-content.d.ts +8 -0
  50. package/dist/src/tui/plugin-content.js +409 -65
  51. package/dist/src/tui/plugin-content.js.map +1 -1
  52. package/dist/src/tui/plugin-detail.d.ts +52 -0
  53. package/dist/src/tui/plugin-detail.js +165 -0
  54. package/dist/src/tui/plugin-detail.js.map +1 -0
  55. package/dist/src/tui/query-header.d.ts +30 -0
  56. package/dist/src/tui/query-header.js +40 -0
  57. package/dist/src/tui/query-header.js.map +1 -0
  58. package/dist/src/tui/reader.d.ts +37 -0
  59. package/dist/src/tui/reader.js +47 -0
  60. package/dist/src/tui/reader.js.map +1 -0
  61. package/dist/src/tui/router.d.ts +10 -0
  62. package/dist/src/tui/router.js.map +1 -1
  63. package/dist/src/tui/screen-registry.d.ts +2 -0
  64. package/dist/src/tui/source-detail-card.d.ts +29 -0
  65. package/dist/src/tui/source-detail-card.js +45 -0
  66. package/dist/src/tui/source-detail-card.js.map +1 -0
  67. package/dist/src/tui/wizard.js +26 -4
  68. package/dist/src/tui/wizard.js.map +1 -1
  69. package/dist/src/utils/local-marketplace.d.ts +1 -0
  70. package/dist/src/utils/local-marketplace.js +22 -0
  71. package/dist/src/utils/local-marketplace.js.map +1 -1
  72. package/package.json +4 -4
@@ -4,6 +4,7 @@ import { analyzeCodexSurface } from '../utils/codex-surface-analysis.js';
4
4
  import { catalogSourceErrorCode, sanitizeCatalogSourceError, } from '../utils/catalog-public-error.js';
5
5
  import { calculateCatalogSourceIdentity } from '../utils/catalog-source-identity.js';
6
6
  import { canonicalMarketplaceRegistrationNames, inventoryCatalogSourceReferences, inventoryLegacyOwnerReferences, } from '../utils/catalog-source-references.js';
7
+ import { readStrictNamespacedMarketplaceRoot } from '../utils/local-marketplace.js';
7
8
  import { readCatalogSourcesConfigSnapshot, resolveCatalogSourceRef } from '../utils/catalog-sources.js';
8
9
  import { formatPluginId, parsePluginId, planPluginSelectorSourceIds, withResolvedMultiSourceCatalog, } from '../utils/multi-source-catalog.js';
9
10
  import { assertStrictSemVer, checkAwCapabilitySupport, compareStrictSemVer, readPluginManifest, tryParseStrictSemVer, } from '../utils/manifest.js';
@@ -438,6 +439,12 @@ function projectDependencyClosureForTarget(options) {
438
439
  return closure;
439
440
  }
440
441
  export function statusRecovery(options) {
442
+ if (options.errorCodes?.includes('removedPluginCleanupRequired')) {
443
+ return [{
444
+ command: 'cleanup',
445
+ description: '整体清理已删除插件在两个平台、用户与当前项目中的安装、设置和遗留记录。',
446
+ }];
447
+ }
441
448
  if (options.errorCodes?.some((code) => code === 'codexProjectPluginVersionTooLow'
442
449
  || code === 'codexProjectPluginUnsupported'
443
450
  || code === 'codexSystemCliUnsupported')) {
@@ -1827,6 +1834,86 @@ async function statusCommandV8InSession(options) {
1827
1834
  const available = catalog.sources.flatMap((source) => 'plugins' in source
1828
1835
  ? source.plugins.map((plugin) => ({ ...plugin, source }))
1829
1836
  : []);
1837
+ const removedProjectionReferences = [];
1838
+ for (const source of catalog.sources) {
1839
+ if (!('plugins' in source))
1840
+ continue;
1841
+ const marketplaceRoot = path.join(resolveAwHome(env), 'marketplaces', source.id);
1842
+ try {
1843
+ const root = await readStrictNamespacedMarketplaceRoot({
1844
+ rootDir: marketplaceRoot, sourceId: source.id, sourceIdentity: source.identity,
1845
+ });
1846
+ if (!root)
1847
+ continue;
1848
+ const currentNames = new Set(source.plugins.map((plugin) => plugin.name));
1849
+ const candidates = new Map();
1850
+ const add = (name, platform) => {
1851
+ if (typeof name !== 'string' || currentNames.has(name))
1852
+ return;
1853
+ try {
1854
+ if (parsePluginId(name).sourceId !== undefined)
1855
+ return;
1856
+ }
1857
+ catch {
1858
+ return;
1859
+ }
1860
+ const supported = candidates.get(name) ?? new Set();
1861
+ supported.add(platform);
1862
+ candidates.set(name, supported);
1863
+ };
1864
+ for (const [platform, manifest] of [
1865
+ ['codex', root.agentsManifest], ['claude', root.claudeManifest],
1866
+ ]) {
1867
+ if (!Array.isArray(manifest?.plugins))
1868
+ continue;
1869
+ for (const plugin of manifest.plugins) {
1870
+ if (plugin && typeof plugin === 'object')
1871
+ add(plugin.name, platform);
1872
+ }
1873
+ }
1874
+ const pluginsRoot = path.join(root.rootDir, 'plugins');
1875
+ const pluginsStats = await fs.promises.lstat(pluginsRoot).catch((error) => {
1876
+ if (error.code === 'ENOENT')
1877
+ return undefined;
1878
+ throw error;
1879
+ });
1880
+ if (pluginsStats && (!pluginsStats.isDirectory() || pluginsStats.isSymbolicLink())) {
1881
+ throw new Error('marketplaceRootInvalid: plugin projection directory is unsafe.');
1882
+ }
1883
+ if (pluginsStats) {
1884
+ for (const entry of await fs.promises.readdir(pluginsRoot, { withFileTypes: true })) {
1885
+ if (!candidates.has(entry.name))
1886
+ add(entry.name, 'codex');
1887
+ }
1888
+ }
1889
+ const registration = userCodexConfig?.snapshot.marketplaces[root.config.marketplaceName];
1890
+ if (platforms.includes('codex')
1891
+ && registration?.sourceType === 'local'
1892
+ && !registration.sourcePointsToManifest
1893
+ && path.resolve(registration.source ?? '') === path.resolve(root.rootDir)
1894
+ && (await inspectCodexSystemConsumer(options.scope === 'project' ? 'project' : 'user')).state === 'compatible') {
1895
+ const observed = await options.codexObservationSession.snapshot(root.config.marketplaceName, options.scope === 'user' ? 'user' : 'both');
1896
+ const suffix = `@${root.config.marketplaceName}`;
1897
+ for (const pluginId of [...(observed.exact?.keys() ?? []), ...(observed.neutral?.keys() ?? [])]) {
1898
+ if (pluginId.endsWith(suffix))
1899
+ add(pluginId.slice(0, -suffix.length), 'codex');
1900
+ }
1901
+ }
1902
+ for (const [pluginName, supported] of candidates) {
1903
+ for (const platform of supported)
1904
+ removedProjectionReferences.push({
1905
+ kind: 'namespacedMarketplace', location: path.join(root.rootDir, 'config.json'),
1906
+ sourceId: source.id, sourceIdentity: source.identity,
1907
+ marketplaceName: root.config.marketplaceName, pluginName, platform, scope: 'user',
1908
+ });
1909
+ }
1910
+ }
1911
+ catch (error) {
1912
+ const projected = projectStateInventoryError(error, env, options.cwd);
1913
+ selectedInventoryErrors.push({ ...projected, relevance: { sourceId: source.id, global: false } });
1914
+ }
1915
+ }
1916
+ const statusReferences = [...ownerInventory.references, ...removedProjectionReferences];
1830
1917
  const desiredTargetStates = calculateDesiredTargetStates({
1831
1918
  userIntent,
1832
1919
  projectIntent,
@@ -1868,7 +1955,7 @@ async function statusCommandV8InSession(options) {
1868
1955
  scopes,
1869
1956
  currentProjectLocationKey,
1870
1957
  }));
1871
- const selectorHasLiveOrIntent = ownerInventory.references.some((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
1958
+ const selectorHasLiveOrIntent = statusReferences.some((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
1872
1959
  && reference.pluginName === selector.parsed.pluginName
1873
1960
  && reference.sourceId !== undefined
1874
1961
  && (selector.parsed.sourceId === undefined || reference.sourceId === selector.parsed.sourceId)
@@ -2066,7 +2153,7 @@ async function statusCommandV8InSession(options) {
2066
2153
  targets.push(...unavailableSourceTargets);
2067
2154
  const availablePluginIds = new Set(available.map((entry) => formatPluginId({ sourceId: entry.source.id, pluginName: entry.name })));
2068
2155
  const resolvedSourceIds = new Set(catalog.sources.flatMap((source) => 'plugins' in source ? [source.id] : []));
2069
- const unavailableBundleReferences = ownerInventory.references.filter((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
2156
+ const unavailableBundleReferences = statusReferences.filter((reference) => (reference.kind === 'namespacedOwner' || reference.kind === 'namespacedMarketplace')
2070
2157
  && reference.sourceId
2071
2158
  && configured.has(reference.sourceId)
2072
2159
  && resolvedSourceIds.has(reference.sourceId)
@@ -2076,15 +2163,7 @@ async function statusCommandV8InSession(options) {
2076
2163
  sourceId: reference.sourceId,
2077
2164
  pluginName: reference.pluginName,
2078
2165
  })));
2079
- const isDisabledCodexReference = (reference) => {
2080
- if (reference.kind !== 'namespacedMarketplace' || reference.platform !== 'codex'
2081
- || !reference.pluginName || !reference.marketplaceName)
2082
- return false;
2083
- const config = reference.scope === 'user' ? userCodexConfig : projectCodexConfig;
2084
- return config?.snapshot.plugins[`${reference.pluginName}@${reference.marketplaceName}`]?.enabled === false;
2085
- };
2086
- unavailableBundleReferences.sort((left, right) => Number(isDisabledCodexReference(right)) - Number(isDisabledCodexReference(left)));
2087
- const unavailableBundleTargets = [...new Map(unavailableBundleReferences.flatMap((reference) => {
2166
+ const unavailableBundleTargets = [...new Map((await Promise.all(unavailableBundleReferences.map(async (reference) => {
2088
2167
  if (!reference.sourceId || !reference.pluginName
2089
2168
  || (reference.platform !== 'codex' && reference.platform !== 'claude')
2090
2169
  || (reference.scope !== 'user' && reference.scope !== 'project'))
@@ -2093,9 +2172,10 @@ async function statusCommandV8InSession(options) {
2093
2172
  if (requested.length > 0 && !plannedSelectors.some((selector) => selector.parsed.pluginName === reference.pluginName
2094
2173
  && (selector.parsed.sourceId === undefined || selector.parsed.sourceId === reference.sourceId)))
2095
2174
  return [];
2096
- const disabled = isDisabledCodexReference(reference)
2097
- && ![userIntent, projectIntent].some((intent) => intent.roots.some((root) => root.pluginId === pluginId && root.platforms.includes('codex')))
2098
- && (desiredTargetStates.get(desiredTargetKey(pluginId, 'codex'))?.scopes.length ?? 0) === 0;
2175
+ const registration = reference.platform === 'codex' && reference.marketplaceName
2176
+ ? await inspectCodexRegistration(`${reference.pluginName}@${reference.marketplaceName}`, reference.scope)
2177
+ : undefined;
2178
+ const nativeUnknown = registration && registration.observation.state !== 'observed';
2099
2179
  const target = {
2100
2180
  pluginName: reference.pluginName,
2101
2181
  sourceId: reference.sourceId,
@@ -2104,15 +2184,25 @@ async function statusCommandV8InSession(options) {
2104
2184
  platform: reference.platform,
2105
2185
  scope: reference.scope,
2106
2186
  cwd: path.resolve(options.cwd),
2107
- state: disabled ? 'absent' : 'error',
2108
- components: [],
2109
- errors: disabled ? [] : [finalizeTargetError({
2187
+ state: 'error',
2188
+ components: registration ? [{
2189
+ key: 'native',
2190
+ state: registration.observation.state !== 'observed' ? 'error'
2191
+ : registration.observation.value === 'installed' ? 'present' : 'absent',
2192
+ }] : [],
2193
+ errors: [finalizeTargetError({
2110
2194
  code: 'bundleUnavailable',
2111
2195
  message: `bundleUnavailable: ${pluginId} has live state but is not present in the current source snapshot.`,
2112
- }, 'error')],
2196
+ }, 'error'), finalizeTargetError({
2197
+ code: 'removedPluginCleanupRequired',
2198
+ message: `removedPluginCleanupRequired: ${pluginId} was removed from the current Catalog and has remaining local state.`,
2199
+ }, 'error'), ...(nativeUnknown ? [finalizeTargetError({
2200
+ code: 'codexNativeObservationFailed',
2201
+ message: 'codexNativeObservationFailed: the remaining native installation could not be observed.',
2202
+ }, 'error')] : [])],
2113
2203
  };
2114
2204
  return [[`${pluginId}\0${reference.platform}\0${reference.scope}`, target]];
2115
- })).values()];
2205
+ }))).flat()).values()];
2116
2206
  targets.push(...unavailableBundleTargets);
2117
2207
  const targetKeys = new Set(targets.map((target) => `${target.pluginId}\0${target.platform}\0${target.scope}`));
2118
2208
  for (const [scope, intent] of [