@aiwg/cli 2026.8.0 → 2026.8.2
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 +33 -0
- package/agentic/code/providers/capability-matrix.yaml +511 -0
- package/agentic/code/providers/model-capabilities.v1.json +120 -0
- package/agentic/code/providers/model-catalog.v1.json +96 -0
- package/agentic/code/providers/model-policy-evaluations.v1.json +50 -0
- package/agentic/code/providers/premium-model-allowlist.v1.json +36 -0
- package/bin/aiwg.mjs +14 -10
- package/dist/src/api/index.d.ts +1 -0
- package/dist/src/api/index.js +1 -0
- package/dist/src/artifacts/cli.js +2 -0
- package/dist/src/artifacts/types.js +4 -0
- package/dist/src/auth/client.js +209 -0
- package/dist/src/auth/config.js +38 -0
- package/dist/src/auth/credential-store.js +141 -0
- package/dist/src/auth/resource-credentials.js +25 -0
- package/dist/src/auth/types.js +2 -0
- package/dist/src/channel/manager.mjs +5 -5
- package/dist/src/cli/handlers/auth.js +125 -0
- package/dist/src/cli/handlers/help.js +1 -0
- package/dist/src/cli/handlers/index.js +3 -1
- package/dist/src/cli/handlers/install.js +42 -4
- package/dist/src/cli/handlers/marketplace.js +375 -122
- package/dist/src/cli/handlers/resource-versions.js +2 -0
- package/dist/src/cli/handlers/sessions.js +23 -5
- package/dist/src/cli/handlers/subcommands.js +10 -1
- package/dist/src/cli/handlers/use.js +342 -43
- package/dist/src/config/gitignore.js +1 -0
- package/dist/src/extensions/commands/definitions.js +19 -0
- package/dist/src/marketplace/exchange.js +602 -0
- package/dist/src/marketplace/provenance-types.js +19 -0
- package/dist/src/marketplace/provenance.js +834 -0
- package/dist/src/memory/canonical-context.js +342 -0
- package/dist/src/memory/context-pack.js +282 -0
- package/dist/src/memory/index.js +4 -0
- package/dist/src/memory/intake.js +118 -0
- package/dist/src/packages/adapters/git.js +79 -29
- package/dist/src/packages/package-discovery.js +81 -0
- package/dist/src/packages/package-registry.js +2 -0
- package/dist/src/packages/registry.js +119 -20
- package/dist/src/resources/resolver.js +1 -0
- package/dist/src/resources/web-release.d.ts +3 -1
- package/dist/src/resources/web-release.js +14 -6
- package/dist/src/serve/agentic-sandbox-fleet-client.js +213 -0
- package/dist/src/serve/fleet-mission-conductor.js +293 -0
- package/dist/src/sessions/index.js +1 -0
- package/dist/src/sessions/output-registration.js +338 -0
- package/dist/src/sessions/promotion.js +73 -2
- package/dist/src/sessions/repository.js +2 -1
- package/dist/src/update/notifier.mjs +13 -2
- package/package.json +8 -1
- package/tools/_resolve-impl.mjs +74 -0
- package/tools/agents/deploy-agents.mjs +962 -0
- package/tools/agents/providers/base.mjs +2954 -0
- package/tools/agents/providers/claude.mjs +711 -0
- package/tools/agents/providers/codex.mjs +699 -0
- package/tools/agents/providers/copilot.mjs +659 -0
- package/tools/agents/providers/cursor.mjs +714 -0
- package/tools/agents/providers/factory.mjs +1130 -0
- package/tools/agents/providers/hermes.mjs +663 -0
- package/tools/agents/providers/hook-capabilities.mjs +85 -0
- package/tools/agents/providers/model-role.mjs +56 -0
- package/tools/agents/providers/openclaw-translator.mjs +348 -0
- package/tools/agents/providers/openclaw.mjs +680 -0
- package/tools/agents/providers/opencode.mjs +675 -0
- package/tools/agents/providers/openhuman.mjs +292 -0
- package/tools/agents/providers/warp.mjs +413 -0
- package/tools/agents/providers/windsurf.mjs +748 -0
- package/tools/commands/deploy-prompts-codex.mjs +336 -0
- package/tools/plugin/package-plugins.mjs +1013 -0
- package/tools/skills/deploy-skills-codex.mjs +571 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Deploy Commands as Prompts to Codex
|
|
4
|
+
*
|
|
5
|
+
* Transforms AIWG slash commands to Codex prompt format and deploys to ~/.codex/prompts/
|
|
6
|
+
*
|
|
7
|
+
* Codex Prompt Format:
|
|
8
|
+
* - Location: ~/.codex/prompts/<name>.md
|
|
9
|
+
* - YAML frontmatter (optional): description, argument-hint
|
|
10
|
+
* - Placeholders: $1-$9, $ARGUMENTS, $NAMED
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* node tools/commands/deploy-prompts-codex.mjs [options]
|
|
14
|
+
*
|
|
15
|
+
* Options:
|
|
16
|
+
* --source <path> Source directory (defaults to repo root)
|
|
17
|
+
* --target <path> Target directory (defaults to ~/.codex/prompts)
|
|
18
|
+
* --mode <type> Deployment mode: general, sdlc, marketing (alias: mmk), media-curator, research, or all (default)
|
|
19
|
+
* --dry-run Show what would be deployed without writing
|
|
20
|
+
* --force Overwrite existing files
|
|
21
|
+
* --prefix <str> Prefix for prompt names (default: 'aiwg')
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import realFs from 'fs';
|
|
25
|
+
import { createRequire } from 'module';
|
|
26
|
+
const _require = createRequire(import.meta.url);
|
|
27
|
+
let fs;
|
|
28
|
+
try { const gfs = _require('graceful-fs'); gfs.gracefulify(realFs); fs = realFs; } catch { fs = realFs; }
|
|
29
|
+
import path from 'path';
|
|
30
|
+
import os from 'os';
|
|
31
|
+
import { getFrameworksForMode, normalizeDeploymentMode, getAddonSkillDirs, listSkillDirs, collectFrameworkArtifacts } from '../agents/providers/base.mjs';
|
|
32
|
+
|
|
33
|
+
const CODEX_PROMPTS_DIR = path.join(os.homedir(), '.codex', 'prompts');
|
|
34
|
+
|
|
35
|
+
function parseArgs() {
|
|
36
|
+
const args = process.argv.slice(2);
|
|
37
|
+
const cfg = {
|
|
38
|
+
source: null,
|
|
39
|
+
target: CODEX_PROMPTS_DIR,
|
|
40
|
+
mode: 'all',
|
|
41
|
+
dryRun: false,
|
|
42
|
+
force: false,
|
|
43
|
+
prefix: 'aiwg'
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < args.length; i++) {
|
|
47
|
+
const a = args[i];
|
|
48
|
+
if (a === '--source' && args[i + 1]) cfg.source = path.resolve(args[++i]);
|
|
49
|
+
else if (a === '--target' && args[i + 1]) cfg.target = path.resolve(args[++i]);
|
|
50
|
+
else if (a === '--mode' && args[i + 1]) cfg.mode = String(args[++i]).toLowerCase();
|
|
51
|
+
else if (a === '--dry-run') cfg.dryRun = true;
|
|
52
|
+
else if (a === '--force') cfg.force = true;
|
|
53
|
+
else if (a === '--prefix' && args[i + 1]) cfg.prefix = args[++i];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
cfg.mode = normalizeDeploymentMode(cfg.mode);
|
|
57
|
+
return cfg;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function ensureDir(d) {
|
|
61
|
+
if (!fs.existsSync(d)) fs.mkdirSync(d, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* List .md command files in a directory
|
|
66
|
+
*/
|
|
67
|
+
function listCommandFiles(dir) {
|
|
68
|
+
if (!fs.existsSync(dir)) return [];
|
|
69
|
+
|
|
70
|
+
const excluded = ['README.md', 'manifest.md', 'DEVELOPMENT_GUIDE.md'];
|
|
71
|
+
|
|
72
|
+
return fs.readdirSync(dir, { withFileTypes: true })
|
|
73
|
+
.filter(e => e.isFile() && e.name.endsWith('.md') && !excluded.includes(e.name))
|
|
74
|
+
.map(e => path.join(dir, e.name));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Parse AIWG command frontmatter and body
|
|
79
|
+
*/
|
|
80
|
+
function parseCommandFile(filePath) {
|
|
81
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
82
|
+
|
|
83
|
+
// Check for YAML frontmatter
|
|
84
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
85
|
+
|
|
86
|
+
if (fmMatch) {
|
|
87
|
+
const [, frontmatter, body] = fmMatch;
|
|
88
|
+
const metadata = {};
|
|
89
|
+
|
|
90
|
+
for (const line of frontmatter.split('\n')) {
|
|
91
|
+
const colonIdx = line.indexOf(':');
|
|
92
|
+
if (colonIdx > 0) {
|
|
93
|
+
const key = line.slice(0, colonIdx).trim();
|
|
94
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
95
|
+
metadata[key] = value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return { metadata, body: body.trim(), hasMetadata: true };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// No frontmatter, entire content is body
|
|
103
|
+
return { metadata: {}, body: content.trim(), hasMetadata: false };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Transform AIWG command to Codex prompt format
|
|
108
|
+
*/
|
|
109
|
+
function transformToCodexPrompt(commandPath, prefix) {
|
|
110
|
+
const parsed = parseCommandFile(commandPath);
|
|
111
|
+
const commandName = path.basename(commandPath, '.md');
|
|
112
|
+
|
|
113
|
+
// Extract description from metadata or first paragraph
|
|
114
|
+
let description = '';
|
|
115
|
+
if (parsed.metadata.description) {
|
|
116
|
+
description = parsed.metadata.description;
|
|
117
|
+
} else {
|
|
118
|
+
// Try to extract from first line after any heading
|
|
119
|
+
const lines = parsed.body.split('\n');
|
|
120
|
+
for (const line of lines) {
|
|
121
|
+
const trimmed = line.trim();
|
|
122
|
+
if (trimmed && !trimmed.startsWith('#') && !trimmed.startsWith('-') && !trimmed.startsWith('```')) {
|
|
123
|
+
description = trimmed.slice(0, 200);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Extract argument hints from command body
|
|
130
|
+
let argumentHint = '';
|
|
131
|
+
const argPatterns = parsed.body.match(/\$ARGUMENTS|\$\d+|\$[A-Z_]+/g);
|
|
132
|
+
if (argPatterns) {
|
|
133
|
+
const unique = [...new Set(argPatterns)];
|
|
134
|
+
argumentHint = unique.join(' ');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Convert AIWG placeholders to Codex format
|
|
138
|
+
// AIWG: $ARGUMENTS, $1, etc. -> Same in Codex
|
|
139
|
+
let body = parsed.body;
|
|
140
|
+
|
|
141
|
+
// Convert {{variable}} to $VARIABLE format
|
|
142
|
+
body = body.replace(/\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g, (_, name) => `$${name.toUpperCase()}`);
|
|
143
|
+
|
|
144
|
+
// Build Codex prompt
|
|
145
|
+
const promptName = prefix ? `${prefix}-${commandName}` : commandName;
|
|
146
|
+
|
|
147
|
+
let promptContent = '';
|
|
148
|
+
|
|
149
|
+
// Add frontmatter if we have description or argument-hint
|
|
150
|
+
if (description || argumentHint) {
|
|
151
|
+
promptContent = `---\n`;
|
|
152
|
+
if (description) promptContent += `description: ${description}\n`;
|
|
153
|
+
if (argumentHint) promptContent += `argument-hint: ${argumentHint}\n`;
|
|
154
|
+
promptContent += `---\n\n`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
promptContent += body;
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
name: promptName,
|
|
161
|
+
description,
|
|
162
|
+
argumentHint,
|
|
163
|
+
content: promptContent,
|
|
164
|
+
sourcePath: commandPath
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Deploy prompt to Codex prompts directory
|
|
170
|
+
*/
|
|
171
|
+
function deployPrompt(prompt, targetDir, opts) {
|
|
172
|
+
const { force = false, dryRun = false } = opts;
|
|
173
|
+
const destPath = path.join(targetDir, `${prompt.name}.md`);
|
|
174
|
+
|
|
175
|
+
// Check if prompt already exists
|
|
176
|
+
if (fs.existsSync(destPath)) {
|
|
177
|
+
const existingContent = fs.readFileSync(destPath, 'utf8');
|
|
178
|
+
if (existingContent === prompt.content && !force) {
|
|
179
|
+
console.log(` skip (unchanged): ${prompt.name}`);
|
|
180
|
+
return { action: 'skip', reason: 'unchanged' };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (dryRun) {
|
|
185
|
+
console.log(` [dry-run] deploy: ${prompt.name}`);
|
|
186
|
+
return { action: 'deploy', reason: 'dry-run' };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Write prompt file
|
|
190
|
+
fs.writeFileSync(destPath, prompt.content, 'utf8');
|
|
191
|
+
console.log(` deployed: ${prompt.name}.md`);
|
|
192
|
+
|
|
193
|
+
return { action: 'deploy', reason: 'success' };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Load addon manifest if it exists
|
|
198
|
+
*/
|
|
199
|
+
function loadAddonManifest(addonPath) {
|
|
200
|
+
const manifestPath = path.join(addonPath, 'manifest.json');
|
|
201
|
+
if (fs.existsSync(manifestPath)) {
|
|
202
|
+
try {
|
|
203
|
+
return JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
204
|
+
} catch (e) {
|
|
205
|
+
console.warn(` Warning: Could not parse manifest at ${manifestPath}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return {};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get command directories based on mode
|
|
213
|
+
* Returns objects with: dir, label, isCore (whether to deploy all commands)
|
|
214
|
+
*/
|
|
215
|
+
function getCommandDirectories(srcRoot, mode) {
|
|
216
|
+
const dirs = [];
|
|
217
|
+
|
|
218
|
+
// General commands (not core - apply priority filter)
|
|
219
|
+
if (mode === 'general' || mode === 'all') {
|
|
220
|
+
const generalCommandsDir = path.join(srcRoot, 'commands');
|
|
221
|
+
if (fs.existsSync(generalCommandsDir)) {
|
|
222
|
+
dirs.push({ dir: generalCommandsDir, label: 'general', isCore: false });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Addon commands (dynamically discovered)
|
|
227
|
+
// Check manifest for core/autoInstall flags
|
|
228
|
+
if (mode === 'general' || mode === 'sdlc' || mode === 'both' || mode === 'all') {
|
|
229
|
+
const addonsRoot = path.join(srcRoot, 'agentic', 'code', 'addons');
|
|
230
|
+
if (fs.existsSync(addonsRoot)) {
|
|
231
|
+
const addonEntries = fs.readdirSync(addonsRoot, { withFileTypes: true })
|
|
232
|
+
.filter(e => e.isDirectory());
|
|
233
|
+
|
|
234
|
+
for (const entry of addonEntries) {
|
|
235
|
+
const addonPath = path.join(addonsRoot, entry.name);
|
|
236
|
+
const addonCommandsDir = path.join(addonPath, 'commands');
|
|
237
|
+
|
|
238
|
+
if (fs.existsSync(addonCommandsDir)) {
|
|
239
|
+
const manifest = loadAddonManifest(addonPath);
|
|
240
|
+
// Core addons (core: true or autoInstall: true) deploy ALL commands
|
|
241
|
+
const isCore = manifest.core === true || manifest.autoInstall === true;
|
|
242
|
+
|
|
243
|
+
dirs.push({
|
|
244
|
+
dir: addonCommandsDir,
|
|
245
|
+
label: entry.name,
|
|
246
|
+
isCore
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Framework commands are discovered from framework manifests/directory structure.
|
|
254
|
+
const frameworks = getFrameworksForMode(srcRoot, mode);
|
|
255
|
+
for (const framework of frameworks) {
|
|
256
|
+
if (framework.components.commands.exists) {
|
|
257
|
+
dirs.push({
|
|
258
|
+
dir: framework.components.commands.path,
|
|
259
|
+
label: framework.id,
|
|
260
|
+
isCore: false
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return dirs;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
(async function main() {
|
|
269
|
+
const cfg = parseArgs();
|
|
270
|
+
const { source, target, mode, dryRun, force, prefix } = cfg;
|
|
271
|
+
|
|
272
|
+
// Resolve source directory
|
|
273
|
+
const scriptDir = path.dirname(new URL(import.meta.url).pathname);
|
|
274
|
+
const repoRoot = path.resolve(scriptDir, '..', '..');
|
|
275
|
+
const srcRoot = source || repoRoot;
|
|
276
|
+
|
|
277
|
+
console.log(`Deploying commands as Codex prompts (~/.codex/prompts/)`);
|
|
278
|
+
console.log(` Source: ${srcRoot}`);
|
|
279
|
+
console.log(` Target: ${target}`);
|
|
280
|
+
console.log(` Mode: ${mode}`);
|
|
281
|
+
console.log(` Prefix: ${prefix}`);
|
|
282
|
+
if (dryRun) console.log(` [DRY RUN]`);
|
|
283
|
+
console.log();
|
|
284
|
+
|
|
285
|
+
// Create target directory
|
|
286
|
+
if (!dryRun) {
|
|
287
|
+
ensureDir(target);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Collect skill names to detect command/skill collisions
|
|
291
|
+
const skillNames = new Set();
|
|
292
|
+
const addonSkills = getAddonSkillDirs(srcRoot);
|
|
293
|
+
for (const d of addonSkills) skillNames.add(path.basename(d));
|
|
294
|
+
const frameworkSkills = collectFrameworkArtifacts(srcRoot, mode, {
|
|
295
|
+
includeAgents: false, includeCommands: false, includeSkills: true, includeRules: false
|
|
296
|
+
});
|
|
297
|
+
for (const d of frameworkSkills.skills) skillNames.add(path.basename(d));
|
|
298
|
+
|
|
299
|
+
// Get command directories based on mode
|
|
300
|
+
const commandDirs = getCommandDirectories(srcRoot, mode);
|
|
301
|
+
let totalDeployed = 0;
|
|
302
|
+
let totalSkipped = 0;
|
|
303
|
+
|
|
304
|
+
for (const { dir, label } of commandDirs) {
|
|
305
|
+
const commandFiles = listCommandFiles(dir);
|
|
306
|
+
if (commandFiles.length === 0) continue;
|
|
307
|
+
|
|
308
|
+
console.log(`\n${label} (${commandFiles.length} prompts):`);
|
|
309
|
+
|
|
310
|
+
for (const commandFile of commandFiles) {
|
|
311
|
+
// Skip commands that collide with skills (skills take precedence)
|
|
312
|
+
const commandName = path.basename(commandFile, '.md');
|
|
313
|
+
if (skillNames.has(commandName)) {
|
|
314
|
+
console.log(` skip (skill precedence): command "${commandName}" — skill with same name takes precedence`);
|
|
315
|
+
totalSkipped++;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
const prompt = transformToCodexPrompt(commandFile, prefix);
|
|
320
|
+
const result = deployPrompt(prompt, target, { force, dryRun });
|
|
321
|
+
if (result.action === 'deploy') totalDeployed++;
|
|
322
|
+
else totalSkipped++;
|
|
323
|
+
} catch (err) {
|
|
324
|
+
console.log(` error: ${path.basename(commandFile)} - ${err.message}`);
|
|
325
|
+
totalSkipped++;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
console.log(`\nSummary: ${totalDeployed} deployed, ${totalSkipped} skipped`);
|
|
331
|
+
|
|
332
|
+
if (!dryRun && totalDeployed > 0) {
|
|
333
|
+
console.log(`\nRestart Codex to load new prompts.`);
|
|
334
|
+
console.log(`Use prompts with: /prompts:${prefix}-<command-name>`);
|
|
335
|
+
}
|
|
336
|
+
})();
|