@lesliechan721/aw 0.1.0-beta.10 → 0.1.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring/assets/aw-config.d.mts +1 -50
- package/dist/authoring/assets/aw-config.mjs +58 -928
- package/dist/authoring/assets/aw-config.mjs.map +1 -1
- package/dist/authoring/scripts/init-plugin.mjs +28 -33
- package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/lib/plugin-version-check.d.mts +1 -0
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +229 -8
- package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +165 -45
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/bundle-plugins.js +18 -4
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/test-plugin-scripts.d.ts +2 -0
- package/dist/scripts/test-plugin-scripts.js +21 -5
- package/dist/scripts/test-plugin-scripts.js.map +1 -1
- package/dist/src/commands/aw-capabilities.d.ts +1 -1
- package/dist/src/commands/aw-capabilities.js +1 -1
- package/dist/src/commands/aw-capabilities.js.map +1 -1
- package/dist/src/commands/catalog-dev-source.d.ts +6 -3
- package/dist/src/commands/catalog-dev-source.js +96 -35
- package/dist/src/commands/catalog-dev-source.js.map +1 -1
- package/dist/src/commands/catalog-publication-inspection.d.ts +1 -1
- package/dist/src/commands/catalog-publication-inspection.js +54 -8
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
- package/dist/src/commands/catalog-publication-journal.js +1 -1
- package/dist/src/commands/catalog-publication-journal.js.map +1 -1
- package/dist/src/commands/catalog-source.d.ts +19 -4
- package/dist/src/commands/catalog-source.js +121 -12
- package/dist/src/commands/catalog-source.js.map +1 -1
- package/dist/src/commands/catalog-store.d.ts +26 -7
- package/dist/src/commands/catalog-store.js +361 -42
- package/dist/src/commands/catalog-store.js.map +1 -1
- package/dist/src/commands/console.js +28 -17
- package/dist/src/commands/console.js.map +1 -1
- package/dist/src/commands/operation-plan.d.ts +2 -1
- package/dist/src/commands/operation-plan.js +24 -0
- package/dist/src/commands/operation-plan.js.map +1 -1
- package/dist/src/commands/operation-planner.d.ts +2 -2
- package/dist/src/commands/operation-planner.js +11 -19
- package/dist/src/commands/operation-planner.js.map +1 -1
- package/dist/src/commands/options.d.ts +2 -2
- package/dist/src/commands/options.js +18 -4
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.js +2 -2
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +7 -0
- package/dist/src/commands/rebuild-command.js +769 -279
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +24 -47
- package/dist/src/commands/rebuild-integration.js +1074 -1011
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.d.ts +50 -12
- package/dist/src/commands/rebuild-operations.js +207 -101
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/commands/status-v6.d.ts +21 -2
- package/dist/src/commands/status-v6.js +163 -31
- package/dist/src/commands/status-v6.js.map +1 -1
- package/dist/src/commands/sync-command.d.ts +17 -0
- package/dist/src/commands/sync-command.js +45 -37
- package/dist/src/commands/sync-command.js.map +1 -1
- package/dist/src/commands/write-commands.d.ts +5 -0
- package/dist/src/commands/write-commands.js +50 -3
- package/dist/src/commands/write-commands.js.map +1 -1
- package/dist/src/generators/local-plugin.js +14 -4
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.js +216 -85
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/command-receipt.js +1 -3
- package/dist/src/output/command-receipt.js.map +1 -1
- package/dist/src/output/rebuild-progress.js +1 -3
- package/dist/src/output/rebuild-progress.js.map +1 -1
- package/dist/src/portable/materializer.js +6 -6
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/tui/catalog-generation.js +41 -1
- package/dist/src/tui/catalog-generation.js.map +1 -1
- package/dist/src/tui/catalog-sources/session.d.ts +1 -0
- package/dist/src/tui/catalog-sources/session.js +16 -3
- package/dist/src/tui/catalog-sources/session.js.map +1 -1
- package/dist/src/tui/catalog-sources/types.d.ts +3 -2
- package/dist/src/tui/components.d.ts +4 -0
- package/dist/src/tui/components.js +36 -24
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.d.ts +13 -4
- package/dist/src/tui/console-app-v4.js +2067 -839
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.js +585 -33
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +152 -6
- package/dist/src/tui/controller.js +1168 -156
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/diagnostic-projection.d.ts +22 -0
- package/dist/src/tui/diagnostic-projection.js +437 -0
- package/dist/src/tui/diagnostic-projection.js.map +1 -0
- package/dist/src/tui/diagnostics.d.ts +1 -1
- package/dist/src/tui/diagnostics.js +6 -1
- package/dist/src/tui/diagnostics.js.map +1 -1
- package/dist/src/tui/glossary.d.ts +23 -0
- package/dist/src/tui/glossary.js +42 -0
- package/dist/src/tui/glossary.js.map +1 -0
- package/dist/src/tui/index.d.ts +4 -1
- package/dist/src/tui/index.js +4 -1
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/keys.d.ts +44 -0
- package/dist/src/tui/keys.js +43 -15
- package/dist/src/tui/keys.js.map +1 -1
- package/dist/src/tui/lifecycle-action-view.d.ts +6 -0
- package/dist/src/tui/lifecycle-action-view.js +34 -0
- package/dist/src/tui/lifecycle-action-view.js.map +1 -0
- package/dist/src/tui/model.d.ts +12 -2
- package/dist/src/tui/model.js +128 -52
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/operation-diagnostic-screens.d.ts +21 -0
- package/dist/src/tui/operation-diagnostic-screens.js +101 -0
- package/dist/src/tui/operation-diagnostic-screens.js.map +1 -0
- package/dist/src/tui/operation-history.d.ts +80 -0
- package/dist/src/tui/operation-history.js +130 -0
- package/dist/src/tui/operation-history.js.map +1 -0
- package/dist/src/tui/operation-review-planner.js +306 -86
- package/dist/src/tui/operation-review-planner.js.map +1 -1
- package/dist/src/tui/router.d.ts +82 -17
- package/dist/src/tui/router.js +186 -38
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/tui/screen-registry.d.ts +546 -0
- package/dist/src/tui/screen-registry.js +179 -0
- package/dist/src/tui/screen-registry.js.map +1 -0
- package/dist/src/tui/session-console-app.d.ts +6 -0
- package/dist/src/tui/session-console-app.js +13 -0
- package/dist/src/tui/session-console-app.js.map +1 -0
- package/dist/src/tui/session-host.d.ts +44 -0
- package/dist/src/tui/session-host.js +197 -0
- package/dist/src/tui/session-host.js.map +1 -0
- package/dist/src/types.d.ts +64 -3
- package/dist/src/types.js +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/agent-version.js +1 -1
- package/dist/src/utils/agent-version.js.map +1 -1
- package/dist/src/utils/artifact-renderer.d.ts +2 -1
- package/dist/src/utils/artifact-renderer.js +52 -52
- package/dist/src/utils/artifact-renderer.js.map +1 -1
- package/dist/src/utils/bundle-layout.js +4 -4
- package/dist/src/utils/bundle-layout.js.map +1 -1
- package/dist/src/utils/catalog-capability-projection.d.ts +8 -0
- package/dist/src/utils/catalog-capability-projection.js +14 -0
- package/dist/src/utils/catalog-capability-projection.js.map +1 -0
- package/dist/src/utils/catalog-generation-resolver.d.ts +14 -2
- package/dist/src/utils/catalog-generation-resolver.js +49 -27
- package/dist/src/utils/catalog-generation-resolver.js.map +1 -1
- package/dist/src/utils/catalog-generation-service.d.ts +8 -1
- package/dist/src/utils/catalog-generation-service.js +81 -47
- package/dist/src/utils/catalog-generation-service.js.map +1 -1
- package/dist/src/utils/catalog-generation-store.d.ts +1 -0
- package/dist/src/utils/catalog-generation-store.js +60 -5
- package/dist/src/utils/catalog-generation-store.js.map +1 -1
- package/dist/src/utils/catalog-operation-context.js +1 -0
- package/dist/src/utils/catalog-operation-context.js.map +1 -1
- package/dist/src/utils/catalog-public-error.js +4 -0
- package/dist/src/utils/catalog-public-error.js.map +1 -1
- package/dist/src/utils/catalog-source-impact.d.ts +3 -2
- package/dist/src/utils/catalog-source-impact.js +142 -20
- package/dist/src/utils/catalog-source-impact.js.map +1 -1
- package/dist/src/utils/catalog-source-references.js +95 -9
- package/dist/src/utils/catalog-source-references.js.map +1 -1
- package/dist/src/utils/catalog-sources.d.ts +1 -1
- package/dist/src/utils/catalog-sources.js +19 -3
- package/dist/src/utils/catalog-sources.js.map +1 -1
- package/dist/src/utils/codex-manager.js +8 -0
- package/dist/src/utils/codex-manager.js.map +1 -1
- package/dist/src/utils/codex-native-observation.d.ts +34 -1
- package/dist/src/utils/codex-native-observation.js +132 -0
- package/dist/src/utils/codex-native-observation.js.map +1 -1
- package/dist/src/utils/codex-reconciler.d.ts +0 -2
- package/dist/src/utils/codex-reconciler.js.map +1 -1
- package/dist/src/utils/codex-shared-native.d.ts +2 -26
- package/dist/src/utils/codex-shared-native.js +8 -82
- package/dist/src/utils/codex-shared-native.js.map +1 -1
- package/dist/src/utils/git-catalog-provider.d.ts +3 -0
- package/dist/src/utils/git-catalog-provider.js +40 -1
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/local-marketplace.d.ts +1 -0
- package/dist/src/utils/local-marketplace.js +69 -73
- package/dist/src/utils/local-marketplace.js.map +1 -1
- package/dist/src/utils/multi-source-catalog.js +1 -0
- package/dist/src/utils/multi-source-catalog.js.map +1 -1
- package/dist/src/utils/native-cli.d.ts +9 -4
- package/dist/src/utils/native-cli.js +280 -34
- package/dist/src/utils/native-cli.js.map +1 -1
- package/dist/src/utils/path-catalog-provider.js +2 -0
- package/dist/src/utils/path-catalog-provider.js.map +1 -1
- package/dist/src/utils/plugin-config-write.d.ts +15 -13
- package/dist/src/utils/plugin-config-write.js +418 -198
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-config.d.ts +48 -4
- package/dist/src/utils/plugin-config.js +289 -38
- package/dist/src/utils/plugin-config.js.map +1 -1
- package/dist/src/utils/plugin-scripts.d.ts +20 -12
- package/dist/src/utils/plugin-scripts.js +376 -109
- package/dist/src/utils/plugin-scripts.js.map +1 -1
- package/dist/src/utils/process-tree.d.ts +2 -2
- package/dist/src/utils/process-tree.js +1 -1
- package/dist/src/utils/process-tree.js.map +1 -1
- package/dist/src/utils/project-boundary.d.ts +11 -1
- package/dist/src/utils/project-boundary.js +17 -8
- package/dist/src/utils/project-boundary.js.map +1 -1
- package/dist/src/utils/safe-operation-diagnostic.d.ts +15 -0
- package/dist/src/utils/safe-operation-diagnostic.js +33 -0
- package/dist/src/utils/safe-operation-diagnostic.js.map +1 -0
- package/dist/src/utils/sensitive-content.d.ts +1 -0
- package/dist/src/utils/sensitive-content.js +15 -0
- package/dist/src/utils/sensitive-content.js.map +1 -0
- package/dist/src/utils/windows-claude-shim.d.ts +9 -0
- package/dist/src/utils/windows-claude-shim.js +141 -0
- package/dist/src/utils/windows-claude-shim.js.map +1 -0
- package/dist/vitest.config.js +91 -10
- package/dist/vitest.config.js.map +1 -1
- package/package.json +9 -9
- package/dist/authoring/templates/aw-config-runtime.d.mts +0 -2
- package/dist/authoring/templates/aw-config-runtime.mjs +0 -407
- package/dist/authoring/templates/aw-config-runtime.mjs.map +0 -1
|
@@ -6,6 +6,7 @@ import { canonicalizePluginConfigValues, formatPluginConfigIssue, matchPluginCon
|
|
|
6
6
|
import { assertTestReadablePath, assertTestWritablePath, } from './test-path-fence.js';
|
|
7
7
|
import { canonicalizePathThroughExistingAncestor, resolveAwHome, resolveRepoRootSync, } from './paths.js';
|
|
8
8
|
import { assertRealFileParentWithinRoot, assertSafeFileMutationPath, atomicReplaceSafeFile, } from './safe-fs.js';
|
|
9
|
+
import { assertProjectSharedConfigPathVisible, PROJECT_CONFIG_SHAREABILITY_UNVERIFIED_WARNING, } from './project-boundary.js';
|
|
9
10
|
export function codexNativeRefreshKeys(manifest) {
|
|
10
11
|
return new Set((manifest.artifacts?.targets ?? []).flatMap((target) => target.platform === 'codex'
|
|
11
12
|
&& target.target === 'codex.skill'
|
|
@@ -13,6 +14,51 @@ export function codexNativeRefreshKeys(manifest) {
|
|
|
13
14
|
? target.refreshKeys
|
|
14
15
|
: []));
|
|
15
16
|
}
|
|
17
|
+
function readPluginConfigBinding(value, scope) {
|
|
18
|
+
if (!isRecord(value))
|
|
19
|
+
return null;
|
|
20
|
+
if (scope === 'user') {
|
|
21
|
+
return value.kind === 'source'
|
|
22
|
+
&& typeof value.sourceIdentity === 'string'
|
|
23
|
+
&& /^sha256:[0-9a-f]{64}$/u.test(value.sourceIdentity)
|
|
24
|
+
&& Object.keys(value).every((key) => ['kind', 'sourceIdentity'].includes(key))
|
|
25
|
+
? { kind: 'source', sourceIdentity: value.sourceIdentity }
|
|
26
|
+
: null;
|
|
27
|
+
}
|
|
28
|
+
return value.kind === 'catalog'
|
|
29
|
+
&& typeof value.logicalIdentity === 'string'
|
|
30
|
+
&& value.logicalIdentity.trim().length > 0
|
|
31
|
+
&& Object.keys(value).every((key) => ['kind', 'logicalIdentity'].includes(key))
|
|
32
|
+
? { kind: 'catalog', logicalIdentity: value.logicalIdentity }
|
|
33
|
+
: null;
|
|
34
|
+
}
|
|
35
|
+
const PLUGIN_CONFIG_ENVELOPE_V4_KEYS = new Set([
|
|
36
|
+
'schemaVersion',
|
|
37
|
+
'sourceId',
|
|
38
|
+
'pluginName',
|
|
39
|
+
'binding',
|
|
40
|
+
'values',
|
|
41
|
+
]);
|
|
42
|
+
function readPluginConfigEnvelopeV4(value, scope) {
|
|
43
|
+
if (!isRecord(value)
|
|
44
|
+
|| value.schemaVersion !== 4
|
|
45
|
+
|| typeof value.sourceId !== 'string'
|
|
46
|
+
|| typeof value.pluginName !== 'string'
|
|
47
|
+
|| !isRecord(value.values)
|
|
48
|
+
|| Object.keys(value).some((key) => !PLUGIN_CONFIG_ENVELOPE_V4_KEYS.has(key))) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const binding = readPluginConfigBinding(value.binding, scope);
|
|
52
|
+
if (!binding)
|
|
53
|
+
return null;
|
|
54
|
+
return {
|
|
55
|
+
schemaVersion: 4,
|
|
56
|
+
sourceId: value.sourceId,
|
|
57
|
+
pluginName: value.pluginName,
|
|
58
|
+
binding,
|
|
59
|
+
values: value.values,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
16
62
|
export class PluginConfigResetError extends Error {
|
|
17
63
|
code;
|
|
18
64
|
osCode;
|
|
@@ -356,17 +402,33 @@ async function readNamespacedStoreFile(options) {
|
|
|
356
402
|
if (parsed.state === 'invalidJson')
|
|
357
403
|
return parsed.store;
|
|
358
404
|
const raw = parsed.value;
|
|
359
|
-
if (!isRecord(raw) || raw.schemaVersion !==
|
|
360
|
-
return invalidStore(options.filePath, 'schemaVersionUnsupported', 'Only plugin config store schemaVersion
|
|
405
|
+
if (!isRecord(raw) || raw.schemaVersion !== 4) {
|
|
406
|
+
return invalidStore(options.filePath, 'schemaVersionUnsupported', 'Only plugin config store schemaVersion 4 is supported.', parsed.rawDigest);
|
|
407
|
+
}
|
|
408
|
+
const envelope = readPluginConfigEnvelopeV4(raw, options.scope);
|
|
409
|
+
if (!envelope) {
|
|
410
|
+
return invalidStore(options.filePath, 'schemaVersionUnsupported', 'The plugin config store schemaVersion 4 envelope is invalid.', parsed.rawDigest);
|
|
361
411
|
}
|
|
362
|
-
if (
|
|
363
|
-
||
|
|
364
|
-
|| raw.sourceIdentity !== options.sourceIdentity) {
|
|
412
|
+
if (envelope.sourceId !== options.sourceId
|
|
413
|
+
|| envelope.pluginName !== options.pluginName) {
|
|
365
414
|
return invalidStore(options.filePath, 'identityMismatch', 'The store identity does not match its source and namespaced path.', parsed.rawDigest);
|
|
366
415
|
}
|
|
416
|
+
const binding = envelope.binding;
|
|
417
|
+
const matchesBinding = options.scope === 'user'
|
|
418
|
+
? binding?.kind === 'source'
|
|
419
|
+
&& typeof options.sourceIdentity === 'string'
|
|
420
|
+
&& binding.sourceIdentity === options.sourceIdentity
|
|
421
|
+
: binding?.kind === 'catalog'
|
|
422
|
+
&& typeof options.logicalIdentity === 'string'
|
|
423
|
+
&& binding.logicalIdentity === options.logicalIdentity;
|
|
424
|
+
if (!matchesBinding) {
|
|
425
|
+
return invalidStore(options.filePath, 'identityMismatch', options.scope === 'user'
|
|
426
|
+
? 'The user store is not bound to the requested source identity.'
|
|
427
|
+
: 'The project store is not bound to the requested Catalog logical identity.', parsed.rawDigest);
|
|
428
|
+
}
|
|
367
429
|
return validateStoreValues({
|
|
368
430
|
filePath: options.filePath,
|
|
369
|
-
values:
|
|
431
|
+
values: envelope.values,
|
|
370
432
|
rawDigest: parsed.rawDigest,
|
|
371
433
|
});
|
|
372
434
|
}
|
|
@@ -374,14 +436,18 @@ function namespacedConfigContent(options) {
|
|
|
374
436
|
const values = canonicalizePluginConfigValues(options.values);
|
|
375
437
|
if (!options.sourceId)
|
|
376
438
|
return `${JSON.stringify(values, null, 2)}\n`;
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
439
|
+
const binding = options.scope === 'user'
|
|
440
|
+
? options.sourceIdentity
|
|
441
|
+
? { kind: 'source', sourceIdentity: options.sourceIdentity }
|
|
442
|
+
: (() => { throw new Error('sourceChanged: user plugin config requires a source identity.'); })()
|
|
443
|
+
: options.logicalIdentity
|
|
444
|
+
? { kind: 'catalog', logicalIdentity: options.logicalIdentity }
|
|
445
|
+
: (() => { throw new Error('catalogUnavailable: project plugin config requires verified Catalog logical identity evidence.'); })();
|
|
380
446
|
const envelope = {
|
|
381
|
-
schemaVersion:
|
|
447
|
+
schemaVersion: 4,
|
|
382
448
|
sourceId: options.sourceId,
|
|
383
|
-
sourceIdentity: options.sourceIdentity,
|
|
384
449
|
pluginName: options.pluginName,
|
|
450
|
+
binding,
|
|
385
451
|
values,
|
|
386
452
|
};
|
|
387
453
|
return `${JSON.stringify(envelope, null, 2)}\n`;
|
|
@@ -431,7 +497,9 @@ export async function readPluginConfigStore(options) {
|
|
|
431
497
|
? readNamespacedStoreFile({
|
|
432
498
|
filePath,
|
|
433
499
|
sourceId: options.sourceId,
|
|
500
|
+
scope: options.scope,
|
|
434
501
|
sourceIdentity: options.sourceIdentity,
|
|
502
|
+
logicalIdentity: options.logicalIdentity,
|
|
435
503
|
pluginName: options.pluginName,
|
|
436
504
|
})
|
|
437
505
|
: readStoreFile(filePath);
|
|
@@ -447,16 +515,16 @@ export async function readNamespacedPluginConfigStoreIdentity(options) {
|
|
|
447
515
|
if (parsed.state === 'invalidJson') {
|
|
448
516
|
throw new Error(`${parsed.store.invalidCode}: invalid namespaced plugin config store.`);
|
|
449
517
|
}
|
|
450
|
-
const
|
|
451
|
-
if (!
|
|
452
|
-
||
|
|
453
|
-
||
|
|
518
|
+
const envelope = readPluginConfigEnvelopeV4(parsed.value, options.scope);
|
|
519
|
+
if (!envelope
|
|
520
|
+
|| envelope.sourceId !== options.sourceId
|
|
521
|
+
|| envelope.pluginName !== options.pluginName) {
|
|
454
522
|
throw new Error('schemaVersionUnsupported: invalid namespaced plugin config store.');
|
|
455
523
|
}
|
|
456
|
-
const store = validateStoreValues({ filePath, values:
|
|
524
|
+
const store = validateStoreValues({ filePath, values: envelope.values });
|
|
457
525
|
assertReadyPluginConfigStore(store);
|
|
458
526
|
return {
|
|
459
|
-
|
|
527
|
+
binding: envelope.binding,
|
|
460
528
|
store,
|
|
461
529
|
};
|
|
462
530
|
}
|
|
@@ -496,6 +564,64 @@ export async function listPluginConfigStorePluginNames(options) {
|
|
|
496
564
|
const pluginNames = (await Promise.all(storeRoots.map((storeRoot) => listConfigStoreDirectoryPluginNames(storeRoot)))).flat();
|
|
497
565
|
return [...new Set(pluginNames)].sort((left, right) => left.localeCompare(right));
|
|
498
566
|
}
|
|
567
|
+
export async function listNamespacedPluginConfigStoreIdentities(options) {
|
|
568
|
+
const boundaryRoot = options.scope === 'user'
|
|
569
|
+
? resolveAwHome(options.env)
|
|
570
|
+
: resolveAwProjectRoot(options.cwd);
|
|
571
|
+
if (options.scope === 'user') {
|
|
572
|
+
await canonicalizePathThroughExistingAncestor(boundaryRoot);
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
await fs.realpath(boundaryRoot);
|
|
576
|
+
}
|
|
577
|
+
const storeRoot = path.join(boundaryRoot, ...(options.scope === 'project' ? ['.agent-workflows'] : []), CONFIG_DIR);
|
|
578
|
+
if (!await inspectConfigInventoryStoreRoot(boundaryRoot, storeRoot))
|
|
579
|
+
return [];
|
|
580
|
+
const output = [];
|
|
581
|
+
for (const sourceEntry of await fs.readdir(storeRoot, { withFileTypes: true })) {
|
|
582
|
+
if (!sourceEntry.isDirectory() || sourceEntry.isSymbolicLink())
|
|
583
|
+
continue;
|
|
584
|
+
let sourceId;
|
|
585
|
+
try {
|
|
586
|
+
sourceId = assertSafePluginConfigSegment(sourceEntry.name);
|
|
587
|
+
}
|
|
588
|
+
catch {
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
const sourceRoot = path.join(storeRoot, sourceId);
|
|
592
|
+
let pluginEntries;
|
|
593
|
+
try {
|
|
594
|
+
await assertNoConfigSymlink(boundaryRoot, sourceRoot);
|
|
595
|
+
pluginEntries = await fs.readdir(sourceRoot, { withFileTypes: true });
|
|
596
|
+
}
|
|
597
|
+
catch {
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
for (const pluginEntry of pluginEntries) {
|
|
601
|
+
if (!pluginEntry.isDirectory() || pluginEntry.isSymbolicLink())
|
|
602
|
+
continue;
|
|
603
|
+
let pluginName;
|
|
604
|
+
try {
|
|
605
|
+
pluginName = assertSafePluginConfigSegment(pluginEntry.name);
|
|
606
|
+
await assertNoConfigSymlink(boundaryRoot, path.join(sourceRoot, pluginName));
|
|
607
|
+
}
|
|
608
|
+
catch {
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
611
|
+
let target;
|
|
612
|
+
try {
|
|
613
|
+
target = await lstatIfExists(path.join(sourceRoot, pluginName, CONFIG_FILE));
|
|
614
|
+
}
|
|
615
|
+
catch {
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
if (!target)
|
|
619
|
+
continue;
|
|
620
|
+
output.push({ sourceId, pluginName, pluginId: `${sourceId}/${pluginName}` });
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return output.sort((left, right) => left.pluginId.localeCompare(right.pluginId));
|
|
624
|
+
}
|
|
499
625
|
export async function listNamespacedPluginConfigStores(options) {
|
|
500
626
|
const boundaryRoot = options.scope === 'user'
|
|
501
627
|
? resolveAwHome(options.env)
|
|
@@ -532,17 +658,17 @@ export async function listNamespacedPluginConfigStores(options) {
|
|
|
532
658
|
if (parsed.state === 'invalidJson') {
|
|
533
659
|
throw new Error(`${parsed.store.invalidCode}: invalid namespaced plugin config store "${filePath}".`);
|
|
534
660
|
}
|
|
535
|
-
const
|
|
536
|
-
if (!
|
|
537
|
-
||
|
|
538
|
-
||
|
|
661
|
+
const envelope = readPluginConfigEnvelopeV4(parsed.value, options.scope);
|
|
662
|
+
if (!envelope
|
|
663
|
+
|| envelope.sourceId !== sourceId
|
|
664
|
+
|| envelope.pluginName !== pluginName) {
|
|
539
665
|
throw new Error(`schemaVersionUnsupported: invalid namespaced plugin config store "${filePath}".`);
|
|
540
666
|
}
|
|
541
|
-
const store = validateStoreValues({ filePath, values:
|
|
667
|
+
const store = validateStoreValues({ filePath, values: envelope.values });
|
|
542
668
|
assertReadyPluginConfigStore(store);
|
|
543
669
|
output.push({
|
|
544
670
|
sourceId,
|
|
545
|
-
|
|
671
|
+
binding: envelope.binding,
|
|
546
672
|
pluginName,
|
|
547
673
|
pluginId: `${sourceId}/${pluginName}`,
|
|
548
674
|
values: store.values,
|
|
@@ -560,22 +686,37 @@ export async function writePluginConfigStore(options) {
|
|
|
560
686
|
const allowedRoot = resolvePluginConfigAllowedRoot(options);
|
|
561
687
|
const validated = validateStoreValues({ filePath, values: options.values });
|
|
562
688
|
assertReadyPluginConfigStore(validated);
|
|
689
|
+
const warnings = [];
|
|
563
690
|
await withConfigFileMutation({
|
|
564
691
|
filePath,
|
|
565
692
|
allowedRoot,
|
|
566
|
-
action: async () =>
|
|
567
|
-
|
|
568
|
-
|
|
693
|
+
action: async () => {
|
|
694
|
+
if (Object.keys(validated.values).length === 0) {
|
|
695
|
+
return atomicRemoveConfigFile({ filePath, allowedRoot });
|
|
696
|
+
}
|
|
697
|
+
if (options.scope === 'project') {
|
|
698
|
+
const visibility = await assertProjectSharedConfigPathVisible({
|
|
699
|
+
cwd: options.cwd,
|
|
700
|
+
targetPath: filePath,
|
|
701
|
+
env: options.env,
|
|
702
|
+
});
|
|
703
|
+
if (visibility?.state === 'unverified') {
|
|
704
|
+
warnings.push(PROJECT_CONFIG_SHAREABILITY_UNVERIFIED_WARNING);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return atomicReplaceConfigFile({
|
|
569
708
|
filePath,
|
|
570
709
|
allowedRoot,
|
|
571
710
|
content: namespacedConfigContent({ ...options, values: validated.values }),
|
|
572
711
|
mode: 0o600,
|
|
573
|
-
})
|
|
712
|
+
});
|
|
713
|
+
},
|
|
574
714
|
});
|
|
575
715
|
return {
|
|
576
716
|
pluginName: options.pluginName,
|
|
577
717
|
scope: options.scope,
|
|
578
718
|
path: filePath,
|
|
719
|
+
warnings,
|
|
579
720
|
};
|
|
580
721
|
}
|
|
581
722
|
export async function patchPluginConfigStore(options) {
|
|
@@ -586,6 +727,7 @@ export async function patchPluginConfigStore(options) {
|
|
|
586
727
|
});
|
|
587
728
|
const allowedRoot = resolvePluginConfigAllowedRoot(options);
|
|
588
729
|
const removedKeys = options.removeKeys ?? [];
|
|
730
|
+
const warnings = [];
|
|
589
731
|
await withConfigFileMutation({
|
|
590
732
|
filePath,
|
|
591
733
|
allowedRoot,
|
|
@@ -596,7 +738,9 @@ export async function patchPluginConfigStore(options) {
|
|
|
596
738
|
? await readNamespacedStoreFile({
|
|
597
739
|
filePath,
|
|
598
740
|
sourceId: options.sourceId,
|
|
741
|
+
scope: options.scope,
|
|
599
742
|
sourceIdentity: options.sourceIdentity,
|
|
743
|
+
logicalIdentity: options.logicalIdentity,
|
|
600
744
|
pluginName: options.pluginName,
|
|
601
745
|
})
|
|
602
746
|
: await readStoreFile(filePath)
|
|
@@ -618,6 +762,16 @@ export async function patchPluginConfigStore(options) {
|
|
|
618
762
|
await atomicRemoveConfigFile({ filePath, allowedRoot });
|
|
619
763
|
}
|
|
620
764
|
else {
|
|
765
|
+
if (options.scope === 'project') {
|
|
766
|
+
const visibility = await assertProjectSharedConfigPathVisible({
|
|
767
|
+
cwd: options.cwd,
|
|
768
|
+
targetPath: filePath,
|
|
769
|
+
env: options.env,
|
|
770
|
+
});
|
|
771
|
+
if (visibility?.state === 'unverified') {
|
|
772
|
+
warnings.push(PROJECT_CONFIG_SHAREABILITY_UNVERIFIED_WARNING);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
621
775
|
await atomicReplaceConfigFile({
|
|
622
776
|
filePath,
|
|
623
777
|
allowedRoot,
|
|
@@ -631,6 +785,7 @@ export async function patchPluginConfigStore(options) {
|
|
|
631
785
|
pluginName: options.pluginName,
|
|
632
786
|
scope: options.scope,
|
|
633
787
|
path: filePath,
|
|
788
|
+
warnings,
|
|
634
789
|
updatedKeys: Object.keys(options.updates),
|
|
635
790
|
removedKeys,
|
|
636
791
|
};
|
|
@@ -897,6 +1052,7 @@ export async function resolveEffectivePluginConfig(options) {
|
|
|
897
1052
|
const userStore = await readPluginConfigStore({
|
|
898
1053
|
sourceId: options.sourceId,
|
|
899
1054
|
sourceIdentity: options.sourceIdentity,
|
|
1055
|
+
logicalIdentity: options.logicalIdentity,
|
|
900
1056
|
pluginName,
|
|
901
1057
|
scope: 'user',
|
|
902
1058
|
cwd: options.cwd,
|
|
@@ -907,6 +1063,7 @@ export async function resolveEffectivePluginConfig(options) {
|
|
|
907
1063
|
: await readPluginConfigStore({
|
|
908
1064
|
sourceId: options.sourceId,
|
|
909
1065
|
sourceIdentity: options.sourceIdentity,
|
|
1066
|
+
logicalIdentity: options.logicalIdentity,
|
|
910
1067
|
pluginName,
|
|
911
1068
|
scope: 'project',
|
|
912
1069
|
cwd: options.cwd,
|
|
@@ -920,8 +1077,10 @@ export async function resolveEffectivePluginConfig(options) {
|
|
|
920
1077
|
const sources = {};
|
|
921
1078
|
const fieldStates = {};
|
|
922
1079
|
const ignoredUnknownKeys = [];
|
|
1080
|
+
const unsupportedLayerOverrides = [];
|
|
923
1081
|
const dangerousKeyIssues = [];
|
|
924
1082
|
const schemaKeys = new Set(Object.keys(schema));
|
|
1083
|
+
const userOnlyKeys = codexNativeRefreshKeys(options.manifest);
|
|
925
1084
|
for (const key of schemaKeys) {
|
|
926
1085
|
sources[key] = 'missing';
|
|
927
1086
|
}
|
|
@@ -967,13 +1126,26 @@ export async function resolveEffectivePluginConfig(options) {
|
|
|
967
1126
|
}
|
|
968
1127
|
}
|
|
969
1128
|
}
|
|
1129
|
+
const supportedEntries = scope === 'project'
|
|
1130
|
+
? Object.fromEntries(Object.entries(plainEntries).filter(([key]) => {
|
|
1131
|
+
if (!schemaKeys.has(key) || !userOnlyKeys.has(key))
|
|
1132
|
+
return true;
|
|
1133
|
+
unsupportedLayerOverrides.push({
|
|
1134
|
+
type: 'configLayerUnsupported',
|
|
1135
|
+
key,
|
|
1136
|
+
scope: 'project',
|
|
1137
|
+
source: 'project',
|
|
1138
|
+
});
|
|
1139
|
+
return false;
|
|
1140
|
+
}))
|
|
1141
|
+
: plainEntries;
|
|
970
1142
|
await applyConfigLayer({
|
|
971
1143
|
values,
|
|
972
1144
|
redactedValues,
|
|
973
1145
|
sources,
|
|
974
1146
|
fieldStates,
|
|
975
1147
|
schema,
|
|
976
|
-
entries:
|
|
1148
|
+
entries: supportedEntries,
|
|
977
1149
|
source,
|
|
978
1150
|
});
|
|
979
1151
|
}
|
|
@@ -999,6 +1171,7 @@ export async function resolveEffectivePluginConfig(options) {
|
|
|
999
1171
|
sources,
|
|
1000
1172
|
fieldStates,
|
|
1001
1173
|
issues,
|
|
1174
|
+
unsupportedLayerOverrides,
|
|
1002
1175
|
ignoredUnknownKeys,
|
|
1003
1176
|
schema,
|
|
1004
1177
|
stores: {
|
|
@@ -1030,6 +1203,7 @@ export async function resolveProjectArtifactRenderConfig(options) {
|
|
|
1030
1203
|
readPluginConfigStore({
|
|
1031
1204
|
sourceId: options.sourceId,
|
|
1032
1205
|
sourceIdentity: options.sourceIdentity,
|
|
1206
|
+
logicalIdentity: options.logicalIdentity,
|
|
1033
1207
|
pluginName,
|
|
1034
1208
|
scope: 'user',
|
|
1035
1209
|
cwd: options.cwd,
|
|
@@ -1038,6 +1212,7 @@ export async function resolveProjectArtifactRenderConfig(options) {
|
|
|
1038
1212
|
readPluginConfigStore({
|
|
1039
1213
|
sourceId: options.sourceId,
|
|
1040
1214
|
sourceIdentity: options.sourceIdentity,
|
|
1215
|
+
logicalIdentity: options.logicalIdentity,
|
|
1041
1216
|
pluginName,
|
|
1042
1217
|
scope: 'project',
|
|
1043
1218
|
cwd: options.cwd,
|
|
@@ -1052,6 +1227,7 @@ export async function resolveProjectArtifactRenderConfig(options) {
|
|
|
1052
1227
|
values: {},
|
|
1053
1228
|
sources: {},
|
|
1054
1229
|
issues: [],
|
|
1230
|
+
unsupportedLayerOverrides: [],
|
|
1055
1231
|
ignoredUnknownKeys: [],
|
|
1056
1232
|
schema: {},
|
|
1057
1233
|
stores: { user: userStore, project: projectStore },
|
|
@@ -1067,6 +1243,7 @@ export async function resolveProjectArtifactRenderConfig(options) {
|
|
|
1067
1243
|
values: effective.values,
|
|
1068
1244
|
sources: effective.sources,
|
|
1069
1245
|
issues: effective.issues,
|
|
1246
|
+
unsupportedLayerOverrides: effective.unsupportedLayerOverrides,
|
|
1070
1247
|
ignoredUnknownKeys: effective.ignoredUnknownKeys,
|
|
1071
1248
|
schema: effective.schema,
|
|
1072
1249
|
stores: {
|
|
@@ -1155,6 +1332,7 @@ export async function resolveProjectScopedPluginConfigView(options) {
|
|
|
1155
1332
|
sources: effective.sources,
|
|
1156
1333
|
entries,
|
|
1157
1334
|
issues: effective.issues,
|
|
1335
|
+
unsupportedLayerOverrides: effective.unsupportedLayerOverrides,
|
|
1158
1336
|
ignoredUnknownKeys: effective.ignoredUnknownKeys,
|
|
1159
1337
|
};
|
|
1160
1338
|
}
|
|
@@ -1196,6 +1374,7 @@ async function buildManifestFieldEntries(options) {
|
|
|
1196
1374
|
const userStore = await readPluginConfigStore({
|
|
1197
1375
|
sourceId: options.plugin.sourceId,
|
|
1198
1376
|
sourceIdentity: options.plugin.sourceIdentity,
|
|
1377
|
+
logicalIdentity: options.plugin.catalogLogicalIdentity,
|
|
1199
1378
|
pluginName: options.plugin.manifest.name,
|
|
1200
1379
|
scope: 'user',
|
|
1201
1380
|
cwd: options.cwd,
|
|
@@ -1207,6 +1386,7 @@ async function buildManifestFieldEntries(options) {
|
|
|
1207
1386
|
: await readPluginConfigStore({
|
|
1208
1387
|
sourceId: options.plugin.sourceId,
|
|
1209
1388
|
sourceIdentity: options.plugin.sourceIdentity,
|
|
1389
|
+
logicalIdentity: options.plugin.catalogLogicalIdentity,
|
|
1210
1390
|
pluginName: options.plugin.manifest.name,
|
|
1211
1391
|
scope: 'project',
|
|
1212
1392
|
cwd: options.cwd,
|
|
@@ -1221,6 +1401,7 @@ async function buildManifestFieldEntries(options) {
|
|
|
1221
1401
|
const effective = await resolveEffectivePluginConfig({
|
|
1222
1402
|
sourceId: options.plugin.sourceId,
|
|
1223
1403
|
sourceIdentity: options.plugin.sourceIdentity,
|
|
1404
|
+
logicalIdentity: options.plugin.catalogLogicalIdentity,
|
|
1224
1405
|
pluginName: options.plugin.manifest.name,
|
|
1225
1406
|
manifest: options.plugin.manifest,
|
|
1226
1407
|
targetScope: options.scope === 'user' ? 'user' : 'project',
|
|
@@ -1228,12 +1409,65 @@ async function buildManifestFieldEntries(options) {
|
|
|
1228
1409
|
env: options.env,
|
|
1229
1410
|
});
|
|
1230
1411
|
const userOnlyKeys = codexNativeRefreshKeys(options.plugin.manifest);
|
|
1412
|
+
const projectRemovalFallback = (key) => {
|
|
1413
|
+
const field = schema[key];
|
|
1414
|
+
if (Object.hasOwn(userPlainEntries, key)) {
|
|
1415
|
+
const value = userPlainEntries[key];
|
|
1416
|
+
const validationIssues = validateCorePluginConfigValue(field, value, key);
|
|
1417
|
+
if (validationIssues.length > 0) {
|
|
1418
|
+
return {
|
|
1419
|
+
state: 'invalid',
|
|
1420
|
+
sourceLayer: 'user',
|
|
1421
|
+
issues: validationIssues.map((issue) => ({
|
|
1422
|
+
type: 'invalid-config',
|
|
1423
|
+
key,
|
|
1424
|
+
source: 'user',
|
|
1425
|
+
message: formatPluginConfigIssue(issue),
|
|
1426
|
+
})),
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
return {
|
|
1430
|
+
state: 'valid',
|
|
1431
|
+
effectiveValue: redactValue(field, value),
|
|
1432
|
+
sourceLayer: 'user',
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
if (field.default === undefined)
|
|
1436
|
+
return { state: 'missing' };
|
|
1437
|
+
const validationIssues = validateCorePluginConfigValue(field, field.default, key);
|
|
1438
|
+
if (validationIssues.length > 0) {
|
|
1439
|
+
return {
|
|
1440
|
+
state: 'invalid',
|
|
1441
|
+
sourceLayer: 'default',
|
|
1442
|
+
issues: validationIssues.map((issue) => ({
|
|
1443
|
+
type: 'invalid-config',
|
|
1444
|
+
key,
|
|
1445
|
+
source: 'default',
|
|
1446
|
+
message: formatPluginConfigIssue(issue),
|
|
1447
|
+
})),
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
return {
|
|
1451
|
+
state: 'valid',
|
|
1452
|
+
effectiveValue: redactValue(field, field.default),
|
|
1453
|
+
sourceLayer: 'default',
|
|
1454
|
+
};
|
|
1455
|
+
};
|
|
1231
1456
|
const effectiveFieldState = (key) => {
|
|
1232
1457
|
const source = effective.sources[key];
|
|
1233
1458
|
const sourceLayer = toConfigSourceLayer(source);
|
|
1234
1459
|
const field = schema[key];
|
|
1235
1460
|
const fieldIssues = effective.issues.filter((entry) => entry.key === key);
|
|
1236
1461
|
const fieldState = effective.fieldStates[key];
|
|
1462
|
+
const fallback = options.scope === 'project'
|
|
1463
|
+
? projectRemovalFallback(key)
|
|
1464
|
+
: fieldState?.fallback
|
|
1465
|
+
? {
|
|
1466
|
+
state: 'valid',
|
|
1467
|
+
effectiveValue: fieldState.fallback.redactedValue,
|
|
1468
|
+
sourceLayer: fieldState.fallback.source,
|
|
1469
|
+
}
|
|
1470
|
+
: undefined;
|
|
1237
1471
|
if (source === undefined || source === 'missing') {
|
|
1238
1472
|
return {
|
|
1239
1473
|
valueState: fieldIssues.length > 0 ? 'invalid' : 'default',
|
|
@@ -1253,12 +1487,7 @@ async function buildManifestFieldEntries(options) {
|
|
|
1253
1487
|
issues: fieldState.invalidOverride.issues,
|
|
1254
1488
|
},
|
|
1255
1489
|
} : {}),
|
|
1256
|
-
...(
|
|
1257
|
-
fallback: {
|
|
1258
|
-
effectiveValue: fieldState.fallback.redactedValue,
|
|
1259
|
-
sourceLayer: fieldState.fallback.source,
|
|
1260
|
-
},
|
|
1261
|
-
} : {}),
|
|
1490
|
+
...(fallback ? { fallback } : {}),
|
|
1262
1491
|
...configFieldProjection({
|
|
1263
1492
|
field,
|
|
1264
1493
|
value: issue ? undefined : effective.values[key],
|
|
@@ -1269,12 +1498,18 @@ async function buildManifestFieldEntries(options) {
|
|
|
1269
1498
|
};
|
|
1270
1499
|
const fields = [];
|
|
1271
1500
|
for (const [key, field] of Object.entries(schema)) {
|
|
1501
|
+
const canSet = options.scope !== 'project'
|
|
1502
|
+
|| (!userOnlyKeys.has(key) && field.sensitive !== true);
|
|
1272
1503
|
const base = {
|
|
1273
1504
|
key,
|
|
1274
1505
|
title: field.title ?? key,
|
|
1275
1506
|
kind: 'manifest',
|
|
1276
1507
|
reserved: false,
|
|
1277
|
-
writable:
|
|
1508
|
+
writable: canSet,
|
|
1509
|
+
canSet,
|
|
1510
|
+
canUnset: options.scope === 'user'
|
|
1511
|
+
? Object.hasOwn(userPlainEntries, key)
|
|
1512
|
+
: options.scope === 'project' && Object.hasOwn(projectPlainEntries, key),
|
|
1278
1513
|
valueState: 'default',
|
|
1279
1514
|
effectiveValue: null,
|
|
1280
1515
|
sourceLayer: null,
|
|
@@ -1375,6 +1610,7 @@ async function buildLegacyStoreFieldEntries(options) {
|
|
|
1375
1610
|
const store = await readPluginConfigStore({
|
|
1376
1611
|
sourceId: options.sourceId,
|
|
1377
1612
|
sourceIdentity: options.sourceIdentity,
|
|
1613
|
+
logicalIdentity: options.logicalIdentity,
|
|
1378
1614
|
pluginName: options.pluginName,
|
|
1379
1615
|
scope: location.scope,
|
|
1380
1616
|
cwd: options.cwd,
|
|
@@ -1387,6 +1623,8 @@ async function buildLegacyStoreFieldEntries(options) {
|
|
|
1387
1623
|
kind: 'manifest',
|
|
1388
1624
|
reserved: false,
|
|
1389
1625
|
writable: false,
|
|
1626
|
+
canSet: false,
|
|
1627
|
+
canUnset: false,
|
|
1390
1628
|
valueState: 'configured',
|
|
1391
1629
|
effectiveValue: '[redacted]',
|
|
1392
1630
|
sourceLayer: location.sourceLayer,
|
|
@@ -1437,6 +1675,7 @@ export async function resolveConfigRead(options) {
|
|
|
1437
1675
|
: await buildLegacyStoreFieldEntries({
|
|
1438
1676
|
sourceId: options.sourceId,
|
|
1439
1677
|
sourceIdentity: options.sourceIdentity,
|
|
1678
|
+
logicalIdentity: options.logicalIdentity,
|
|
1440
1679
|
pluginName,
|
|
1441
1680
|
scope: options.scope,
|
|
1442
1681
|
cwd: options.cwd,
|
|
@@ -1446,6 +1685,9 @@ export async function resolveConfigRead(options) {
|
|
|
1446
1685
|
pluginName,
|
|
1447
1686
|
scope: options.scope,
|
|
1448
1687
|
...(schemaAccess.schema ? { schema: schemaAccess.schema } : {}),
|
|
1688
|
+
...(schemaAccess.plugin?.manifest.config?.fields
|
|
1689
|
+
? { fieldDefinitions: schemaAccess.plugin.manifest.config.fields }
|
|
1690
|
+
: {}),
|
|
1449
1691
|
fields: manifestFields,
|
|
1450
1692
|
};
|
|
1451
1693
|
}
|
|
@@ -1588,13 +1830,21 @@ export function toCliConfigPromptOptions(model) {
|
|
|
1588
1830
|
requiredKeys: [...model.requiredKeys],
|
|
1589
1831
|
};
|
|
1590
1832
|
}
|
|
1591
|
-
function
|
|
1833
|
+
export function formatPluginConfigSetRecoveryCommand(pluginName, key, field, scope) {
|
|
1834
|
+
return field.sensitive === true
|
|
1835
|
+
? `aw config set ${pluginName} ${key} --scope user --value-stdin`
|
|
1836
|
+
: `aw config set ${pluginName} ${key} --scope ${scope} --value-json '<json>'`;
|
|
1837
|
+
}
|
|
1838
|
+
function formatRequiredConfigSetCommands(pluginName, issues, defaultScope, schema) {
|
|
1592
1839
|
const commands = new Set();
|
|
1593
1840
|
for (const issue of issues) {
|
|
1594
1841
|
const scope = issue.source === 'user' || issue.source === 'project'
|
|
1595
1842
|
? issue.source
|
|
1596
1843
|
: defaultScope;
|
|
1597
|
-
|
|
1844
|
+
const field = schema[issue.key];
|
|
1845
|
+
if (!field)
|
|
1846
|
+
continue;
|
|
1847
|
+
commands.add(formatPluginConfigSetRecoveryCommand(pluginName, issue.key, field, scope));
|
|
1598
1848
|
}
|
|
1599
1849
|
return [...commands].map((command) => `\`${command}\``).join(' 或 ');
|
|
1600
1850
|
}
|
|
@@ -1620,6 +1870,7 @@ export async function preflightRequiredPluginConfigs(options) {
|
|
|
1620
1870
|
let effective = await resolveEffectivePluginConfig({
|
|
1621
1871
|
sourceId: target.sourceId,
|
|
1622
1872
|
sourceIdentity: target.sourceIdentity,
|
|
1873
|
+
logicalIdentity: target.logicalIdentity,
|
|
1623
1874
|
pluginName,
|
|
1624
1875
|
manifest: target.manifest,
|
|
1625
1876
|
cwd: options.cwd,
|
|
@@ -1630,7 +1881,7 @@ export async function preflightRequiredPluginConfigs(options) {
|
|
|
1630
1881
|
continue;
|
|
1631
1882
|
}
|
|
1632
1883
|
const details = blockingIssues.map((issue) => issue.key).join(', ');
|
|
1633
|
-
const setCommands = formatRequiredConfigSetCommands(pluginName, blockingIssues, options.defaultScope);
|
|
1884
|
+
const setCommands = formatRequiredConfigSetCommands(pluginName, blockingIssues, options.defaultScope, target.manifest.config.fields);
|
|
1634
1885
|
throw new Error(`${pluginName} requires valid AW config before install/upgrade: ${details}. ` +
|
|
1635
1886
|
`Run ${setCommands}, or open \`aw\` to complete setup.`);
|
|
1636
1887
|
}
|