@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.
Files changed (53) hide show
  1. package/README.md +4 -4
  2. package/dist/src/api/index.d.ts +1 -0
  3. package/dist/src/api/index.js +1 -0
  4. package/dist/src/artifacts/browser-export.js +7 -0
  5. package/dist/src/artifacts/citation-parser.js +96 -35
  6. package/dist/src/artifacts/index-builder.js +54 -17
  7. package/dist/src/artifacts/state-transfer.js +27 -0
  8. package/dist/src/artifacts/stats.js +8 -0
  9. package/dist/src/cli/cli-extension-loader.js +73 -0
  10. package/dist/src/cli/handlers/index.js +3 -1
  11. package/dist/src/cli/handlers/sessions.js +966 -0
  12. package/dist/src/cli/handlers/skill-lint.js +49 -45
  13. package/dist/src/cli/handlers/use.js +143 -60
  14. package/dist/src/cli/handlers/utilities.js +22 -8
  15. package/dist/src/cli/skill-usage.js +146 -24
  16. package/dist/src/extensions/commands/definitions.js +29 -0
  17. package/dist/src/extensions/manifest.js +29 -0
  18. package/dist/src/sessions/adapters/claude.js +357 -0
  19. package/dist/src/sessions/adapters/codex.js +521 -0
  20. package/dist/src/sessions/adapters/copilot.js +226 -0
  21. package/dist/src/sessions/adapters/cursor.js +372 -0
  22. package/dist/src/sessions/adapters/factory.js +345 -0
  23. package/dist/src/sessions/adapters/generic.js +225 -0
  24. package/dist/src/sessions/adapters/hermes.js +341 -0
  25. package/dist/src/sessions/adapters/openclaw.js +381 -0
  26. package/dist/src/sessions/adapters/opencode.js +454 -0
  27. package/dist/src/sessions/adapters/openhuman.js +315 -0
  28. package/dist/src/sessions/adapters/warp.js +160 -0
  29. package/dist/src/sessions/adapters/windsurf.js +212 -0
  30. package/dist/src/sessions/candidates.js +210 -0
  31. package/dist/src/sessions/contracts.js +310 -0
  32. package/dist/src/sessions/discovery.js +51 -0
  33. package/dist/src/sessions/fixtures.js +12 -0
  34. package/dist/src/sessions/importer.js +315 -0
  35. package/dist/src/sessions/index.js +25 -0
  36. package/dist/src/sessions/knowledge-shard.js +61 -0
  37. package/dist/src/sessions/optional-backends.js +238 -0
  38. package/dist/src/sessions/policy.js +192 -0
  39. package/dist/src/sessions/ports.js +2 -0
  40. package/dist/src/sessions/promotion.js +367 -0
  41. package/dist/src/sessions/readers.js +176 -0
  42. package/dist/src/sessions/repository.js +1551 -0
  43. package/dist/src/skills/adapters/agent-skills.js +59 -0
  44. package/dist/src/skills/adapters/local.js +19 -1
  45. package/dist/src/skills/agent-skills.js +249 -0
  46. package/dist/src/skills/cli.js +463 -7
  47. package/dist/src/skills/deployer.js +554 -0
  48. package/dist/src/skills/doctor.js +105 -0
  49. package/dist/src/skills/exporter.js +382 -0
  50. package/dist/src/skills/importer.js +921 -0
  51. package/dist/src/skills/registry.js +19 -0
  52. package/dist/src/skills/validator.js +323 -0
  53. package/package.json +2 -2
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Managed Agent Skills adapter.
3
+ *
4
+ * Imported sources remain separate from provider deployments. This adapter
5
+ * supports inspection and import only; provider projection is implemented by
6
+ * the deployment layer.
7
+ *
8
+ * @implements #1877
9
+ */
10
+ import fs from 'node:fs';
11
+ import path from 'node:path';
12
+ import { getImportedAgentSkill, importAgentSkill, listImportedAgentSkills, } from '../importer.js';
13
+ export class AgentSkillsAdapter {
14
+ projectDir;
15
+ id = 'agentskills';
16
+ name = 'Agent Skills (Managed Imports)';
17
+ constructor(projectDir) {
18
+ this.projectDir = projectDir;
19
+ }
20
+ resolveProjectDir() {
21
+ return this.projectDir ?? process.cwd();
22
+ }
23
+ async isAvailable() {
24
+ return true;
25
+ }
26
+ async list() {
27
+ return listImportedAgentSkills(this.resolveProjectDir()).map((record) => ({
28
+ name: record.name,
29
+ description: record.description,
30
+ source: this.id,
31
+ installed: true,
32
+ }));
33
+ }
34
+ async search(query) {
35
+ const normalized = query.toLowerCase();
36
+ return (await this.list()).filter((skill) => (skill.name.toLowerCase().includes(normalized)
37
+ || skill.description.toLowerCase().includes(normalized)));
38
+ }
39
+ async info(name) {
40
+ const record = getImportedAgentSkill(this.resolveProjectDir(), name);
41
+ if (!record)
42
+ return undefined;
43
+ const skillPath = path.join(record.managedLocation, 'SKILL.md');
44
+ const managedDrift = record.diagnostics.some((item) => item.code === 'AS_IMPORT_MANAGED_DRIFT');
45
+ return {
46
+ name: record.name,
47
+ description: record.description,
48
+ source: this.id,
49
+ installed: true,
50
+ path: skillPath,
51
+ content: managedDrift ? undefined : fs.readFileSync(skillPath, 'utf8'),
52
+ imported: record,
53
+ };
54
+ }
55
+ async importSource(source, options) {
56
+ return importAgentSkill(source, options);
57
+ }
58
+ }
59
+ //# sourceMappingURL=agent-skills.js.map
@@ -11,7 +11,25 @@ import path from 'path';
11
11
  import { fileURLToPath } from 'url';
12
12
  import { getProviderDefinition, resolveProviderPathValue, } from '../../providers/provider-definitions.js';
13
13
  const _scriptDir = path.dirname(fileURLToPath(import.meta.url));
14
- const AIWG_ROOT = process.env.AIWG_ROOT || path.resolve(_scriptDir, '../../../');
14
+ function resolveAiwgRoot() {
15
+ if (process.env.AIWG_ROOT)
16
+ return process.env.AIWG_ROOT;
17
+ const candidates = [
18
+ path.resolve(_scriptDir, '../../../'),
19
+ path.resolve(_scriptDir, '../../../../'),
20
+ ];
21
+ const repoRoot = candidates.find((candidate) => (fs.existsSync(path.join(candidate, 'package.json'))
22
+ && fs.existsSync(path.join(candidate, 'agentic', 'code'))));
23
+ if (repoRoot)
24
+ return repoRoot;
25
+ for (const candidate of candidates) {
26
+ if (fs.existsSync(path.join(candidate, 'agentic', 'code'))) {
27
+ return candidate;
28
+ }
29
+ }
30
+ return candidates[0];
31
+ }
32
+ const AIWG_ROOT = resolveAiwgRoot();
15
33
  function resolveSkillFallbackPath(target, projectDir, name) {
16
34
  const definition = getProviderDefinition(target);
17
35
  if (!definition)
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Agent Skills portability contract.
3
+ *
4
+ * This module intentionally contains no filesystem or execution behavior. It is
5
+ * the typed boundary shared by import, validation, and provider projection.
6
+ *
7
+ * @implements #1875
8
+ */
9
+ export const AGENT_SKILLS_BASELINE = {
10
+ repository: 'agentskills/agentskills',
11
+ revision: '38a2ff82958afee88dadf4831509e6f7e9d8ef4e',
12
+ referenceValidatorVersion: '0.1.0',
13
+ pinnedAt: '2026-07-25',
14
+ };
15
+ export const AGENT_SKILLS_SIDECAR_SCHEMA = 'https://aiwg.io/schemas/skills/agent-skill-sidecar.v1.schema.json';
16
+ export const STANDARD_SKILL_FIELDS = [
17
+ 'name',
18
+ 'description',
19
+ 'license',
20
+ 'compatibility',
21
+ 'metadata',
22
+ 'allowed-tools',
23
+ ];
24
+ export const AGENT_SKILL_VALIDATION_PROFILES = Object.freeze({
25
+ strict: {
26
+ recognizedAiwgFields: false,
27
+ unknownField: 'error',
28
+ cosmeticNameDefect: 'error',
29
+ missingDescription: 'error',
30
+ invalidYaml: 'error',
31
+ },
32
+ compatible: {
33
+ recognizedAiwgFields: true,
34
+ unknownField: 'error',
35
+ cosmeticNameDefect: 'error',
36
+ missingDescription: 'error',
37
+ invalidYaml: 'error',
38
+ },
39
+ discovery: {
40
+ recognizedAiwgFields: true,
41
+ unknownField: 'warning',
42
+ cosmeticNameDefect: 'warning',
43
+ missingDescription: 'error',
44
+ invalidYaml: 'error',
45
+ },
46
+ });
47
+ export const AGENT_SKILL_PROJECTION_STATUSES = [
48
+ 'native',
49
+ 'projected',
50
+ 'degraded',
51
+ 'unsupported',
52
+ ];
53
+ export const AIWG_SKILL_CONTROL_FIELDS = [
54
+ 'namespace',
55
+ 'platforms',
56
+ 'commandHint',
57
+ 'triggers',
58
+ 'version',
59
+ 'ensures',
60
+ 'invariants',
61
+ 'requires',
62
+ 'tools',
63
+ 'errors',
64
+ 'kernel',
65
+ 'category',
66
+ 'script',
67
+ 'status',
68
+ 'aliases',
69
+ 'userInvocable',
70
+ 'author',
71
+ 'capabilities',
72
+ 'deprecated_names',
73
+ 'legacyName',
74
+ 'triggerPhrases',
75
+ 'autoTrigger',
76
+ 'autoTriggerConditions',
77
+ 'references',
78
+ 'inputRequirements',
79
+ 'outputFormat',
80
+ 'effort',
81
+ 'disableModelInvocation',
82
+ 'context',
83
+ 'allowedTools',
84
+ ];
85
+ /**
86
+ * Higher values win. This preserves the upstream project-over-user rule while
87
+ * keeping explicitly imported skills ahead of AIWG's packaged defaults.
88
+ */
89
+ export const AGENT_SKILL_COLLISION_PRECEDENCE = Object.freeze({
90
+ project: 400,
91
+ user: 300,
92
+ imported: 200,
93
+ 'aiwg-managed': 100,
94
+ });
95
+ export function resolveAgentSkillCollision(origins) {
96
+ return origins.reduce((winner, origin) => {
97
+ if (!winner)
98
+ return origin;
99
+ return AGENT_SKILL_COLLISION_PRECEDENCE[origin]
100
+ > AGENT_SKILL_COLLISION_PRECEDENCE[winner]
101
+ ? origin
102
+ : winner;
103
+ }, undefined);
104
+ }
105
+ const PORTABLE_SKILL_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
106
+ /**
107
+ * Validate the metadata invariants needed by the AIWG-compatible corpus gate.
108
+ * The shared parser/validator extends this diagnostic model in #1878.
109
+ */
110
+ export function validateCompatibleAgentSkillMetadata(frontmatter, directoryName, file, lineCount) {
111
+ const diagnostics = [];
112
+ const add = (code, severity, yamlPath, message, remediation) => {
113
+ diagnostics.push({
114
+ code,
115
+ severity,
116
+ file,
117
+ yamlPath,
118
+ message,
119
+ upstreamBaseline: AGENT_SKILLS_BASELINE.revision,
120
+ remediation,
121
+ });
122
+ };
123
+ const name = frontmatter['name'];
124
+ if (typeof name !== 'string' || name.length === 0) {
125
+ add('AS_NAME_REQUIRED', 'error', '$.name', 'name must be a non-empty string', 'Set name to the lowercase hyphenated skill directory name.');
126
+ }
127
+ else {
128
+ if (name.length > 64 || !PORTABLE_SKILL_NAME.test(name)) {
129
+ add('AS_NAME_FORMAT', 'error', '$.name', 'name must be 1-64 ASCII lowercase letters, numbers, or single hyphens', 'Use the conservative Agent Skills ASCII name rule.');
130
+ }
131
+ if (name !== directoryName) {
132
+ add('AS_NAME_DIRECTORY', 'error', '$.name', `name "${name}" does not match directory "${directoryName}"`, `Set name to "${directoryName}" and retain old names as AIWG aliases.`);
133
+ }
134
+ }
135
+ const description = frontmatter['description'];
136
+ if (typeof description !== 'string' || description.length === 0) {
137
+ add('AS_DESCRIPTION_REQUIRED', 'error', '$.description', 'description must be a non-empty string', 'Add a description that explains what the skill does and when to use it.');
138
+ }
139
+ else if (description.length > 1024) {
140
+ add('AS_DESCRIPTION_LENGTH', 'error', '$.description', 'description exceeds the 1,024-character limit', 'Shorten description without truncating it during deployment.');
141
+ }
142
+ const license = frontmatter['license'];
143
+ if (license !== undefined && typeof license !== 'string') {
144
+ add('AS_LICENSE_TYPE', 'error', '$.license', 'license must be a string', 'Use a license name or a relative reference to a bundled license file.');
145
+ }
146
+ const compatibility = frontmatter['compatibility'];
147
+ if (compatibility !== undefined) {
148
+ if (typeof compatibility !== 'string') {
149
+ add('AS_COMPATIBILITY_TYPE', 'error', '$.compatibility', 'compatibility must be a string', 'Describe environment or product requirements in a string.');
150
+ }
151
+ else if (compatibility.length === 0 || compatibility.length > 500) {
152
+ add('AS_COMPATIBILITY_LENGTH', 'error', '$.compatibility', 'compatibility must contain 1-500 characters', 'Keep compatibility within the normative limit.');
153
+ }
154
+ }
155
+ const metadata = frontmatter['metadata'];
156
+ if (metadata !== undefined) {
157
+ if (typeof metadata !== 'object'
158
+ || metadata === null
159
+ || Array.isArray(metadata)) {
160
+ add('AS_METADATA_TYPE', 'error', '$.metadata', 'metadata must be a string-to-string map', 'Replace metadata with an object whose values are all strings.');
161
+ }
162
+ else {
163
+ for (const key of Object.keys(metadata).sort()) {
164
+ if (typeof metadata[key] !== 'string') {
165
+ add('AS_METADATA_VALUE_TYPE', 'error', `$.metadata.${key}`, `metadata value "${key}" must be a string`, 'String-encode the value or move AIWG control structure to the sidecar.');
166
+ }
167
+ }
168
+ }
169
+ }
170
+ const allowedTools = frontmatter['allowed-tools'];
171
+ if (allowedTools !== undefined && typeof allowedTools !== 'string') {
172
+ add('AS_ALLOWED_TOOLS_TYPE', 'error', '$.allowed-tools', 'allowed-tools must be a space-delimited string', 'Serialize experimental allowed-tools as one string.');
173
+ }
174
+ const recognizedFields = new Set([
175
+ ...STANDARD_SKILL_FIELDS,
176
+ ...AIWG_SKILL_CONTROL_FIELDS,
177
+ ]);
178
+ for (const key of Object.keys(frontmatter).sort()) {
179
+ if (!recognizedFields.has(key)) {
180
+ add('AS_FIELD_UNKNOWN', 'error', `$.${key}`, `unrecognized top-level field "${key}"`, 'Remove the field or map it explicitly before granting AIWG policy meaning.');
181
+ }
182
+ }
183
+ if (lineCount !== undefined && lineCount > 500) {
184
+ add('AS_ADVISORY_LINES', 'warning', '$', `SKILL.md has ${lineCount} lines; the recommendation is at most 500`, 'Move detailed material to referenced resources as progressive-disclosure debt.');
185
+ }
186
+ return diagnostics.sort((left, right) => (left.code.localeCompare(right.code)
187
+ || left.yamlPath.localeCompare(right.yamlPath)
188
+ || left.message.localeCompare(right.message)));
189
+ }
190
+ /**
191
+ * Return a deterministic strict projection. AIWG control fields and unknown
192
+ * external fields have no code path into this object.
193
+ */
194
+ export function projectStrictAgentSkill(document) {
195
+ const { standard } = document;
196
+ const projection = {
197
+ name: standard.name,
198
+ description: standard.description,
199
+ };
200
+ if (standard.license !== undefined)
201
+ projection.license = standard.license;
202
+ if (standard.compatibility !== undefined) {
203
+ projection.compatibility = standard.compatibility;
204
+ }
205
+ if (standard.metadata !== undefined) {
206
+ projection.metadata = { ...standard.metadata };
207
+ }
208
+ const allowedTools = standard['allowed-tools'] ?? equivalentPortableAllowedTools(document.aiwg);
209
+ if (allowedTools !== undefined) {
210
+ projection['allowed-tools'] = allowedTools;
211
+ }
212
+ return projection;
213
+ }
214
+ /**
215
+ * Only the direct AIWG `allowedTools` policy has equivalent pre-approval
216
+ * semantics. Legacy `commandHint.allowedTools` describes command generation and
217
+ * must not be translated to the portable field.
218
+ */
219
+ export function equivalentPortableAllowedTools(aiwg) {
220
+ if (!Array.isArray(aiwg.allowedTools)
221
+ || !aiwg.allowedTools.every((tool) => (typeof tool === 'string' && tool.trim().length > 0 && !/\s/.test(tool)))) {
222
+ return undefined;
223
+ }
224
+ return aiwg.allowedTools.join(' ');
225
+ }
226
+ export function createAgentSkillSidecar(document, provenance, validationProfile, trust) {
227
+ return {
228
+ $schema: AGENT_SKILLS_SIDECAR_SCHEMA,
229
+ schemaVersion: 1,
230
+ aiwg: structuredClone(document.aiwg),
231
+ provenance: structuredClone(provenance),
232
+ validationProfile,
233
+ trust: { ...trust },
234
+ };
235
+ }
236
+ /**
237
+ * Restore AIWG metadata omitted at a strict portability boundary. Portable
238
+ * content remains authoritative for standard fields, body, and resources.
239
+ */
240
+ export function restoreAgentSkillFromSidecar(standard, body, resources, sidecar) {
241
+ return {
242
+ standard: structuredClone(standard),
243
+ body,
244
+ resources: resources.map((resource) => ({ ...resource })),
245
+ aiwg: structuredClone(sidecar.aiwg),
246
+ unknownFields: [],
247
+ };
248
+ }
249
+ //# sourceMappingURL=agent-skills.js.map