@lesliechan721/aw 0.1.0-beta.54 → 0.1.0-beta.55
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/scripts/lib/plugin-version-check.mjs +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +208 -31
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/bundle-plugins.js +8 -3
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/src/adapters/helpers.d.ts +7 -0
- package/dist/src/adapters/helpers.js.map +1 -1
- package/dist/src/commands/aw-capabilities.d.ts +1 -1
- package/dist/src/commands/aw-capabilities.js +2 -0
- package/dist/src/commands/aw-capabilities.js.map +1 -1
- package/dist/src/commands/managed-commands.d.ts +26 -0
- package/dist/src/commands/managed-commands.js +277 -0
- package/dist/src/commands/managed-commands.js.map +1 -0
- package/dist/src/commands/operation-plan.d.ts +30 -1
- package/dist/src/commands/operation-plan.js.map +1 -1
- package/dist/src/commands/operation-planner.d.ts +1 -0
- package/dist/src/commands/operation-planner.js +1 -0
- package/dist/src/commands/operation-planner.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.js +29 -1
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +2 -1
- package/dist/src/commands/rebuild-command.js +66 -26
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +13 -1
- package/dist/src/commands/rebuild-integration.js +516 -61
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.d.ts +3 -1
- package/dist/src/commands/rebuild-operations.js +9 -5
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/generators/local-plugin.js +16 -0
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/generators/permissions.d.ts +5 -2
- package/dist/src/generators/permissions.js +28 -15
- package/dist/src/generators/permissions.js.map +1 -1
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/command-receipt.d.ts +3 -1
- package/dist/src/output/command-receipt.js +30 -9
- package/dist/src/output/command-receipt.js.map +1 -1
- package/dist/src/output/rebuild-progress.js +14 -0
- package/dist/src/output/rebuild-progress.js.map +1 -1
- package/dist/src/portable/materializer.js +3 -0
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/review/skill-materialization.d.ts +14 -1
- package/dist/src/review/skill-materialization.js +138 -0
- package/dist/src/review/skill-materialization.js.map +1 -1
- package/dist/src/tui/console-app-v4.js +19 -7
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.js +23 -9
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +5 -1
- package/dist/src/tui/controller.js +24 -3
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/diagnostic-projection.js +34 -6
- package/dist/src/tui/diagnostic-projection.js.map +1 -1
- package/dist/src/tui/operation-review-planner.js +102 -16
- package/dist/src/tui/operation-review-planner.js.map +1 -1
- package/dist/src/types.d.ts +22 -2
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/artifact-plan.d.ts +4 -3
- package/dist/src/utils/artifact-plan.js +50 -7
- package/dist/src/utils/artifact-plan.js.map +1 -1
- package/dist/src/utils/artifact-renderer.d.ts +7 -3
- package/dist/src/utils/artifact-renderer.js +19 -6
- package/dist/src/utils/artifact-renderer.js.map +1 -1
- package/dist/src/utils/artifact-request.d.ts +16 -5
- package/dist/src/utils/artifact-request.js +27 -15
- package/dist/src/utils/artifact-request.js.map +1 -1
- package/dist/src/utils/artifact-sources.d.ts +4 -0
- package/dist/src/utils/artifact-sources.js +17 -0
- package/dist/src/utils/artifact-sources.js.map +1 -1
- package/dist/src/utils/bundle-layout.js +7 -0
- package/dist/src/utils/bundle-layout.js.map +1 -1
- package/dist/src/utils/claude-skills-root.d.ts +8 -0
- package/dist/src/utils/claude-skills-root.js +76 -0
- package/dist/src/utils/claude-skills-root.js.map +1 -0
- package/dist/src/utils/codex-skills-root.d.ts +4 -0
- package/dist/src/utils/codex-skills-root.js +25 -0
- package/dist/src/utils/codex-skills-root.js.map +1 -0
- package/dist/src/utils/dynamic-skill-tree.d.ts +1 -0
- package/dist/src/utils/dynamic-skill-tree.js +25 -6
- package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
- package/dist/src/utils/local-marketplace.d.ts +9 -0
- package/dist/src/utils/local-marketplace.js +170 -90
- package/dist/src/utils/local-marketplace.js.map +1 -1
- package/dist/src/utils/managed-command-closure.d.ts +3 -0
- package/dist/src/utils/managed-command-closure.js +35 -0
- package/dist/src/utils/managed-command-closure.js.map +1 -0
- package/dist/src/utils/managed-command-evidence.d.ts +7 -0
- package/dist/src/utils/managed-command-evidence.js +86 -0
- package/dist/src/utils/managed-command-evidence.js.map +1 -0
- package/dist/src/utils/managed-command-materialization.d.ts +106 -0
- package/dist/src/utils/managed-command-materialization.js +307 -0
- package/dist/src/utils/managed-command-materialization.js.map +1 -0
- package/dist/src/utils/managed-command-runtime.d.ts +32 -0
- package/dist/src/utils/managed-command-runtime.js +110 -0
- package/dist/src/utils/managed-command-runtime.js.map +1 -0
- package/dist/src/utils/managed-command-store.d.ts +120 -0
- package/dist/src/utils/managed-command-store.js +563 -0
- package/dist/src/utils/managed-command-store.js.map +1 -0
- package/dist/src/utils/ownership.d.ts +2 -0
- package/dist/src/utils/plugin-config-impact.d.ts +8 -1
- package/dist/src/utils/plugin-config-impact.js +101 -26
- package/dist/src/utils/plugin-config-impact.js.map +1 -1
- package/dist/src/utils/plugin-config-write.js +142 -60
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/rendered-contract.js +18 -1
- package/dist/src/utils/rendered-contract.js.map +1 -1
- package/package.json +3 -3
|
@@ -10,7 +10,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
10
10
|
import { compareStrictSemVer, parseStrictSemVer } from './semver.mjs';
|
|
11
11
|
import { assertAuthoringPluginPathFence, resolveAuthoringPluginRoot, } from './plugin-root.mjs';
|
|
12
12
|
const execFileAsync = promisify(execFile);
|
|
13
|
-
const EXPECTED_MANIFEST_CONTRACT_VERSION =
|
|
13
|
+
const EXPECTED_MANIFEST_CONTRACT_VERSION = 17;
|
|
14
14
|
const PLUGIN_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
15
15
|
const GIT_OBJECT_ID_PATTERN = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u;
|
|
16
16
|
const MAX_GIT_BLOB_BYTES = 50 * 1024 * 1024;
|
|
@@ -6,7 +6,7 @@ import { createRequire } from 'node:module';
|
|
|
6
6
|
import * as os from 'node:os';
|
|
7
7
|
import * as path from 'node:path';
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
9
|
-
import { AW_RUNTIME_CONFIG_READER_PATH, createRuntimeConfigSnapshot, getPluginAuthoringAcceptedValues as getCorePluginAuthoringAcceptedValues, getSkillFrontmatterCapabilityRegistry, normalizePluginConfigDefinition, } from '@lesliechan721/aw-plugin-core/manifest';
|
|
9
|
+
import { AW_RUNTIME_CONFIG_READER_PATH, createRuntimeConfigSnapshot, getPluginAuthoringAcceptedValues as getCorePluginAuthoringAcceptedValues, getSkillFrontmatterCapabilityRegistry, getManagedCommandArtifactTargets, normalizePluginConfigDefinition, parseManagedCommandPlaceholders, replaceManagedCommandPlaceholders, validateCommandEntryFiles, } from '@lesliechan721/aw-plugin-core/manifest';
|
|
10
10
|
import { checkPluginVersions } from './lib/plugin-version-check.mjs';
|
|
11
11
|
import { scanJavaScriptImportSpecifiers } from './lib/javascript-import-scanner.mjs';
|
|
12
12
|
import { assertAuthoringPluginPathFence, assertCanonicalAuthoringPluginRoot, } from './lib/plugin-root.mjs';
|
|
@@ -18,7 +18,7 @@ const CLI_PACKAGE_ROOT = path.basename(authoringRuntimeRoot) === 'dist'
|
|
|
18
18
|
: authoringRuntimeRoot;
|
|
19
19
|
const errors = [];
|
|
20
20
|
const warnings = [];
|
|
21
|
-
const SOURCE_PLUGIN_MANIFEST_CONTRACT_VERSION =
|
|
21
|
+
const SOURCE_PLUGIN_MANIFEST_CONTRACT_VERSION = 17;
|
|
22
22
|
let capabilityDiagnostic = null;
|
|
23
23
|
const MAX_SKILL_NAME_LEN = 64;
|
|
24
24
|
const MAX_SKILL_DESCRIPTION_LEN = 1024;
|
|
@@ -315,18 +315,25 @@ async function tryLoadCliManifestTools() {
|
|
|
315
315
|
const manifestModulePath = path.join(CLI_PACKAGE_ROOT, 'dist', 'src', 'utils', 'manifest.js');
|
|
316
316
|
const runtimeProjectionModulePath = path.join(CLI_PACKAGE_ROOT, 'dist', 'src', 'utils', 'catalog-runtime-projection.js');
|
|
317
317
|
const capabilityModulePath = path.join(CLI_PACKAGE_ROOT, 'dist', 'src', 'commands', 'aw-capabilities.js');
|
|
318
|
+
const artifactPlanPath = path.join(CLI_PACKAGE_ROOT, 'dist', 'src', 'utils', 'artifact-plan.js');
|
|
319
|
+
const artifactRequestPath = path.join(CLI_PACKAGE_ROOT, 'dist', 'src', 'utils', 'artifact-request.js');
|
|
320
|
+
const commandMaterializationPath = path.join(CLI_PACKAGE_ROOT, 'dist', 'src', 'utils', 'managed-command-materialization.js');
|
|
318
321
|
if (!fs.existsSync(manifestModulePath)
|
|
319
322
|
|| !fs.existsSync(runtimeProjectionModulePath)
|
|
320
323
|
|| !fs.existsSync(capabilityModulePath))
|
|
321
324
|
return null;
|
|
322
325
|
try {
|
|
323
|
-
const [manifestModule, runtimeProjectionModule, capabilityModule] = await Promise.all([
|
|
326
|
+
const [manifestModule, runtimeProjectionModule, capabilityModule, artifactPlanModule, artifactRequestModule, commandModule] = await Promise.all([
|
|
324
327
|
import(pathToFileURL(manifestModulePath).href),
|
|
325
328
|
import(pathToFileURL(runtimeProjectionModulePath).href),
|
|
326
329
|
import(pathToFileURL(capabilityModulePath).href),
|
|
330
|
+
import(pathToFileURL(artifactPlanPath).href),
|
|
331
|
+
import(pathToFileURL(artifactRequestPath).href),
|
|
332
|
+
import(pathToFileURL(commandMaterializationPath).href),
|
|
327
333
|
]);
|
|
328
334
|
if (manifestModule.SOURCE_PLUGIN_MANIFEST_CONTRACT_VERSION
|
|
329
|
-
!== SOURCE_PLUGIN_MANIFEST_CONTRACT_VERSION
|
|
335
|
+
!== SOURCE_PLUGIN_MANIFEST_CONTRACT_VERSION
|
|
336
|
+
|| typeof artifactRequestModule.requiresNonSensitiveArtifactInput !== 'function') {
|
|
330
337
|
return null;
|
|
331
338
|
}
|
|
332
339
|
return {
|
|
@@ -337,6 +344,11 @@ async function tryLoadCliManifestTools() {
|
|
|
337
344
|
resolvePluginRequirements: manifestModule.resolvePluginRequirements ?? null,
|
|
338
345
|
implementedCapabilities: capabilityModule.IMPLEMENTED_AW_CAPABILITIES ?? null,
|
|
339
346
|
createRuntimeResolver: runtimeProjectionModule.createCatalogRuntimeImportResolver ?? null,
|
|
347
|
+
validateArtifactPlan: artifactPlanModule.validateArtifactPlan,
|
|
348
|
+
requiresNonSensitiveArtifactInput: artifactRequestModule.requiresNonSensitiveArtifactInput,
|
|
349
|
+
prepareManagedCommandPackageFiles: commandModule.prepareManagedCommandPackageFiles,
|
|
350
|
+
managedCommandProducerIdentity: commandModule.managedCommandProducerIdentity,
|
|
351
|
+
createManagedCommandReferenceResolver: commandModule.createManagedCommandReferenceResolver,
|
|
340
352
|
};
|
|
341
353
|
}
|
|
342
354
|
catch {
|
|
@@ -505,6 +517,7 @@ function validateManifestLightweight(manifest) {
|
|
|
505
517
|
'scripts',
|
|
506
518
|
'config',
|
|
507
519
|
'artifacts',
|
|
520
|
+
'managedCommands',
|
|
508
521
|
]);
|
|
509
522
|
if (manifest.dependencies !== undefined) {
|
|
510
523
|
if (!Array.isArray(manifest.dependencies)) {
|
|
@@ -2366,7 +2379,25 @@ function validateRenderedSkillTree(options) {
|
|
|
2366
2379
|
}
|
|
2367
2380
|
for (const [relativePath, content] of files) {
|
|
2368
2381
|
const text = content.toString('utf8');
|
|
2369
|
-
|
|
2382
|
+
let remaining = text;
|
|
2383
|
+
if (relativePath.endsWith('.md')) {
|
|
2384
|
+
try {
|
|
2385
|
+
const placeholders = parseManagedCommandPlaceholders(text);
|
|
2386
|
+
if (placeholders.length > 0 && !(manifest.requires?.aw?.capabilities ?? []).includes('aw.managed-commands.v1')) {
|
|
2387
|
+
error(`${fieldName} managed command references require aw.managed-commands.v1`);
|
|
2388
|
+
}
|
|
2389
|
+
if (declaration.target === 'agent-skills.skill' && placeholders.length > 0) {
|
|
2390
|
+
error(`${fieldName} managedCommandPortableUnsupported: Portable Skills cannot contain managed command references`);
|
|
2391
|
+
}
|
|
2392
|
+
else if (options.managedTrees) {
|
|
2393
|
+
remaining = replaceManagedCommandPlaceholders(text, () => `cmdp_${'0'.repeat(64)}`);
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
catch (cause) {
|
|
2397
|
+
error(`${fieldName} ${cause.message}`);
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
if (/\{\{[^{}]+\}\}/u.test(remaining)) {
|
|
2370
2401
|
error(`${fieldName} final file tree contains an unresolved template in "${relativePath}"`);
|
|
2371
2402
|
}
|
|
2372
2403
|
}
|
|
@@ -2385,6 +2416,7 @@ function validateRenderedSkillTree(options) {
|
|
|
2385
2416
|
if (declaration.target === 'codex.skill' && files.has('agents/openai.yaml')) {
|
|
2386
2417
|
validateOpenAiYaml(path.join(materializedRoot, 'agents', 'openai.yaml'), declaration.skillKey, true, manifest, materializedRoot, skillValidationTools);
|
|
2387
2418
|
}
|
|
2419
|
+
options.managedTrees?.push({ declaration, files, scope: options.managedScope });
|
|
2388
2420
|
}
|
|
2389
2421
|
function validateStaticPortableFinalTrees(pluginDir, manifest, runtimeImports, skillValidationTools) {
|
|
2390
2422
|
const portableRoot = manifest.distributions?.agentSkills?.skills;
|
|
@@ -2444,6 +2476,12 @@ function validateRenderedArtifactPlan(plan, declarations, scopeLabel, options) {
|
|
|
2444
2476
|
const entry = expectRecord(artifact, fieldName);
|
|
2445
2477
|
if (!entry)
|
|
2446
2478
|
return;
|
|
2479
|
+
if (entry.target === 'aw.command-set' || entry.target === 'aw.command-package') {
|
|
2480
|
+
const declaration = byKey.get(`${entry.id}:${entry.target}`);
|
|
2481
|
+
if (declaration)
|
|
2482
|
+
returned.add(`${entry.id}:${entry.target}`);
|
|
2483
|
+
return; // Shared ArtifactPlan validation owns command response fields.
|
|
2484
|
+
}
|
|
2447
2485
|
validateAllowedKeys(entry, fieldName, [
|
|
2448
2486
|
'id',
|
|
2449
2487
|
'platform',
|
|
@@ -2550,6 +2588,8 @@ function validateRenderedArtifactPlan(plan, declarations, scopeLabel, options) {
|
|
|
2550
2588
|
runtimeImports: options.runtimeImports,
|
|
2551
2589
|
materializedRoot: path.join(options.tempRoot, `${declaration.platform ?? declaration.distribution}-${scopeLabel.split('/')[1]}-${index}`),
|
|
2552
2590
|
skillValidationTools: options.skillValidationTools,
|
|
2591
|
+
managedTrees: options.managedTrees,
|
|
2592
|
+
managedScope: scopeLabel.split('/')[1],
|
|
2553
2593
|
});
|
|
2554
2594
|
}
|
|
2555
2595
|
}
|
|
@@ -2564,7 +2604,7 @@ function validateRenderedArtifactPlan(plan, declarations, scopeLabel, options) {
|
|
|
2564
2604
|
}
|
|
2565
2605
|
}
|
|
2566
2606
|
}
|
|
2567
|
-
function resolveArtifactRendererFixtureRequests(declarations, manifest) {
|
|
2607
|
+
function resolveArtifactRendererFixtureRequests(declarations, manifest, requiresNonSensitiveArtifactInput) {
|
|
2568
2608
|
const awOwned = new Map();
|
|
2569
2609
|
const codexNative = new Map();
|
|
2570
2610
|
for (const declaration of declarations) {
|
|
@@ -2581,7 +2621,9 @@ function resolveArtifactRendererFixtureRequests(declarations, manifest) {
|
|
|
2581
2621
|
codexNative.set(scope, request);
|
|
2582
2622
|
continue;
|
|
2583
2623
|
}
|
|
2584
|
-
const surface = declaration.
|
|
2624
|
+
const surface = declaration.surface?.kind === 'aw'
|
|
2625
|
+
? declaration.surface.name
|
|
2626
|
+
: declaration.platform ?? declaration.distribution;
|
|
2585
2627
|
if (!surface)
|
|
2586
2628
|
continue;
|
|
2587
2629
|
for (const scope of declaration.scopes) {
|
|
@@ -2598,37 +2640,33 @@ function resolveArtifactRendererFixtureRequests(declarations, manifest) {
|
|
|
2598
2640
|
}
|
|
2599
2641
|
}
|
|
2600
2642
|
const partitionedAwOwned = [...awOwned.values()].flatMap((request) => {
|
|
2601
|
-
const
|
|
2602
|
-
|
|
2603
|
-
|| declaration.target === 'agent-skills.skill');
|
|
2604
|
-
const hasSensitiveNonSkill = request.declarations.some((declaration) => declaration.target !== 'codex.skill'
|
|
2605
|
-
&& declaration.target !== 'claude.skill'
|
|
2606
|
-
&& declaration.target !== 'agent-skills.skill'
|
|
2643
|
+
const hasNonSensitiveTarget = request.declarations.some(requiresNonSensitiveArtifactInput);
|
|
2644
|
+
const hasSensitiveOtherTarget = request.declarations.some((declaration) => !requiresNonSensitiveArtifactInput(declaration)
|
|
2607
2645
|
&& declaration.refreshKeys.some((key) => configFieldContainsSensitiveValue(manifest.config?.fields?.[key])));
|
|
2608
|
-
if (!
|
|
2646
|
+
if (!hasNonSensitiveTarget || !hasSensitiveOtherTarget)
|
|
2609
2647
|
return [request];
|
|
2610
|
-
const
|
|
2611
|
-
|
|
2612
|
-
|| declaration.target === 'agent-skills.skill');
|
|
2613
|
-
const nonSkillDeclarations = request.declarations.filter((declaration) => !skillDeclarations.includes(declaration));
|
|
2648
|
+
const nonSensitiveDeclarations = request.declarations.filter(requiresNonSensitiveArtifactInput);
|
|
2649
|
+
const otherDeclarations = request.declarations.filter((declaration) => !requiresNonSensitiveArtifactInput(declaration));
|
|
2614
2650
|
return [
|
|
2615
|
-
{ ...request, declarations:
|
|
2616
|
-
{ ...request, declarations:
|
|
2651
|
+
{ ...request, declarations: nonSensitiveDeclarations },
|
|
2652
|
+
{ ...request, declarations: otherDeclarations },
|
|
2617
2653
|
];
|
|
2618
2654
|
});
|
|
2619
2655
|
return [...partitionedAwOwned, ...codexNative.values()];
|
|
2620
2656
|
}
|
|
2621
|
-
function runArtifactRendererFixture(pluginDir, manifest, renderEntry, declarations, resolvedRuntimeImports, skillValidationTools) {
|
|
2657
|
+
async function runArtifactRendererFixture(pluginDir, manifest, renderEntry, declarations, resolvedRuntimeImports, skillValidationTools, managedContext, requiresNonSensitiveArtifactInput) {
|
|
2622
2658
|
if (!renderEntry || declarations.length === 0)
|
|
2623
|
-
return;
|
|
2624
|
-
const requests = resolveArtifactRendererFixtureRequests(declarations, manifest);
|
|
2659
|
+
return [];
|
|
2660
|
+
const requests = resolveArtifactRendererFixtureRequests(declarations, manifest, requiresNonSensitiveArtifactInput);
|
|
2625
2661
|
const values = defaultConfigValues(manifest);
|
|
2626
2662
|
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'aw-artifact-render-'));
|
|
2663
|
+
const returnedArtifacts = [];
|
|
2627
2664
|
try {
|
|
2628
2665
|
for (const [requestIndex, request] of requests.entries()) {
|
|
2629
2666
|
const { kind, surface, scope, configScope, declarations: scopedDeclarations, } = request;
|
|
2630
2667
|
const distribution = surface === 'agent-skills' ? surface : undefined;
|
|
2631
|
-
const
|
|
2668
|
+
const awSurface = surface === 'managed-commands';
|
|
2669
|
+
const platform = distribution || awSurface ? undefined : surface;
|
|
2632
2670
|
const event = distribution ? 'materialize' : 'install';
|
|
2633
2671
|
const requestRoot = path.join(tempRoot, `${requestIndex}-${kind}-${surface}-${scope}`);
|
|
2634
2672
|
const rendererAwHome = path.join(requestRoot, 'aw-home');
|
|
@@ -2636,7 +2674,7 @@ function runArtifactRendererFixture(pluginDir, manifest, renderEntry, declaratio
|
|
|
2636
2674
|
const rendererClaudeHome = path.join(requestRoot, 'claude-home');
|
|
2637
2675
|
fs.mkdirSync(requestRoot, { recursive: true });
|
|
2638
2676
|
const contextPath = path.join(requestRoot, 'context.json');
|
|
2639
|
-
const runtimeImports = scopedDeclarations.flatMap((target) => target.runtimeImports.map((runtimeImport, importIndex) => {
|
|
2677
|
+
const runtimeImports = scopedDeclarations.flatMap((target) => (target.runtimeImports ?? []).map((runtimeImport, importIndex) => {
|
|
2640
2678
|
const resolved = resolvedRuntimeImports?.artifactImports.get(authorRuntimeImportKey(target.id, importIndex));
|
|
2641
2679
|
if (!resolved)
|
|
2642
2680
|
return null;
|
|
@@ -2684,7 +2722,7 @@ function runArtifactRendererFixture(pluginDir, manifest, renderEntry, declaratio
|
|
|
2684
2722
|
}
|
|
2685
2723
|
fs.writeFileSync(contextPath, JSON.stringify({
|
|
2686
2724
|
event,
|
|
2687
|
-
surface: distribution
|
|
2725
|
+
surface: awSurface ? { kind: 'aw', name: 'managed-commands' } : distribution
|
|
2688
2726
|
? { kind: 'distribution', name: distribution }
|
|
2689
2727
|
: { kind: 'platform', name: platform },
|
|
2690
2728
|
...(platform ? { platform } : {}),
|
|
@@ -2713,6 +2751,9 @@ function runArtifactRendererFixture(pluginDir, manifest, renderEntry, declaratio
|
|
|
2713
2751
|
target: target.target,
|
|
2714
2752
|
sourceDirs: target.sourceDirs.map((sourceDir) => path.join(pluginDir, normalizeRelativePath(sourceDir))),
|
|
2715
2753
|
})),
|
|
2754
|
+
commandSources: (managedContext?.manifest.managedCommands?.packages ?? [])
|
|
2755
|
+
.filter((entry) => scopedDeclarations.some((target) => target.packageKey === entry.key))
|
|
2756
|
+
.map((entry) => ({ packageKey: entry.key, sourceDir: path.join(pluginDir, normalizeRelativePath(entry.sourceDir)) })),
|
|
2716
2757
|
runtimeImports,
|
|
2717
2758
|
paths: {
|
|
2718
2759
|
awHome: rendererAwHome,
|
|
@@ -2747,6 +2788,7 @@ function runArtifactRendererFixture(pluginDir, manifest, renderEntry, declaratio
|
|
|
2747
2788
|
AW_PLUGIN_EVENT: event,
|
|
2748
2789
|
...(platform ? { AW_PLUGIN_PLATFORM: platform } : {}),
|
|
2749
2790
|
...(distribution ? { AW_PLUGIN_DISTRIBUTION: distribution } : {}),
|
|
2791
|
+
...(awSurface ? { AW_PLUGIN_SURFACE: 'managed-commands' } : {}),
|
|
2750
2792
|
AW_PLUGIN_SCOPE: scope,
|
|
2751
2793
|
};
|
|
2752
2794
|
if (process.platform === 'win32') {
|
|
@@ -2793,24 +2835,153 @@ function runArtifactRendererFixture(pluginDir, manifest, renderEntry, declaratio
|
|
|
2793
2835
|
runtimeImports: resolvedRuntimeImports,
|
|
2794
2836
|
tempRoot,
|
|
2795
2837
|
skillValidationTools,
|
|
2838
|
+
managedTrees: managedContext?.trees,
|
|
2796
2839
|
});
|
|
2840
|
+
if (managedContext) {
|
|
2841
|
+
try {
|
|
2842
|
+
const validated = managedContext.tools.validateArtifactPlan({
|
|
2843
|
+
manifest: managedContext.manifest,
|
|
2844
|
+
plan,
|
|
2845
|
+
platform: surface,
|
|
2846
|
+
scope,
|
|
2847
|
+
requestedArtifactIds: scopedDeclarations.map((target) => target.id),
|
|
2848
|
+
renderConfig: { values: scopedValues, sources: Object.fromEntries(Object.keys(scopedValues).map((key) => [key, 'default'])), issues: [] },
|
|
2849
|
+
});
|
|
2850
|
+
returnedArtifacts.push(...validated.artifacts.map((artifact) => ({ artifact, scope, surface })));
|
|
2851
|
+
}
|
|
2852
|
+
catch (cause) {
|
|
2853
|
+
error(`${fieldName}: ${cause.message}`);
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2797
2856
|
}
|
|
2798
2857
|
}
|
|
2799
2858
|
finally {
|
|
2800
2859
|
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
2801
2860
|
}
|
|
2861
|
+
return returnedArtifacts;
|
|
2802
2862
|
}
|
|
2803
|
-
function validateDynamicArtifactsLightweight(pluginDir, manifest, renderEntry, runtimeImports, skillValidationTools) {
|
|
2863
|
+
async function validateDynamicArtifactsLightweight(pluginDir, manifest, renderEntry, runtimeImports, skillValidationTools, managedContext, requiresNonSensitiveArtifactInput) {
|
|
2804
2864
|
const declarations = validateArtifactsConfigLightweight(pluginDir, manifest);
|
|
2865
|
+
if (managedContext)
|
|
2866
|
+
declarations.push(...getManagedCommandArtifactTargets(managedContext.manifest));
|
|
2805
2867
|
const hasTargets = declarations.length > 0;
|
|
2806
2868
|
const hasRenderer = Boolean(manifest.scripts?.artifacts?.render);
|
|
2807
2869
|
if (hasTargets && !hasRenderer) {
|
|
2808
2870
|
error('artifacts.targets requires scripts.artifacts.render');
|
|
2809
2871
|
}
|
|
2810
2872
|
if (hasRenderer && !hasTargets) {
|
|
2811
|
-
error('scripts.artifacts.render requires artifacts.targets');
|
|
2873
|
+
error('scripts.artifacts.render requires artifacts.targets or dynamic managedCommands targets');
|
|
2874
|
+
}
|
|
2875
|
+
return runArtifactRendererFixture(pluginDir, manifest, renderEntry, declarations, runtimeImports, skillValidationTools, managedContext, requiresNonSensitiveArtifactInput);
|
|
2876
|
+
}
|
|
2877
|
+
async function validateAuthorManagedCommands(pluginDir, manifest, rendered, context) {
|
|
2878
|
+
const { tools, trees } = context;
|
|
2879
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'aw-author-commands-'));
|
|
2880
|
+
const env = { AW_HOME: path.join(tempRoot, 'aw-home'), AW_CODEX_HOME: path.join(tempRoot, 'codex-home'), AW_CLAUDE_HOME: path.join(tempRoot, 'claude-home') };
|
|
2881
|
+
const plugin = { manifest, rootDir: pluginDir, sourceId: 'authoring', sourceIdentity: `sha256:${'0'.repeat(64)}` };
|
|
2882
|
+
const candidates = [];
|
|
2883
|
+
const cleanups = [];
|
|
2884
|
+
try {
|
|
2885
|
+
const root = manifest.skills && path.join(pluginDir, normalizeRelativePath(manifest.skills));
|
|
2886
|
+
if (root && fs.existsSync(root)) {
|
|
2887
|
+
for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
|
|
2888
|
+
if (!entry.isDirectory())
|
|
2889
|
+
continue;
|
|
2890
|
+
for (const platform of targetedPlatforms(manifest)) {
|
|
2891
|
+
if ((manifest.artifacts?.targets ?? []).some((target) => target.platform === platform && target.kind === 'skill' && target.skillKey === entry.name))
|
|
2892
|
+
continue;
|
|
2893
|
+
const files = new Map();
|
|
2894
|
+
collectArtifactSourceFiles(path.join(root, entry.name), `static Skill ${entry.name}`, files);
|
|
2895
|
+
for (const [relative, bytes] of files) {
|
|
2896
|
+
if (isTemplateTextFile(relative))
|
|
2897
|
+
files.set(relative, Buffer.from(renderTemplateForPlatform(manifest, `${normalizeRelativePath(manifest.skills)}/${entry.name}/${relative}`, bytes.toString('utf8'), platform)));
|
|
2898
|
+
}
|
|
2899
|
+
const producer = await tools.managedCommandProducerIdentity({
|
|
2900
|
+
plugin,
|
|
2901
|
+
producer: { kind: 'static-skill', platform, skillKey: entry.name },
|
|
2902
|
+
scope: 'user',
|
|
2903
|
+
cwd: pluginDir,
|
|
2904
|
+
});
|
|
2905
|
+
trees.push({ declaration: { target: `${platform}.skill`, platform, skillKey: entry.name, staticSkill: true }, files, scope: producer.scope });
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
const setOutputs = (set, platform, scope) => {
|
|
2910
|
+
if (set.mode === 'static')
|
|
2911
|
+
return { set: set.set, state: 'present', entries: set.entries };
|
|
2912
|
+
const output = rendered.find((entry) => entry.artifact.id === `command-set.${set.set}` && entry.scope === scope && entry.surface === platform)?.artifact;
|
|
2913
|
+
if (!output)
|
|
2914
|
+
throw new Error(`commandReferenceInvalid: dynamic command set ${set.set} was not returned`);
|
|
2915
|
+
return { set: set.set, state: output.state, entries: output.entries };
|
|
2916
|
+
};
|
|
2917
|
+
for (const commandPackage of manifest.managedCommands?.packages ?? []) {
|
|
2918
|
+
const sets = (manifest.managedCommands?.sets ?? [])
|
|
2919
|
+
.filter((set) => set.producer.kind === 'package' && set.producer.packageKey === commandPackage.key)
|
|
2920
|
+
.map((set) => setOutputs(set, 'managed-commands', commandPackage.scope));
|
|
2921
|
+
const files = rendered.find((entry) => entry.artifact.id === `command-package.${commandPackage.key}`)?.artifact.files ?? {};
|
|
2922
|
+
const prepared = await tools.prepareManagedCommandPackageFiles({ sourceRoot: path.join(pluginDir, normalizeRelativePath(commandPackage.sourceDir)), files, entries: sets.flatMap((set) => set.entries) });
|
|
2923
|
+
cleanups.push(prepared.cleanup);
|
|
2924
|
+
candidates.push({ producer: await tools.managedCommandProducerIdentity({ plugin, producer: { kind: 'package', packageKey: commandPackage.key }, scope: commandPackage.scope, cwd: pluginDir }), sets });
|
|
2925
|
+
}
|
|
2926
|
+
for (const [index, tree] of trees.entries()) {
|
|
2927
|
+
const { declaration } = tree;
|
|
2928
|
+
const scope = declaration.delivery?.mode === 'codex-native' ? 'user' : tree.scope;
|
|
2929
|
+
if (!declaration.platform)
|
|
2930
|
+
continue;
|
|
2931
|
+
const producer = declaration.staticSkill
|
|
2932
|
+
? { kind: 'static-skill', platform: declaration.platform, skillKey: declaration.skillKey }
|
|
2933
|
+
: { kind: 'artifact', artifactId: declaration.id };
|
|
2934
|
+
const sets = (manifest.managedCommands?.sets ?? []).filter((set) => JSON.stringify(set.producer) === JSON.stringify(producer))
|
|
2935
|
+
.map((set) => setOutputs(set, declaration.platform, scope));
|
|
2936
|
+
const resourceRoot = path.join(tempRoot, `skill-${index}`);
|
|
2937
|
+
for (const [relative, bytes] of tree.files) {
|
|
2938
|
+
const target = path.join(resourceRoot, ...relative.split('/'));
|
|
2939
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
2940
|
+
fs.writeFileSync(target, bytes);
|
|
2941
|
+
}
|
|
2942
|
+
await validateCommandEntryFiles(resourceRoot, sets.flatMap((set) => set.entries));
|
|
2943
|
+
candidates.push({ producer: await tools.managedCommandProducerIdentity({ plugin, producer, scope, cwd: pluginDir }), sets });
|
|
2944
|
+
}
|
|
2945
|
+
for (const tree of trees) {
|
|
2946
|
+
if (!tree.declaration.platform)
|
|
2947
|
+
continue;
|
|
2948
|
+
const scope = tree.declaration.delivery?.mode === 'codex-native' ? 'user' : tree.scope;
|
|
2949
|
+
const resolve = await tools.createManagedCommandReferenceResolver({ plugin, platform: tree.declaration.platform, scope, cwd: pluginDir, env, candidates });
|
|
2950
|
+
for (const [relative, bytes] of tree.files) {
|
|
2951
|
+
if (!relative.endsWith('.md'))
|
|
2952
|
+
continue;
|
|
2953
|
+
const text = bytes.toString('utf8');
|
|
2954
|
+
if (parseManagedCommandPlaceholders(text).length > 0 && !(manifest.requires?.aw?.capabilities ?? []).includes('aw.managed-commands.v1'))
|
|
2955
|
+
throw new Error('managed command references require aw.managed-commands.v1');
|
|
2956
|
+
replaceManagedCommandPlaceholders(text, resolve);
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
for (const permission of manifest.extensions?.permissions ?? []) {
|
|
2960
|
+
for (const platform of targetedPlatforms(manifest)) {
|
|
2961
|
+
for (const scope of platform === 'codex' ? ['user'] : ['user', 'project']) {
|
|
2962
|
+
const resolve = await tools.createManagedCommandReferenceResolver({ plugin, platform, scope, cwd: pluginDir, env, candidates });
|
|
2963
|
+
const override = permission.agentOverrides?.[platform];
|
|
2964
|
+
if (override === null)
|
|
2965
|
+
continue;
|
|
2966
|
+
for (const decision of ['allow', 'ask', 'deny'])
|
|
2967
|
+
for (const rule of override?.[decision] ?? permission[decision] ?? [])
|
|
2968
|
+
if (typeof rule !== 'string')
|
|
2969
|
+
resolve(rule.command);
|
|
2970
|
+
if (platform === 'claude')
|
|
2971
|
+
for (const rule of override?.sandbox?.excludedCommands ?? [])
|
|
2972
|
+
resolve(rule.command);
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2977
|
+
catch (cause) {
|
|
2978
|
+
error(`managed command authoring candidate: ${cause.message}`);
|
|
2979
|
+
}
|
|
2980
|
+
finally {
|
|
2981
|
+
for (const cleanup of cleanups)
|
|
2982
|
+
await cleanup();
|
|
2983
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
2812
2984
|
}
|
|
2813
|
-
runArtifactRendererFixture(pluginDir, manifest, renderEntry, declarations, runtimeImports, skillValidationTools);
|
|
2814
2985
|
}
|
|
2815
2986
|
function validateScriptsLightweight(pluginDir, manifest) {
|
|
2816
2987
|
validateConfigSchemaLightweight(manifest.config);
|
|
@@ -3404,8 +3575,9 @@ async function validatePluginDir(pluginDir, options) {
|
|
|
3404
3575
|
}
|
|
3405
3576
|
}
|
|
3406
3577
|
const skillValidationTools = await tryLoadCliSkillValidationTools();
|
|
3578
|
+
let normalizedManifest;
|
|
3407
3579
|
try {
|
|
3408
|
-
|
|
3580
|
+
normalizedManifest = await cliManifestTools.validateSourcePluginManifest(pluginDir, manifest);
|
|
3409
3581
|
// Renderer fixtures consume the same compiled config as installed runtime consumers.
|
|
3410
3582
|
if (normalizedManifest.config)
|
|
3411
3583
|
manifest.config = normalizedManifest.config;
|
|
@@ -3448,7 +3620,12 @@ async function validatePluginDir(pluginDir, options) {
|
|
|
3448
3620
|
cliManifestTools,
|
|
3449
3621
|
});
|
|
3450
3622
|
validateStaticPortableFinalTrees(pluginDir, manifest, runtimeImports, skillValidationTools);
|
|
3451
|
-
|
|
3623
|
+
const managedContext = normalizedManifest
|
|
3624
|
+
? { manifest: normalizedManifest, tools: cliManifestTools, trees: [] }
|
|
3625
|
+
: undefined;
|
|
3626
|
+
const rendered = await validateDynamicArtifactsLightweight(pluginDir, manifest, artifactRenderEntry, runtimeImports, skillValidationTools, managedContext, cliManifestTools.requiresNonSensitiveArtifactInput);
|
|
3627
|
+
if (managedContext)
|
|
3628
|
+
await validateAuthorManagedCommands(pluginDir, normalizedManifest, rendered ?? [], managedContext);
|
|
3452
3629
|
validateMcpContent(pluginDir, manifest);
|
|
3453
3630
|
validateAppsContent(pluginDir, manifest);
|
|
3454
3631
|
warnCodexProjectScopeLimitations(manifest);
|