@aiwg/cli 2026.7.20 → 2026.7.21
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/README.md +4 -4
- package/dist/src/api/index.d.ts +1 -0
- package/dist/src/api/index.js +1 -0
- package/dist/src/artifacts/browser-export.js +7 -0
- package/dist/src/artifacts/citation-parser.js +96 -35
- package/dist/src/artifacts/index-builder.js +54 -17
- package/dist/src/artifacts/state-transfer.js +27 -0
- package/dist/src/artifacts/stats.js +8 -0
- package/dist/src/cli/cli-extension-loader.js +73 -0
- package/dist/src/cli/handlers/index.js +3 -1
- package/dist/src/cli/handlers/sessions.js +966 -0
- package/dist/src/cli/handlers/skill-lint.js +49 -45
- package/dist/src/cli/handlers/use.js +143 -60
- package/dist/src/cli/handlers/utilities.js +22 -8
- package/dist/src/cli/skill-usage.js +146 -24
- package/dist/src/extensions/commands/definitions.js +29 -0
- package/dist/src/extensions/manifest.js +29 -0
- package/dist/src/sessions/adapters/claude.js +357 -0
- package/dist/src/sessions/adapters/codex.js +521 -0
- package/dist/src/sessions/adapters/copilot.js +226 -0
- package/dist/src/sessions/adapters/cursor.js +372 -0
- package/dist/src/sessions/adapters/factory.js +345 -0
- package/dist/src/sessions/adapters/generic.js +225 -0
- package/dist/src/sessions/adapters/hermes.js +341 -0
- package/dist/src/sessions/adapters/openclaw.js +381 -0
- package/dist/src/sessions/adapters/opencode.js +454 -0
- package/dist/src/sessions/adapters/openhuman.js +315 -0
- package/dist/src/sessions/adapters/warp.js +160 -0
- package/dist/src/sessions/adapters/windsurf.js +212 -0
- package/dist/src/sessions/candidates.js +210 -0
- package/dist/src/sessions/contracts.js +310 -0
- package/dist/src/sessions/discovery.js +51 -0
- package/dist/src/sessions/fixtures.js +12 -0
- package/dist/src/sessions/importer.js +315 -0
- package/dist/src/sessions/index.js +25 -0
- package/dist/src/sessions/knowledge-shard.js +61 -0
- package/dist/src/sessions/optional-backends.js +238 -0
- package/dist/src/sessions/policy.js +192 -0
- package/dist/src/sessions/ports.js +2 -0
- package/dist/src/sessions/promotion.js +367 -0
- package/dist/src/sessions/readers.js +176 -0
- package/dist/src/sessions/repository.js +1551 -0
- package/dist/src/skills/adapters/agent-skills.js +59 -0
- package/dist/src/skills/adapters/local.js +19 -1
- package/dist/src/skills/agent-skills.js +249 -0
- package/dist/src/skills/cli.js +463 -7
- package/dist/src/skills/deployer.js +554 -0
- package/dist/src/skills/doctor.js +105 -0
- package/dist/src/skills/exporter.js +382 -0
- package/dist/src/skills/importer.js +921 -0
- package/dist/src/skills/registry.js +19 -0
- package/dist/src/skills/validator.js +323 -0
- package/package.json +2 -2
package/dist/src/skills/cli.js
CHANGED
|
@@ -11,12 +11,23 @@
|
|
|
11
11
|
* @implements #539
|
|
12
12
|
*/
|
|
13
13
|
import { spawn } from 'child_process';
|
|
14
|
-
import { searchSkills, listSkills, getSkillInfo, installSkill, publishSkill, getAllAdapters, } from './registry.js';
|
|
14
|
+
import { searchSkills, listSkills, getSkillInfo, installSkill, publishSkill, importSkillSource, getAllAdapters, } from './registry.js';
|
|
15
|
+
import { AgentSkillImportError } from './importer.js';
|
|
16
|
+
import { AgentSkillDeploymentError, deployImportedAgentSkill, uninstallImportedAgentSkill, } from './deployer.js';
|
|
17
|
+
import { AgentSkillExportError, exportAgentSkillDirectory, } from './exporter.js';
|
|
18
|
+
import { PROVIDER_IDS } from '../providers/provider-definitions.js';
|
|
15
19
|
import { parseAgentSpawnFlags, buildAgentArgs, getProviderConfig, isSpawnableProvider, } from '../cli/agent-spawn.js';
|
|
16
|
-
const SUPPORTED_TARGETS =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
const SUPPORTED_TARGETS = PROVIDER_IDS;
|
|
21
|
+
export function importedSkillActivationError(details) {
|
|
22
|
+
if (!details.imported
|
|
23
|
+
|| (details.imported.trust.state === 'trusted'
|
|
24
|
+
&& details.imported.trust.activation === 'active')) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return (`Imported skill '${details.name}' is `
|
|
28
|
+
+ `${details.imported.trust.state}/${details.imported.trust.activation}. `
|
|
29
|
+
+ `Explicitly trust and activate digest ${details.imported.digest} before execution.`);
|
|
30
|
+
}
|
|
20
31
|
/**
|
|
21
32
|
* Parse --provider and --target flags from args
|
|
22
33
|
*/
|
|
@@ -131,6 +142,20 @@ async function handleInfo(args) {
|
|
|
131
142
|
console.log('');
|
|
132
143
|
console.log(`Path: ${details.path}`);
|
|
133
144
|
}
|
|
145
|
+
if (details.imported) {
|
|
146
|
+
console.log('');
|
|
147
|
+
console.log(`Digest: ${details.imported.digest}`);
|
|
148
|
+
console.log(`Profile: ${details.imported.validationProfile}`);
|
|
149
|
+
console.log(`Trust: ${details.imported.trust.state}`);
|
|
150
|
+
console.log(`Activation: ${details.imported.trust.activation}`);
|
|
151
|
+
console.log(`Source kind: ${details.imported.source.kind}`);
|
|
152
|
+
console.log(`Locator: ${details.imported.source.locator}`);
|
|
153
|
+
if (details.imported.source.kind === 'git') {
|
|
154
|
+
console.log(`Subpath: ${details.imported.source.subpath}`);
|
|
155
|
+
console.log(`Requested: ${details.imported.source.requestedRevision}`);
|
|
156
|
+
console.log(`Resolved: ${details.imported.source.resolvedRevision}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
134
159
|
console.log('');
|
|
135
160
|
}
|
|
136
161
|
/**
|
|
@@ -200,6 +225,416 @@ async function handleInstall(args) {
|
|
|
200
225
|
process.exit(1);
|
|
201
226
|
}
|
|
202
227
|
}
|
|
228
|
+
function parseImportArgs(args) {
|
|
229
|
+
let gitUrl;
|
|
230
|
+
let revision;
|
|
231
|
+
let subpath;
|
|
232
|
+
let profile;
|
|
233
|
+
let dryRun = false;
|
|
234
|
+
let update = false;
|
|
235
|
+
let force = false;
|
|
236
|
+
let trust = false;
|
|
237
|
+
let activate = false;
|
|
238
|
+
let json = false;
|
|
239
|
+
const positional = [];
|
|
240
|
+
const takeValue = (index, flag) => {
|
|
241
|
+
const value = args[index + 1];
|
|
242
|
+
if (!value || value.startsWith('--')) {
|
|
243
|
+
throw new Error(`${flag} requires a value`);
|
|
244
|
+
}
|
|
245
|
+
return value;
|
|
246
|
+
};
|
|
247
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
248
|
+
const argument = args[index];
|
|
249
|
+
switch (argument) {
|
|
250
|
+
case '--git':
|
|
251
|
+
gitUrl = takeValue(index, argument);
|
|
252
|
+
index += 1;
|
|
253
|
+
break;
|
|
254
|
+
case '--rev':
|
|
255
|
+
revision = takeValue(index, argument);
|
|
256
|
+
index += 1;
|
|
257
|
+
break;
|
|
258
|
+
case '--subpath':
|
|
259
|
+
subpath = takeValue(index, argument);
|
|
260
|
+
index += 1;
|
|
261
|
+
break;
|
|
262
|
+
case '--profile': {
|
|
263
|
+
const value = takeValue(index, argument);
|
|
264
|
+
if (value !== 'strict' && value !== 'compatible') {
|
|
265
|
+
throw new Error('--profile must be strict or compatible');
|
|
266
|
+
}
|
|
267
|
+
profile = value;
|
|
268
|
+
index += 1;
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
case '--dry-run':
|
|
272
|
+
dryRun = true;
|
|
273
|
+
break;
|
|
274
|
+
case '--update':
|
|
275
|
+
update = true;
|
|
276
|
+
break;
|
|
277
|
+
case '--force':
|
|
278
|
+
force = true;
|
|
279
|
+
break;
|
|
280
|
+
case '--trust':
|
|
281
|
+
trust = true;
|
|
282
|
+
break;
|
|
283
|
+
case '--activate':
|
|
284
|
+
activate = true;
|
|
285
|
+
break;
|
|
286
|
+
case '--json':
|
|
287
|
+
json = true;
|
|
288
|
+
break;
|
|
289
|
+
default:
|
|
290
|
+
if (argument.startsWith('--')) {
|
|
291
|
+
throw new Error(`unknown import option "${argument}"`);
|
|
292
|
+
}
|
|
293
|
+
positional.push(argument);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (gitUrl || revision || subpath) {
|
|
297
|
+
if (!gitUrl || !revision || !subpath) {
|
|
298
|
+
throw new Error('Git import requires --git, --rev, and --subpath');
|
|
299
|
+
}
|
|
300
|
+
if (positional.length > 0) {
|
|
301
|
+
throw new Error('Git import does not accept a local directory argument');
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
source: {
|
|
305
|
+
kind: 'git',
|
|
306
|
+
url: gitUrl,
|
|
307
|
+
revision,
|
|
308
|
+
subpath,
|
|
309
|
+
},
|
|
310
|
+
options: { profile, dryRun, update, force, trust, activate },
|
|
311
|
+
json,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
if (positional.length !== 1) {
|
|
315
|
+
throw new Error('local import requires exactly one skill directory');
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
source: {
|
|
319
|
+
kind: 'directory',
|
|
320
|
+
path: positional[0],
|
|
321
|
+
},
|
|
322
|
+
options: { profile, dryRun, update, force, trust, activate },
|
|
323
|
+
json,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function printImportUsage() {
|
|
327
|
+
console.log('Usage:');
|
|
328
|
+
console.log(' aiwg skills import <directory> [options]');
|
|
329
|
+
console.log(' aiwg skills import --git <url> --rev <revision> --subpath <path> [options]');
|
|
330
|
+
console.log('');
|
|
331
|
+
console.log('Options:');
|
|
332
|
+
console.log(' --profile strict|compatible Validation profile (default: strict)');
|
|
333
|
+
console.log(' --dry-run Validate and plan without writing');
|
|
334
|
+
console.log(' --update Update changed content from the same source');
|
|
335
|
+
console.log(' --force Replace an imported name from a different source');
|
|
336
|
+
console.log(' --trust --activate Explicitly trust and activate this exact digest');
|
|
337
|
+
console.log(' --json Emit deterministic structured output');
|
|
338
|
+
}
|
|
339
|
+
async function handleImport(args) {
|
|
340
|
+
let parsed;
|
|
341
|
+
try {
|
|
342
|
+
parsed = parseImportArgs(args);
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
346
|
+
printImportUsage();
|
|
347
|
+
process.exit(1);
|
|
348
|
+
}
|
|
349
|
+
try {
|
|
350
|
+
const result = await importSkillSource(parsed.source, {
|
|
351
|
+
...parsed.options,
|
|
352
|
+
projectDir: process.cwd(),
|
|
353
|
+
});
|
|
354
|
+
if (parsed.json) {
|
|
355
|
+
console.log(JSON.stringify(result, null, 2));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
console.log('');
|
|
359
|
+
console.log(`Agent Skill import: ${result.status}`);
|
|
360
|
+
console.log(`Name: ${result.name}`);
|
|
361
|
+
console.log(`Description: ${result.description}`);
|
|
362
|
+
console.log(`Digest: ${result.digest}`);
|
|
363
|
+
console.log(`Source: ${result.source.kind}`);
|
|
364
|
+
console.log(`Locator: ${result.source.locator}`);
|
|
365
|
+
if (result.source.kind === 'git') {
|
|
366
|
+
console.log(`Subpath: ${result.source.subpath}`);
|
|
367
|
+
console.log(`Requested: ${result.source.requestedRevision}`);
|
|
368
|
+
console.log(`Resolved: ${result.source.resolvedRevision}`);
|
|
369
|
+
}
|
|
370
|
+
console.log(`Profile: ${result.validationProfile}`);
|
|
371
|
+
console.log(`Trust: ${result.trust.state}`);
|
|
372
|
+
console.log(`Activation: ${result.trust.activation}`);
|
|
373
|
+
console.log(`Managed: ${result.managedLocation}`);
|
|
374
|
+
console.log(`Files: ${result.fileCount}`);
|
|
375
|
+
console.log(`Bytes: ${result.totalBytes}`);
|
|
376
|
+
if (result.diagnostics.length > 0) {
|
|
377
|
+
console.log('');
|
|
378
|
+
console.log('Diagnostics:');
|
|
379
|
+
for (const item of result.diagnostics) {
|
|
380
|
+
console.log(` ${item.severity} ${item.code} ${item.file} ${item.yamlPath}: ${item.message}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
console.log('');
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
const importError = error instanceof AgentSkillImportError ? error : undefined;
|
|
387
|
+
if (parsed.json) {
|
|
388
|
+
console.log(JSON.stringify({
|
|
389
|
+
schemaVersion: 1,
|
|
390
|
+
status: 'error',
|
|
391
|
+
code: importError?.code ?? 'AS_IMPORT_FAILED',
|
|
392
|
+
message: error instanceof Error ? error.message : String(error),
|
|
393
|
+
diagnostics: importError?.diagnostics ?? [],
|
|
394
|
+
}, null, 2));
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
398
|
+
for (const item of importError?.diagnostics ?? []) {
|
|
399
|
+
console.error(` ${item.severity} ${item.code} ${item.file} ${item.yamlPath}: ${item.message}`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
function parseDeploymentArgs(args) {
|
|
406
|
+
let target = 'claude';
|
|
407
|
+
let dryRun = false;
|
|
408
|
+
let json = false;
|
|
409
|
+
const positional = [];
|
|
410
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
411
|
+
const argument = args[index];
|
|
412
|
+
switch (argument) {
|
|
413
|
+
case '--target': {
|
|
414
|
+
const value = args[index + 1];
|
|
415
|
+
if (!value || value.startsWith('--')) {
|
|
416
|
+
throw new Error('--target requires a provider ID or all');
|
|
417
|
+
}
|
|
418
|
+
target = value;
|
|
419
|
+
index += 1;
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
case '--dry-run':
|
|
423
|
+
dryRun = true;
|
|
424
|
+
break;
|
|
425
|
+
case '--json':
|
|
426
|
+
json = true;
|
|
427
|
+
break;
|
|
428
|
+
default:
|
|
429
|
+
if (argument.startsWith('--')) {
|
|
430
|
+
throw new Error(`unknown deployment option "${argument}"`);
|
|
431
|
+
}
|
|
432
|
+
positional.push(argument);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (positional.length !== 1) {
|
|
436
|
+
throw new Error('deployment requires exactly one imported skill name');
|
|
437
|
+
}
|
|
438
|
+
if (target !== 'all' && !SUPPORTED_TARGETS.includes(target)) {
|
|
439
|
+
throw new Error(`unknown target "${target}"`);
|
|
440
|
+
}
|
|
441
|
+
return {
|
|
442
|
+
name: positional[0],
|
|
443
|
+
targets: target === 'all' ? [...SUPPORTED_TARGETS] : [target],
|
|
444
|
+
dryRun,
|
|
445
|
+
json,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
function printDeploymentUsage(operation) {
|
|
449
|
+
console.log(`Usage: aiwg skills ${operation} <name> [--target <provider|all>] [--dry-run] [--json]`);
|
|
450
|
+
console.log('');
|
|
451
|
+
console.log(`Supported targets: ${SUPPORTED_TARGETS.join(', ')}`);
|
|
452
|
+
}
|
|
453
|
+
function printDeploymentResults(operation, results, json) {
|
|
454
|
+
if (json) {
|
|
455
|
+
console.log(JSON.stringify({
|
|
456
|
+
schemaVersion: 1,
|
|
457
|
+
operation,
|
|
458
|
+
results,
|
|
459
|
+
}, null, 2));
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
console.log('');
|
|
463
|
+
console.log(`Agent Skill ${operation}:`);
|
|
464
|
+
for (const item of results) {
|
|
465
|
+
console.log(` ${item.provider.padEnd(10)} ${item.outcome.padEnd(9)} `
|
|
466
|
+
+ `${item.projectionStatus.padEnd(11)} ${item.path}`);
|
|
467
|
+
console.log(` digest: ${item.sourceDigest || 'unavailable'}`);
|
|
468
|
+
for (const reason of item.reasons)
|
|
469
|
+
console.log(` reason: ${reason}`);
|
|
470
|
+
for (const warning of item.warnings)
|
|
471
|
+
console.log(` warning: ${warning}`);
|
|
472
|
+
}
|
|
473
|
+
console.log('');
|
|
474
|
+
}
|
|
475
|
+
async function handleDeployment(operation, args) {
|
|
476
|
+
let parsed;
|
|
477
|
+
try {
|
|
478
|
+
parsed = parseDeploymentArgs(args);
|
|
479
|
+
}
|
|
480
|
+
catch (error) {
|
|
481
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
482
|
+
printDeploymentUsage(operation);
|
|
483
|
+
process.exit(1);
|
|
484
|
+
}
|
|
485
|
+
try {
|
|
486
|
+
const options = (target) => ({
|
|
487
|
+
projectDir: process.cwd(),
|
|
488
|
+
target,
|
|
489
|
+
dryRun: parsed.dryRun,
|
|
490
|
+
});
|
|
491
|
+
const results = parsed.targets.map((target) => (operation === 'deploy'
|
|
492
|
+
? deployImportedAgentSkill(parsed.name, options(target))
|
|
493
|
+
: uninstallImportedAgentSkill(parsed.name, options(target))));
|
|
494
|
+
printDeploymentResults(operation, results, parsed.json);
|
|
495
|
+
if (results.some((item) => item.outcome === 'blocked')) {
|
|
496
|
+
process.exitCode = 1;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
catch (error) {
|
|
500
|
+
const deploymentError = error instanceof AgentSkillDeploymentError
|
|
501
|
+
? error
|
|
502
|
+
: undefined;
|
|
503
|
+
if (parsed.json) {
|
|
504
|
+
console.log(JSON.stringify({
|
|
505
|
+
schemaVersion: 1,
|
|
506
|
+
operation,
|
|
507
|
+
status: 'error',
|
|
508
|
+
code: deploymentError?.code ?? 'AS_DEPLOY_FAILED',
|
|
509
|
+
message: error instanceof Error ? error.message : String(error),
|
|
510
|
+
results: [],
|
|
511
|
+
}, null, 2));
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
515
|
+
}
|
|
516
|
+
process.exit(1);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
function parseExportArgs(args) {
|
|
520
|
+
let provider = 'local';
|
|
521
|
+
let outDir;
|
|
522
|
+
let dryRun = false;
|
|
523
|
+
let force = false;
|
|
524
|
+
let json = false;
|
|
525
|
+
const positional = [];
|
|
526
|
+
const takeValue = (index, flag) => {
|
|
527
|
+
const value = args[index + 1];
|
|
528
|
+
if (!value || value.startsWith('--')) {
|
|
529
|
+
throw new Error(`${flag} requires a value`);
|
|
530
|
+
}
|
|
531
|
+
return value;
|
|
532
|
+
};
|
|
533
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
534
|
+
const argument = args[index];
|
|
535
|
+
switch (argument) {
|
|
536
|
+
case '--provider':
|
|
537
|
+
provider = takeValue(index, argument);
|
|
538
|
+
index += 1;
|
|
539
|
+
break;
|
|
540
|
+
case '--out':
|
|
541
|
+
outDir = takeValue(index, argument);
|
|
542
|
+
index += 1;
|
|
543
|
+
break;
|
|
544
|
+
case '--dry-run':
|
|
545
|
+
dryRun = true;
|
|
546
|
+
break;
|
|
547
|
+
case '--force':
|
|
548
|
+
force = true;
|
|
549
|
+
break;
|
|
550
|
+
case '--json':
|
|
551
|
+
json = true;
|
|
552
|
+
break;
|
|
553
|
+
default:
|
|
554
|
+
if (argument.startsWith('--')) {
|
|
555
|
+
throw new Error(`unknown export option "${argument}"`);
|
|
556
|
+
}
|
|
557
|
+
positional.push(argument);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if (positional.length !== 1) {
|
|
561
|
+
throw new Error('export requires exactly one skill name');
|
|
562
|
+
}
|
|
563
|
+
if (!outDir) {
|
|
564
|
+
throw new Error('export requires --out <directory>');
|
|
565
|
+
}
|
|
566
|
+
return {
|
|
567
|
+
name: positional[0],
|
|
568
|
+
provider,
|
|
569
|
+
outDir,
|
|
570
|
+
dryRun,
|
|
571
|
+
force,
|
|
572
|
+
json,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
function printExportUsage() {
|
|
576
|
+
console.log('Usage: aiwg skills export <name> --out <directory> [options]');
|
|
577
|
+
console.log('');
|
|
578
|
+
console.log('Options:');
|
|
579
|
+
console.log(' --provider <registry> Skill registry to read from (default: local)');
|
|
580
|
+
console.log(' --out <directory> Parent directory for the exported Agent Skill');
|
|
581
|
+
console.log(' --dry-run Validate and plan without writing');
|
|
582
|
+
console.log(' --force Replace an existing export directory after review');
|
|
583
|
+
console.log(' --json Emit deterministic structured output');
|
|
584
|
+
}
|
|
585
|
+
async function handleExport(args) {
|
|
586
|
+
let parsed;
|
|
587
|
+
try {
|
|
588
|
+
parsed = parseExportArgs(args);
|
|
589
|
+
}
|
|
590
|
+
catch (error) {
|
|
591
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
592
|
+
printExportUsage();
|
|
593
|
+
process.exit(1);
|
|
594
|
+
}
|
|
595
|
+
try {
|
|
596
|
+
const details = await getSkillInfo(parsed.name, parsed.provider);
|
|
597
|
+
if (!details?.path) {
|
|
598
|
+
throw new AgentSkillExportError('AS_EXPORT_SKILL_NOT_FOUND', `skill '${parsed.name}' was not found in ${parsed.provider} with a local SKILL.md path`);
|
|
599
|
+
}
|
|
600
|
+
const options = {
|
|
601
|
+
outDir: parsed.outDir,
|
|
602
|
+
dryRun: parsed.dryRun,
|
|
603
|
+
force: parsed.force,
|
|
604
|
+
};
|
|
605
|
+
const result = exportAgentSkillDirectory(details.path.replace(/(?:^|[/\\])SKILL\.md$/, ''), options);
|
|
606
|
+
if (parsed.json) {
|
|
607
|
+
console.log(JSON.stringify(result, null, 2));
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
console.log('');
|
|
611
|
+
console.log(`Agent Skill export: ${result.status}`);
|
|
612
|
+
console.log(`Name: ${result.name}`);
|
|
613
|
+
console.log(`Output: ${result.outputPath}`);
|
|
614
|
+
console.log(`Source digest: ${result.sourceDigest}`);
|
|
615
|
+
console.log(`Export digest: ${result.exportDigest}`);
|
|
616
|
+
console.log(`Files: ${result.fileCount}`);
|
|
617
|
+
if (result.omittedAiwgFields.length > 0) {
|
|
618
|
+
console.log(`Omitted AIWG fields: ${result.omittedAiwgFields.join(', ')}`);
|
|
619
|
+
}
|
|
620
|
+
console.log('');
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
const exportError = error instanceof AgentSkillExportError ? error : undefined;
|
|
624
|
+
if (parsed.json) {
|
|
625
|
+
console.log(JSON.stringify({
|
|
626
|
+
schemaVersion: 1,
|
|
627
|
+
status: 'error',
|
|
628
|
+
code: exportError?.code ?? 'AS_EXPORT_FAILED',
|
|
629
|
+
message: error instanceof Error ? error.message : String(error),
|
|
630
|
+
}, null, 2));
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
634
|
+
}
|
|
635
|
+
process.exit(1);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
203
638
|
/**
|
|
204
639
|
* Handle 'skills publish' command
|
|
205
640
|
*/
|
|
@@ -253,6 +688,11 @@ async function handleRun(args) {
|
|
|
253
688
|
console.log("Run 'aiwg skills list' to see available skills");
|
|
254
689
|
process.exit(1);
|
|
255
690
|
}
|
|
691
|
+
const activationError = importedSkillActivationError(details);
|
|
692
|
+
if (activationError) {
|
|
693
|
+
console.error(`Error: ${activationError}`);
|
|
694
|
+
process.exit(1);
|
|
695
|
+
}
|
|
256
696
|
if (!details.content) {
|
|
257
697
|
console.error(`Error: Skill '${skillName}' has no executable content`);
|
|
258
698
|
process.exit(1);
|
|
@@ -306,12 +746,24 @@ export async function main(args) {
|
|
|
306
746
|
case 'install':
|
|
307
747
|
await handleInstall(subcommandArgs);
|
|
308
748
|
break;
|
|
749
|
+
case 'import':
|
|
750
|
+
await handleImport(subcommandArgs);
|
|
751
|
+
break;
|
|
752
|
+
case 'deploy':
|
|
753
|
+
await handleDeployment('deploy', subcommandArgs);
|
|
754
|
+
break;
|
|
755
|
+
case 'uninstall':
|
|
756
|
+
await handleDeployment('uninstall', subcommandArgs);
|
|
757
|
+
break;
|
|
758
|
+
case 'export':
|
|
759
|
+
await handleExport(subcommandArgs);
|
|
760
|
+
break;
|
|
309
761
|
case 'publish':
|
|
310
762
|
await handlePublish(subcommandArgs);
|
|
311
763
|
break;
|
|
312
764
|
case undefined:
|
|
313
765
|
console.error('Error: Skills subcommand required');
|
|
314
|
-
console.log('Available: run, search, info, list, install, publish');
|
|
766
|
+
console.log('Available: run, search, info, list, install, import, deploy, uninstall, export, publish');
|
|
315
767
|
console.log('');
|
|
316
768
|
console.log('Examples:');
|
|
317
769
|
console.log(' aiwg skills run workspace-health');
|
|
@@ -323,11 +775,15 @@ export async function main(args) {
|
|
|
323
775
|
console.log(' aiwg skills install parallel-dispatch');
|
|
324
776
|
console.log(' aiwg skills install parallel-dispatch --target copilot');
|
|
325
777
|
console.log(' aiwg skills install my-skill --provider clawhub --target cursor');
|
|
778
|
+
console.log(' aiwg skills import ./my-skill --dry-run');
|
|
779
|
+
console.log(' aiwg skills deploy my-skill --target all --dry-run');
|
|
780
|
+
console.log(' aiwg skills uninstall my-skill --target claude');
|
|
781
|
+
console.log(' aiwg skills export my-skill --out ./agent-skills');
|
|
326
782
|
process.exit(1);
|
|
327
783
|
break;
|
|
328
784
|
default:
|
|
329
785
|
console.error(`Error: Unknown skills subcommand '${subcommand}'`);
|
|
330
|
-
console.log('Available: run, search, info, list, install, publish');
|
|
786
|
+
console.log('Available: run, search, info, list, install, import, deploy, uninstall, export, publish');
|
|
331
787
|
process.exit(1);
|
|
332
788
|
}
|
|
333
789
|
}
|